/usr/local/jetapps/var/www/jetbackup5/docroot/app
(function () { 'use strict'; define('app',[ ], function () { var app = angular.module("JetBackupApp", [ "ngRoute", "ngAnimate", "ngSanitize", "ngMaterial", "ui.bootstrap", "permission", "permission.ng", "angular-loading-bar", "moment-picker", "chart.js", "jm.i18next" ]).run(["permissions", function(permissions) { permissions.init(window.PAGE.permissions); }]).config([ '$routeProvider', '$httpProvider', '$animateProvider', '$controllerProvider', '$compileProvider', '$filterProvider', '$permissionProvider', '$provide', 'cfpLoadingBarProvider', function ($routeProvider, $httpProvider, $animateProvider, $controllerProvider, $compileProvider, $filterProvider, $permissionProvider, $provide, cfpLoadingBarProvider) { $animateProvider.classNameFilter(/(action-module)/); $permissionProvider.suppressUndefinedPermissionWarning(true); cfpLoadingBarProvider.includeSpinner = false; cfpLoadingBarProvider.includeBar = true; cfpLoadingBarProvider.parentSelector = '#loading-bar-container'; $httpProvider.interceptors.push('responseObserver'); $httpProvider.defaults.ignoreLoadingBar = true; app.register = { controller: $controllerProvider.register, directive: $compileProvider.directive, filter: $filterProvider.register, factory: $provide.factory, service: $provide.service }; var template = window.PAGE.template; var path = window.PAGE.path.media + '/app/views'; var version = window.PAGE.info.version; var rootPermissions = { permissions: { only: 'isRoot', redirectTo: '/' } }; var allPermissions = { permissions: { except: ['isLicenseIssue', 'isDisableUI' ,'isAgreement', 'isDisasterRecovery', 'isAgreementPanel'], redirectTo: { isLicenseIssue: '/license', isDisableUI: '/disableui', isAgreement: '/agreement', isDisasterRecovery: '/disasterRecovery', isAgreementPanel: '/agreementPanel', } }}; if(template === 'reseller') { allPermissions.permissions.except.push('isShowcase'); allPermissions.permissions.redirectTo.isShowcase = '/showcase'; $routeProvider .when('/accounts', { templateUrl: path + "/accounts.htm?v=" + version, data: { permissions: { only: 'canManageAccounts', redirectTo: '/' } } }) .when('/accountsOrphans', { templateUrl: path + "/accountsOrphans.htm?v=" + version, data: { permissions: { only: ['canManageAccounts','isReseller'], redirectTo: '/' } } }) .when('/accountManage/:id', { templateUrl: path + "/accountManage.htm?v=" + version, data: { permissions: { only: 'canManageAccounts', redirectTo: '/' } } }) .when('/alerts', { templateUrl: path + "/alerts.htm?v=" + version, data: { permissions: { only: 'canViewAlerts', redirectTo: '/' } } }) .when('/queue', { templateUrl: path + "/queue.htm?v=" + version, data: { permissions: { only: 'canManageQueue', redirectTo: '/' } } }) .when('/destinations', { templateUrl: path + "/destinations.htm?v=" + version, data: { permissions: { only: 'canManageDestinations', redirectTo: '/' } } }) .when('/destinationManage/:id', { templateUrl: path + "/destinationManage.htm?v=" + version, data: { permissions: { only: 'canManageDestinations', redirectTo: '/' } } }) .when('/destinationManage', { templateUrl: path + "/destinationManage.htm?v=" + version, data: { permissions: { only: 'canManageDestinations', redirectTo: '/' } } }) .when("/restoreConditions", { templateUrl: path + "/restoreConditions.htm?v=" + version, data: { permissions: { only: 'isRoot', redirectTo: '/' } } }) .when("/restoreConditionManage", { templateUrl: path + "/restoreConditionManage.htm?v=" + version, data: { permissions: { only: 'isRoot', redirectTo: '/' } } }) .when("/restoreConditionManage/:id", { templateUrl: path + "/restoreConditionManage.htm?v=" + version, data: { permissions: { only: 'isRoot', redirectTo: '/' } } }) .when("/filePermissions", { templateUrl: path + "/filePermissions.htm?v=" + version, data: rootPermissions }) .when("/filePermissionsManage", { templateUrl: path + "/filePermissionsManage.htm?v=" + version, data: rootPermissions }) .when("/filePermissionsManage/:id", { templateUrl: path + "/filePermissionsManage.htm?v=" + version, data: rootPermissions }) .when("/queuePriorities", { templateUrl: path + "/queuePriorities.htm?v=" + version, data: rootPermissions }) .when("/queuePriorityManage", { templateUrl: path + "/queuePriorityManage.htm?v=" + version, data: rootPermissions }) .when("/queuePriorityManage/:id", { templateUrl: path + "/queuePriorityManage.htm?v=" + version, data: rootPermissions }) .when('/permissions', { templateUrl: path + "/permissions.htm?v=" + version, data: { permissions: { only: 'canManagePermissions', redirectTo: '/' } } }) .when('/backupJobs', { templateUrl: path + "/backupJobs.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) .when("/backupJobManage/:id", { templateUrl: path + "/backupJobManage.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) .when("/backupJobManage", { templateUrl: path + "/backupJobManage.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) .when('/cloneJobs', { templateUrl: path + "/cloneJobs.htm?v=" + version, data: { permissions: { only: 'canManageCloneJobs', redirectTo: '/' } } }) .when("/cloneJobManage/:id", { templateUrl: path + "/cloneJobManage.htm?v=" + version, data: { permissions: { only: 'canManageCloneJobs', redirectTo: '/' } } }) .when("/cloneJobManage", { templateUrl: path + "/cloneJobManage.htm?v=" + version, data: { permissions: { only: 'canManageCloneJobs', redirectTo: '/' } } }) .when('/settings', { templateUrl: path + "/settings.htm?v=" + version, data: rootPermissions }) .when('/settings/:section', { templateUrl: path + "/settings.htm?v=" + version, data: rootPermissions }) .when('/settings/notification/manage', { templateUrl: path + "/settings/notificationManage.htm?v=" + version, data: rootPermissions }) .when('/settings/notification/manage/:id', { templateUrl: path + "/settings/notificationManage.htm?v=" + version, data: rootPermissions }) .when('/security', { templateUrl: path + "/security.htm?v=" + version, data: rootPermissions }) .when('/extension', { templateUrl: path + "/extension.htm?v=" + version, data: { permissions: { only: 'isWPIntegration', redirectTo: '/' } } }) .when('/downloads', { templateUrl: path + "/downloads.htm?v=" + version, data: { permissions: { only: 'canDownloadBackups', redirectTo: '/' } } }) .when('/restore/singleaccount', { templateUrl: path + "/restore.htm?v=" + version, controller: 'accountBackups', resolve: { $uibModalInstance: function () { return {close:function(){}}; }, account: function() { return null; } }, data: { permissions: { only: 'canManageAccountBackups', redirectTo: '/' } } }) .when('/restore/:section', { templateUrl: path + "/restore.htm?v=" + version, data: { permissions: { only: 'canManageAccountBackups', redirectTo: '/' } } }) //.when('/restoreSingle', { templateUrl: path + "/restoreSingle.htm?v=" + version, controller: "accountBackups", resolve: { $uibModalInstance: function () { return {close:function(){}}; }, account: function() { return window.PAGE.account; } }, data: { permissions: { only: 'canManageAccountBackups', redirectTo: '/' } } }) .when('/hooks', { templateUrl: path + "/hooks.htm?v=" + version, data: { permissions: { only: 'canManageHooks', redirectTo: '/' } } }) .when("/hookManage", { templateUrl: path + "/hookManage.htm?v=" + version, data: { permissions: { only: 'canManageHooks', redirectTo: '/' } } }) .when("/hookManage/:id", { templateUrl: path + "/hookManage.htm?v=" + version, data: { permissions: { only: 'canManageHooks', redirectTo: '/' } } }) .when('/tags', { templateUrl: path + "/tags.htm?v=" + version, data: rootPermissions }) .when("/tagManage", { templateUrl: path + "/tagManage.htm?v=" + version, data: rootPermissions }) .when("/tagManage/:id", { templateUrl: path + "/tagManage.htm?v=" + version, data: rootPermissions }) .when('/plugins', { templateUrl: path + "/plugins.htm?v=" + version, data: rootPermissions }) .when('/plugins/:section', { templateUrl: path + "/plugins.htm?v=" + version, data: rootPermissions }) .when('/plugin/:plugin', { templateUrl: path + "/plugin.htm?v=" + version, data: allPermissions }) .when('/repositoryManage', { templateUrl: path + "/repositoryManage.htm?v=" + version, data: rootPermissions }) .when('/repositoryManage/:id', { templateUrl: path + "/repositoryManage.htm?v=" + version, data: rootPermissions }) .when('/logs', { templateUrl: path + "/logs.htm?v=" + version, data: { permissions: { only: 'canViewLogs', redirectTo: '/' } } }) .when('/fileManager/:type/:id', { templateUrl: path + "/fileManager.htm?v=" + version, data: { permissions: { only: ['canManageDestinations','canManageFileBackups'], redirectTo: '/' } } }) //.when("/accountFilterGroups", { templateUrl: path + "/accountFilterGroups.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) //.when("/accountFilterGroupManage", { templateUrl: path + "/accountFilterGroupManage.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) //.when("/accountFilterGroupManage/:id", { templateUrl: path + "/accountFilterGroupManage.htm?v=" + version, data: { permissions: { only: 'canManageBackupJobs', redirectTo: '/' } } }) .when('/accountFilters', { templateUrl: path + "/accountFilters.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/accountFilterManage', { templateUrl: path + "/accountFilterManage.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/accountFilterManage/:id', { templateUrl: path + "/accountFilterManage.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/schedules', { templateUrl: path + "/schedules.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/scheduleManage', { templateUrl: path + "/scheduleManage.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/scheduleManage/:id', { templateUrl: path + "/scheduleManage.htm?v=" + version, data: { permissions: { only: ['canManageBackupJobs','canManageCloneJobs'], redirectTo: '/' } } }) .when('/license', { templateUrl: path + "/license.htm?v=" + version, data: { permissions: { only: 'isLicenseIssue', redirectTo: '/' } } }) .when("/disasterRecovery", { templateUrl: path + "/disasterRecovery.htm?v=" + version, data: { permissions: { only: 'isDisasterRecovery', except: ['isDisableUI', 'isLicenseIssue', 'isAgreement'], redirectTo: '/' } } }) .when('/agreement', { templateUrl: path + "/agreement.htm?v=" + version, data: { permissions: { only: 'isAgreement', except: ['isDisableUI', 'isLicenseIssue'], redirectTo: '/' } } }) .when('/agreementPanel', { templateUrl: path + "/agreementPanel.htm?v=" + version, data: { permissions: { only: 'isAgreementPanel', except: ['isDisableUI', 'isLicenseIssue', 'isAgreement','isDisasterRecovery'], redirectTo: '/' } } }) .when('/disableui', { templateUrl: path + "/disableUI.htm?v=" + version, data: { permissions: { only: 'isDisableUI', except: ['isLicenseIssue'], redirectTo: '/' } } }) .when('/showcase', { templateUrl: path + "/showcase.htm?v=" + version, data: { permissions: { only: 'isShowcase', except: ['isLicenseIssue', 'isAgreement', 'isAgreementPanel', 'isDisasterRecovery'], redirectTo: '/' } } }) .when('/support', { templateUrl: path + "/support.htm?v=" + version, data: rootPermissions }) .when('/404', { templateUrl: path + "/404.htm?v=" + version }) .when('/myAccount', { templateUrl: path + "/myAccount.htm?v=" + version, data: allPermissions }) .when('/', { templateUrl: path + "/dashboard.htm?v=" + version, data: allPermissions }) .otherwise('/404'); } else { $routeProvider .when('/alerts', { templateUrl: path + "/alerts.htm?v=" + version, data: { permissions: { only: 'canViewAlerts', redirectTo: '/' } } }) .when('/queue', { templateUrl: path + "/queue.htm?v=" + version, data: { permissions: { only: 'canManageQueue', redirectTo: '/' } } }) .when('/downloads', { templateUrl: path + "/downloads.htm?v=" + version, data: { permissions: { only: 'canDownloadBackups', redirectTo: '/' } } }) .when('/restore/:type', { templateUrl: path + "_enduser/restore.htm?v=" + version, data: { permissions: { only: 'canManageAccountBackups', redirectTo: '/' } } }) .when('/disableui', { templateUrl: path + "/disableUI.htm?v=" + version, data: { permissions: { only: 'isDisableUI', except: ['isLicenseIssue'], redirectTo: '/' } } }) .when('/license', { templateUrl: path + "_enduser/rootActionRequired.htm?v=" + version, data: { permissions: { only: 'isLicenseIssue', redirectTo: '/' } } }) .when('/plugin/:plugin', { templateUrl: path + "/plugin.htm?v=" + version, data: allPermissions }) .when('/disasterRecovery', { templateUrl: path + "_enduser/rootActionRequired.htm?v=" + version, data: { permissions: { only: 'isDisasterRecovery', except: ['isDisableUI', 'isLicenseIssue', 'isAgreement'], redirectTo: '/' } } }) .when('/agreement', { templateUrl: path + "_enduser/rootActionRequired.htm?v=" + version, data: { permissions: { only: 'isAgreement', except: ['isDisableUI', 'isLicenseIssue'], redirectTo: '/' } } }) .when('/agreementPanel', { templateUrl: path + "/agreementPanel.htm?v=" + version, data: { permissions: { only: 'isAgreementPanel', except: ['isDisableUI', 'isLicenseIssue', 'isAgreement','isDisasterRecovery'], redirectTo: '/' } } }) .when('/404', { templateUrl: path + "/404.htm?v=" + version }) .when('/myAccount', { templateUrl: path + "/myAccount.htm?v=" + version, data: allPermissions }) .when('/', { templateUrl: path + "_enduser/dashboard.htm?v=" + version, data: allPermissions }) .otherwise('/404'); } } ]).controller("JetBackup", ["$rootScope", "$scope", "$location", "$route", "$timeout", "lang", "permissions", "consts", "util", "api", "alert", "$uibModalStack", function($rootScope, $scope, $location, $route, $timeout, lang, permissions, consts, util, api, alert, $uibModalStack) { $rootScope.util = util; $rootScope.const = consts; $rootScope.perm = permissions; $rootScope.lang = lang; $rootScope.path = window.PAGE.path; $rootScope.template = window.PAGE.template; $rootScope.primaryURL = $rootScope.path.location + window.location.search + '#!'; $rootScope.loggedAccount = window.PAGE.account; $rootScope.license = window.PAGE.license; $rootScope.plugins = window.PAGE.plugins; $rootScope.avx_enabled = window.PAGE.avxenabled; $rootScope.logoutURL = window.PAGE.logout_url !== undefined ? window.PAGE.logout_url : ''; $rootScope.reloadPage = function () { window.location.reload(); }; app.registerPluginController = function(plugin, callback) { app.registerController( plugin.type + plugin.code, 'plugins/' + plugin.type + '/' + plugin.code, callback ); }; app.registerShowcaseController = function(showcase, callback) { app.registerController( showcase.feature + showcase.order, 'showcase/' + showcase.order + "_" + showcase.feature, callback ); }; app.registerController = function(controllerName, controllerPath, callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; var controllerFile = controllerPath + '/controller'; require.undef(controllerFile); require([controllerFile], function () { var queue = app._invokeQueue; for(var i = 0; i < queue.length; i++) { var controller = queue[i]; var pattern = new RegExp("^" + controllerName + "($|_)"); if(controller[0] !== '$controllerProvider' || controller[1] !== 'register' || !pattern.test(controller[2][0])) continue; app.register.controller(controller[2][0], controller[2][1]); } $timeout(callback($scope.path.media + '/app/' + controllerPath, controllerName)); }); }; $rootScope.includePath = function(file, views) { if(!file) return ''; if(!views) views = 'views'; return $rootScope.path.media + '/app/' + views + '/' + file + '.htm?v=' + $rootScope.info.version; }; $rootScope.downloadURL = function (args) { var sep = /\?/.test($scope.path.download) ? '&' : '?'; return $scope.path.download + sep + args; }; $rootScope.changeView = function(view) { $uibModalStack.dismissAll(); $location.path(view); }; $rootScope.info = window.PAGE.info; $rootScope.info.currentYear = new Date().getUTCFullYear(); $rootScope.menuItem = 'Dashboard'; $rootScope.$on('menuItem', function(event, item) { $rootScope.menuItem = item; }); $rootScope.menuExpanded = !!parseInt(localStorage.getItem('menuExpanded')); $scope.toggleMenu = function() { $rootScope.menuExpanded = !$rootScope.menuExpanded; localStorage.setItem('menuExpanded', $scope.menuExpanded ? 1 : 0); }; $rootScope.expandedRow = {}; $rootScope.openActions = function(row, group) { if(group === undefined) group = 'general'; $rootScope.expandedRow[group] = ($rootScope.expandedRow[group] !== undefined && $rootScope.expandedRow[group] === row) ? undefined : row; }; $rootScope.isOpenedActions = function(row, group) { if(group === undefined) group = 'general'; return $rootScope.expandedRow[group] === row; }; $rootScope.$on('$routeChangeStart', function() { lang.initNS('dashboard'); }); $rootScope.processStatus = true; $rootScope.processSyncAccountsStatus = true; $rootScope.inRescueMode = true; $rootScope.canDeleteSnapshots = false; $scope.checkProcess = function () { api.getProcessStatus({ withLoader: false, success: function(data) { $rootScope.processStatus = !!data.status; $rootScope.processSyncAccountsStatus = !data.sync_accounts; $rootScope.inRescueMode = !!data.rescue; $rootScope.canDeleteSnapshots = !!data.delete_snapshots; // if service is up check every 30 sec, if down every 5 sec setTimeout($scope.checkProcess, $rootScope.processStatus && $rootScope.processSyncAccountsStatus ? 30000 : 2000); }, failed: function (message) { alert.error(message); } }); }; $scope.checkProcess(); } ] ).factory('responseObserver', ["$q", "storage", function responseObserver($q, storage) { return { responseError: function(errorResponse) { var apiConfig = storage.create('api'); // On valid response - reset the counter if(errorResponse.status < 300) { apiConfig.set('failedCounter', 0); apiConfig.save(); } // On invalid response - count for 5 seconds and then reload the page else { var now = (new Date()).getTime(); var failedCounter = apiConfig.get('failedCounter', 0); if(failedCounter == 0) failedCounter = now; if((now - failedCounter) >= 10000) { apiConfig.set('failedCounter', 0); apiConfig.save(); location.reload(); } else { apiConfig.set('failedCounter', failedCounter); apiConfig.save(); } } return $q.reject(errorResponse); } }; }]); return app; }); define('controllers/404',['app'], function(app) { app.controller("404", ["$rootScope", "$scope", "cfpLoadingBar", function ($rootScope, $scope, cfpLoadingBar) { cfpLoadingBar.complete(); } ] ); }); define('controllers/myAccount',['app'], function(app) { app.controller("myAccount", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "$q", "api", "meta", "lang", "filter", "util", "consts", "confirm", "alert", function ($rootScope, $scope, $location, $timeout, $interval, $q, api, meta, lang, filter, util, consts, confirm, alert) { $rootScope.$emit('menuItem', 'Accounts'); $scope.info = {}; $scope.details = { email: '', backup_type: 0, encryption_key: 0, privacy: 0 }; $scope.saveData = util.duplicateObject($scope.details); $scope.encryptionKey = ''; $scope.currentEncryptionKey = ''; $scope.saveing = false; $scope.changed = false; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.requireEncryptionKey = function() { return ($scope.details.backup_type == 1 && $scope.details.encryption_key_type == 1 && ($scope.saveData.backup_type != 1 || $scope.saveData.encryption_key_type != 1)); }; $scope.resetEncryptionKey = function() { confirm.open({ message: lang.t("Once you reset the account encryption key, ALL BACKUPS becomes inaccessible and will be deleted."), confirmLabel: lang.t("Delete Encryption Key"), confirm: function () { api.resetEncryptionKey({ data: { _id: $scope.details._id }, success: function (data, message) { $scope.details.secret_key = false; alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.saveChanges = function() { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); if($scope.currentEncryptionKey) apiParams.encryption_key = $scope.currentEncryptionKey; $scope.encryptionKey = ''; $scope.currentEncryptionKey = ''; api.manageMyAccount({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.details = util.duplicateObject($scope.saveData); if(data.encryption_key !== undefined) $scope.encryptionKey = data.encryption_key; alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; $scope.fetchAccountData = function() { api.getMyAccount({ success: function(data) { $scope.info = data.info; delete data.info; $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; $timeout(function () { $scope.fetchAccountData(); }); } ] ); }); define('controllers/agreement',['app'], function(app) { app.controller("agreement", ["$rootScope", "$scope", "$location", "api", "alert", "lang", "permissions", function ($rootScope, $scope, $location, api, alert, lang, permissions) { $scope.currYear = new Date().getYear() + 1900; $scope.setAgree = function () { api.approveAgreement({ success: function() { window.PAGE.system.agreement = false; permissions.init(window.PAGE.permissions); $location.path('/'); }, failed: function (message) { alert.error(message); } }); } } ] ); }); define('controllers/agreementPanel',['app'], function(app) { app.controller("agreementPanel", ["$rootScope", "$scope", "$location", "api", "alert", "lang", "permissions", function ($rootScope, $scope, $location, api, alert, lang, permissions) { $scope.details = {}; $scope.approve = { user_agreement: 0, privacy_policy: 0 }; $scope.togglePrivacyPolicy = function() { $scope.approve.privacy_policy = $scope.approve.privacy_policy == 0 ? 1 : 0; }; $scope.toggleUserAgreement = function() { $scope.approve.user_agreement = $scope.approve.user_agreement == 0 ? 1 : 0; }; $scope.currYear = new Date().getYear() + 1900; $scope.continueToPanel = function () { if($scope.approve.user_agreement == 0 || $scope.approve.privacy_policy == 0) { alert.error(lang.t("You must accept User Agreement and Privacy Policy in order to continue to panel")); return; } api.manageMyAccount({ data: { terms: 1 }, success: function() { window.PAGE.system.agreement_panel = false; permissions.init(window.PAGE.permissions); $location.path('/'); }, failed: function (message) { alert.error(message); } }); }; api.getMyAccount({ success: function(data) { $scope.details = data.info; } }); } ] ); }); define('controllers/dashboard',[ 'app', ], function(app) { app.controller("dashboard", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", function($rootScope, $scope, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert) { $rootScope.$emit('menuItem', 'Dashboard'); $scope.stats = { alerts: 0, accounts: 0, backup_jobs: 0, clone_jobs: 0, backups: 0, over_quota: 0, backup_jobs_running: 0, clone_jobs_running: 0 }; $scope.loadingStatistics = true; $scope.loadingDestinations = false; $scope.loadingBackups = false; $scope.loadingClones = false; $scope.loadingQueues = false; $scope.loadingAlerts = false; $scope.destroyed = false; $scope.lockDestinations = false; $scope.lockBackups = false; $scope.lockClones = false; $scope.queue_summary = {}; $scope.alerts = []; $scope.destinations = []; $scope.backups = []; $scope.clones = []; $scope.queues = []; $scope.reloadTimeout = undefined; $scope.destinationMeta = meta.new("dashboard_destinations"); $scope.destinationMetaData = $scope.destinationMeta.getData(); $scope.destinationMeta.setSortBy("jobs_count"); $scope.destinationMeta.setSortDirection("asc"); $scope.destinationMeta.setTotalItems($scope.destinations.length); $scope.destinationMeta.setPageSizes([5,10,25]); $scope.destinationMeta.setPageSize(5); $scope.destinationMeta.setLimit(5); $scope.destinationMeta.setMaxPages(1); $scope.backupMeta = meta.new("dashboard_backups"); $scope.backupMetaData = $scope.backupMeta.getData(); $scope.backupMeta.setSortBy("next_run"); $scope.backupMeta.setSortDirection("asc"); $scope.backupMeta.setTotalItems($scope.backups.length); $scope.backupMeta.setPageSizes([5,10,25]); $scope.backupMeta.setPageSize(5); $scope.backupMeta.setLimit(5); $scope.backupMeta.setMaxPages(1); $scope.cloneMeta = meta.new("dashboard_clones"); $scope.cloneMetaData = $scope.cloneMeta.getData(); $scope.cloneMeta.setSortBy("next_run"); $scope.cloneMeta.setSortDirection("asc"); $scope.cloneMeta.setTotalItems($scope.clones.length); $scope.cloneMeta.setPageSizes([5,10,25]); $scope.cloneMeta.setPageSize(5); $scope.cloneMeta.setLimit(5); $scope.cloneMeta.setMaxPages(1); $scope.queueMeta = meta.new("dashboard_queues"); $scope.queueMetaData = $scope.queueMeta.getData(); $scope.queueMeta.setSortBy("created"); $scope.queueMeta.setSortDirection("desc"); $scope.queueMeta.setTotalItems($scope.queues.length); $scope.queueMeta.setPageSizes([5,10,25]); $scope.queueMeta.setPageSize(5); $scope.queueMeta.setLimit(5); $scope.fetchData = function(callback) { if(callback === undefined | typeof callback !== 'function') callback = function() {}; api.getDashboardDetails({ success: function(data, message) { $scope.stats.alerts = data.statistics.total_new_alerts; $scope.stats.accounts = data.statistics.total_accounts; $scope.stats.backup_jobs = data.statistics.total_backup_jobs; $scope.stats.clone_jobs = data.statistics.total_clone_jobs; $scope.stats.backups = data.statistics.total_backups; $scope.stats.disk_usage = data.statistics.total_disk_usage; $scope.stats.backup_jobs_running = data.statistics.total_backup_jobs_running; $scope.stats.clone_jobs_running = data.statistics.total_clone_jobs_running; $scope.alerts = data.alerts.alerts; $scope.queue_summary = data.queue_summary; $scope.destinationMeta.setTotalItems(data.destinations.total); $scope.destinationMeta.calculate(data.destinations.destinations); $scope.destinations = data.destinations.destinations; $scope.backupMeta.setTotalItems(data.backup_jobs.total); $scope.backupMeta.calculate(data.backup_jobs.jobs); $scope.backups = data.backup_jobs.jobs; for(var i = 0; i < $scope.backups.length; i++) { var names = []; var contains = parseInt($scope.backups[i].contains); if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else if($scope.backups[i].type == consts.BACKUP_TYPE_DIRECTORY) names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } $scope.backups[i].contains_name = names.join(', '); } $scope.cloneMeta.setTotalItems(data.clone_jobs.total); $scope.cloneMeta.calculate(data.clone_jobs.jobs); $scope.clones = data.clone_jobs.jobs; for(var i = 0; i < $scope.clones.length; i++) { var names = []; var contains = parseInt($scope.clones[i].contains); if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else if($scope.clones[i].type == consts.BACKUP_TYPE_DIRECTORY) names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } $scope.clones[i].contains_name = names.join(', '); } $scope.queueMeta.setTotalItems(data.queue.total); $scope.queueMeta.calculate(data.queue.groups); $scope.queues = []; for(var i = 0; i < data.queue.groups.length; i++) { var group = data.queue.groups[i]; if(parseInt(group.items_completed) <= 0 || parseInt(group.items) <= 0) group.items_progress_percentage = 0 else group.items_progress_percentage = parseInt((parseInt(group.items_completed) / parseInt(group.items)) * 100); $scope.queues.push(group); } callback(); }, failed: function (message) { alert.error(message); callback(); } }); }; /* $scope.interval = $interval(function () { $scope.fetchData(); }, 10000); $scope.$on("$destroy", function() { if ($scope.interval === undefined) return; $interval.cancel($scope.interval); $scope.interval = undefined; }); */ $scope.$on('fetch', fetch); function fetch() { $scope.loadingStatistics = true; $scope.fetchData(function() { $scope.loadingStatistics = false; }); } $scope.reloadData = function() { api.getDashboardDetails({ withLoader: false, success: function(data) { $scope.stats.alerts = data.statistics.total_new_alerts; $scope.stats.accounts = data.statistics.total_accounts; $scope.stats.jobs = data.statistics.total_backup_jobs; $scope.stats.backups = data.statistics.total_backups; $scope.stats.disk_usage = data.statistics.total_disk_usage; $scope.stats.jobs_running = data.statistics.total_backup_jobs_running; $scope.alerts = data.alerts.alerts; $scope.queue_summary = data.queue_summary; $scope.listDestinations(false, function () { $scope.listBackupJobs(false, function () { $scope.listQueueItems(false, function () { if($scope.destroyed) return; $scope.reloadTimeout = setTimeout($scope.reloadData, 5000); }); }); }); } }); }; $scope.reloadTimeout = setTimeout($scope.reloadData, 5000); $scope.toggleDestinationStatus = function(destination) { if($scope.lockDestinations) return; api.manageDestination({ data: { action: 'modify', _id: destination._id, disabled: !destination.disabled }, success: function(data) { destination.disabled = data.disabled; }, failed: function (message) { alert.error(message); } }); }; $scope.toggleBackupJobStatus = function(job) { if($scope.lockBackups) return; api.manageBackupJob({ data: { action: 'modify', _id: job._id, disabled: !job.disabled }, success: function(data) { job.disabled = data.disabled; }, failed: function (message) { alert.error(message); } }); }; $scope.toggleCloneJobStatus = function(job) { if($scope.lockClones) return; api.manageCloneJob({ data: { action: 'modify', _id: job._id, disabled: !job.disabled }, success: function(data) { job.disabled = data.disabled; }, failed: function (message) { alert.error(message); } }); }; $scope.listDestinations = function(loading, callback) { if(loading === undefined) loading = true; if(callback === undefined || typeof callback != 'function') callback = function(){}; if(!loading) { $scope.loadingDestinations = false; $scope.lockDestinations = true; } else { $scope.destinations = []; $scope.loadingDestinations = true; } var sort = {}; sort[$scope.destinationMeta.getSortBy()] = $scope.destinationMeta.getSortDirectionInt(); api.listDestinations({ withLoader: loading, data: { sort: sort, skip: $scope.destinationMeta.getSkip(), limit: $scope.destinationMeta.getPageSize() }, success: function(data) { callback(); setTimeout(function () { $scope.lockDestinations = false; }, 300); $scope.destinationMeta.setTotalItems(data.total); $scope.destinationMeta.calculate(data.destinations); $scope.destinations = data.destinations; $scope.loadingDestinations = false; }, failed: function () { callback(); setTimeout(function () { $scope.lockDestinations = false; }, 300); $scope.loadingDestinations = false; } }); }; $scope.listBackupJobs = function(loading, callback) { if(callback === undefined || typeof callback != 'function') callback = function(){}; if(loading !== undefined && !loading) { $scope.loadingBackups = false; $scope.lockBackups = true; } else { $scope.backups = []; $scope.loadingBackups = true; } var sort = {}; sort[$scope.backupMeta.getSortBy()] = $scope.backupMeta.getSortDirectionInt(); api.listBackupJobs({ withLoader: loading, data: { sort: sort, skip: $scope.backupMeta.getSkip(), limit: $scope.backupMeta.getPageSize() }, success: function(data) { callback(); setTimeout(function () { $scope.lockBackups = false; }, 300); $scope.loadingBackups = false; $scope.backupMeta.setTotalItems(data.total); $scope.backupMeta.calculate(data.jobs); $scope.backups = data.jobs; for(var i = 0; i < $scope.backups.length; i++) { var names = []; var contains = parseInt($scope.backups[i].contains); if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else if($scope.backups[i].type == consts.BACKUP_TYPE_DIRECTORY) names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } $scope.backups[i].contains_name = names.join(', '); } }, failed: function () { callback(); setTimeout(function () { $scope.lockBackups = false; }, 300); $scope.loadingBackups = false; } }); }; $scope.listCloneJobs = function(loading, callback) { if(callback === undefined || typeof callback != 'function') callback = function(){}; if(loading !== undefined && !loading) { $scope.loadingClones = false; $scope.lockClones = true; } else { $scope.clones = []; $scope.loadingClones = true; } var sort = {}; sort[$scope.cloneMeta.getSortBy()] = $scope.cloneMeta.getSortDirectionInt(); api.listCloneJobs({ withLoader: loading, data: { sort: sort, skip: $scope.cloneMeta.getSkip(), limit: $scope.cloneMeta.getPageSize() }, success: function(data) { callback(); setTimeout(function () { $scope.lockClones = false; }, 300); $scope.loadingClones = false; $scope.cloneMeta.setTotalItems(data.total); $scope.cloneMeta.calculate(data.jobs); $scope.clones = data.jobs; for(var i = 0; i < $scope.clones.length; i++) { var names = []; var contains = parseInt($scope.clones[i].contains); if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else if($scope.clones[i].type == consts.BACKUP_TYPE_DIRECTORY) names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } $scope.clones[i].contains_name = names.join(', '); } }, failed: function () { callback(); setTimeout(function () { $scope.lockClones = false; }, 300); $scope.loadingClones = false; } }); }; $scope.listQueueItems = function(loading, callback) { if(callback === undefined || typeof callback != 'function') callback = function(){}; if(loading !== undefined && !loading) $scope.loadingQueues = false; else { $scope.queues = []; $scope.loadingQueues = true; } var sort = {}; sort[$scope.queueMeta.getSortBy()] = $scope.queueMeta.getSortDirectionInt(); var type = consts.QUEUE_ITEM_TYPE_BACKUP | consts.QUEUE_ITEM_TYPE_CLONE | consts.QUEUE_ITEM_TYPE_REINDEX; if(permissions.canRestoreBackups) type |= consts.QUEUE_ITEM_TYPE_RESTORE; if(permissions.canDownloadBackups) type |= consts.QUEUE_ITEM_TYPE_DOWNLOAD; if(permissions.isRoot) type |= (consts.QUEUE_ITEM_TYPE_SECURITY | consts.QUEUE_ITEM_TYPE_INTEGRITY_CHECK | consts.QUEUE_ITEM_TYPE_SNAPSHOT_DELETE | consts.QUEUE_ITEM_TYPE_EXTENSION_INSTALLATION | consts.QUEUE_ITEM_TYPE_EXTENSION_QUEUE); api.listQueueGroups({ withLoader: loading, data: { sort: sort, skip: $scope.queueMeta.getSkip(), limit: $scope.queueMeta.getPageSize(), type: type }, success: function(data) { callback(); $scope.loadingQueues = false; $scope.queueMeta.setTotalItems(data.total); $scope.queueMeta.calculate(data.groups); $scope.queues = []; for(var i = 0; i < data.groups.length; i++) { var group = data.groups[i]; if(parseInt(group.items_completed) <= 0 || parseInt(group.items) <= 0) group.items_progress_percentage = 0 else group.items_progress_percentage = parseInt((parseInt(group.items_completed) / parseInt(group.items)) * 100); $scope.queues.push(group); } }, failed: function () { callback(); $scope.loadingQueues = false; } }); }; $scope.$on("$destroy", function() { $scope.destroyed = true; if ($scope.reloadTimeout === undefined) return; clearTimeout($scope.reloadTimeout); $scope.reloadTimeout = undefined; }); $timeout(fetch); } ] ); }); define('controllers/alerts',['app'], function(app) { app.controller("alerts", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "consts", "lang", "confirm", "alert", function ($rootScope, $scope, $location, $timeout, api, meta, consts, lang, confirm, alert) { $rootScope.$emit('menuItem', 'Alerts'); $scope.alerts = []; $scope.loadingAlerts = false; $scope.saveing = false; $scope.filter = 0; $scope.filterOptions = [ { label: lang.t('All Alerts'), value: 0 }, { label: lang.t('Information Alerts'), value: consts.ALERT_LEVEL_INFO }, { label: lang.t('Warning Alerts'), value: consts.ALERT_LEVEL_WARNING }, { label: lang.t('Critical Alerts'), value: consts.ALERT_LEVEL_CRITICAL } ]; meta = meta.new("alerts"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["created","message","owner","level"]); meta.setTotalItems($scope.alerts.length); $scope.clearAlerts = function () { if($scope.saveing) return; $scope.saveing = true; confirm.open({ message: lang.t("All alerts will be deleted and no future notifications will be sent"), confirm: function () { api.clearAlerts({ success: function(data, message) { $scope.saveing = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.fetch = function() { $scope.loadingAlerts = true; var find = {}; if(parseInt($scope.filter) > 0) find.level = parseInt($scope.filter); var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: find, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.alerts = []; api.listAlerts({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.alerts); $scope.alerts = data.alerts; $scope.loadingAlerts = false; } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/accounts',['app'], function(app) { app.controller("accounts", ["$rootScope", "$scope", "$location", "$timeout", "api", "lang", "meta", "confirm", "alert", "consts", "util", "permissions", "popup", function ($rootScope, $scope, $location, $timeout, api, lang, meta, confirm, alert, consts, util, permissions, popup) { $rootScope.$emit('menuItem', 'Accounts'); $scope.accounts = []; $scope.tags = {}; $scope.loadingAccounts = false; $scope.deleteTag = false; $scope.filter = ''; if(permissions.isRoot) { $scope.filterOptions = [ {label: lang.t("No Tags Filter"), value: ""}, {label: lang.t("Without Any Tags"), value: "none"} ]; } else { $scope.filterOptions = []; } $scope.loaders = { quota: false, snapshot: false }; var metaAcct = meta.new("accounts"); $scope.meta = metaAcct; $scope.metaData = metaAcct.getData(); metaAcct.setSortReverse(false); if(!metaAcct.getSortBy()) metaAcct.setSortBy("username"); if(!metaAcct.getSortDirection()) metaAcct.setSortDirection("asc"); metaAcct.setSortFields(["username", "owner"]); metaAcct.setTotalItems($scope.accounts.length); $scope.manageTags = function(account) { popup.open({ template: 'tagsSelection', resolve: { tags: function() { return account.tags; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }).result.then(function(selected) { account.deletetags = true; api.manageAccount({ data: { _id: account._id, tags: selected }, success: function () { account.deletetags = false; account.tags = selected; }, failed: function (message) { account.deletetags = false; alert.error(message); } }); }, function () {}); }; $scope.removeTag = function(account, index) { if($scope.deleteTag) return; $scope.deleteTag = true; confirm.open({ message: lang.t("This tag will be removed from this account"), confirm: function () { account.deletetags = true; var tags = util.duplicateObject(account.tags); tags.splice(index, 1); api.manageAccount({ data: { _id: account._id, tags: tags }, success: function () { $scope.deleteTag = false; account.deletetags = false; account.tags.splice(index, 1); }, failed: function (message) { $scope.deleteTag = false; account.deletetags = false; alert.error(message); } }); }, cancel: function () { $scope.deleteTag = false; } }); }; $scope.reassign = function (account) { popup.open({ size: "lg", template: 'accountReassign', resolve: { account_details: function() { return account; } } }).result.then(function(refresh) { if(refresh) $scope.fetch(); }, function(){ $scope.fetch(); }); }; $scope.createSnapshot = function(account) { if($scope.loaders.snapshot) return; $scope.loaders.snapshot = true; confirm.open({ message: lang.t("Are you sure you want to create backup on demand for this account?"), confirm: function () { api.createBackupOnDemand({ data: { account_id: account._id }, success: function(data, message) { $scope.loaders.snapshot = false; alert.success(message); }, failed: function(message) { $scope.loaders.snapshot = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.snapshot = false; } }); }; $scope.viewBackups = function (account) { popup.open({ size: "xl", template: 'accountBackups', resolve: { account: function() { return account; } } }).result.then(function(refresh) { if(refresh) $scope.fetch(); }, function(){}); }; $scope.viewDownloads = function (account) { popup.open({ size: "xl", template: 'accountDownloads', resolve: { account: function() { return account; } } }).result.then(function() {}, function(){}); }; $scope.fetch = function() { $scope.loadingAccounts = true; var apiParams = { sort: {}, skip: metaAcct.getSkip(), limit: metaAcct.getPageSize(), find: {}, filter: metaAcct.getFilter() }; apiParams.sort[metaAcct.getSortBy()] = metaAcct.getSortDirectionInt(); if($scope.filter) apiParams.find.tags = $scope.filter; $scope.accounts = []; api.listAccounts({ data: apiParams, success: function(data) { metaAcct.setTotalItems(data.total); metaAcct.calculate(data.accounts); $scope.accounts = data.accounts; $scope.loadingAccounts = false; } }); }; if(permissions.isRoot) { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) { $scope.filterOptions.push({label: data.tags[i].name, value: data.tags[i]._id}); $scope.tags[data.tags[i]._id] = data.tags[i]; } $timeout($scope.fetch); } }); } else { $timeout($scope.fetch); } }]); }); define('controllers/accountsOrphans',['app'], function(app) { app.controller("accountsOrphans", ["$rootScope", "$scope", "$location", "$timeout", "api", "lang", "meta", "popup", "permissions", "consts", function ($rootScope, $scope, $location, $timeout, api, lang, meta, popup, permissions, consts) { $rootScope.$emit('menuItem', 'Accounts'); $scope.accounts = []; $scope.tags = {}; $scope.loadingAccounts = false; $scope.deleteTag = false; $scope.filter = ''; if(permissions.isRoot) { $scope.filterOptions = [ {label: lang.t("No Tags Filter"), value: ""}, {label: lang.t("Without Any Tags"), value: "none"} ]; } else { $scope.filterOptions = []; } $scope.loaders = { quota: false, }; var metaAcct = meta.new("accountsOrphans"); $scope.meta = metaAcct; $scope.metaData = metaAcct.getData(); metaAcct.setSortReverse(false); if(!metaAcct.getSortBy()) metaAcct.setSortBy("username"); if(!metaAcct.getSortDirection()) metaAcct.setSortDirection("asc"); metaAcct.setSortFields(["username", "owner"]); metaAcct.setTotalItems($scope.accounts.length); $scope.manageTags = function(account) { popup.open({ template: 'tagsSelection', resolve: { tags: function() { return account.tags; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }).result.then(function(selected) { account.deletetags = true; api.manageAccount({ data: { _id: account._id, tags: selected }, success: function () { account.deletetags = false; account.tags = selected; }, failed: function (message) { account.deletetags = false; alert.error(message); } }); }, function () {}); }; $scope.removeTag = function(account, index) { if($scope.deleteTag) return; $scope.deleteTag = true; confirm.open({ message: lang.t("This tag will be removed from this account"), confirm: function () { account.deletetags = true; var tags = util.duplicateObject(account.tags); tags.splice(index, 1); api.manageAccount({ data: { _id: account._id, tags: tags }, success: function () { $scope.deleteTag = false; account.deletetags = false; account.tags.splice(index, 1); }, failed: function (message) { $scope.deleteTag = false; account.deletetags = false; alert.error(message); } }); }, cancel: function () { $scope.deleteTag = false; } }); }; $scope.viewBackups = function (account) { popup.open({ size: "xl", template: 'accountBackups', resolve: { account: function() { return account; } } }).result.then(function(refresh) { if(refresh) $scope.fetch(); }, function(){}); }; $scope.viewDownloads = function (account) { popup.open({ size: "xl", template: 'accountDownloads', resolve: { account: function() { return account; } } }).result.then(function() {}, function(){}); }; $scope.fetch = function() { $scope.loadingAccounts = true; var apiParams = { sort: {}, skip: metaAcct.getSkip(), limit: metaAcct.getPageSize(), find: {}, filter: metaAcct.getFilter() }; apiParams.sort[metaAcct.getSortBy()] = metaAcct.getSortDirectionInt(); if($scope.filter) apiParams.find.tags = $scope.filter; apiParams.orphan = 1; $scope.accounts = []; api.listAccounts({ data: apiParams, success: function(data) { metaAcct.setTotalItems(data.total); metaAcct.calculate(data.accounts); $scope.accounts = data.accounts; $scope.loadingAccounts = false; } }); }; if(permissions.isRoot) { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) { $scope.filterOptions.push({label: data.tags[i].name, value: data.tags[i]._id}); $scope.tags[data.tags[i]._id] = data.tags[i]; } $timeout($scope.fetch); } }); } else { $timeout($scope.fetch); } }]); }); define('controllers/accountManage',['app'], function(app) { app.controller("accountManage", ["$rootScope", "$scope", "$routeParams", "$q", "$location", "$timeout", "api", "meta", "util", "lang", "confirm", "alert", "consts", "popup", function ($rootScope, $scope, $routeParams, $q, $location, $timeout, api, meta, util, lang, confirm, alert, consts, popup) { $rootScope.$emit('menuItem', 'Accounts'); if(!$routeParams.id) $location.path("/"); $scope.tags = {}; $scope.details = { email: '', max_snapshots: '', queue_priority: '' }; $scope.saveData = util.duplicateObject($scope.details); $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.queuePriorities = [ { _id: '', name: lang.t('Default') } ]; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.searchTags = function(query) { if(!query) return []; var deferred = $q.defer(); api.listTags({ data: { filter: query, sort: { name: 1 }, find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function(data) { var results = []; for(var i = 0; i < data.tags.length; i++) { var tag = data.tags[i]; if($scope.saveData.tags.indexOf(tag._id) >= 0) continue; results.push(tag); } deferred.resolve( results ); } }); return deferred.promise; }; $scope.selectItem = function(item, obj) { if(item === undefined) return; $scope.saveData.tags.push(item._id); obj.searchItemText = ''; }; $scope.manageTags = function() { popup.open({ template: 'tagsSelection', scope: $scope, resolve: { tags: function() { return $scope.saveData.tags; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }).result.then(function(selected) { $scope.saveData.tags = selected; }, function () {}); }; $scope.resetEncryptionKey = function() { confirm.open({ message: lang.t("Once you reset the account encryption key, ALL BACKUPS becomes inaccessible and will be deleted."), confirmLabel: lang.t("Delete Encryption Key"), confirm: function () { api.resetEncryptionKey({ data: { username: $scope.details.username }, success: function (data, message) { $scope.details.secret_key = false; alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.manageExcludes = function () { popup.open({ size: "lg", template: 'accountExcludeListSelection', resolve: { account: function() { return $scope.details; } } }).result.then(function() {}, function(){}); }; $scope.fetchQueuePriorities = function() { api.listQueuePriorities({ success: function (data) { var priorities = data.priorities; for(var i=0; i< priorities.length; i++ ){ $scope.queuePriorities.push(priorities[i]); } }, failed: function (message) { alert.error(message); } }); }; $scope.cancel = function() { $scope.cancelled = true; $location.path('/accounts'); }; $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); api.manageAccount({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.details.email = $scope.saveData.email; $scope.details.max_snapshots = $scope.saveData.max_snapshots; //$location.path('/accountManage/' + $scope.details._id); if(!apply) $location.path('/accounts'); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; $scope.fetchAccountData = function(id) { api.getAccount({ data: { _id: id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; $scope.fetchTags = function() { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) $scope.tags[data.tags[i]._id] = data.tags[i]; } }); }; $timeout(function () { $scope.fetchTags(); $scope.fetchQueuePriorities(); $scope.fetchAccountData($routeParams.id); }); } ] ); }); define('controllers/accountReassign',['app'], function(app) { app.controller("accountReassign", ["$uibModalInstance", "$scope", "$location", "$timeout", "api", "meta", "util", "lang", "confirm", "alert", "account_details", function ($uibModalInstance, $scope, $location, $timeout, api, meta, util, lang, confirm, alert, account_details) { $scope.saveing = false; $scope.account = account_details; $scope.accounts = []; $scope.loadingAccounts = false; $scope.refresh = false; var metaAcct = meta.new("account_reassign"); $scope.meta = metaAcct; $scope.metaData = metaAcct.getData(); metaAcct.setSortReverse(false); if(!metaAcct.getSortBy()) metaAcct.setSortBy("active"); if(!metaAcct.getSortDirection()) metaAcct.setSortDirection("desc"); metaAcct.setPageSizes([5,10]); metaAcct.setPageSize(10); metaAcct.setSortFields(["active"]); metaAcct.setTotalItems($scope.accounts.length); $scope.reassignAccount = function(account) { if($scope.saveing) return; $scope.saveing = true; confirm.open({ message: lang.t("This account will be reassign to different account data, including backups and personal information."), confirm: function () { api.reassignAccount({ data: { _id: account._id }, success: function(data, message) { $scope.saveing = false; $scope.refresh = true; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.fetch = function() { $scope.loadingAccounts = true; var apiParams = { sort: {}, skip: metaAcct.getSkip(), limit: metaAcct.getPageSize(), find: {}, filter: metaAcct.getFilter() }; apiParams.account = $scope.account.username; apiParams.sort[metaAcct.getSortBy()] = metaAcct.getSortDirectionInt(); $scope.accounts = []; api.listAssignableAccounts({ data: apiParams, success: function(data) { metaAcct.setTotalItems(data.total); metaAcct.calculate(data.accounts); $scope.accounts = data.accounts; $scope.loadingAccounts = false; }, failed: function () { $location.path('/accounts'); } }); }; $timeout($scope.fetch); $scope.ok = function () { $uibModalInstance.close($scope.refresh); }; } ] ); }); define('controllers/accountExcludeListSelection',['app'], function(app) { app.controller('accountExcludeListSelection', ["$uibModalInstance", "$scope", "alert", "lang", "api", "consts", "popup", "account", function($uibModalInstance, $scope, alert, lang, api, consts, popup, account) { $scope.account = account; $scope.excludes = {}; $scope.excluderow = ''; $scope.selected_job = "global"; $scope.jobs = [ { _id: 'global', name: "- " + lang.t("All Backup Jobs (Global)") + " -" } ]; api.getAccountExcludeList({ data: { _id: account._id }, success: function (data) { $scope.excludes = data; } }); api.listBackupJobs({ data: { find: { type: consts.BACKUP_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.jobs.push(data.jobs[i]); if($scope.excludes[data.jobs[i]._id] === undefined) $scope.excludes[data.jobs[i]._id] = []; } } }); var checkDuplicateItems = function(value) { var withoutTrailing = value.replace(/\/+$/, ''); var withTrailing = withoutTrailing + '/'; return ($scope.excludes[$scope.selected_job].indexOf(withoutTrailing) >= 0 || $scope.excludes[$scope.selected_job].indexOf(withTrailing) >= 0); }; var validateListPath = function (path) { if(!path.trim()) return false; return !consts.PATH_FILTER_PATTERNS.test(path); }; $scope.addMultiListRow = function() { $scope.listTitle = lang.t("Directories and Files to exclude"); $scope.listData = $scope.excludes[$scope.selected_job].join("\n"); $scope.listUIB = popup.open({ size: "xl", template: 'listSelection', scope: $scope, noController: true }); $scope.listUIB.result.then(function(records) { while($scope.excludes[$scope.selected_job].length) $scope.excludes[$scope.selected_job].pop(); records = records.split("\n"); var invalidPaths = []; var duplicatePaths = []; for(var i = 0; i < records.length; i++) { if(checkDuplicateItems(records[i])) duplicatePaths.push(records[i]); else if(validateListPath(records[i])) { if ($scope.excludes[$scope.selected_job].indexOf(records[i]) < 0 ) $scope.excludes[$scope.selected_job].push(records[i]); } else invalidPaths.push(records[i]); } if(invalidPaths.length) alert.error(lang.t('The following paths ("%s") is invalid. The path must start with a "/" and can\'t have trailing "/"' + (type === 'include' ? ', also patterns are not allowed.' : '.'), invalidPaths.join(", ") )) if(duplicatePaths.length) alert.error(lang.t('The provided path(s) ("%s") already exists on the list.', duplicatePaths.join(", "))); }, function () { }); }; $scope.addListRow = function() { var path = $scope.excluderow.trim(); if(checkDuplicateItems(path)){ alert.error(lang.t('The provided path ("%s") already exists on the list.', path)); } else if(validateListPath(path)) { $scope.excludes[$scope.selected_job].push(path); } else { alert.error(lang.t('The provided path ("%s") is invalid. The path must start with a "/"', path )); } $scope.excluderow = ''; }; $scope.ok = function () { api.manageAccountExcludeList({ data: { _id: $scope.account._id, excludes: $scope.excludes }, success: function (data, message) { $uibModalInstance.close(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }]); }); define('controllers/modifyDatabasesExcludes',['app'], function(app) { app.controller('modifyDatabasesExcludes', ["$uibModalInstance", "$rootScope", "$scope", "$routeParams", "$location", "permissions", "lang", "db_excludes", function($uibModalInstance, $rootScope, $scope, $routeParams, $location, permissions, lang, db_excludes) { $scope.dbExcludesSections = [ { _id: 'mysql', name: lang.t('MySQL'), template: 'modifyMySQLExcludes', icon: 'fa-database', hidden: false }, { _id: 'postgresql', name: lang.t('PostgreSQL'), template: 'modifyPostgreSQLExcludes', icon: 'fa-database', hidden: false }, { _id: 'mongodb', name: lang.t('MongoDB'), template: 'modifyMongoDBExcludes', icon: 'fa-database', hidden: false }, ]; $scope.getDBExcludesSection = function (section_id) { for(var i = 0; i < $scope.dbExcludesSections.length; i++) { if($scope.dbExcludesSections[i]._id === section_id) { return $scope.dbExcludesSections[i]; } } return $scope.dbExcludesSections[0]; }; $scope.loadDBExcludesSection = function (section) { $scope.currentDBExcludesSection = section; $scope.dbExcludesSection = $scope.includePath(section.template); }; $scope.loadDBExcludesSection($scope.getDBExcludesSection($routeParams.section ? $routeParams.section : 'mysql')); if (db_excludes === undefined) db_excludes = { mysql_exclude_db_by_size: 0, postgresql_exclude_db_by_size: 0, mongodb_exclude_db_by_size: 0 }; $scope.excludes = { mysql_exclude_db_by_size: db_excludes.mysql_exclude_db_by_size, postgresql_exclude_db_by_size: db_excludes.postgresql_exclude_db_by_size, mongodb_exclude_db_by_size: db_excludes.mongodb_exclude_db_by_size, }; $scope.ok = function () { $uibModalInstance.close($scope.excludes); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }]); }); define('controllers/destinations',['app'], function(app) { app.controller("destinations", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "lang", "alert", "confirm", "consts", function ($rootScope, $scope, $location, $timeout, api, meta, lang, alert, confirm, consts) { $rootScope.$emit('menuItem', 'Destinations'); $scope.loadingDestinations = false; $scope.destinations = []; $scope.checkReindexTimeout = undefined; $scope.types = {}; $scope.filter = ''; $scope.filterOptions = [{ label: lang.t('All Destinations'), value: '' }]; $scope.saveing = false; $scope.jobs = {}; $scope.loaders = { state: false, validation: false, dr: false, hide: false, delete: false, reindex: false, speed: false }; meta = meta.new("destinations"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","owner","engine","count","disabled","dr"]); meta.setTotalItems($scope.destinations.length); $scope.onClickDelete = function(destination) { if($scope.saveing) return; if(destination.jobs_count > 0) { alert.error(lang.t("This destination has an assigned jobs, Please remove those jobs before deleting this destination.")); return false; } $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This destination will be permanently deleted!"), confirm: function () { api.deleteDestination({ data: { _id: destination._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; function apiDestination(params, callback) { if($scope.saveing) return; $scope.saveing = true; if(!params === undefined) params = {}; api.manageDestination({ data: params, success: function(data, message) { $scope.saveing = false; if(callback !== undefined) callback({ success: true, data: data, message: message }); }, failed: function (message) { alert.error(message); if(callback !== undefined) callback({ success: false, data: {}, message: message }); } }); } $scope.measureSpeed = function (destination) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.speed = true; confirm.open({ message: lang.t("JetBackup will use a 100MB file for the speed test, and depending on your destination, charges may apply."), confirm: function () { api.measureDestinationSpeed({ data: { _id: destination._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.speed = false; alert.success(message); destination.speed = data.speed; }, failed: function (message) { $scope.saveing = false; $scope.loaders.speed = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.speed = false; } }); }; $scope.reindex = function(destination) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.reindex = true; confirm.open({ message: lang.t("All running processes (backup, restore and etc) related to this destination will be aborted"), confirm: function () { api.reindexDestination({ data: { _id: destination._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.reindex = false; alert.success(message); destination.reindex = true; $scope.checkReindex(); }, failed: function (message) { $scope.saveing = false; $scope.loaders.reindex = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.reindex = false; } }); }; $scope.toggleDR = function(destination) { $scope.loaders.dr = true; var dr = !destination.dr; apiDestination({ _id: destination._id, action: 'modify', dr: dr }, function(response) { $scope.loaders.dr = false; if(response.success) destination.dr = dr; }); }; $scope.toggleStatus = function(destination) { $scope.loaders.state = true; var disabled = !destination.disabled; if(!disabled && destination.type !== 'Clones') { var model = confirm.open({ message: lang.t("WARNING: By Enabling the Destination you are also enabling automated tasks to run in the background for this destination. This could result in backups being cleaned using the Manual Backups TTL or Orphan Backups TTL settings. Are you sure you want to enable and perform background tasks on the destination?"), buttons: [ { label: lang.t("Change Settings"), class: 'btn-primary', click: function () { $location.path("/settings"); model.dismiss(); } } ], confirm: function () { if($scope.saveing) return; $scope.saveing = true; api.manageDestinationState({ data: { _id: destination._id, disabled: disabled }, success: function(data, message) { $scope.saveing = false; $scope.loaders.state = false; destination.disabled = disabled; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.state = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.state = false; } }); } else { if($scope.saveing) return; $scope.saveing = true; api.manageDestinationState({ data: { _id: destination._id, disabled: disabled }, success: function(data, message) { $scope.saveing = false; $scope.loaders.state = false; destination.disabled = disabled; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.state = false; alert.error(message); } }); } }; $scope.toggleHidden = function(destination) { $scope.loaders.hide = true; var hidden = !destination.hidden; apiDestination({ _id: destination._id, action: 'modify', hidden: hidden }, function(response) { $scope.loaders.hide = false; if(response.success) destination.hidden = hidden; }); }; $scope.validateDestination = function(destination) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.validation = true; api.validateDestination({ data: { _id: destination._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.validation = false; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.validation = false; alert.error(message); } }); }; $scope.listDestinations = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function(){}; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; if($scope.filter) apiParams.find.type = $scope.filter; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listDestinations({ data: apiParams, success: function (data, message) { callback({ success: true, data: data, message: message}); }, failed: function (data, message) { callback({ success: false, data: data, message: message}); } }); }; $scope.fetch = function() { if($scope.loadingDestinations) return; $scope.loadingDestinations = true; $scope.listDestinations(function (response) { $scope.destinations = []; $scope.loadingDestinations = false; meta.setTotalItems(response.data.total); meta.calculate(response.data.destinations); var reindex = false; for(var i = 0; i < response.data.destinations.length; i++) { var destination = response.data.destinations[i]; $scope.destinations.push(destination); if(destination.reindex) reindex = true; } if(reindex) $scope.checkReindex(); }); }; $scope.getDestination = function(destination_id) { for(var i = 0; i < $scope.destinations.length; i++) { if($scope.destinations[i]._id == destination_id) return $scope.destinations[i]; } return null; }; $scope.checkReindex = function() { $scope.listDestinations(function (response) { var reindex = false; for(var i = 0; i < response.data.destinations.length; i++) { var destination_new = response.data.destinations[i]; if(destination_new.reindex) reindex = true; var destination = $scope.getDestination(destination_new._id); if(destination) destination.reindex = destination_new.reindex; } if(reindex) $scope.checkReindexTimeout = setTimeout($scope.checkReindex, 3000); }); }; $scope.$on('$destroy', function() { if(!$scope.checkReindexTimeout) return; clearTimeout($scope.checkReindexTimeout); $scope.checkReindexTimeout = null; }); api.listDestinationTypes({ /*data: { types: consts.DESTINATION_JOB_TYPE_BACKUP },*/ success: function (data) { $scope.types = data; for(var i = 0; i < data.types.length; i++) { $scope.filterOptions.push({ label: consts.DESTINATION_JOB_TYPE_NAMES[data.types[i].type] + ' - ' + data.types[i].name, value: data.types[i].key }); } } }); api.listBackupJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { var job = data.jobs[i]; for(var j = 0; j < job.destination.length; j++) { if($scope.jobs[job.destination[j]] === undefined) $scope.jobs[job.destination[j]] = []; $scope.jobs[job.destination[j]].push(job); } } } }); $timeout($scope.fetch); } ] ); }); define('controllers/destinationManage',['app'], function(app) { app.controller("destinationManage", ["$rootScope", "$scope", "$routeParams", "$q", "$location", "$timeout", "api", "meta", "util", "confirm", "permissions", "lang", "consts", "alert", function ($rootScope, $scope, $routeParams, $q, $location, $timeout, api, meta, util, confirm, permissions, lang, consts, alert) { $rootScope.$emit('menuItem', 'Destinations'); $scope.details = {}; $scope.saveData = { job_type: consts.DESTINATION_JOB_TYPE_BACKUP, type: '', owner: $scope.loggedAccount._id, owner_name: $scope.loggedAccount.username, disk_limit: 95, threads: 150, readonly: 0, options: {} }; $scope.forks = { backup: 0, queueable: 0, system: 0, total: 0, }; $scope.autocomplete = { accountText: $scope.saveData.owner_name }; $scope.saveing = false; $scope.changed = true; $scope.forkThreads = 0; //$scope.cancelled = false; $scope.types = {}; $scope.types[consts.DESTINATION_JOB_TYPE_BACKUP] = []; $scope.types[consts.DESTINATION_JOB_TYPE_CLONE] = []; $scope.publicDir = ''; $scope.plugin = {}; $scope.plugin_available = {}; $scope.plugins_available = {}; $scope.installing = false; $scope.experimental = ''; $scope.disklimits = [ { label: lang.t("Disabled"), value: 0 }, { label: "50%", value: 50 }, { label: "55%", value: 55 }, { label: "60%", value: 60 }, { label: "65%", value: 65 }, { label: "70%", value: 70 }, { label: "75%", value: 75 }, { label: "80%", value: 80 }, { label: "85%", value: 85 }, { label: "90%", value: 90 }, { label: "95%", value: 95 } ]; $scope.isAvailableDestinations = function() { return $scope.saveData.type && $scope.saveData.type.indexOf('AvailableDestinations') >= 0; }; $scope.selectAccount = function(account) { if(account === undefined) return; $scope.saveData.owner = account._id; $scope.saveData.owner_name = account.username; $scope.autocomplete.accountText = account.username; var activeElement = document.activeElement; if (activeElement) activeElement.blur(); }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.resetOptions = function () { //$scope.saveData.options = {}; $scope.options = { disklimit: true, threads: false }; }; $scope.loadTemplate = function(type) { if(!type) return; if(type.indexOf('::') >= 0) { var parts = type.split('::'); type = parts[0]; $scope.plugin_available = $scope.plugins_available[parts[1]]; } $scope.resetOptions(); switch(type) { case 'AvailableDestinations': $scope.destinationType = $scope.includePath('destinations/' + type); $scope.experimental = $scope.plugin_available.experimental !== undefined ? $scope.plugin_available.experimental : ''; break; default: if($scope.plugin[type] === undefined) return; lang.setDefaultNS('plugins-destination-' + type); app.registerPluginController($scope.plugin[type], function(path) { $scope.publicDir = path; $scope.destinationType = $scope.publicDir + '/view.htm?v=' + $scope.plugin[type].version; $scope.experimental = $scope.plugin[type].experimental; }); break; } }; $scope.loadDestinationType = function(resetOptions) { if(resetOptions === undefined) resetOptions = false; if(resetOptions) $scope.saveData.options = {}; $scope.loadTemplate($scope.saveData.type); }; $scope.toggleEngine = function(details) { if(details === undefined) return; if(details.checked) details.engine = 1; return details.checked; }; $scope.resetOptions(); $scope.$on('options', function (event, options) { for(var key in options) $scope.options[key] = options[key]; }); $scope.$watch("saveData.job_type", function(){ if($routeParams.id) return; if($scope.types[$scope.saveData.job_type][0] !== undefined) { $scope.details.type = $scope.types[$scope.saveData.job_type][0].value; $scope.saveData.type = $scope.types[$scope.saveData.job_type][0].value; $scope.loadDestinationType(); } else { $scope.details.type = ''; $scope.saveData.type = ''; } }, true); $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); $scope.forkThreads = $scope.forks.total > 0 ? Math.ceil($scope.saveData.threads / $scope.forks.total) : 0; }, true); $scope.$on('$destroy', function() { if(!$scope.changed || $scope.cancelled || $scope.disasterRecovery) return; confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); }); $scope.cancel = function() { //$scope.cancelled = true; $location.path('/destinations'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, [], function(key) { return ($scope.details._id === undefined && key === 'type'); }); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageDestination({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); if(callback === undefined) { if(apply) $location.path('/destinationManage/' + data._id); else $location.path('/destinations'); alert.success(message); } if(callback !== undefined && typeof callback === 'function') callback(); }, failed: function (message) { $scope.saveing = false; alert.error(message); if(callback !== undefined && typeof callback === 'function') callback(); } }); }; $scope.installDestination = function() { if($scope.installing) return; $scope.installing = true; confirm.open({ message: lang.t("This destination will be installed on this server!"), confirm: function () { api.installPlugin({ data: { package_id: $scope.plugin_available._id, disabled: 0 }, success: function (data, message) { $scope.installing = false; //$scope.installed_plugin = data; $scope.plugin_available = {}; $scope.loadDestinations(function () { $scope.saveData.type = data.code; $scope.loadDestinationType(); alert.success(message); }); }, failed: function (message) { $scope.installing = false; alert.error(message); } }); }, cancel: function () { $scope.installing = false; } }); }; $scope.loadDestinations = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; $scope.types[consts.DESTINATION_JOB_TYPE_BACKUP] = []; $scope.types[consts.DESTINATION_JOB_TYPE_CLONE] = []; $scope.plugins_available = {}; api.listDestinationTypes({ success: function (data) { for(var i = 0; i < data.types.length; i++) { var type = data.types[i]; if((type.key == 'Local' || type.key == 'Localv2') && !permissions.isRoot) continue; $scope.types[type.type].push({ label: type.name + (type.experimental ? " - " + lang.t("Experimental") : ''), value: type.key, group: lang.t('Installed Destinations') }); $scope.plugin[type.key] = { type: consts.PLUGIN_TYPE_DESTINATION, code: type.key, job_type: type.type, version: type.version, experimental: type.experimental }; if(!$scope.details.type && !$routeParams.id) { $scope.details.type = type.key; $scope.saveData.type = type.key; $scope.loadDestinationType(); } } api.listPackagesAvailable({ data: { find: { type: consts.PLUGIN_TYPE_DESTINATION } }, success: function(data) { for(var i = 0; i < data.packages.length; i++) { var pkg = data.packages[i]; $scope.plugins_available[pkg.code] = pkg; $scope.types[consts.DESTINATION_JOB_TYPE_BACKUP].push({ label: lang.t("%s via %s", pkg.name, pkg.repo_name) + (pkg.experimental ? " - " + lang.t("Experimental") : ''), value: "AvailableDestinations::" + pkg.code, group: lang.t('Available Destinations') }); } callback(); }, failed: function () { callback(); } }); } }); }; $scope.loadDestinations(function () { if(!$routeParams.id) return; api.getDestination({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; if({}.toString.apply($scope.details.options) !== '[object Object]') { $scope.details.options = {}; } $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete.accountText = $scope.saveData.owner_name; //delete $scope.details.options; $scope.loadDestinationType(); } }); }); api.getSettings({ data: { section: 'performance' }, success: function(data) { $scope.forks = { backup: data.backup_forks, queueable: data.queueable_forks, system: data.system_forks, total: data.backup_forks + data.queueable_forks + data.system_forks, }; } }) }]); }); define('controllers/disasterRecovery',['app'], function(app) { app.controller("disasterRecovery", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "confirm", "PermPermissionStore", "lang", "alert", function ($rootScope, $scope, $location, $timeout, api, meta, confirm, PermPermissionStore, lang, alert) { $scope.disasterRecovery = true; $scope.saveing = false; $scope.newInstallation = false; $scope.loadingMessage = ""; $scope.saveToDB = function() { sessionStorage.disasterRecovery = JSON.stringify({ details: $scope.details, step: $scope.currentStep }); }; $scope.steps = [ { title: lang.t("What to do next?"), description: lang.t("Please select whether to start to recover your server from a disaster, continue with the default JetBackup configuration, or keep current configuration"), template: 'disasterRecovery/selection' }, { title: lang.t("JB Configurations destination"), description: lang.t("Connect to the destination where the JetBackup configuration files are stored"), template: 'disasterRecovery/destination' }, { title: lang.t("Available JB configuration files"), description: lang.t("Select the desired JB configuration file"), template: 'disasterRecovery/backups' }, { title: lang.t("Adjust Settings"), description: lang.t("Adjust the settings"), template: 'disasterRecovery/settings' }, { title: lang.t("Accounts to recover"), description: lang.t("Select the desired accounts you want to restore"), template: 'disasterRecovery/accounts' } ]; if(sessionStorage.disasterRecovery) { var disasterRecovery = JSON.parse(sessionStorage.disasterRecovery); $scope.details = disasterRecovery.details; $scope.currentStep = disasterRecovery.step; } else { $scope.currentStep = 0; $scope.details = { destination_id: '', drbackups: [], drbackup: '' }; $scope.saveToDB(); } $scope.$watch("details", function(){ $scope.saveToDB(); }, true); $scope.changeStep = function (step) { $scope.currentStep = step; $scope.saveToDB(); $scope.currentStepView = $scope.includePath($scope.steps[step].template); }; /* $scope.concurrent = 1; api.getSettings({section: 'Performance'}, function (response) { if(response.success && response.data.concurrentqueueprocesses) $scope.concurrent = response.data.concurrentqueueprocesses; }); $scope.updateConcurrentProcess = function(val) { if($scope.concurrent + val <= 0) return; $scope.concurrent += val; var apiParams = { section: 'Performance', concurrentqueueprocesses: $scope.concurrent }; jetapi.manageSettings(apiParams, function(response) { if(!response.success) console.log(response); }); }; */ $scope.changeStep($scope.currentStep); $scope.exitDRSure = function (apiCall) { if (apiCall === undefined || typeof apiCall !== 'function') apiCall = function (callback) {}; confirm.open({ message: lang.t("Are you sure you want to exit disaster recovery mode?"), confirm: function () { delete sessionStorage.disasterRecovery; apiCall(function() { window.location = $rootScope.path.location + window.location.search; }); } }); }; $scope.freshInstallation = function() { $scope.exitDRSure(function (callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; $scope.newInstallation = true; api.factoryReset({ success: callback, failed: function (message) { $scope.newInstallation = false; alert.error(message); } }); }); }; $scope.startDR = function() { confirm.open({ message: lang.t("Are you sure you want start disaster recovery? All current data will be lost"), confirm: function () { $scope.loadingMessage = lang.t("Dropping all JetBackup data from database"); api.factoryReset({ data: { drmode: true }, success: function () { api.panelPreload({ success: function (data) { $rootScope.loggedAccount = data.account; $scope.nextStep(); }, failed: function (message) { alert.error(message); } }); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.exitDR = function() { $scope.exitDRSure(function (callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; api.exitDisasterRecovery({ success: callback, failed: function (message) { alert.error(message); } }); }); }; $scope.nextStep = function() { if($scope.saveing) return; $scope.saveing = true; $scope.loadingMessage = ''; $rootScope.$broadcast("nextStep"); }; $scope.startOver = function() { if($scope.saveing) return; delete sessionStorage.disasterRecovery; $scope.changeStep(1); }; $scope.$on('nonrecoverable', function (event, message) { $scope.saveing = false; alert.error(lang.t("Failed restoring JB Configurations, the DR Wizard will now exit and start over. Error: %s", message)); $scope.loadingMessage = lang.t("Dropping all JetBackup data from database"); api.factoryReset({ data: { drmode: true }, success: function () { $scope.loadingMessage = ''; $scope.startOver() }, failed: function (message) { alert.error(message); } }); }); $scope.$on('error', function (event, message) { $scope.saveing = false; alert.error(message); $scope.loadingMessage = ''; }); $scope.$on('loadingMessage', function (event, message) { $scope.loadingMessage = message; }); $scope.$on('commitNextStep', function (event, data) { for(var i in data) $scope.details[i] = data[i]; $scope.saveing = false; $scope.changeStep($scope.currentStep+1); $scope.loadingMessage = ''; }); } ] ); }); define('controllers/disasterRecovery/selection',['app'], function(app) { app.controller("disasterRecoverySelection", ["$rootScope", "$scope", "api", function ($rootScope, $scope, api) { $scope.installed = false; api.getSettings({ data: { section: 'general' }, success: function (data) { $scope.installed = data.installed; } }); $scope.$on('nextStep', function() { $scope.$emit("commitNextStep", {}); }); }] ); }); define('controllers/disasterRecovery/destination',['app'], function(app) { app.controller("disasterRecoveryDestination", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "consts", "lang", "util", function ($rootScope, $scope, $routeParams, $location, $timeout, api, consts, lang, util) { $scope.destination_id = ''; $scope.reindex = function(destination_id, callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; api.reindexDestination({ data: { _id: destination_id, backup_type: consts.BACKUP_TYPE_JB_CONFIG }, success: function(data) { var checkQueueInterval = setInterval(function () { api.getQueueGroup({ data: { _id: data._id }, success: function (data) { if(data.status < consts.QUEUE_STATUS_COMPLETED) return; if(checkQueueInterval !== null) clearInterval(checkQueueInterval); checkQueueInterval = null; callback({ success: data.status == consts.QUEUE_STATUS_COMPLETED, message: lang.t("Reindex process finished with %s status", consts.QUEUE_STATUS_NAMES[data.status]) }); }, failed: function (message) { if(checkQueueInterval !== null) clearInterval(checkQueueInterval); checkQueueInterval = null; callback({ success: false, message: message }); } }); }, 5000); }, failed: function (message) { callback({ success: false, message: message }); } }); }; var listBackups = function(contains, success) { if(success === undefined) success = function(){}; api.listBackups({ data: { destination: $scope.destination_id, type: consts.BACKUP_TYPE_JB_CONFIG, contains:contains, sort: { created: -1 } }, success: function (data) { success(data); }, failed: function (message) { api.deleteDestination({ data: { _id: $scope.destination_id } }); $scope.$emit("error", message); } }); }; $scope.$on('nextStep', function() { $scope.$emit("loadingMessage", lang.t("Creating destination and reindexing JB configurations backups...")); var apiParams = util.saveParams($scope.saveData, $scope.details, [], function(key) { return ($scope.details._id === undefined && key === 'type'); }); apiParams.name = "DR destination " + (new Date()).getTime(); apiParams.readonly = true; apiParams.no_reindex = true; apiParams.action = 'create'; api.manageDestination({ data: apiParams, success: function(data) { $scope.destination_id = data._id; $scope.reindex($scope.destination_id, function (response) { if(!response.success) { api.deleteDestination({ data: { _id: $scope.destination_id } }); $scope.$emit("error", response.message); return; } listBackups(consts.BACKUP_TYPE_JB_CONFIG_FULL, function (data) { var backups = data.backups; listBackups((consts.BACKUP_TYPE_JB_CONFIG_FULL^consts.BACKUP_TYPE_JB_CONFIG_WIREDTIGER), function (data) { for(var i = 0; i < data.backups.length; i++) backups.push(data.backups[i]); if(!backups.length) { api.deleteDestination({ data: { _id: $scope.destination_id } }); $scope.$emit("error", lang.t("No JetBackup 5 configuration files found on this destination. Please verify the Destination Path is set to a directory that includes JetBackup 5 Configuration Backups.")); return; } $scope.$emit("commitNextStep", { destination_id: $scope.destination_id, drbackups: backups, drbackup: backups[0]._id }); }); }); }); }, failed: function (message) { $scope.$emit("error", message); } }); }); } ] ); }); define('controllers/disasterRecovery/settings',['app'], function(app) { app.controller("disasterRecoverySettings", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "consts", "lang", "util", function ($rootScope, $scope, $routeParams, $location, $timeout, api, consts, lang, util) { $scope.saveData = { general: {}, performance: {}, resource: {}, options: {} }; $scope.validateOptions = {}; $scope.settingsSection = ''; api.getSettings({ data: { section: 'general' }, success: function (data) { $scope.saveData.general = data; $scope.general = util.duplicateObject($scope.saveData.general); } }); api.getSettings({ data: { section: 'performance' }, success: function (data) { $scope.saveData.performance = data; $scope.performance = util.duplicateObject($scope.saveData.performance); } }); api.getSettings({ data: { section: 'resource' }, success: function (data) { $scope.saveData.resource = data; $scope.resource = util.duplicateObject($scope.saveData.resource); } }); api.getSettings({ data: { section: 'panel' }, success: function (data) { $scope.saveData.options = data.options; $scope.panel = util.duplicateObject($scope.saveData.options); } }); $scope.$on('validateOptions', function (e, data) { $scope.validateOptions = data; }); app.registerController( 'panelSettings', 'plugins/panel', function(path) { $scope.settingsSection = $scope.includePath('panel/view', 'plugins'); } ); $scope.$on('nextStep', function() { $scope.$emit("loadingMessage", lang.t("Adjusting settings...")); for (var key in $scope.saveData.options) { if($scope.validateOptions[key] === undefined) continue; if(!$scope.validateOptions[key].validation($scope.saveData.options[key])) { $scope.$emit("error", lang.t("Invalid value provided for %s", $scope.validateOptions[key].name)); return; } } var general = util.saveParams($scope.saveData.general, $scope.general); general.section = 'general'; var performance = util.saveParams($scope.saveData.performance, $scope.performance); performance.section = 'performance'; var resource = util.saveParams($scope.saveData.resource, $scope.resource); resource.section = 'resource'; var panel = util.saveParams($scope.saveData.options, $scope.panel); api.manageSettings({ data: general, success: function () { api.manageSettings({ data: performance, success: function () { api.manageSettings({ data: resource, success: function () { api.manageSettings({ data: { section: 'panel', options: panel }, success: function () { $scope.$emit("commitNextStep", {}); }, failed: function (message) { $scope.$emit("error", message); } }); }, failed: function (message) { $scope.$emit("error", message); } }); }, failed: function (message) { $scope.$emit("error", message); } }); }, failed: function (message) { $scope.$emit("error", message); } }); }); } ] ); }); define('controllers/disasterRecovery/backups',['app'], function(app) { app.controller("disasterRecoveryBackups", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, api, consts, lang, popup) { $scope.restore = function(_id, encryption_key) { $scope.$emit("loadingMessage", lang.t("Restoring selected JB configurations backup...")); var args = { type: consts.QUEUE_ITEM_TYPE_RESTORE, items: [_id] }; if(encryption_key !== undefined) args.encryption_key = encryption_key; api.addQueueItems({ data: args, success: function(data) { $scope.failedCounter = 0; var checkQueueInterval = setInterval(function () { api.getQueueGroup({ data: { _id: data._id }, success: function (data) { var group_status = parseInt(data.status); if(group_status < consts.QUEUE_STATUS_COMPLETED) { if(group_status > consts.QUEUE_STATUS_PROCESSING) $scope.$emit("loadingMessage", consts.QUEUE_STATUS_SUB_NAMES[data.type][group_status]); return; } if(checkQueueInterval !== null) clearInterval(checkQueueInterval); checkQueueInterval = null; if(group_status === consts.QUEUE_STATUS_COMPLETED) { var params = {}; if(encryption_key !== undefined) params.private_key = encryption_key; $scope.$emit("commitNextStep", params); return; } api.listQueueItems({ data: { group_id: data._id }, success: function (data) { var message = ''; if(data.items[0] === undefined) message = lang.t("Restore process finished with %s status", consts.QUEUE_STATUS_NAMES[group_status]); else message = data.items[0].message; if(data.items[0].data.nonrecoverable) $scope.$emit("nonrecoverable", message); else $scope.$emit("error", message); }, failed: function (message) { $scope.$emit("error", message); } }); }, failed: function (message) { if(($scope.failedCounter++ < 10)) return; if(checkQueueInterval !== null) clearInterval(checkQueueInterval); checkQueueInterval = null; $scope.$emit("error", message); } }); }, 5000); }, failed: function (message) { $scope.$emit("error", message); } }); }; $scope.$on('nextStep', function() { var backup = { _id: $scope.details.drbackup }; for(var i = 0; i < $scope.details.drbackups.length; i++) { if(backup._id === $scope.details.drbackups[i]._id) { backup = $scope.details.drbackups[i]; break; } } if(backup.encrypted) { $scope.privateKeyUIB = popup.open({ template: 'encryptionKeySelection', noController: true, scope: $scope }); $scope.privateKeyUIB.result.then(function(encryption_key) { if(!encryption_key) { $scope.$emit("error", lang.t("You must provide root master key")); return; } $scope.restore(backup._id, encryption_key); }, function() { $scope.$emit("error", lang.t("You must provide root master key")); }); } else { $scope.restore(backup._id); } }); }]); }); define('controllers/disasterRecovery/accounts',['app'], function(app) { app.controller("disasterRecoveryAccounts", ["$rootScope", "$scope", function ($rootScope, $scope) { $scope.drMode = true; }]); }); define('controllers/restoreConditions',['app'], function(app) { app.controller("restoreConditions", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "$q", "api", "meta", "confirm", "alert", "lang", function ($rootScope, $scope, $location, $timeout, $interval, $q, api, meta, confirm, alert, lang) { $rootScope.$emit('menuItem', 'Settings'); $scope.conditions = []; $scope.loadingConditions = false; $scope.loaders = { state: false, delete: false }; meta = meta.new("restore_conditions"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("title"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["title", "content", "type"]); meta.setTotalItems($scope.conditions.length); $scope.toggleState = function(condition) { api.manageRestoreCondition({ data: { action: 'modify', _id: condition._id, disabled: !condition.disabled }, success: function(data, message) { $scope.loaders.state = false; condition.disabled = data.disabled; alert.success(message); }, failed: function (message) { alert.error(message); } }); $scope.loaders.state = true; }; $scope.onClickDelete = function(condition) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This restore condition will be permanently deleted!"), confirm: function () { api.deleteRestoreCondition({ data: { _id: condition._id }, success: function(data, message) { $scope.loaders.delete = false; $scope.saveing = false; $scope.fetch(); alert.success(message); }, failed: function(message) { $scope.loaders.delete = false; $scope.saveing = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.delete = false; $scope.saveing = false; } }); }; $scope.fetch = function() { $scope.loadingConditions = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.conditions = []; api.listRestoreConditions({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.conditions); $scope.conditions = data.conditions; $scope.loadingConditions = false; } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/restoreConditionManage',['app'], function(app) { app.controller("restoreConditionManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "util", "confirm", "lang", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, util, confirm, lang, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.details = {}; $scope.saveData = { condition: '' }; $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/restoreConditions'); }; $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageRestoreCondition({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = response.data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/restoreConditionManage/' + data._id); else $location.path('/restoreConditions'); alert.success(message); }, failed: function(message) { $scope.saveing = false; alert.error(message); }, }); }; $scope.fetch = function() { api.getRestoreCondition({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; if($routeParams.id) $timeout($scope.fetch()); } ] ); }); define('controllers/backupJobs',['app'], function(app) { app.controller("backupJobs", ["$rootScope", "$scope", "$location", "$timeout", "$sce", "$interval", "$q", "api", "meta", "lang", "filter", "consts", "confirm", "alert", function ($rootScope, $scope, $location, $timeout, $sce, $interval, $q, api, meta, lang, filter, consts, confirm, alert) { $rootScope.$emit('menuItem', 'BackupJobs'); $scope.jobs = []; $scope.checkingJob = {}; $scope.loadingJobs = false; $scope.filters = {}; $scope.destinations = undefined; $scope.running = {}; $scope.checkRunningInterval = null; $scope.run_now = false; $scope.currentTime = parseInt(Date.now() / 1000); $interval(function () { $scope.currentTime = parseInt(Date.now() / 1000); }, 100); $scope.loaders = { state: false, quota: false, runnow: false, duplicate: false, delete: false }; meta = meta.new("backup_jobs"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","owner","retain","last_run","disabled"]); meta.setTotalItems($scope.jobs.length); $scope.viewLogs = function(job) { var logsFilter = filter.new("logs_filter"); logsFilter.setFilter(consts.LOG_TYPE_BACKUP); var logsSubFilter = filter.new("logs_subfilter"); logsSubFilter.setFilter(job._id); $scope.changeView('/logs'); }; $scope.duplicate = function(job) { confirm.open({ message: lang.t("This backup job will be duplicated!"), confirm: function () { $scope.loaders.duplicate = true; api.duplicateBackupJob({ data: { _id: job._id }, success: function (data, message) { $scope.loaders.duplicate = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.duplicate = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.toggleState = function(job) { $scope.loaders.state = true; var newState = !job.disabled; api.manageBackupJob({ data: { action: 'modify', _id: job._id, disabled: newState }, success: function(data) { $scope.loaders.state = false; job.disabled = data.disabled; job.next_run = data.next_run; }, failed: function (message) { $scope.loaders.state = false; alert.error(message); } }); }; $scope.runBackupJobManually = function(job) { if($scope.loaders.runnow) return; $scope.loaders.runnow = true; api.runBackupJobManually({ data: { _id: job._id }, success: function (data, message) { $scope.loaders.runnow = false; for(var key in data) job[key] = data[key]; $scope.running[job._id] = job; alert.success(message); }, failed: function (message) { $scope.loaders.runnow = false; alert.error(message); } }); }; $scope.onClickDelete = function(job) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This backup job will be permanently deleted!"), confirm: function () { api.deleteBackupJob({ data: { _id: job._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; api.listAccountFilters({ success: function (data) { for(var i = 0; i < data.filters.length; i++) { $scope.filters[data.filters[i].group_id] = data.filters[i].name; } } }); $scope.createBackupJob = function() { $scope.destinationsCheck(function () { $scope.changeView('/backupJobManage'); }); }; $scope.destinationsCheck = function (callback) { if(callback === undefined) callback = function () {}; if($scope.destinations !== undefined) { if(!$scope.destinations) { alert.error(lang.t("You must first create a destination before creating a backup job for this server")); return; } callback(); return; } $scope.destinations = false; api.listDestinations({ data: { readonly:0 }, success: function(data) { $scope.destinations = !!data.destinations.length; if(!$scope.destinations) { alert.error(lang.t("You must first create a destination before creating a backup job for this server")); return; } callback(); }, failed: function (message) { alert.error(message); } }); }; $scope.checkRunning = function() { for(var id in $scope.running) { api.getBackupJob({ data: { _id: id }, success: function (data) { if(data.running) return; for(var key in data) $scope.running[id][key] = data[key]; delete $scope.running[id]; } }); } }; $scope.$on('$destroy', function() { if($scope.checkRunningInterval === null) return; clearInterval($scope.checkRunningInterval); $scope.checkRunningInterval = null; }); $scope.fetch = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; $scope.loadingJobs = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.jobs = []; $scope.running = {}; api.listBackupJobs({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.jobs); $scope.jobs = data.jobs; for(var i = 0; i < $scope.jobs.length; i++) { var job = $scope.jobs[i]; var type = parseInt(job.type); var contains = parseInt(job.contains); var names = []; switch(type) { case consts.BACKUP_TYPE_ACCOUNT: if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } break; case consts.BACKUP_TYPE_DIRECTORY: names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); break; case consts.BACKUP_TYPE_JB_CONFIG: names.push(consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_FULL]); break; case consts.BACKUP_TYPE_DR: names.push(consts.BACKUP_TYPE_DR_NAMES[consts.BACKUP_TYPE_DR_FULL]); break; } job.contains_name = names.join(', '); job.filters_sorted = []; if(job.filters !== undefined) { for(var j = 0; j < job.filters.length; j++) { for(var a = 0; a < job.filters[j].length; a++) { job.filters_sorted.push(job.filters[j][a]); } } } if(job.running) $scope.running[job._id] = job; var destinations_list = []; job.destinations = ''; for(var k = 0; k < job.destination_details.length; k++) destinations_list.push(job.destination_details[k].name + (job.destination_details[k].disabled ? " <span style=\"color: #cc0000; font-size: 11px;\">(" + lang.t("Disabled") + ")</span>" : '')); job.destinations = $sce.trustAsHtml(destinations_list.join(", ")); //job.next_run_int = job.next_run ? parseInt((new Date(job.next_run)).getTime() / 1000) : 0; } $scope.loadingJobs = false; callback(); } }); }; $timeout(function () { $scope.fetch(function () { $scope.checkRunningInterval = setInterval($scope.checkRunning, 3000); }); }); } ] ); }); define('controllers/backupJobManage',['app'], function(app) { app.controller("backupJobManage", ["$rootScope", "$scope", "$routeParams", "$templateCache", "$route", "$location", "$timeout", "$q", "api", "meta", "util", "lang", "alert", "permissions", "consts", "filterManager", "confirm", "popup", function ($rootScope, $scope, $routeParams, $templateCache, $route, $location, $timeout, $q, api, meta, util, lang, alert, permissions, consts, filterManager, confirm, popup) { $rootScope.$emit('menuItem', 'BackupJobs'); $scope.saveData = { name: '', destination: [], owner: $scope.loggedAccount._id, owner_name: $scope.loggedAccount.username, type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_FULL, mysql_exclude_db_by_size: 0, postgresql_exclude_db_by_size: 0, mongodb_exclude_db_by_size: 0, encrypted: 0, retry_failed: 0, //options: 0, structure: consts.BACKUP_STRUCTURE_INCREMENTAL, time_parsed: '12:00 AM', time: 0, monitor: {ranfor:0,notran:0}, schedules: [], filters: [], include_list: [], exclude_list: [] }; $scope.autocomplete = { accountText: $scope.saveData.owner_name }; $scope.details = {}; $scope.destinations = {}; $scope.schedules = {}; $scope.filters = {}; $scope.backup_job_names = {}; $scope.clone_job_names = {}; $scope.cancelled = false; $scope.excluderow = ''; $scope.includerow = ''; $scope.type_description = lang.t("Backup the account data that you choose - Files, Emails, Databases, Cron Jobs, Domains, SSL & Panel Configs (If relevant)"); $scope.type_experimental = ''; $scope.structures = [ { label: consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_INCREMENTAL], value: consts.BACKUP_STRUCTURE_INCREMENTAL }, { label: consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_ARCHIVED], value: consts.BACKUP_STRUCTURE_ARCHIVED }, { label: consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_COMPRESSED], value: consts.BACKUP_STRUCTURE_COMPRESSED } ]; $scope.types = [ { label: consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_ACCOUNT], value: consts.BACKUP_TYPE_ACCOUNT } ]; if(permissions.isRoot) { $scope.types.push({ label: consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_DIRECTORY], value: consts.BACKUP_TYPE_DIRECTORY }); $scope.types.push({ label: consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_DR], value: consts.BACKUP_TYPE_DR }); } $scope.account_types = [ { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG], value: consts.BACKUP_TYPE_ACCOUNT_CONFIG }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR], value: consts.BACKUP_TYPE_ACCOUNT_HOMEDIR }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES], value: consts.BACKUP_TYPE_ACCOUNT_DATABASES }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS], value: consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS], value: consts.BACKUP_TYPE_ACCOUNT_EMAILS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FTP], value: consts.BACKUP_TYPE_ACCOUNT_FTP }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS], value: consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS], value: consts.BACKUP_TYPE_ACCOUNT_DOMAINS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES], value: consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES } ]; $scope.filtersConditions = [ {_id:1,name:lang.t("OR")}, {_id:2,name:lang.t("AND")} ]; $scope.filtersStructure = []; $scope.$watch("saveData.structure", function () { if($scope.saveData.structure == consts.BACKUP_STRUCTURE_ARCHIVED || $scope.saveData.structure == consts.BACKUP_STRUCTURE_COMPRESSED) return; $scope.saveData.encrypted = 0; }); $scope.$watch("filtersStructure", function(){ $scope.buildFilters(true); }, true); $scope.addRecommendedExcludes = function(list) { if(consts.RECOMMENDED_EXCLUDES_ACCOUNT[list] === undefined) return; var defaults = consts.RECOMMENDED_EXCLUDES_ACCOUNT[list]; for(var i = 0; i < defaults.length; i++) { var exclude = defaults[i]; if ($scope.saveData.exclude_list.indexOf(exclude) < 0) $scope.saveData.exclude_list.push(exclude); } }; $scope.selectAccount = function(account) { if(account === undefined) return; $scope.saveData.owner = account._id; $scope.saveData.owner_name = account.username; $scope.autocomplete.accountText = account.username; var activeElement = document.activeElement; if (activeElement) activeElement.blur(); }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.buildFilters = function(revert) { if(revert === undefined) revert = false; if(revert) $scope.saveData.filters = filterManager.buildFilters($scope.filtersStructure); else if($scope.saveData.filters !== undefined) $scope.filtersStructure = filterManager.reBuildStructure($scope.saveData.filters); }; $scope.removeFilter = function(index) { $scope.filtersStructure = filterManager.removeFilter($scope.filtersStructure, index); }; $scope.upFilter = function(index) { if(index === 0) return; var clickedValue = $scope.filtersStructure[index]; var upValue = $scope.filtersStructure[index-1]; if(index === 1) { upValue.cond = clickedValue.cond; delete clickedValue.cond; } $scope.filtersStructure[index] = upValue; $scope.filtersStructure[index-1] = clickedValue; }; $scope.downFilter = function(index) { if(index === ($scope.filtersStructure.length-1)) return; var clickedValue = $scope.filtersStructure[index]; var downValue = $scope.filtersStructure[index+1]; if(index === 0) { clickedValue.cond = downValue.cond; delete downValue.cond; } $scope.filtersStructure[index] = downValue; $scope.filtersStructure[index+1] = clickedValue; }; $scope.fileBrowse = function() { popup.open({ size: "lg", template: 'fileBrowse', scope: $scope, resolve: { listPaths: function () { return $scope.saveData.include_list; } } }).result.then(function(paths) { $scope.saveData.include_list = paths; }, function() {}); }; $scope.filterSelection = function () { popup.open({ size: "lg", template: 'accountFilterGroupSelection', scope: $scope, resolve: { filters: function() { return $scope.filters; } , details: function() { return $scope.details; } } }).result.then(function(filter_id) { if(!filter_id) return; var data = { _id: filter_id }; if($scope.filtersStructure.length > 0) data.cond = 1; $scope.filtersStructure.push(data); }, function () {}); }; $scope.manageDestination = function() { popup.open({ template: 'destinationsSelection', scope: $scope, resolve: { destinations: function() { return $scope.saveData.destination; }, readonly: function () { return false; }, types: function () { return consts.DESTINATION_JOB_TYPE_BACKUP; }, legacy: function () { return consts.BACKUP_ALLOW_LEGACY_DESTINATION[$scope.saveData.type]; }, local: function () { return consts.BACKUP_ALLOW_LOCAL_DESTINATION[$scope.saveData.type]; }, timebased: function () { return consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[$scope.saveData.type]; } } }).result.then(function(selected) { $scope.saveData.destination = selected; }, function () {}); }; $scope.databasesExcludes = function() { popup.open({ size: "lg", template: 'modifyDatabasesExcludes', scope: $scope, resolve: { db_excludes: function() { return { mysql_exclude_db_by_size: $scope.saveData.mysql_exclude_db_by_size, postgresql_exclude_db_by_size: $scope.saveData.postgresql_exclude_db_by_size, mongodb_exclude_db_by_size: $scope.saveData.mongodb_exclude_db_by_size } } } }).result.then(function(response) { $scope.saveData.mysql_exclude_db_by_size = response.mysql_exclude_db_by_size; $scope.saveData.postgresql_exclude_db_by_size = response.postgresql_exclude_db_by_size; $scope.saveData.mongodb_exclude_db_by_size = response.mongodb_exclude_db_by_size; }, function () {}); }; $scope.scheduleSelection = function (schedule) { popup.open({ size: "lg", template: 'scheduleSelection', scope: $scope, resolve: { schedules: function() { return $scope.schedules; } , schedule: function() { return schedule; }, details: function() { return $scope.saveData; }, retain: function () { return true; } } }).result.then(function(scheduleDetails) { if(!scheduleDetails._id || scheduleDetails.retain <= 0) { alert.error(lang.t("No schedule and/or backups retain selected")); return; } scheduleDetails.display = $scope.scheduleDisplay(scheduleDetails); $scope.schedules[scheduleDetails._id] = scheduleDetails; if(schedule !== undefined) { for(var i in scheduleDetails) { if(schedule[i] !== undefined) schedule[i] = scheduleDetails[i]; } } else { $scope.saveData.schedules.push({ _id: scheduleDetails._id, name: scheduleDetails.name, retain: scheduleDetails.retain, next_run: 0 }); } $scope.checkScheduleTimeMismatch(); }, function () {}); }; $scope.checkScheduleTimeMismatch = function () { var time = 0; for(var i = 0; i < $scope.saveData.schedules.length; i++) { if($scope.schedules[$scope.saveData.schedules[i]._id] === undefined) return; var currentSchedule = $scope.schedules[$scope.saveData.schedules[i]._id]; if([1,2,3,4].indexOf(currentSchedule.type) < 0) continue; if(currentSchedule.type === 1) { // TODO validate hourly times continue; } if(!time) time = currentSchedule.time; if(currentSchedule.time !== time) { $scope.scheduleTimeMismatch = true; return; } } $scope.scheduleTimeMismatch = false; }; $scope.removeSchedule = function (schedule) { confirm.open({ message: lang.t("Are you sure you want to remove this schedule from this job? Please note that all snapshots assigned to this schedule will be deleted in the next job run."), confirm: function () { for(var i = 0; i < $scope.saveData.schedules.length; i++) { if(schedule._id === $scope.saveData.schedules[i]._id) { $scope.saveData.schedules.splice(i, 1); $scope.checkScheduleTimeMismatch(); break; } } alert.success("Schedule removed successfully"); } }); }; $scope.timeToStr = function(time) { time = parseInt(time); var ampm = 'AM'; if(time >= 1200) { ampm = 'PM'; time -= 1200; } time = '' + time; if(time.length < 2) time = '0' + time; var minute = time.substr(-2); var hour = time.length > 2 ? time.substr(0, time.length-2) : 12; if(parseInt(hour) < 10) hour = "0" + parseInt(hour); return hour + ":" + minute + " " + ampm; }; $scope.strToTime = function (str) { var matches = /^([0-9]+):([0-9]+)\s+(AM+|PM+)$/g.exec(str); if(!matches) return 0; var output = parseInt(matches[1] + matches[2]); if(output >= 1200) output -= 1200; if(matches[3] === 'PM') output += 1200; return output; }; $scope.validateListPath = function (path, allowPatterns) { if(!path.trim()) return false; if(allowPatterns) return !consts.PATH_FILTER_PATTERNS.test(path); return !consts.PATH_FILTER.test(path); }; $scope.typeChecked = function(type, types) { return ( type & types ); }; $scope.toggleOptionsTypes = function(option) { if($scope.typeChecked(option, $scope.saveData.options)) $scope.saveData.options ^= option; else $scope.saveData.options |= option; }; $scope.checkChange = function() { $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }; $scope.$watch("saveData", $scope.checkChange, true); $scope.$watch("details", $scope.checkChange, true); $scope.validateSchedules = function(schedules, callback) { if(schedules.length) return callback(true); confirm.open({ message: lang.t("We noticed that you didn't set any schedule for this job. That means that this job will never run automatically, only manually"), cancelLabel: lang.t("No, let me set schedules"), confirm: function () { callback(true); }, cancel: function () { callback(false); } }); }; $scope.fetchSchedules = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listSchedules({ success: function(data) { for (var i = 0; i < data.schedules.length; i++) { var id = data.schedules[i]._id; $scope.schedules[id] = data.schedules[i]; $scope.schedules[id].display = $scope.scheduleDisplay($scope.schedules[id]); } callback(); }, failed: function () { callback(); } }); }; $scope.fetchFilters = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listAccountFilterGroups({ success: function(data) { for(var i = 0; i < data.groups.length; i++) { $scope.filters[data.groups[i]._id] = data.groups[i]; } callback(); }, failed: function () { callback(); } }); }; $scope.fetchDestinations = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listDestinations({ success: function(data) { for(var i = 0; i < data.destinations.length; i++) { var destination = data.destinations[i]; destination.display = lang.t("%s destination", destination.type); $scope.destinations[destination._id] = destination; } callback(); } }); }; $scope.removeDestination = function (destination_id) { for(var i = 0; i < $scope.saveData.destination.length; i++) { if(destination_id === $scope.saveData.destination[i]) { $scope.saveData.destination.splice(i, 1); break; } } }; $scope.updateData = function(details) { $scope.details = details; $scope.saveData = util.duplicateObject($scope.details); $scope.checkScheduleTimeMismatch(); $scope.buildFilters(); }; $scope.toggleBackupType = function(type) { switch(type) { case consts.BACKUP_TYPE_ACCOUNT: $scope.saveData.contains = consts.BACKUP_TYPE_ACCOUNT_FULL; $scope.type_description = lang.t("Backup the account data that you choose - Files, Emails, Databases, Cron Jobs, Domains, SSL & Panel Configs (If relevant)"); $scope.type_experimental = ''; break; case consts.BACKUP_TYPE_DIRECTORY: $scope.saveData.contains = consts.BACKUP_TYPE_DIRECTORY_FULL; $scope.type_description = lang.t("Backup server files/folders that you choose to include (not necessarily related to accounts)."); $scope.type_experimental = ''; if($scope.saveData.include_list === undefined) $scope.saveData.include_list = []; if($scope.saveData.exclude_list === undefined) $scope.saveData.exclude_list = []; break; case consts.BACKUP_TYPE_DR: $scope.saveData.contains = consts.BACKUP_TYPE_DR_FULL; $scope.type_description = lang.t("Create an entire server backup (BMR) for disaster recovery restore, this will create a bootable ISO to restore from. Note that this works alongside the accounts, so for a full recovery you will need an active all-accounts backup job."); $scope.type_experimental = ''; break; } var newDestinations = []; for(var i = 0; i < $scope.saveData.destination.length; i++) { var details = $scope.destinations[$scope.saveData.destination[i]]; if(!consts.BACKUP_ALLOW_LEGACY_DESTINATION[type] && details.legacy) continue; if(!consts.BACKUP_ALLOW_LOCAL_DESTINATION[type] && (details.type == 'Local' || details.type == 'Localv2')) continue; if(!consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[type] && details.time_based) continue; newDestinations.push($scope.saveData.destination[i]); } $scope.saveData.destination = newDestinations; }; $scope.toggleContains = function(type) { if($scope.typeChecked(type, $scope.saveData.contains)) $scope.saveData.contains ^= type; else $scope.saveData.contains |= type; }; var checkDuplicateIncludeItems = function(value, list) { var withoutTrailing = value.replace(/\/+$/, ''); var withTrailing = withoutTrailing + '/'; return (list.indexOf(withoutTrailing) >= 0 || list.indexOf(withTrailing) >= 0); }; $scope.addListRow = function (value, list) { if($scope[value] === undefined || !$scope[value].trim()) return; if(checkDuplicateIncludeItems($scope[value].trim(), list)){ alert.error(lang.t('The provided path ("%s") already exists on the list.', $scope[value].trim())); } else if($scope.validateListPath($scope[value].trim(), value === 'excluderow')) { list.push($scope[value].trim()); } else { alert.error(lang.t('The provided path ("%s") is invalid. The path must start with a "/"' + (value !== 'excluderow' ? ', also patterns are not allowed.' : '.'), $scope[value].trim() )); } $scope[value] = ''; }; $scope.addMultiListRow = function(type, list) { if(type == 'include') { $scope.listTitle = lang.t("Directories and Files to include"); $scope.listData = $scope.saveData.include_list.join("\n"); } else { $scope.listTitle = lang.t("Directories and Files to exclude"); $scope.listData = $scope.saveData.exclude_list.join("\n"); } $scope.listUIB = popup.open({ template: 'listSelection', noController: true, scope: $scope }); $scope.listUIB.result.then(function(records) { while(list.length) list.pop(); records = records.split("\n"); var invalidPaths = []; var duplicatePaths = []; for(var i = 0; i < records.length; i++) { if(type === 'include' && checkDuplicateIncludeItems(records[i], list)) duplicatePaths.push(records[i]); else if(!(type === 'include' && records[i] === '/') && $scope.validateListPath(records[i], type === 'exclude')) { if (list.indexOf(records[i]) < 0 ) list.push(records[i]); } else invalidPaths.push(records[i]); } if(invalidPaths.length) alert.error(lang.t('The following paths ("%s") is invalid. The path must start with a "/" and can\'t have trailing "/"' + (type === 'include' ? ', also patterns are not allowed.' : '.'), invalidPaths.join(", ") )) if(duplicatePaths.length) alert.error(lang.t('The provided path(s) ("%s") already exists on the list.', duplicatePaths.join(", "))); }, function () {}); }; $scope.$on('$destroy', function() { if(!$scope.changed || $scope.cancelled) return; confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/backupJobs'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, ['backuptype']); if(apiParams.time_parsed) apiParams.time = $scope.strToTime(apiParams.time_parsed); apiParams.action = $scope.details._id ? 'modify' : 'create'; $scope.validateSchedules($scope.saveData.schedules, function(isConfirm) { if(isConfirm) { api.manageBackupJob({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.details = util.duplicateObject($scope.saveData); $scope.updateData($scope.details); if(callback === undefined) { if (apply) $location.path('/backupJobManage/' + data._id); else $location.path('/backupJobs'); alert.success(message); } if(callback !== undefined && typeof callback === 'function') callback(); }, failed: function (message) { $scope.saveing = false; alert.error(message); if(callback !== undefined && typeof callback === 'function') callback(); } }); } else $scope.saveing = false; }); }; $scope.hideTime = function() { if(!$scope.saveData.schedules || !$scope.saveData.schedules.length) return true; for(var i=0; i < $scope.saveData.schedules.length; i++) { if ($scope.schedules[$scope.saveData.schedules[i]._id].type < 5) return false; } return true; }; $scope.$on('fetchJobData', function(event, data) { $scope.fetchJobData(data._id, data.callback); }); $scope.fetchJobData = function() { api.getBackupJob({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; $scope.details.time_parsed = $scope.timeToStr($scope.details.time); $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete.accountText = $scope.saveData.owner_name; $scope.buildFilters(); } }); }; $scope.fetchBackupJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listBackupJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.backup_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.fetchCloneJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listCloneJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.clone_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.scheduleDisplay = function(schedule) { var list = []; switch(schedule.type) { case consts.SCHEDULE_TYPE_HOURLY: return lang.t("Hourly Schedule runs every %s Hours", schedule.type_data); case consts.SCHEDULE_TYPE_DAILY: list = schedule.type_data.map(function (value) { return consts.SCHEDULE_WEEK_DAYS_NAMES[value]; }); return lang.t("Daily Schedule runs every %s", schedule.type_data.length === 7 ? lang.t("day") : list.join(", ")); case consts.SCHEDULE_TYPE_WEEKLY: return lang.t("Weekly Schedule runs every %s", consts.SCHEDULE_WEEK_DAYS_NAMES[schedule.type_data]); case consts.SCHEDULE_TYPE_MONTHLY: list = schedule.type_data.map(function (value) { value = String(value); return value + consts.SCHEDULE_TYPE_MONTHLY_SUFFIX[value.substr(value.length-1)]; }); return lang.t("Monthly Schedule runs every %s of every month", list.join(", ")); case consts.SCHEDULE_TYPE_BACKUP_DONE: return lang.t("Runs %safter the \"%s\" backup job End", (schedule.delay_amount > 0 ? schedule.delay_amount + ' ' + consts.SCHEDULE_DELAY_TYPE_NAMES[schedule.delay_type] + ' ' : ''), $scope.backup_job_names[schedule.type_data]); case consts.SCHEDULE_TYPE_CLONE_DONE: return lang.t("Runs %safter the \"%s\" clone job End", (schedule.delay_amount > 0 ? schedule.delay_amount + ' ' + consts.SCHEDULE_DELAY_TYPE_NAMES[schedule.delay_type] + ' ' : ''), $scope.clone_job_names[schedule.type_data]); } }; $scope.fetchFilters(function () { $scope.fetchBackupJobs(function () { $scope.fetchCloneJobs(function () { $scope.fetchSchedules(function () { $scope.fetchDestinations(function () { $scope.fetchJobData(); }); }); }); }); }); } ] ); }); define('controllers/cloneJobs',['app'], function(app) { app.controller("cloneJobs", ["$rootScope", "$scope", "$location", "$timeout", "$sce", "$interval", "$q", "api", "meta", "lang", "filter", "consts", "confirm", "alert", function ($rootScope, $scope, $location, $timeout, $sce, $interval, $q, api, meta, lang, filter, consts, confirm, alert) { $rootScope.$emit('menuItem', 'CloneJobs'); $scope.jobs = []; $scope.checkingJob = {}; $scope.loadingJobs = false; $scope.filters = {}; $scope.destinations = undefined; $scope.running = {}; $scope.checkRunningInterval = null; $scope.run_now = false; $scope.currentTime = parseInt(Date.now() / 1000); $interval(function () { $scope.currentTime = parseInt(Date.now() / 1000); }, 100); $scope.loaders = { state: false, quota: false, runnow: false, duplicate: false, delete: false }; meta = meta.new("clone_jobs"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","owner","retain","last_run","disabled"]); meta.setTotalItems($scope.jobs.length); $scope.viewLogs = function(job) { var logsFilter = filter.new("logs_filter"); logsFilter.setFilter(consts.LOG_TYPE_CLONE); var logsSubFilter = filter.new("logs_subfilter"); logsSubFilter.setFilter(job._id); $scope.changeView('/logs'); }; $scope.duplicate = function(job) { confirm.open({ message: lang.t("This clone job will be duplicated!"), confirm: function () { $scope.loaders.duplicate = true; api.duplicateCloneJob({ data: { _id: job._id }, success: function (data, message) { $scope.loaders.duplicate = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.duplicate = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.toggleState = function(job) { $scope.loaders.state = true; var newState = !job.disabled; api.manageCloneJob({ data: { action: 'modify', _id: job._id, disabled: newState }, success: function(data) { $scope.loaders.state = false; job.disabled = data.disabled; job.next_run = data.next_run; }, failed: function (message) { $scope.loaders.state = false; alert.error(message); } }); }; $scope.runCloneJobManually = function(job) { if($scope.loaders.runnow) return; $scope.loaders.runnow = true; api.runCloneJobManually({ data: { _id: job._id }, success: function (data, message) { $scope.loaders.runnow = false; for(var key in data) job[key] = data[key]; $scope.running[job._id] = job; alert.success(message); }, failed: function (message) { $scope.loaders.runnow = false; alert.error(message); } }); }; $scope.onClickDelete = function(job) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This clone job will be permanently deleted!"), confirm: function () { api.deleteCloneJob({ data: { _id: job._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; api.listAccountFilters({ success: function (data) { for(var i = 0; i < data.filters.length; i++) { $scope.filters[data.filters[i].group_id] = data.filters[i].name; } } }); $scope.createCloneJob = function() { $scope.destinationsCheck(function () { $scope.changeView('/cloneJobManage'); }); }; $scope.destinationsCheck = function (callback) { if(callback === undefined) callback = function () {}; if($scope.destinations !== undefined) { if(!$scope.destinations) { alert.error(lang.t("You must first create a destination before creating a clone job for this server")); return; } callback(); return; } $scope.destinations = false; api.listDestinations({ data: { readonly:0 }, success: function(data) { $scope.destinations = !!data.destinations.length; if(!$scope.destinations) { alert.error(lang.t("You must first create a destination before creating a clone job for this server")); return; } callback(); }, failed: function (message) { alert.error(message); } }); }; $scope.checkRunning = function() { for(var id in $scope.running) { api.getCloneJob({ data: { _id: id }, success: function (data) { if(data.running) return; for(var key in data) $scope.running[id][key] = data[key]; delete $scope.running[id]; } }); } }; $scope.$on('$destroy', function() { if($scope.checkRunningInterval === null) return; clearInterval($scope.checkRunningInterval); $scope.checkRunningInterval = null; }); $scope.fetch = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function() {}; $scope.loadingJobs = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.jobs = []; $scope.running = {}; api.listCloneJobs({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.jobs); $scope.jobs = data.jobs; for(var i = 0; i < $scope.jobs.length; i++) { var job = $scope.jobs[i]; var type = parseInt(job.type); var contains = parseInt(job.contains); var names = []; switch(type) { case consts.CLONE_TYPE_ACCOUNT: if(contains == consts.CLONE_TYPE_ACCOUNT_FULL) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_FULL]); else { if(contains & consts.CLONE_TYPE_ACCOUNT_CONFIG) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CONFIG]); if(contains & consts.CLONE_TYPE_ACCOUNT_HOMEDIR) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.CLONE_TYPE_ACCOUNT_DATABASES) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASES]); if(contains & consts.CLONE_TYPE_ACCOUNT_EMAILS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_EMAILS]); if(contains & consts.CLONE_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.CLONE_TYPE_ACCOUNT_DOMAINS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.CLONE_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CERTIFICATES]); } break; /* case consts.CLONE_TYPE_DIRECTORY: names.push(consts.CLONE_TYPE_DIRECTORY_NAMES[consts.CLONE_TYPE_DIRECTORY_FULL]); break; */ } job.contains_name = names.join(', '); job.filters_sorted = []; if(job.filters !== undefined) { for(var j = 0; j < job.filters.length; j++) { for(var a = 0; a < job.filters[j].length; a++) { job.filters_sorted.push(job.filters[j][a]); } } } if(job.running) $scope.running[job._id] = job; var destinations_list = []; job.destinations = ''; for(var k = 0; k < job.destination_details.length; k++) destinations_list.push(job.destination_details[k].name + (job.destination_details[k].disabled ? " <span style=\"color: #cc0000; font-size: 11px;\">(" + lang.t("Disabled") + ")</span>" : '')); job.destinations = $sce.trustAsHtml(destinations_list.join(", ")); //job.next_run_int = job.next_run ? parseInt((new Date(job.next_run)).getTime() / 1000) : 0; } $scope.loadingJobs = false; callback(); } }); }; $timeout(function () { $scope.fetch(function () { $scope.checkRunningInterval = setInterval($scope.checkRunning, 3000); }); }); } ] ); }); define('controllers/cloneJobManage',['app'], function(app) { app.controller("cloneJobManage", ["$rootScope", "$scope", "$routeParams", "$templateCache", "$route", "$location", "$timeout", "$q", "api", "meta", "util", "lang", "alert", "permissions", "consts", "filterManager", "confirm", "popup", function ($rootScope, $scope, $routeParams, $templateCache, $route, $location, $timeout, $q, api, meta, util, lang, alert, permissions, consts, filterManager, confirm, popup) { $rootScope.$emit('menuItem', 'cloneJobs'); $scope.saveData = { name: '', destination: '', owner: $scope.loggedAccount._id, owner_name: $scope.loggedAccount.username, type: consts.CLONE_TYPE_ACCOUNT, contains: consts.CLONE_TYPE_ACCOUNT_FULL, //options: 0, default_package: '', default_owner: '', suspend_after: 0, time_parsed: '12:00 AM', time: 0, monitor: {ranfor:0,notran:0}, schedules: [], filters: [], include_list: [], exclude_list: [] }; $scope.autocomplete = { accountText: $scope.saveData.owner_name }; $scope.details = {}; $scope.destinations = {}; $scope.schedules = {}; $scope.filters = {}; $scope.backup_job_names = {}; $scope.clone_job_names = {}; $scope.cancelled = false; $scope.excluderow = ''; $scope.includerow = ''; $scope.types = [ { label: consts.CLONE_TYPE_NAMES[consts.CLONE_TYPE_ACCOUNT], value: consts.CLONE_TYPE_ACCOUNT } ]; $scope.account_types = [ //{ label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CONFIG], value: consts.CLONE_TYPE_ACCOUNT_CONFIG }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_HOMEDIR], value: consts.CLONE_TYPE_ACCOUNT_HOMEDIR }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASES], value: consts.CLONE_TYPE_ACCOUNT_DATABASES }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASE_USERS], value: consts.CLONE_TYPE_ACCOUNT_DATABASE_USERS }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_EMAILS], value: consts.CLONE_TYPE_ACCOUNT_EMAILS }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_FTP], value: consts.CLONE_TYPE_ACCOUNT_FTP }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CRON_JOBS], value: consts.CLONE_TYPE_ACCOUNT_CRON_JOBS }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DOMAINS], value: consts.CLONE_TYPE_ACCOUNT_DOMAINS }, { label: consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CERTIFICATES], value: consts.CLONE_TYPE_ACCOUNT_CERTIFICATES } ]; $scope.filtersConditions = [ {_id:1,name:lang.t("OR")}, {_id:2,name:lang.t("AND")} ]; $scope.filtersStructure = []; $scope.$watch("filtersStructure", function(){ $scope.buildFilters(true); }, true); $scope.selectAccount = function(account) { if(account === undefined) return; $scope.saveData.owner = account._id; $scope.saveData.owner_name = account.username; $scope.autocomplete.accountText = account.username; var activeElement = document.activeElement; if (activeElement) activeElement.blur(); }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.buildFilters = function(revert) { if(revert === undefined) revert = false; if(revert) $scope.saveData.filters = filterManager.buildFilters($scope.filtersStructure); else if($scope.saveData.filters !== undefined) $scope.filtersStructure = filterManager.reBuildStructure($scope.saveData.filters); }; $scope.removeFilter = function(index) { $scope.filtersStructure = filterManager.removeFilter($scope.filtersStructure, index); }; $scope.upFilter = function(index) { if(index === 0) return; var clickedValue = $scope.filtersStructure[index]; var upValue = $scope.filtersStructure[index-1]; if(index === 1) { upValue.cond = clickedValue.cond; delete clickedValue.cond; } $scope.filtersStructure[index] = upValue; $scope.filtersStructure[index-1] = clickedValue; }; $scope.downFilter = function(index) { if(index === ($scope.filtersStructure.length-1)) return; var clickedValue = $scope.filtersStructure[index]; var downValue = $scope.filtersStructure[index+1]; if(index === 0) { clickedValue.cond = downValue.cond; delete downValue.cond; } $scope.filtersStructure[index] = downValue; $scope.filtersStructure[index+1] = clickedValue; }; $scope.fileBrowse = function() { popup.open({ size: "lg", template: 'fileBrowse', scope: $scope, resolve: { listPaths: function () { return $scope.saveData.include_list; } } }).result.then(function(paths) { $scope.saveData.include_list = paths; }, function() {}); }; $scope.filterSelection = function () { popup.open({ size: "lg", template: 'accountFilterGroupSelection', scope: $scope, resolve: { filters: function() { return $scope.filters; } , details: function() { return $scope.details; } } }).result.then(function(filter_id) { if(!filter_id) return; var data = { _id: filter_id }; if($scope.filtersStructure.length > 0) data.cond = 1; $scope.filtersStructure.push(data); }, function () {}); }; $scope.manageDestination = function() { popup.open({ template: 'destinationsSelection', scope: $scope, resolve: { destinations: function() { return $scope.saveData.destination; }, readonly: function () { return false; }, types: function () { return consts.DESTINATION_JOB_TYPE_CLONE; }, legacy: function () { return true; }, local: function () { return true; }, timebased: function () { return true; } } }).result.then(function(selected) { $scope.saveData.destination = selected; }, function () { //$log.info('Modal dismissed at: ' + new Date()); }); }; $scope.scheduleSelection = function (schedule) { popup.open({ size: "lg", template: 'scheduleSelection', scope: $scope, resolve: { schedules: function() { return $scope.schedules; } , schedule: function() { return schedule; }, details: function() { return $scope.saveData; }, retain: function () { return false; } } }).result.then(function(scheduleDetails) { if(!scheduleDetails._id) { alert.error(lang.t("No schedule selected")); return; } scheduleDetails.display = $scope.scheduleDisplay(scheduleDetails); $scope.schedules[scheduleDetails._id] = scheduleDetails; if(schedule !== undefined) { for(var i in scheduleDetails) { if(schedule[i] !== undefined) schedule[i] = scheduleDetails[i]; } } else { $scope.saveData.schedules.push({ _id: scheduleDetails._id, name: scheduleDetails.name, retain: scheduleDetails.retain, next_run: 0 }); } $scope.checkScheduleTimeMismatch(); }, function () {}); }; $scope.checkScheduleTimeMismatch = function () { var time = 0; for(var i = 0; i < $scope.saveData.schedules.length; i++) { if($scope.schedules[$scope.saveData.schedules[i]._id] === undefined) return; var currentSchedule = $scope.schedules[$scope.saveData.schedules[i]._id]; if([1,2,3,4].indexOf(currentSchedule.type) < 0) continue; if(currentSchedule.type === 1) { // TODO validate hourly times continue; } if(!time) time = currentSchedule.time; if(currentSchedule.time !== time) { $scope.scheduleTimeMismatch = true; return; } } $scope.scheduleTimeMismatch = false; }; $scope.removeSchedule = function (schedule) { confirm.open({ message: lang.t("Are you sure you want to remove this schedule from this job? Please note that all snapshots assigned to this schedule will be deleted in the next job run."), confirm: function () { for(var i = 0; i < $scope.saveData.schedules.length; i++) { if(schedule._id === $scope.saveData.schedules[i]._id) { $scope.saveData.schedules.splice(i, 1); $scope.checkScheduleTimeMismatch(); break; } } alert.success("Schedule removed successfully"); } }); }; $scope.timeToStr = function(time) { time = parseInt(time); var ampm = 'AM'; if(time >= 1200) { ampm = 'PM'; time -= 1200; } time = '' + time; if(time.length < 2) time = '0' + time; var minute = time.substr(-2); var hour = time.length > 2 ? time.substr(0, time.length-2) : 12; if(parseInt(hour) < 10) hour = "0" + parseInt(hour); return hour + ":" + minute + " " + ampm; }; $scope.strToTime = function (str) { var matches = /^([0-9]+):([0-9]+)\s+(AM+|PM+)$/g.exec(str); if(!matches) return 0; var output = parseInt(matches[1] + matches[2]); if(output >= 1200) output -= 1200; if(matches[3] === 'PM') output += 1200; return output; }; $scope.validateListPath = function (path, allowPatterns) { if(!path.trim()) return false; if(allowPatterns) return !consts.PATH_FILTER_PATTERNS.test(path); return !consts.PATH_FILTER.test(path); }; $scope.typeChecked = function(type, types) { return ( type & types ); }; $scope.toggleOptionsTypes = function(option) { if($scope.typeChecked(option, $scope.saveData.options)) $scope.saveData.options ^= option; else $scope.saveData.options |= option; }; $scope.checkChange = function() { $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }; $scope.$watch("saveData", $scope.checkChange, true); $scope.$watch("details", $scope.checkChange, true); $scope.validateSchedules = function(schedules, callback) { if(schedules.length) return callback(true); confirm.open({ message: lang.t("We noticed that you didn't set any schedule for this job. That means that this job will never run automatically, only manually"), cancelLabel: lang.t("No, let me set schedules"), confirm: function () { callback(true); }, cancel: function () { callback(false); } }); }; $scope.fetchSchedules = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listSchedules({ success: function(data) { for (var i = 0; i < data.schedules.length; i++) { var id = data.schedules[i]._id; $scope.schedules[id] = data.schedules[i]; $scope.schedules[id].display = $scope.scheduleDisplay($scope.schedules[id]); } callback(); }, failed: function () { callback(); } }); }; $scope.fetchFilters = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listAccountFilterGroups({ success: function(data) { for(var i = 0; i < data.groups.length; i++) { $scope.filters[data.groups[i]._id] = data.groups[i]; } callback(); }, failed: function () { callback(); } }); }; $scope.fetchDestinations = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listDestinations({ success: function(data) { for(var i = 0; i < data.destinations.length; i++) { var destination = data.destinations[i]; destination.display = lang.t("%s destination", destination.type); $scope.destinations[destination._id] = destination; } callback(); } }); }; $scope.removeDestination = function (destination_id) { for(var i = 0; i < $scope.saveData.destination.length; i++) { if(destination_id === $scope.saveData.destination[i]) { $scope.saveData.destination.splice(i, 1); break; } } }; $scope.updateData = function(details) { $scope.details = details; $scope.saveData = util.duplicateObject($scope.details); $scope.checkScheduleTimeMismatch(); $scope.buildFilters(); }; $scope.toggleCloneType = function(type) { switch(type) { case consts.CLONE_TYPE_ACCOUNT: $scope.saveData.contains = consts.CLONE_TYPE_ACCOUNT_FULL; break; /* case consts.BACKUP_TYPE_DIRECTORY: $scope.saveData.contains = consts.BACKUP_TYPE_DIRECTORY_FULL; break; */ } }; $scope.toggleContains = function(type) { if($scope.typeChecked(type, $scope.saveData.contains)) $scope.saveData.contains ^= type; else $scope.saveData.contains |= type; }; var checkDuplicateIncludeItems = function(value, list) { var withoutTrailing = value.replace(/\/+$/, ''); var withTrailing = withoutTrailing + '/'; return (list.indexOf(withoutTrailing) >= 0 || list.indexOf(withTrailing) >= 0); }; $scope.addListRow = function (value, list) { if($scope[value] === undefined || !$scope[value].trim()) return; if(checkDuplicateIncludeItems($scope[value].trim(), list)){ alert.error(lang.t('The provided path ("%s") already exists on the list.', $scope[value].trim())); } else if($scope.validateListPath($scope[value].trim(), value === 'excluderow')) { list.push($scope[value].trim()); } else { alert.error(lang.t('The provided path ("%s") is invalid. The path must start with a "/"' + (value !== 'excluderow' ? ', also patterns are not allowed.' : '.'), $scope[value].trim() )); } $scope[value] = ''; }; $scope.addMultiListRow = function(type, list) { if(type == 'include') { $scope.listTitle = lang.t("Directories and Files to include"); $scope.listData = $scope.saveData.include_list.join("\n"); } else { $scope.listTitle = lang.t("Directories and Files to exclude"); $scope.listData = $scope.saveData.exclude_list.join("\n"); } $scope.listUIB = popup.open({ template: 'listSelection', noController: true, scope: $scope }); $scope.listUIB.result.then(function(records) { while(list.length) list.pop(); records = records.split("\n"); var invalidPaths = []; var duplicatePaths = []; for(var i = 0; i < records.length; i++) { if(type === 'include' && checkDuplicateIncludeItems(records[i], list)) duplicatePaths.push(records[i]); else if($scope.validateListPath(records[i], type === 'exclude')) { if (list.indexOf(records[i]) < 0 ) list.push(records[i]); } else invalidPaths.push(records[i]); } if(invalidPaths.length) alert.error(lang.t('The following paths ("%s") is invalid. The path must start with a "/" and can\'t have trailing "/"' + (type === 'include' ? ', also patterns are not allowed.' : '.'), invalidPaths.join(", ") )) if(duplicatePaths.length) alert.error(lang.t('The provided path(s) ("%s") already exists on the list.', duplicatePaths.join(", "))); }, function () {}); }; $scope.$on('$destroy', function() { if(!$scope.changed || $scope.cancelled) return; confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/cloneJobs'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, ['clonetype']); if(apiParams.time_parsed) apiParams.time = $scope.strToTime(apiParams.time_parsed); apiParams.action = $scope.details._id ? 'modify' : 'create'; $scope.validateSchedules($scope.saveData.schedules, function(isConfirm) { if(isConfirm) { api.manageCloneJob({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.details = util.duplicateObject($scope.saveData); $scope.updateData($scope.details); if(callback === undefined) { if (apply) $location.path('/cloneJobManage/' + data._id); else $location.path('/cloneJobs'); alert.success(message); } if(callback !== undefined && typeof callback === 'function') callback(); }, failed: function (message) { $scope.saveing = false; alert.error(message); if(callback !== undefined && typeof callback === 'function') callback(); } }); } else $scope.saveing = false; }); }; $scope.hideTime = function() { if(!$scope.saveData.schedules || !$scope.saveData.schedules.length) return true; for(var i=0; i < $scope.saveData.schedules.length; i++) { if ($scope.schedules[$scope.saveData.schedules[i]._id].type < 5) return false; } return true; }; $scope.$on('fetchJobData', function(event, data) { $scope.fetchJobData(data._id, data.callback); }); $scope.fetchJobData = function() { api.getCloneJob({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; $scope.details.time_parsed = $scope.timeToStr($scope.details.time); $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete.accountText = $scope.saveData.owner_name; $scope.buildFilters(); } }); }; $scope.fetchBackupJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listBackupJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.backup_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.fetchCloneJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listCloneJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.clone_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.scheduleDisplay = function(schedule) { var list = []; switch(schedule.type) { case consts.SCHEDULE_TYPE_HOURLY: return lang.t("Hourly Schedule runs every %s Hours", schedule.type_data); case consts.SCHEDULE_TYPE_DAILY: list = schedule.type_data.map(function (value) { return consts.SCHEDULE_WEEK_DAYS_NAMES[value]; }); return lang.t("Daily Schedule runs every %s", schedule.type_data.length === 7 ? lang.t("day") : list.join(", ")); case consts.SCHEDULE_TYPE_WEEKLY: return lang.t("Weekly Schedule runs every %s", consts.SCHEDULE_WEEK_DAYS_NAMES[schedule.type_data]); case consts.SCHEDULE_TYPE_MONTHLY: list = schedule.type_data.map(function (value) { value = String(value); return value + consts.SCHEDULE_TYPE_MONTHLY_SUFFIX[value.substr(value.length-1)]; }); return lang.t("Monthly Schedule runs every %s of every month", list.join(", ")); case consts.SCHEDULE_TYPE_BACKUP_DONE: return lang.t("Runs %safter the \"%s\" backup job End", (schedule.delay_amount > 0 ? schedule.delay_amount + ' ' + consts.SCHEDULE_DELAY_TYPE_NAMES[schedule.delay_type] + ' ' : ''), $scope.backup_job_names[schedule.type_data]); case consts.SCHEDULE_TYPE_CLONE_DONE: return lang.t("Runs %safter the \"%s\" clone job End", (schedule.delay_amount > 0 ? schedule.delay_amount + ' ' + consts.SCHEDULE_DELAY_TYPE_NAMES[schedule.delay_type] + ' ' : ''), $scope.clone_job_names[schedule.type_data]); } }; $scope.fetchFilters(function () { $scope.fetchBackupJobs(function () { $scope.fetchCloneJobs(function () { $scope.fetchSchedules(function () { $scope.fetchDestinations(function () { $scope.fetchJobData(); }); }); }); }); }); } ] ); }); define('controllers/permissions',['app'], function(app) { app.controller("permissions", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "confirm", "util", "permissions", "lang", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, confirm, util, permissions, lang, alert) { $rootScope.$emit('menuItem', 'Permissions'); $scope.saveing = false; $scope.changed = false; $scope.loading = false; $scope.totalFiltered = 0; $scope.selectedAccount = ''; $scope.autocomplete = { accountText: '' }; $scope.details = {}; $scope.filtered = {}; $scope.saveData = {}; $scope.meta = { sectionValue: -1, filterType: 1, filterValue: "" }; $scope.permissions = { canView: false, canManage: false }; $scope.types = [ { value: 1, label: lang.t('Global Permissions') }, { value: 2, label: lang.t('Specific Permissions') } ]; $scope.fetch = function() { if($scope.meta.filterType === 2 && !$scope.selectedAccount) { $scope.details = {}; $scope.filtered = {}; $scope.saveData = {}; $scope.totalFiltered = 0; return; } $scope.loading = true; var apiParams = {}; if($scope.meta.filterType === 2 && $scope.selectedAccount) apiParams.username = $scope.selectedAccount; api.getPermissions({ data: apiParams, success: function(data) { $scope.details = data.permissions; $scope.totalFiltered = 1; $scope.saveData = util.duplicateObject($scope.details); $scope.filteredList(); $scope.loading = false; } }); }; $scope.startFetching = function () { $scope.details = {}; $scope.filtered = {}; $scope.saveData = {}; $scope.totalFiltered = 0; $scope.fetch(); }; $scope.resetPermissions = function () { confirm.open({ message: ($scope.meta.filterType === 2 && $scope.selectedAccount) ? lang.t('Are you sure you want to reset all permissions for the account "%s" to defaults?', $scope.selectedAccount) : lang.t("Are you sure you want to reset all permissions to defaults?"), confirm: function () { var apiParams = {}; if($scope.meta.filterType === 2 && $scope.selectedAccount) apiParams.username = $scope.selectedAccount; api.resetPermissions({ data: apiParams, success: function(data, message) { alert.success(message); $scope.startFetching(); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.selectAccount = function(account) { if(account === undefined) return; $scope.selectedAccount = account.username; //$scope.autocomplete.accountText = account.username; $scope.startFetching(); }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.filteredList = function() { $scope.filtered = {}; $scope.totalFiltered = 0; if(!$scope.meta.filterValue && $scope.meta.sectionValue === -1) { $scope.totalFiltered = 1; $scope.filtered = util.duplicateObject($scope.details); return; } for(var i in $scope.details) { var details = permissions.get(i); if(details === null) continue; if( ($scope.meta.filterValue && !(new RegExp('(' + $scope.meta.filterValue + ')', 'gi')).test(details.name)) || ($scope.meta.sectionValue >= 0) ) continue; $scope.totalFiltered++; $scope.filtered[i] = $scope.details[i]; } }; $scope.$on('$destroy', function() { if($scope.changed) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.startFetching(); $scope.$watch("autocomplete.accountText", function() { if($scope.autocomplete.accountText !== '') return; $scope.selectAccount({ username: '' }); }); $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details); }, true); $scope.saveChanges = function(callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = { permissions: util.saveParams($scope.saveData, $scope.details) }; if($scope.meta.filterType === 2 && $scope.selectedAccount) apiParams.username = $scope.selectedAccount; api.managePermissions({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.details = util.duplicateObject($scope.saveData); for(var i in apiParams.permissions) { if($scope.filtered[i] !== undefined) $scope.filtered[i] = apiParams.permissions[i]; } if(callback !== undefined) callback(); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; }]); }); define('controllers/schedules',['app'], function(app) { app.controller("schedules", ["$rootScope", "$scope", "$location", "$timeout", "api", "lang", "meta", "confirm", "alert", "consts", function ($rootScope, $scope, $location, $timeout, api, lang, meta, confirm, alert, consts) { $rootScope.$emit('menuItem', 'Schedules'); $scope.schedules = []; $scope.loadingSchedules = false; $scope.backup_job_names = {}; $scope.clone_job_names = {}; $scope.loaders = { delete: false }; meta = meta.new("schedules"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","owner"]); meta.setTotalItems($scope.schedules.length); $scope.onClickDelete = function(schedule) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This schedule will be permanently deleted!"), confirm: function () { api.deleteSchedule({ data: { _id: schedule._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.scheduleDisplay = function(schedule) { var list = []; switch(schedule.type) { case consts.SCHEDULE_TYPE_HOURLY: return lang.t("Hourly Schedule runs every %s Hours", schedule.type_data); case consts.SCHEDULE_TYPE_DAILY: list = schedule.type_data.map(function (value) { return consts.SCHEDULE_WEEK_DAYS_NAMES[value]; }); return lang.t("Daily Schedule runs every %s", schedule.type_data.length === 7 ? lang.t("day") : list.join(", ")); case consts.SCHEDULE_TYPE_WEEKLY: return lang.t("Weekly Schedule runs every %s", consts.SCHEDULE_WEEK_DAYS_NAMES[schedule.type_data]); case consts.SCHEDULE_TYPE_MONTHLY: list = schedule.type_data.map(function (value) { value = String(value); return value + consts.SCHEDULE_TYPE_MONTHLY_SUFFIX[value.substr(value.length-1)]; }); return lang.t("Monthly Schedule runs every %s of every month", list.join(", ")); case consts.SCHEDULE_TYPE_BACKUP_DONE: return lang.t("Runs after the \"%s\" backup job Ends", $scope.backup_job_names[schedule.type_data]); case consts.SCHEDULE_TYPE_CLONE_DONE: return lang.t("Runs after the \"%s\" clone job Ends", $scope.clone_job_names[schedule.type_data]); } }; $scope.fetchBackupJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listBackupJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.backup_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.fetchCloneJobs = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function() {}; api.listCloneJobs({ success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.clone_job_names[data.jobs[i]._id] = data.jobs[i].name; } callback(); }, failed: function () { callback(); } }) }; $scope.fetch = function() { $scope.loadingSchedules = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.schedules = []; api.listSchedules({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.schedules); $scope.schedules = data.schedules; $scope.loadingSchedules = false; } }); }; $scope.fetchBackupJobs(function () { $scope.fetchCloneJobs(function () { $scope.fetch(); }); }); }]); }); define('controllers/scheduleManage',['app'], function(app) { app.controller("scheduleManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "meta", "lang", "util", "consts", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, api, meta, lang, util, consts, alert) { $rootScope.$emit('menuItem', 'BackupJobs'); $scope.saveData = {}; $scope.details = { name: '', type: 1, type_data: '', delay_type: 'minutes', delay_amount: 0 }; $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.types = [ //{ label: lang.t('Manually'), value: 8 }, { label: lang.t('Hourly'), value: consts.SCHEDULE_TYPE_HOURLY }, { label: lang.t('Daily'), value: consts.SCHEDULE_TYPE_DAILY }, { label: lang.t('Weekly'), value: consts.SCHEDULE_TYPE_WEEKLY }, { label: lang.t('Monthly'), value: consts.SCHEDULE_TYPE_MONTHLY }, { label: lang.t('After Backup Job Done'), value: consts.SCHEDULE_TYPE_BACKUP_DONE }, { label: lang.t('After Clone Job Done'), value: consts.SCHEDULE_TYPE_CLONE_DONE } ]; $scope.hours = [ { label: lang.t('Every Hour'), value: 1 }, { label: lang.t('Every 2 Hours'), value: 2 }, { label: lang.t('Every 3 Hours'), value: 3 }, { label: lang.t('Every 4 Hours'), value: 4 }, { label: lang.t('Every 6 Hours'), value: 6 }, { label: lang.t('Every 8 Hours'), value: 8 }, { label: lang.t('Every 12 Hours'), value: 12 } ]; $scope.days = [ { label: lang.t('Sunday'), value: 1 }, { label: lang.t('Monday'), value: 2 }, { label: lang.t('Tuesday'), value: 3 }, { label: lang.t('Wednesday'), value: 4 }, { label: lang.t('Thursday'), value: 5 }, { label: lang.t('Friday'), value: 6 }, { label: lang.t('Saturday'), value: 7 } ]; $scope.months = [ { label: lang.t('%sst of the month', 1), value: 1 }, { label: lang.t('%sth of the month', 7), value: 7 }, { label: lang.t('%sth of the month', 14), value: 14 }, { label: lang.t('%sst of the month', 21), value: 21 }, { label: lang.t('%sth of the month', 28), value: 28 } ]; $scope.delay_types = [ { label: lang.t('Minutes'), value: consts.SCHEDULE_DELAY_TYPE_MINUTES }, { label: lang.t('Hours'), value: consts.SCHEDULE_DELAY_TYPE_HOURS }, { label: lang.t('Days'), value: consts.SCHEDULE_DELAY_TYPE_DAYS } ]; $scope.backups = [ { _id: '', name: lang.t("- Select Backup Job -") } ]; $scope.clones = [ { _id: '', name: lang.t("- Select Clone Job -") } ]; $scope.toggleTypeData = function(value) { var idx = $scope.saveData.type_data.indexOf(value); if (idx > -1) $scope.saveData.type_data.splice(idx, 1); else $scope.saveData.type_data.push(value); }; $scope.loadScheduleType = function(type, defaults) { if($scope.saveData !== undefined) var name = $scope.saveData.name; $scope.saveData = util.duplicateObject($scope.details); if(name !== undefined) $scope.saveData.name = name; if(typeof $scope.details.type_data === 'object') { $scope.saveData.type_data = []; for(var i = 0; i < $scope.details.type_data.length; i++) $scope.saveData.type_data.push($scope.details.type_data[i]); } $scope.saveData.type = type; var mongoIdPattern = new RegExp("^[a-f0-9]{24}$", 'g'); switch(type) { case consts.SCHEDULE_TYPE_HOURLY: if(defaults) $scope.saveData.type_data = 1; break; case consts.SCHEDULE_TYPE_DAILY: case consts.SCHEDULE_TYPE_MONTHLY: if(defaults) $scope.saveData.type_data = []; break; case consts.SCHEDULE_TYPE_WEEKLY: if(defaults) $scope.saveData.type_data = 1; break; case consts.SCHEDULE_TYPE_BACKUP_DONE: if( $scope.saveData.type_data === undefined || typeof $scope.saveData.type_data !== 'string' || !mongoIdPattern.test($scope.saveData.type_data.trim()) ) $scope.saveData.type_data = ''; api.listBackupJobs({ success: function(data) { for(var i = 0; i < data.jobs.length; i++) { if($scope.excludeids && $scope.excludeids.indexOf(data.jobs[i]._id) >=0) continue; $scope.backups.push({ _id: data.jobs[i]._id, name: data.jobs[i].name }); } } }); break; case consts.SCHEDULE_TYPE_CLONE_DONE: if( $scope.saveData.type_data === undefined || typeof $scope.saveData.type_data !== 'string' || !mongoIdPattern.test($scope.saveData.type_data.trim()) ) $scope.saveData.type_data = ''; api.listCloneJobs({ success: function(data) { for(var i = 0; i < data.jobs.length; i++) { if($scope.excludeids && $scope.excludeids.indexOf(data.jobs[i]._id) >=0) continue; $scope.clones.push({ _id: data.jobs[i]._id, name: data.jobs[i].name }); } } }); break; } }; $scope.fetchScheduleData = function(schedule_id) { api.getSchedule({ data: { _id: schedule_id }, success: function(data) { $scope.details = data; //$scope.details.time = $scope.details.time_parsed; $scope.loadScheduleType($scope.details.type); } }); }; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id','checked']); }, true); $scope.$on('createSchedule', function (event) { $scope.saveChanges(true, function(state, data, message) { $scope.$emit('scheduleResponse', { success: state, data: data, message: message }); }); }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/schedules'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, [], function (key) { if(key === 'type') return true; // More validations return false; }); //if([2,3,4].indexOf(apiParams.type) >= 0 && typeof apiParams.time === 'string') apiParams.time = $scope.parseTime(apiParams.time); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageSchedule({ data: apiParams, success: function(data, message) { $scope.saveing = false; if(callback !== undefined) { callback(true, data, message); return; } $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/scheduleManage/' + data._id); else $location.path('/schedules'); alert.success(message); }, failed: function (message) { $scope.saveing = false; if(callback !== undefined) { callback(false, {}, message); return; } alert.error(message); } }); }; var schedule_id = $routeParams.id; if(schedule_id) $timeout($scope.fetchScheduleData(schedule_id)); else $scope.loadScheduleType($scope.details.type, true); }]); }); define('controllers/scheduleManagePopup',['app'], function(app) { app.controller('scheduleManagePopup', ["$uibModalInstance", "$routeParams", "$rootScope", "$scope", "api", "lang", "schedule", "excludeids", "alert", function($uibModalInstance, $routeParams, $rootScope, $scope, api, lang, schedule, excludeids, alert) { $scope.excludeids = excludeids; $scope.schedule = schedule; /* $scope.saveData = { name: '', type: 1, typedata: '', time: '01:00 AM', delaytype: 'minutes', delayamount: 0 }; */ $routeParams.id = null; $scope.saveData = {}; if($scope.schedule) $routeParams.id = $scope.schedule._id; $scope.$on('scheduleResponse', function (event, response) { if(!response.success) { alert.error(response.message); return; } api.getSchedule({ data: { _id: response.data._id }, success: function(data) { alert.success(response.message); $uibModalInstance.close(data); }, failed: function (message) { alert.error(message); } }); }); $scope.ok = function () { $rootScope.$broadcast('createSchedule'); }; $scope.cancel = function () { $uibModalInstance.dismiss(); }; }]); }); define('controllers/scheduleSelection',['app'], function(app) { app.controller('scheduleSelection', ["$uibModalInstance", "$scope", "lang", "schedules", "schedule", "details", "alert", "retain", "popup", function($uibModalInstance, $scope, lang, schedules, schedule, details, alert, retain, popup) { $scope.schedule = schedule; $scope.schedules = []; $scope.allSchedules = schedules; $scope.includeRetain = retain; $scope.scheduleDetails = { retain: 0 }; $scope.details = (schedule !== undefined) ? schedule : { _id: '', retain: 0 } function checkScheduleId(id) { for(var i = 0; i < $scope.schedules.length; i++) if($scope.schedules[i]._id == id) return true; return false; } $scope.newSchedule = function () { popup.open({ size: "lg", template: 'scheduleManagePopup', scope: $scope, resolve: { schedule: function() { return {}/*schedule*/; }, excludeids: function() { return []; } } }).result.then(function(scheduleDetails) { if(!scheduleDetails._id) { alert.error(lang.t("Failed to create schedule")); return; } $scope.allSchedules[scheduleDetails._id] = scheduleDetails; $scope.calculateUsableSchedules(function () { if(!checkScheduleId(scheduleDetails._id)) { alert.error(lang.t("You can't use this type of schedule as same schedule type is already assigned to this job")); return; } $scope.details._id = scheduleDetails._id; }); }, function () {}); }; $scope.calculateUsableSchedules = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; $scope.schedules = []; $scope.schedulesTypesInUse = []; for(var i = 0; i < details.schedules.length; i++) { if(schedules[details.schedules[i]._id] === undefined) continue; $scope.schedulesTypesInUse.push(schedules[details.schedules[i]._id].type); } for(var i in $scope.allSchedules) { if((schedule === undefined || $scope.allSchedules[schedule._id].type !== $scope.allSchedules[i].type) && $scope.schedulesTypesInUse.indexOf($scope.allSchedules[i].type) >= 0) continue; var add = true; for(var a = 0; a < details.schedules.length; a++) { if( (i === details.schedules[a]._id && (schedule === undefined || schedule._id !== i)) ) { add = false; break; } } if(add) { $scope.allSchedules[i].label = $scope.allSchedules[i].name + ' (' + $scope.allSchedules[i].type_name + ')'; $scope.schedules.push($scope.allSchedules[i]); } } callback(); }; $scope.calculateUsableSchedules(); $scope.$watch('details', function() { if(!$scope.details._id) { if($scope.schedules.length) { $scope.scheduleDetails = $scope.schedules[0]; $scope.details._id = $scope.scheduleDetails._id; } return; } $scope.scheduleDetails = $scope.allSchedules[$scope.details._id]; $scope.scheduleDetails.retain = $scope.details.retain; }, true); /* if(schedule !== undefined) { for(var i in schedule) $scope.scheduleDetails[i] = schedule[i]; } else { if($scope.schedules.length) { for(var i in $scope.schedules[0]) $scope.scheduleDetails[i] = $scope.schedules[0][i]; } else { $scope.scheduleDetails = { retain: 0 }; } } */ $scope.ok = function () { $scope.scheduleDetails.retain = parseInt($scope.scheduleDetails.retain); $uibModalInstance.close( $scope.scheduleDetails ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }]); }); define('controllers/queue',['app'], function(app) { app.controller("queue", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "consts", "lang", "permissions", "confirm", "alert", "popup", function ($rootScope, $scope, $location, $timeout, api, meta, consts, lang, permissions, confirm, alert, popup) { $rootScope.$emit('menuItem', 'Queue'); var type = consts.QUEUE_ITEM_TYPE_BACKUP | consts.QUEUE_ITEM_TYPE_CLONE | consts.QUEUE_ITEM_TYPE_REINDEX; if(permissions.canRestoreBackups) type |= consts.QUEUE_ITEM_TYPE_RESTORE; if(permissions.canDownloadBackups) type |= consts.QUEUE_ITEM_TYPE_DOWNLOAD; if(permissions.isRoot) type |= (consts.QUEUE_ITEM_TYPE_SECURITY | consts.QUEUE_ITEM_TYPE_INTEGRITY_CHECK | consts.QUEUE_ITEM_TYPE_SNAPSHOT_DELETE | consts.QUEUE_ITEM_TYPE_EXTENSION_INSTALLATION | consts.QUEUE_ITEM_TYPE_EXTENSION_QUEUE); var groupsProcessing = []; var groupsById = {}; $scope.groups = []; $scope.loadingGroups = false; $scope.stopping = false; $scope.destroy = false; $scope.filter = type; $scope.filterOptions = [ { label: lang.t('All Queue Items'), value: type }, { label: lang.t('Backup Queue Items'), value: consts.QUEUE_ITEM_TYPE_BACKUP }, { label: lang.t('Clone Queue Items'), value: consts.QUEUE_ITEM_TYPE_CLONE } ]; if(permissions.canRestoreBackups) $scope.filterOptions.push({ label: lang.t('Restore Queue Items'), value: consts.QUEUE_ITEM_TYPE_RESTORE }); if(permissions.canDownloadBackups) $scope.filterOptions.push({ label: lang.t('Download Queue Items'), value: consts.QUEUE_ITEM_TYPE_DOWNLOAD }); if(permissions.isRoot) { $scope.filterOptions.push({ label: lang.t('Security Queue Items'), value: consts.QUEUE_ITEM_TYPE_SECURITY }); $scope.filterOptions.push({ label: lang.t('Integrity Check Queue Items'), value: consts.QUEUE_ITEM_TYPE_INTEGRITY_CHECK }); $scope.filterOptions.push({ label: lang.t('Snapshot Cleanup Queue Items'), value: consts.QUEUE_ITEM_TYPE_SNAPSHOT_DELETE }); $scope.filterOptions.push({ label: lang.t('Wordpress Installation'), value: consts.QUEUE_ITEM_TYPE_EXTENSION_INSTALLATION }); $scope.filterOptions.push({ label: lang.t('Wordpress Mass Deployment'), value: consts.QUEUE_ITEM_TYPE_EXTENSION_QUEUE }); } $scope.filterOptions.push({ label: lang.t('Reindex Queue Items'), value: consts.QUEUE_ITEM_TYPE_REINDEX }); meta = meta.new("queue"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setTotalItems($scope.groups.length); $scope.stopGroup = function(group) { if($scope.stopping) return; $scope.stopping = true; api.stopQueueGroup({ data: { _id: group._id }, success: function (data, message) { $scope.stopping = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.stopping = false; alert.error(message); } }); }; var fetchGroups = function(apiParams, withLoader, callback) { if(withLoader === undefined) withLoader = true; if(callback === undefined || typeof callback !== 'function') callback = function(){}; api.listQueueGroups({ data: apiParams, withLoader: withLoader, success: function(data) { var groups = []; for(var i = 0; i < data.groups.length; i++) { var group = data.groups[i]; if(parseInt(group.items_completed) <= 0 || parseInt(group.items) <= 0) group.items_progress_percentage = 0 else group.items_progress_percentage = parseInt((parseInt(group.items_completed) / parseInt(group.items)) * 100); if(group.type === consts.QUEUE_ITEM_TYPE_BACKUP) { if(group.data.snapshot) { group.data = { schedule: lang.t("Backup on Demand"), account: group.owner_name, }; } else { group.data = { schedule: group.data.manually ? lang.t("Manually") : lang.t("Backup Job Schedule"), "Job Id": group.data._id, "Job Name": group.data.name, } } } groups.push(group); } callback(groups, data.total); }, failed: function (message) { alert.error(message); callback([], 0); } }); }; $scope.cancelAll = function() { confirm.open({ message: lang.t("All queue items will be cancelled"), confirm: function () { api.stopAllQueueGroup({ success: function(data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.viewGroupItems = function(group) { popup.open({ size: "xl", template: 'queueItems', scope: $scope, resolve: { group: function() { return group; } } }).result.then(function() {}, function () {}); }; $scope.viewGroupLog = function(group) { api.getQueueGroup({ data: { _id: group._id, get_log_contents: 1 }, success: function (data) { if(!data.log_contents) { alert.error(lang.t("No log content found")); return; } popup.open({ size: "lg", template: 'queueLogViewer', scope: $scope, resolve: { group: function() { return data; }, reload: function() { return function(callback) { api.getQueueGroup({ data: { _id: group._id, get_log_contents: 1 }, success: function (data) { if(callback !== undefined) callback(data); } }); } } } }).result.then(function() {}, function () {}); }, failed: function (message) { alert.error(message); } }); }; $scope.checkRunningStatusesTimeout = null; $scope.rerunFailedItem = function(group) { api.rerunFailedQueueGroup({ data: { _id: group._id }, success: function (data, message) { for(var key in data) group[key] = data[key]; groupsProcessing.push(group._id); $scope.startRunningStatuses(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.clear = function() { api.clearQueue({ success: function () { $scope.fetch(); }, failed: function (message) { alert.error(message); } }); }; $scope.fetch = function() { $scope.loadingGroups = true; var apiParams = { skip: meta.getSkip(), limit: meta.getPageSize(), type: $scope.filter }; $scope.groups = []; fetchGroups(apiParams, true, function(groups, total) { meta.setTotalItems(total); meta.calculate(groups); var allGroups = []; for(var i = 0; i < groups.length; i++) { var group = groups[i]; if(group.status < consts.QUEUE_STATUS_COMPLETED) groupsProcessing.push(group._id); groupsById[group._id] = group; allGroups.push(group); } $scope.groups = allGroups; if(groupsProcessing.length > 0) $scope.startRunningStatuses(); $scope.loadingGroups = false; }); }; var checkRunningStatuses = function() { fetchGroups({ type: $scope.filter }, false, function(groups, total) { for(var i = 0; i < groups.length; i++) { var group = groups[i]; var index = groupsProcessing.indexOf(group._id); if(index < 0) continue; for(var key in groupsById[group._id]) groupsById[group._id][key] = group[key]; if(group.status >= consts.QUEUE_STATUS_COMPLETED) groupsProcessing.splice(index, 1); } if(groupsProcessing.length > 0) $scope.startRunningStatuses(); }); }; $scope.clearRunningStatuses = function() { if($scope.checkRunningStatusesTimeout !== null) clearTimeout($scope.checkRunningStatusesTimeout); $scope.checkRunningStatusesTimeout = null; }; $scope.startRunningStatuses = function() { $scope.clearRunningStatuses(); if($scope.destroy) return; $scope.checkRunningStatusesTimeout = setTimeout(checkRunningStatuses, 1000); }; $scope.$on('$destroy', function() { $scope.destroy = true; $scope.clearRunningStatuses(); }); $timeout($scope.fetch); } ] ); }); define('controllers/queueItems',['app'], function(app) { app.controller('queueItems', ["$uibModalInstance", "$scope", "$timeout", "lang", "meta", "api", "consts", "alert", "group", "popup", function($uibModalInstance, $scope, $timeout, lang, meta, api, consts, alert, group, popup) { var itemsProcessing = []; var itemsById = {}; $scope.group = group; $scope.items = []; $scope.loadingItems = false; $scope.checkRunningStatusesTimeout = null; $scope.destroy = false; $scope.loaders = { view: false }; meta = meta.new("queue_items"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("priority"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["priority","started","ended","execution_time","owner","status"]); meta.setTotalItems($scope.items.length); meta.setPageSizes([5,10]); meta.setPageSize(10); meta.setLimit(10); $scope.viewLogItem = function(item) { $scope.loaders.view = true; api.getQueueItem({ data: { _id: item._id, get_log_contents: 1 }, success: function (data) { $scope.loaders.view = false; if(!data.content) { alert.error(lang.t("No log content found")); return; } popup.open({ size: "lg", template: 'logViewer', scope: $scope, resolve: { log: function() { return { _id: data._id, file: data.file, content: data.content, start_time: data.started, end_time: data.ended, execution_time: data.execution_time, status: consts.QUEUE_STATUS_TO_LOG[data.status] === undefined ? consts.LOG_STATUS_PROCESSING : consts.QUEUE_STATUS_TO_LOG[data.status], information: [] }; }, reload: function () { return function(callback) { api.getQueueItem({ data: { _id: item._id, get_log_contents: 1 }, success: function (data) { if(callback !== undefined) callback({ _id: data._id, file: data.file, content: data.content, start_time: data.started, end_time: data.ended, execution_time: data.execution_time, status: consts.QUEUE_STATUS_TO_LOG[data.status] === undefined ? consts.LOG_STATUS_PROCESSING : consts.QUEUE_STATUS_TO_LOG[data.status], information: [] }); } }); } } } }).result.then(function() {}, function () {}); }, failed: function (message) { $scope.loaders.view = false; alert.error(message); } }); }; var fetchItems = function(apiParams, withLoader, callback) { if(withLoader === undefined) withLoader = true; if(callback === undefined || typeof callback !== 'function') callback = function(){}; apiParams.group_id = $scope.group._id; api.listQueueItems({ data: apiParams, withLoader: withLoader, success: function(data) { callback(data.items, data.total); }, failed: function (message) { alert.error(message); callback([], 0); } }); }; var checkRunningStatuses = function() { fetchItems({}, false, function(items, total) { for(var i = 0; i < items.length; i++) { var item = items[i]; var index = itemsProcessing.indexOf(item._id); if(index < 0) continue; for(var key in itemsById[item._id]) itemsById[item._id][key] = item[key]; if(item.status >= consts.QUEUE_STATUS_COMPLETED) itemsProcessing.splice(index, 1); } if(itemsProcessing.length > 0) $scope.startRunningStatuses(); }); }; $scope.clearRunningStatuses = function() { if($scope.checkRunningStatusesTimeout !== null) clearTimeout($scope.checkRunningStatusesTimeout); $scope.checkRunningStatusesTimeout = null; }; $scope.startRunningStatuses = function() { $scope.clearRunningStatuses(); if($scope.destroy) return; $scope.checkRunningStatusesTimeout = setTimeout(checkRunningStatuses, 1000); }; $scope.fetch = function() { $scope.loadingItems = true; var apiParams = { skip: meta.getSkip(), limit: meta.getPageSize(), sort: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.items = []; fetchItems(apiParams, true, function (items, total) { meta.setTotalItems(total); meta.calculate(items); var allItems = []; for(var i = 0; i < items.length; i++) { var item = items[i]; if(item.status < consts.QUEUE_STATUS_COMPLETED) itemsProcessing.push(item._id); itemsById[item._id] = item; allItems.push(item); } $scope.items = allItems; if(itemsProcessing.length > 0) $scope.startRunningStatuses(); $scope.loadingItems = false; }); /* if(update === undefined) update = false; if(callback === undefined || typeof callback !== "function") callback = function(){}; if($scope.loadingItems) { if(update && !$scope.destroied) $scope.timeout = setTimeout(function() { $scope.fetch(true); }, 1000); return; } $scope.updating = update; $scope.loadingItems = true; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); //$scope.items = []; api.listQueueItems({ withLoader: !update, data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.items); if(update) { for(var i = 0; i < data.items.length; i++) { var item = data.items[i]; for(var j = 0; j < $scope.items.length; j++) { if($scope.items[j]._id !== item._id) continue; $scope.items[j].priority = item.priority; $scope.items[j].started = item.started; $scope.items[j].ended = item.ended; $scope.items[j].execution_time = item.execution_time; $scope.items[j].status = item.status; break; } } if(!$scope.destroied) $scope.timeout = setTimeout(function() { $scope.fetch(true); }, 1000); } else { $scope.items = data.items; } $scope.loadingItems = false; $scope.updating = false; callback(); } }); */ }; $scope.$on('$destroy', function() { $scope.destroy = true; $scope.clearRunningStatuses(); }); $timeout($scope.fetch); $scope.close = function () { $uibModalInstance.close(); }; }]); }); define('controllers/queueLogViewer',['app'], function(app) { app.controller('queueLogViewer', ["$uibModalInstance", "$scope", "$timeout", "consts", "group", "reload", function($uibModalInstance, $scope, $timeout, consts, group, reload) { $scope.group = group; $scope.autoScroll = true; $scope.logContent = null; $scope.timeout = null; $timeout(function () { $scope.logContent = document.getElementById('logContentQueue'); $scope.logContent.scrollTop = $scope.logContent.scrollHeight $scope.logContent.addEventListener('scroll', function () { $scope.autoScroll = Math.abs($scope.logContent.scrollHeight - $scope.logContent.scrollTop - $scope.logContent.clientHeight) < 1; }); }); $scope.reloadLog = function () { $scope.timeout = null; reload(function(data) { $scope.group = data; $timeout(function () { if ($scope.autoScroll && $scope.logContent) $scope.logContent.scrollTop = $scope.logContent.scrollHeight; }); if($scope.group.status < consts.QUEUE_STATUS_COMPLETED) $scope.timeout = setTimeout($scope.reloadLog, 2000); }); } if($scope.group.status < consts.QUEUE_STATUS_COMPLETED) $scope.reloadLog(); $scope.ok = function () { $uibModalInstance.close(); }; $scope.$on('$destroy', function () { if($scope.timeout) clearTimeout($scope.timeout); $scope.timeout = null; }); } ] ); }); define('controllers/queuePriorities',[ 'app' ], function(app) { app.controller("queuePriorities", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "$q", "api", "meta", "lang", "consts", "confirm", "alert", function ($rootScope, $scope, $location, $timeout, $interval, $q, api, meta, lang, consts, confirm, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.priorities = []; $scope.tags = {}; $scope.loadingPriorities = false; $scope.loaders = { default: false, delete: false }; meta = meta.new("queue_priorities"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name", "priority"]); meta.setTotalItems($scope.priorities.length); $scope.onClickDelete = function(priority) { if($scope.saveing) return; $scope.saveing = true; confirm.open({ message: lang.t("This queue priority will be permanently deleted!"), confirm: function () { $scope.loaders.delete = true; api.deleteQueuePriority({ data: { _id: priority._id }, success: function(data, message) { $scope.loaders.delete = false; $scope.saveing = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.delete = false; $scope.saveing = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.setDefault = function (priority) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.default = true; api.manageQueuePriority({ data: { action: 'modify', _id: priority._id, default: 1 }, success: function(data, message) { $scope.saveing = false; $scope.loaders.default = false; for(var i =0 ; i < $scope.priorities.length; i++) { if($scope.priorities[i].default) { $scope.priorities[i].default = 0; break; } } priority.default = 1; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.default = false; alert.error(message); } }); }; $scope.fetch = function() { $scope.loadingPriorities = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.priorities = []; api.listQueuePriorities({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.priorities); $scope.priorities = data.priorities; $scope.loadingPriorities = false; } }); }; $scope.fetchTags = function() { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) $scope.tags[data.tags[i]._id] = data.tags[i]; } }); }; $timeout(function () { $scope.fetchTags(); $scope.fetch(); }); } ] ); }); define('controllers/queuePriorityManage',[ 'app' ], function(app) { app.controller("queuePriorityManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "consts", "lang", "meta", "util", "confirm", "alert", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, consts, lang, meta, util, confirm, alert, popup) { $rootScope.$emit('menuItem', 'Settings'); $scope.details = {}; $scope.saveData = { name: '', tags: [], backup_priority: '', clone_priority: '', restore_priority: '', download_priority: '' }; $scope.tags = {}; $scope.saveing = false; $scope.status = undefined; $scope.changed = false; $scope.cancelled = false; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/queuePriorities'); }; $scope.searchTags = function(query) { if(!query) return []; var deferred = $q.defer(); api.listTags({ data: { filter: query, sort: { name: 1 }, find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function(data) { var results = []; for(var i = 0; i < data.tags.length; i++) { var tag = data.tags[i]; if($scope.saveData.tags.indexOf(tag._id) >= 0) continue; results.push(tag); } deferred.resolve( results ); } }); return deferred.promise; }; $scope.selectItem = function(item, obj) { if(item === undefined) return; $scope.saveData.tags.push(item._id); obj.searchItemText = ''; }; $scope.manageTags = function() { popup.open({ template: 'tagsSelection', scope: $scope, resolve: { tags: function() { return $scope.saveData.tags; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }).result.then(function(selected) { $scope.saveData.tags = selected; }, function () {}); }; $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageQueuePriority({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/queuePriorityManage/' + data._id); else $location.path('/queuePriorities'); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; $scope.fetch = function(priority_id) { api.getQueuePriority({ data: { _id: priority_id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; $scope.fetchTags = function() { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) $scope.tags[data.tags[i]._id] = data.tags[i]; var priority_id = $routeParams.id; if(priority_id) $timeout($scope.fetch(priority_id)); } }); }; $timeout(function () { $scope.fetchTags(); }); } ] ); }); define('controllers/security',['app'], function(app) { app.controller("security", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "meta", "confirm", "util", "lang", "consts", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, api, meta, confirm, util, lang, consts, alert) { $rootScope.$emit('menuItem', 'Security'); $scope.saveing = false; $scope.loading = false; $scope.pluginTemplate = ''; $scope.pluginsList = {}; $scope.publicDir = ''; $scope.plugins_available = {}; $scope.plugin_available = {}; $scope.saveData = { plugin: '', restore: 0, lock: 0, options: {} }; $scope.plugins = []; $scope.isAvailablePlugins = function() { return $scope.saveData.plugin && $scope.saveData.plugin.indexOf('AvailablePlugins') >= 0; }; $scope.changePlugin = function() { if(!$scope.saveData.plugin) { $scope.pluginTemplate = ''; $scope.details = {}; return; } if($scope.isAvailablePlugins()) { var parts = $scope.saveData.plugin.split("::"); $scope.plugin_available = $scope.plugins_available[parts[1]]; $scope.pluginTemplate = $scope.includePath('securityAvailablePlugins') } else { //$scope.saveData = util.duplicateObject($scope.pluginsList[$scope.plugin]); $scope.details = util.duplicateObject($scope.pluginsList[$scope.saveData.plugin]); lang.setDefaultNS('plugins-security-' + $scope.details.code); app.registerPluginController($scope.details, function(path) { $scope.publicDir = path; $scope.pluginTemplate = $scope.publicDir + '/view.htm?v=' + $scope.details.version; }); } }; $scope.installDestination = function() { if($scope.installing) return; $scope.installing = true; confirm.open({ message: lang.t("This plugin will be installed on this server!"), confirm: function () { api.installPlugin({ data: { package_id: $scope.plugin_available._id, disabled: 0 }, success: function (data, message) { $scope.installing = false; //$scope.installed_plugin = response.data; $scope.plugin_available = {}; $scope.fetch(function () { $scope.loading = false; $scope.saveData.plugin = ''; for(var id in $scope.pluginsList) { if($scope.pluginsList[id].code === data.code) { $scope.saveData.plugin = id; break; } } $scope.changePlugin(); alert.success(message); }); }, failed: function (message) { $scope.installing = false; alert.error(message); } }); }, cancel: function () { $scope.installing = false; } }); }; $scope.saveChanges = function(callback) { if($scope.saveing) return; if(callback === undefined || typeof callback !== 'function') callback = function() {}; $scope.saveing = true; var apiParams = util.duplicateObject($scope.saveData); api.manageSecurityPlugin({ data: apiParams, success: function(data, message) { $scope.saveing = false; callback(); alert.success(message); }, failed: function(message) { $scope.saveing = false; alert.error(message); } }); }; $scope.loadPackagesAvailable = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; api.listPackagesAvailable({ data: { find: { type: 'security' } }, success: function (data) { for(var i = 0; i < data.packages.length; i++) { var pkg = data.packages[i]; $scope.plugins_available[pkg.code] = pkg; $scope.plugins.push({ name: lang.t("%s via %s", pkg.name, pkg.repo_name), _id: "AvailablePlugins::" + pkg.code, group: lang.t('Available Plugins') }); } callback(); }, failed: function (message) { callback(); } }); }; $scope.fetch = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; $scope.plugins = [ {_id: '', name: lang.t('Disabled') } ]; $scope.pluginsList = {}; $scope.plugins_available = {}; $scope.loading = true; api.listPlugins({ data: { find: { type: consts.PLUGIN_TYPE_SECURITY, disabled: false } }, success: function (data) { for(var i = 0; i < data.plugins.length; i++) { $scope.plugins.push({_id: data.plugins[i]._id, name: data.plugins[i].name, group: lang.t("Installed Plugins")}); $scope.pluginsList[data.plugins[i]._id] = data.plugins[i]; } $scope.loadPackagesAvailable(callback); }, failed: function () { $scope.loadPackagesAvailable(callback); } }); }; $scope.fetch(function () { api.getSettings({ data: { section: 'security' }, success: function (data) { $scope.loading = false; $scope.saveData = data; $scope.changePlugin(); }, failed: function (message) { alert.error(message); } }, function(response) { }); }); }]); }); define('controllers/extension',['app'], function(app) { app.controller("extension", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "popup", "confirm", "util", "lang", "consts", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, api, popup, confirm, util, lang, consts, alert) { $rootScope.$emit('menuItem', 'Extension'); $scope.excluderow = ''; $scope.saving = false; $scope.loading = false; $scope.permissions = 0; $scope.details = {}; $scope.saveData = { vendors: [], excludes: [], partner_token: '' }; $scope.integrations = window.PAGE.wp_integrations; $scope.toggleVendor = function(vendor) { var index = $scope.saveData.vendors.indexOf(vendor); if (index > -1) $scope.saveData.vendors.splice(index, 1); else $scope.saveData.vendors.push(vendor); }; $scope.isVendorEnabled = function (vendor) { return $scope.saveData.vendors.indexOf(vendor) >= 0; }; $scope.addListRow = function () { const record = $scope.excluderow.trim(); if(!/^([a-z0-9.\-\[\]*\/]+)$/.test(record)) alert.error(lang.t('The following sites ("%s") is invalid.', record)); else if ($scope.saveData.excludes.indexOf(record) >= 0) alert.error(lang.t('The provided site(s) ("%s") already exists on the list.', record)); else $scope.saveData.excludes.push(record); $scope.excluderow = ''; }; $scope.addMultiListRow = function() { $scope.listTitle = lang.t("Wordpress sites to exclude"); $scope.listData = $scope.saveData.excludes.join("\n"); $scope.listUIB = popup.open({ template: 'listSelection', noController: true, scope: $scope }); $scope.listUIB.result.then(function(records) { while($scope.saveData.excludes.length) $scope.saveData.excludes.pop(); var invalidRecords = []; var duplicateRecords = []; records = records.split("\n"); for(var i = 0; i < records.length; i++) { const record = records[i]; if(!/^([a-z0-9.\-\[\]*\/]+)$/.test(record)) invalidRecords.push(record); else if ($scope.saveData.excludes.indexOf(record) >= 0) duplicateRecords.push(record); else $scope.saveData.excludes.push(record); } if(invalidRecords.length) alert.error(lang.t('The following sites ("%s") is invalid.', invalidRecords.join(", ") )) if(duplicateRecords.length) alert.error(lang.t('The provided site(s) ("%s") already exists on the list.', duplicateRecords.join(", "))); }, function () {}); }; $scope.togglePermissions = function() { var newStatus = $scope.permissions == 1 ? 0 : 1; api.managePermissions({ data: { permissions: { [consts.PERMISSIONS_CAN_ACCESS_SOCKET_API]: newStatus } }, success: function (data, message) { $scope.permissions = newStatus; console.log("AFTER:" + $scope.permissions) alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.massDeployment = function () { if($scope.deploy) return; $scope.deploy = true; api.runExtensionDeployment({ success: function (data, message) { $scope.deploy = false; alert.success(message); }, failed: function (message) { $scope.deploy = false; alert.error(message); } }); }; $scope.saveChanges = function () { if($scope.saving) return; $scope.saving = true; var apiParams = util.saveParams($scope.saveData, $scope.details, [], function (key) { return key === 'vendors' }); apiParams.section = 'extension'; api.manageSettings({ data: apiParams, success: function (data, message) { $scope.saving = false; alert.success(message); }, failed: function (message) { $scope.saving = false; alert.error(message); } }); }; $scope.fetch = function() { $scope.loading = true; api.getSettings({ data: { section: 'extension' }, success: function(data) { api.getPermissions({ success: function(prem_data) { console.log(prem_data.permissions[consts.PERMISSIONS_CAN_ACCESS_SOCKET_API]); $scope.permissions = prem_data.permissions[consts.PERMISSIONS_CAN_ACCESS_SOCKET_API]; $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); $scope.loading = false; }, failed: function (message) { alert.error(message); $scope.loading = false; } }); }, failed: function (message) { alert.error(message); $scope.loading = false; } }); }; $timeout($scope.fetch); }]); }); define('controllers/support',['app'], function(app) { app.controller("support", ["$rootScope", "$scope", "alert", "api", "lang", function ($rootScope, $scope, alert, api, lang) { $rootScope.$emit('menuItem', 'Support'); $scope.cancel = function() { $scope.loading = false; $scope.wizard = 0; $scope.info = {}; $scope.url = ""; $scope.options = { configurations: false, access: false, whitelisted: false, sshkey: '1' }; }; $scope.cancel(); $scope.setWizardStep = function(step) { $scope.wizard = step; }; $scope.addSSHKey = function() { if($scope.options.access) { if(!$scope.options.whitelisted) { alert.error(lang.t("Please confirm all conditions")); return false; } if($scope.options.sshkey === '1') { // TODO add SSH Key $scope.loading = true; } } $scope.setWizardStep(3); }; $scope.transmitData = function() { if(!$scope.options.configurations) { alert.error(lang.t("You must allow JetApps staff to review your configurations. If you don't want to let JetApps staff to review your configurations, Please open a ticket directly to JetApps Helpdesk at https://billing.jetapps.com/submitticket.php")); return false; } $scope.loading = true; api.createSupportTicketKey({ success: function (data) { $scope.loading = false; $scope.info = data.info; $scope.key = data.key; $scope.ip = data.ip; $scope.url = $scope.info.url; $scope.url += ($scope.url.indexOf('?') >= 0) ? '&' : '?'; $scope.url += "key=" + data.key + "&ip=" + data.ip + "&allowaccess=" + ($scope.options.access ? "yes" : "no"); $scope.setWizardStep(2); }, failed: function(message) { $scope.loading = false; alert.error(message); } }); }; } ] ); }); define('controllers/repositories',['app'], function(app) { app.controller("repositories", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "filter", "confirm", "alert", "lang", function ($rootScope, $scope, $location, $timeout, api, meta, filter, confirm, alert, lang) { $rootScope.$emit('menuItem', 'Plugins'); $scope.repositories = []; $scope.loadingRepositories = false; $scope.loaders = { reload: false, delete: false }; meta = meta.new("repositories"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["created"]); meta.setTotalItems($scope.repositories.length); $scope.reloadDB = function(repository) { $scope.loaders.reload = true; api.reloadRepository({ data: { _id: repository._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.reload = false; repository.last_checked = data.last_checked; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.reload = false; alert.error(message); } }); }; $scope.onClickDelete = function(repository) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This repository will be permanently deleted!"), confirm: function () { api.deleteRepository({ data: { _id: repository._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.fetch = function() { $scope.loadingRepositories = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.repositories = []; api.listRepositories({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.repositories); $scope.repositories = data.repositories; $scope.loadingRepositories = false; } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/repositoryManage',['app'], function(app) { app.controller("repositoryManage", ["$rootScope", "$scope", "$location", "$routeParams", "$timeout", "api", "meta", "filter", "confirm", "lang", "util", "alert", function ($rootScope, $scope, $location, $routeParams, $timeout, api, meta, filter, confirm, lang, util, alert) { $rootScope.$emit('menuItem', 'Plugins'); $scope.details = { name: '', url: '' }; $scope.saveData = util.duplicateObject($scope.details); $scope.saveing = false; $scope.changed = true; $scope.cancelled = false; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/plugins/repositories'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageRepository({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(callback === undefined) { if(apply) $location.path('/repositoryManage/' + data._id); else $location.path('/plugins/repositories'); alert.success(message); } if(callback !== undefined && typeof callback === 'function') callback(); }, failed: function (message) { $scope.saveing = false; alert.error(message); if(callback !== undefined && typeof callback === 'function') callback(); } }); }; $scope.fetchRepoData = function() { api.getRepository({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; if($routeParams.id) $scope.fetchRepoData(); } ] ); }); define('controllers/filePermissions',['app'], function(app) { app.controller("filePermissions", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "$q", "api", "meta", "confirm", "lang", "alert", function ($rootScope, $scope, $location, $timeout, $interval, $q, api, meta, confirm, lang, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.permissions = []; $scope.loadingPermissions = false; $scope.loaders = { delete: false }; meta = meta.new("file_permissions"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("regex"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["regex", "owner", "group", "permissions"]); meta.setTotalItems($scope.permissions.length); $scope.onClickDelete = function(permission) { if($scope.saveing) return; $scope.loaders.delete = true; $scope.saveing = true; confirm.open({ message: lang.t("This file permission will be permanently deleted!"), confirm: function () { api.deleteFilePermissions({ data: { _id: permission._id }, success: function(data, message) { $scope.loaders.delete = false; $scope.saveing = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.delete = false; $scope.saveing = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.delete = false; $scope.saveing = false; } }); }; $scope.fetch = function() { $scope.loadingPermissions = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.permissions = []; api.listFilePermissions({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.permissions); $scope.permissions = data.permissions; $scope.loadingPermissions = false; } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/filePermissionsManage',['app'], function(app) { app.controller("filePermissionsManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "util", "lang", "consts", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, util, lang, consts, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.details = {}; $scope.saveData = { regex: '', category: consts.FILE_PERMISSIONS_CATEGORY_HOMEDIR_DATA, owner: '', group: '', recursive: 0, dirs_permissions: '', files_permissions: '' }; $scope.saveing = false; $scope.changed = false; $scope.categories = [ {_id: consts.FILE_PERMISSIONS_CATEGORY_HOMEDIR_DATA, name: consts.FILE_PERMISSIONS_CATEGORIES[consts.FILE_PERMISSIONS_CATEGORY_HOMEDIR_DATA] }, {_id: consts.FILE_PERMISSIONS_CATEGORY_EMAIL_DATA, name: consts.FILE_PERMISSIONS_CATEGORIES[consts.FILE_PERMISSIONS_CATEGORY_EMAIL_DATA] } ]; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageFilePermissions({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/filePermissionsManage/' + data._id); else $location.path('/filePermissions'); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; $scope.fetch = function(permission_id) { api.getFilePermissions({ data: { _id: permission_id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }); }; var permission_id = $routeParams.id; if(permission_id) $timeout($scope.fetch(permission_id)); } ] ); }); define('controllers/hooks',['app'], function(app) { app.controller("hooks", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "confirm", "alert", "lang", "consts", function ($rootScope, $scope, $location, $timeout, api, meta, confirm, alert, lang, consts) { $rootScope.$emit('menuItem', 'Hooks'); $scope.hooks = []; $scope.loading = false; $scope.saveing = false; $scope.filter = ''; $scope.filterOptions = [ { label: lang.t('All Hook Positions'), value: '' }, { label: lang.t('Pre'), value: consts.HOOK_TYPE_POSITION_PRE }, { label: lang.t('Post'), value: consts.HOOK_TYPE_POSITION_POST } ]; $scope.loaders = { delete: false, state: false }; $scope.backups = {}; $scope.clones = {}; $scope.destinations = {}; $scope.types = {}; $scope.types[consts.BACKUP_TYPE_ACCOUNT] = lang.t("Accounts"); $scope.types[consts.BACKUP_TYPE_DIRECTORY] = lang.t("Directories"); $scope.positions = {}; $scope.positions[consts.HOOK_POSITION_BACKUP] = lang.t("Backup"); $scope.positions[consts.HOOK_POSITION_BACKUP_ACCOUNT] = lang.t("Backup Account"); $scope.positions[consts.HOOK_POSITION_RESTORE] = lang.t("Restore"); $scope.positions[consts.HOOK_POSITION_DOWNLOAD] = lang.t("Download"); $scope.positions[consts.HOOK_POSITION_REINDEX] = lang.t("Reindex"); $scope.positions[consts.HOOK_POSITION_SNAPSHOT] = lang.t("Snapshot"); $scope.positions[consts.HOOK_POSITION_CLONE] = lang.t("Clone"); $scope.positions[consts.HOOK_POSITION_CLONE_ACCOUNT] = lang.t("Clone Account"); $scope.position_types = {}; $scope.position_types[consts.HOOK_TYPE_POSITION_PRE] = lang.t("Pre"); $scope.position_types[consts.HOOK_TYPE_POSITION_POST] = lang.t("Post"); meta = meta.new("hooks"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","position_type","position","owner","disabled"]); meta.setTotalItems($scope.hooks.length); $scope.onClickDelete = function(hook) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This hook will be permanently deleted!"), confirm: function () { api.deleteHook({ data: { _id: hook._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.toggleStatus = function(hook) { $scope.loaders.state = true; var disabled = !hook.disabled; api.manageHook({ data: { _id: hook._id, action: 'modify', disabled: disabled }, success: function(data, message) { $scope.loaders.state = false; hook.disabled = disabled; alert.success(message); }, failed: function (message) { $scope.loaders.state = false; alert.error(message); } }); }; $scope.init = false; $scope.fetch = function(init) { if(!$scope.init && !init) return; $scope.init = true; $scope.loading = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); if($scope.filter) apiParams.find.position_type = $scope.filter; $scope.hooks = []; api.listHooks({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.hooks); for(var i = 0; i < data.hooks.length; i++) { var list = data.hooks[i].data_list; if(list.length) { switch(data.hooks[i].position) { case consts.HOOK_POSITION_BACKUP: case consts.HOOK_POSITION_BACKUP_ACCOUNT: for(var j = 0; j < list.length; j++) list[j] = ($scope.backups[list[j]] !== undefined) ? $scope.backups[list[j]].name : 'Unknown'; break; case consts.HOOK_POSITION_RESTORE: case consts.HOOK_POSITION_DOWNLOAD: for(var j = 0; j < list.length; j++) list[j] = ($scope.types[list[j]] !== undefined) ? $scope.types[list[j]] : 'Unknown'; break; case consts.HOOK_POSITION_REINDEX: for(var j = 0; j < list.length; j++) list[j] = ($scope.destinations[list[j]] !== undefined) ? $scope.destinations[list[j]].name : 'Unknown'; break; } } $scope.hooks.push(data.hooks[i]); } $scope.loading = false; }, failed: function (message) { alert.error(message) } }); }; api.listBackupJobs({ success: function(data) { for(var i = 0; i < data.jobs.length; i++) $scope.backups[data.jobs[i]._id] = data.jobs[i]; api.listDestinations({ success: function(data) { for(var i = 0; i < data.destinations.length; i++) $scope.destinations[data.destinations[i]._id] = data.destinations[i]; $timeout($scope.fetch(true)); } }); } }); } ] ); }); define('controllers/hookManage',['app'], function(app) { app.controller("hookManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "util", "lang", "consts", "confirm", "cfpLoadingBar", "alert", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, util, lang, consts, confirm, cfpLoadingBar, alert, popup) { $rootScope.$emit('menuItem', 'Hooks'); $scope.details = {}; $scope.saveData = { name: '', position_type: consts.HOOK_POSITION_BACKUP, position: consts.HOOK_TYPE_POSITION_PRE, data_list: [], script: '' }; $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.backups = {}; $scope.clones = {}; $scope.destinations = {}; $scope.positions = [ { label: lang.t("Backup"), value: consts.HOOK_POSITION_BACKUP }, { label: lang.t("Backup Account"), value: consts.HOOK_POSITION_BACKUP_ACCOUNT }, { label: lang.t("Clone"), value: consts.HOOK_POSITION_CLONE }, { label: lang.t("Clone Account"), value: consts.HOOK_POSITION_CLONE_ACCOUNT }, { label: lang.t("Restore"), value: consts.HOOK_POSITION_RESTORE }, { label: lang.t("Download"), value: consts.HOOK_POSITION_DOWNLOAD }, { label: lang.t("Reindex"), value: consts.HOOK_POSITION_REINDEX } //{ label: lang.t("Snapshot"), value: consts.HOOK_POSITION_SNAPSHOT } ]; $scope.position_types = [ { label: lang.t("Pre"), value: consts.HOOK_TYPE_POSITION_PRE }, { label: lang.t("Post"), value: consts.HOOK_TYPE_POSITION_POST } ]; $scope.types = {}; $scope.types[consts.HOOK_POSITION_RESTORE] = [ {label:lang.t("Accounts"), value: consts.BACKUP_TYPE_ACCOUNT}//, //{label:lang.t("Directories"), value: consts.BACKUP_TYPE_DIRECTORY} ]; $scope.types[consts.HOOK_POSITION_DOWNLOAD] = [ {label:lang.t("Accounts"), value: consts.BACKUP_TYPE_ACCOUNT}//, //{label:lang.t("Directories"), value: consts.BACKUP_TYPE_DIRECTORY} ]; $scope.itemsSelection = function () { var types = {}; types[consts.HOOK_POSITION_BACKUP] = { template: 'backupJobsSelection', resolve: { jobs: function() { return $scope.saveData.data_list; } } }; types[consts.HOOK_POSITION_BACKUP_ACCOUNT] = types[consts.HOOK_POSITION_BACKUP]; types[consts.HOOK_POSITION_CLONE] = { template: 'cloneJobsSelection', resolve: { jobs: function() { return $scope.saveData.data_list; } } }; types[consts.HOOK_POSITION_CLONE_ACCOUNT] = types[consts.HOOK_POSITION_CLONE]; types[consts.HOOK_POSITION_REINDEX] = { template: 'destinationsSelection', controller: 'destinationsSelection', resolve: { destinations: function() { return $scope.saveData.data_list; }, readonly: function () { return true; }, types: function () { return consts.DESTINATION_JOB_TYPE_BACKUP; }, legacy: function () { return true; }, local: function () { return true; }, timebased: function () { return true; } } }; if(types[$scope.saveData.position] === undefined) return; popup.open(types[$scope.saveData.position]).result.then(function(selected) { $scope.saveData.data_list = selected; }, function () { //$log.info('Modal dismissed at: ' + new Date()); }); }; $scope.searchCloneJobs = function(query) { if(query) { var deferred = $q.defer(); api.listCloneJobs({ data: { filter: query, sort: { name: 1 } }, success: function(data) { var result = []; for(var i = 0; i < data.jobs.length; i++) { if($scope.saveData.data_list.indexOf(data.jobs[i]._id) >= 0) continue; var job = data.jobs[i]; var type = parseInt(job.type); var contains = parseInt(job.contains); var names = []; switch(type) { case consts.CLONE_TYPE_ACCOUNT: if(contains == consts.CLONE_TYPE_ACCOUNT_FULL) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_FULL]); else { if(contains & consts.CLONE_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.CLONE_TYPE_ACCOUNT_HOMEDIR) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.CLONE_TYPE_ACCOUNT_DATABASES) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASES]); if(contains & consts.CLONE_TYPE_ACCOUNT_EMAILS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_EMAILS]); if(contains & consts.CLONE_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.CLONE_TYPE_ACCOUNT_DOMAINS) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.CLONE_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CERTIFICATES]); } break; /* case consts.CLONE_TYPE_DIRECTORY: names.push(consts.CLONE_TYPE_DIRECTORY_NAMES[consts.CLONE_TYPE_DIRECTORY_FULL]); break; */ } job.contains_name = names.join(', '); result.push(job); } deferred.resolve(result); } }); return deferred.promise; } return []; }; $scope.searchBackupJobs = function(query) { if(query) { var deferred = $q.defer(); api.listBackupJobs({ data: { filter: query, sort: { name: 1 } }, success: function(data) { var result = []; for(var i = 0; i < data.jobs.length; i++) { if($scope.saveData.data_list.indexOf(data.jobs[i]._id) >= 0) continue; var job = data.jobs[i]; var type = parseInt(job.type); var contains = parseInt(job.contains); var names = []; switch(type) { case consts.BACKUP_TYPE_ACCOUNT: if(contains == consts.BACKUP_TYPE_ACCOUNT_FULL) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL]); else { if(contains & consts.BACKUP_TYPE_ACCOUNT_CONFIG) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG]); if(contains & consts.BACKUP_TYPE_ACCOUNT_HOMEDIR) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DATABASES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES]); if(contains & consts.BACKUP_TYPE_ACCOUNT_EMAILS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_DOMAINS) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS]); if(contains & consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES) names.push(consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES]); } break; case consts.BACKUP_TYPE_DIRECTORY: names.push(consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL]); break; } job.contains_name = names.join(', '); result.push(job); } deferred.resolve(result); } }); return deferred.promise; } return []; }; $scope.searchDestinations = function(query) { if(query) { var deferred = $q.defer(); api.listDestinations({ data: { filter: query, sort: { name: 1 } }, success: function(data) { var result = []; for(var i = 0; i < data.destinations.length; i++) { if($scope.saveData.data_list.indexOf(data.destinations[i]._id) >= 0) continue; result.push(data.destinations[i]); } deferred.resolve(result); } }); return deferred.promise; } return []; }; $scope.selectItem = function(item, obj) { if(item === undefined) return; $scope.saveData.data_list.push(item._id); obj.searchBackupText = ''; obj.searchCloneText = ''; obj.searchDestinationText = ''; }; $scope.fetchHookData = function(hook_id) { api.getHook({ data: { _id: hook_id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); }, failed: function () { $location.path('/hooks'); } }); }; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.resetList = function() { $scope.saveData.data_list = []; }; $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.manageTypesList = function(type) { var index = $scope.saveData.data_list.indexOf(type); if(index >= 0) $scope.saveData.data_list.splice(index, 1); else $scope.saveData.data_list.push(type); }; $scope.cancel = function() { $scope.cancelled = true; $location.path('/hooks'); }; $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageHook({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/hookManage/' + data._id); else $location.path('/hooks'); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; api.listBackupJobs({ success: function(data) { for(var i = 0; i < data.jobs.length; i++) $scope.backups[data.jobs[i]._id] = data.jobs[i]; } }); api.listCloneJobs({ success: function(data) { for(var i = 0; i < data.jobs.length; i++) $scope.clones[data.jobs[i]._id] = data.jobs[i]; } }); api.listDestinations({ success: function(data) { for(var i = 0; i < data.destinations.length; i++) $scope.destinations[data.destinations[i]._id] = data.destinations[i]; } }); var hook_id = $routeParams.id; if(hook_id) $timeout($scope.fetchHookData(hook_id)); else cfpLoadingBar.complete(); }]); }); define('controllers/tags',['app'], function(app) { app.controller("tags", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "confirm", "alert", "lang", "consts", function ($rootScope, $scope, $location, $timeout, api, meta, confirm, alert, lang, consts) { $rootScope.$emit('menuItem', 'Accounts'); $scope.tags = []; $scope.loading = false; $scope.saveing = false; $scope.filter = ''; /* $scope.filterOptions = [ { label: lang.t('All Tag Types'), value: '' }, { label: lang.t('Account'), value: consts.TAG_TYPE_ACCOUNT }, ]; */ $scope.types = {}; $scope.types[consts.TAG_TYPE_ACCOUNT] = lang.t('Account'); $scope.loaders = { delete: false }; meta = meta.new("tags"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","color","owner"]); meta.setTotalItems($scope.tags.length); $scope.onClickDelete = function(tag) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This tag will be permanently deleted, also this tag will be removed from all accounts that are using it!"), confirm: function () { api.deleteTag({ data: { _id: tag._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.fetch = function() { if($scope.loading) return; $scope.loading = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); if($scope.filter) apiParams.find.type = $scope.filter; $scope.tags = []; api.listTags({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.tags); $scope.tags = data.tags; $scope.loading = false; } }); }; $timeout($scope.fetch()); } ] ); }); define('controllers/tagManage',['app'], function(app) { app.controller("tagManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "util", "lang", "consts", "confirm", "cfpLoadingBar", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, util, lang, consts, confirm, cfpLoadingBar, alert) { $rootScope.$emit('menuItem', 'Accounts'); var randomColor = function() { var letters = '0123456789ABCDEF'; var color = '#'; for (var i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color.toLowerCase(); }; $scope.details = {}; $scope.saveData = { name: '', type: consts.TAG_TYPE_ACCOUNT, color: randomColor(), }; $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.colors = [ '#3e3c3e', '#666366', '#8d8a8d', '#b4b2b4', '#e5a8de', '#d87bcc', '#cb4dba', '#ab329b', '#7e2572', '#511849', '#900c3f', '#c70039', '#ff5733', '#ff8d1a', '#ffc300', '#eddd53', '#add45c', '#57c785', '#00baad', '#2a7b9b', '#3d3d6b', '#6464a6', '#4848c2', '#2c2cde']; $scope.types = [ {label:lang.t("Account"), value: consts.TAG_TYPE_ACCOUNT} ]; $scope.randomColor = function() { $scope.saveData.color = randomColor(); }; $scope.fetchTagData = function(tag_id) { api.getTag({ data: { _id: tag_id }, success: function(data) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); }, failed: function () { $location.path('/tags'); } }); }; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/tags'); }; $scope.saveChanges = function(apply) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageTag({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/tagManage/' + data._id); else $location.path('/tags'); alert.success(message); }, failed: function (message) { $scope.saveing = false; alert.error(message); } }); }; var tag_id = $routeParams.id; if(tag_id) $timeout($scope.fetchTagData(tag_id)); else cfpLoadingBar.complete(); }]); }); define('controllers/tagsSelection',['app'], function(app) { app.controller('tagsSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "lang", "tags", "type", function($uibModalInstance, $scope, $timeout, api, lang, tags, type) { $scope.loading = false; $scope.tags = []; $scope.fetchTags = function () { $scope.loading = true; api.listTags({ data: { find: { type: type }, sort: { name: 1 } }, success: function (data) { for (var i = 0; i < data.tags.length; i++) { data.tags[i].checked = tags !== undefined && tags.length ? tags.indexOf(data.tags[i]._id) >= 0 : false; $scope.tags.push(data.tags[i]); } $scope.loading = false; } }); }; $timeout($scope.fetchTags()); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.tags.length; i++) { if($scope.tags[i].checked) selected.push($scope.tags[i]._id); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/destinationsSelection',['app'], function(app) { app.controller('destinationsSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "lang", "meta", "destinations", "readonly", "types", "legacy", "local", "timebased", function($uibModalInstance, $scope, $timeout, api, lang, meta, destinations, readonly, types, legacy, local, timebased) { $scope.loading = false; $scope.destinations = []; $scope.fetchDestinations = function () { $scope.loading = true; api.listDestinations({ data: { types: types, readonly: readonly, sort: { name: 1 } }, success: function (data) { for (var i = 0; i < data.destinations.length; i++) { if(!legacy && data.destinations[i].legacy) continue; if(!timebased && data.destinations[i].time_based) continue; if(!local && (data.destinations[i].type == 'Local' || data.destinations[i].type == 'Localv2')) continue; data.destinations[i].checked = destinations !== undefined && destinations.length ? destinations.indexOf(data.destinations[i]._id) >= 0 : false; $scope.destinations.push(data.destinations[i]); } $scope.loading = false; } }); }; $timeout($scope.fetchDestinations); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.destinations.length; i++) { if($scope.destinations[i].checked) selected.push($scope.destinations[i]._id); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/backupJobsSelection',['app'], function(app) { app.controller('backupJobsSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "lang", "meta", "jobs", function($uibModalInstance, $scope, $timeout, api, lang, meta, jobs) { $scope.loading = false; $scope.jobs = []; $scope.fetchJobs = function () { $scope.loading = true; api.listBackupJobs({ data: { sort: { name: 1 } }, success: function (data) { for (var i = 0; i < data.jobs.length; i++) { data.jobs[i].checked = jobs !== undefined && jobs.length ? jobs.indexOf(data.jobs[i]._id) >= 0 : false; } $scope.jobs = data.jobs; $scope.loading = false; } }); }; $timeout($scope.fetchJobs()); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.jobs.length; i++) { if($scope.jobs[i].checked) selected.push($scope.jobs[i]._id); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/cloneJobsSelection',['app'], function(app) { app.controller('cloneJobsSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "lang", "meta", "jobs", function($uibModalInstance, $scope, $timeout, api, lang, meta, jobs) { $scope.loading = false; $scope.jobs = []; $scope.fetchJobs = function () { $scope.loading = true; api.listCloneJobs({ data: { sort: { name: 1 } }, success: function (data) { for (var i = 0; i < data.jobs.length; i++) { data.jobs[i].checked = jobs !== undefined && jobs.length ? jobs.indexOf(data.jobs[i]._id) >= 0 : false; } $scope.jobs = data.jobs; $scope.loading = false; } }); }; $timeout($scope.fetchJobs()); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.jobs.length; i++) { if($scope.jobs[i].checked) selected.push($scope.jobs[i]._id); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/backupLockSelection',[ 'app', ], function(app) { app.controller('backupLockSelection', ["$uibModalInstance", "$scope", "lang", function($uibModalInstance, $scope, lang) { $scope.ttl = 0; $scope.ok = function () { $uibModalInstance.close($scope.ttl); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ]); }); define('controllers/plugins',['app'], function(app) { app.controller("plugins", ["$rootScope", "$scope", "$routeParams", "$location", "lang", function ($rootScope, $scope, $routeParams, $location, lang) { $rootScope.$emit('menuItem', 'Plugins'); $scope.plugins = []; $scope.loadingPlugins = false; $scope.loaders = { state: false, uninstall: false }; $scope.sections = [ {_id: "installed",name: lang.t("Installed Plugins"),icon:"fa-edit",template: $scope.includePath("pluginManage")}, {_id: "packages",name: lang.t("Available Plugins"),icon:"fa-box",template: $scope.includePath("packages")}, {_id: "repositories",name: lang.t("Repositories"),icon:"fa-layer-group",template: $scope.includePath("repositories")} ]; $scope.getSection = function (section_id) { for(var i = 0; i < $scope.sections.length; i++) { if($scope.sections[i]._id === section_id) { return $scope.sections[i]; } } return $scope.sections[0]; }; $scope.changeSection = function (section) { if($routeParams.section === section._id) $scope.currentSection = section; $location.path('/plugins/' + section._id); }; $scope.changeSection($scope.getSection($routeParams.section ? $routeParams.section : $scope.sections[0]._id)); } ] ); }); define('controllers/packages',['app'], function(app) { app.controller("packages", ["$rootScope", "$scope", "$location", "$timeout", "api", "lang", "confirm", "alert", "meta", "consts", function ($rootScope, $scope, $location, $timeout, api, lang, confirm, alert, meta, consts) { $rootScope.$emit('menuItem', 'Plugins'); /* $scope.installing = false; $scope.package = ''; $scope.packages = [ {value: '', label: lang.t("Select Package")} ]; api.listAvailablePlugins({}, function (response) { if(!response.success) return; for(var i = 0; i < response.data.plugins.length; i++) { $scope.packages.push({ value: response.data.plugins[i], label: response.data.plugins[i]}); } }); $scope.install = function() { if($scope.installing) return; $scope.installing = true; api.installPlugin({ "package_name": $scope.package }, function (response) { $scope.installing = false; if(response.success) alert.success(response.message); else alert.error(response.message); }); }; */ $scope.packages = []; $scope.filterRepos = [{ label: lang.t('All Repositories'), value: '' }]; $scope.repo = ''; $scope.filterTypes = [ { value: '', label: lang.t('All Types') }, { value: consts.PLUGIN_TYPE_DESTINATION, label: lang.t("Destinations") }, { value: consts.PLUGIN_TYPE_NOTIFICATION, label: lang.t("Notification") }, { value: consts.PLUGIN_TYPE_SECURITY, label: lang.t("Security") }, { value: consts.PLUGIN_TYPE_ADDON, label: lang.t("Addons") } ]; $scope.type = ''; $scope.loadingPackages = false; $scope.loaders = { install: false }; meta = meta.new("packages"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([30,60,120,240]); meta.setPageSize(30); meta.setSortFields(["created"]); meta.setTotalItems($scope.packages.length); $scope.switchRepo = function(packageData) { confirm.open({ message: lang.t("Are you sure you want to switch this plugin installation to the repository \"%s\"? This plugin will start picking up updates from this repository", packageData.repo_name), confirm: function () { api.managePlugin({ data: { _id: packageData.plugin_id, repo: packageData.repo }, success: function(data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.uninstall = function(packageData) { confirm.open({ message: lang.t("This plugin and all his settings will be permanently deleted!"), confirm: function () { api.uninstallPlugin({ data: { _id: packageData.plugin._id }, success: function(data, message) { $scope.loaders.uninstall = false; if($rootScope.plugins[packageData.plugin._id] !== undefined) { $rootScope.plugins[packageData.plugin._id].visible = false; $rootScope.plugins[packageData.plugin._id].disabled = true; } $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.uninstall = false; alert.error(message); } }); } }); }; $scope.reinstall = function(packageData) { confirm.open({ message: lang.t("This plugin will be reinstalled!"), confirm: function () { api.installPlugin({ data: { package_id: packageData._id }, success: function (data, message) { packageData.installed = true; packageData.installable = false; if(data.type == consts.PLUGIN_TYPE_ADDON) $rootScope.plugins[data._id] = data; $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.install = function(packageData) { confirm.open({ message: lang.t("This plugin will be installed on this server!"), confirm: function () { api.installPlugin({ data: { package_id: packageData._id }, success: function (data, message) { packageData.installed = true; packageData.installable = false; if(data.type == consts.PLUGIN_TYPE_ADDON) $rootScope.plugins[data._id] = data; $scope.fetch(); alert.success(message); confirm.open({ message: lang.t("Would you like to enable this plugin?"), confirmLabel: lang.t("Enable Plugin"), confirm: function () { api.managePlugin({ data: { _id: data._id, disabled: false, visible: data.type == consts.PLUGIN_TYPE_ADDON }, success: function(data, message) { if($rootScope.plugins[data._id] !== undefined) { for(var key in $rootScope.plugins[data._id]) $rootScope.plugins[data._id][key] = data[key]; } alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.update = function(packageData) { confirm.open({ message: lang.t("This plugin will be updated to version %s", packageData.version), confirm: function () { api.updatePlugin({ data: { _id: packageData.plugin._id }, success: function(data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.fetch = function() { $scope.loadingPackages = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); if($scope.repo) apiParams.find.repo = $scope.repo; if($scope.type) apiParams.find.type = $scope.type; $scope.packages = []; api.listPackages({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.packages); $scope.packages = data.packages; $scope.loadingPackages = false; } }); }; api.listRepositories({ success: function (data) { for(var i = 0; i < data.repositories.length; i++) { $scope.filterRepos.push({ label: data.repositories[i].name, value: data.repositories[i]._id }); } } }); $timeout($scope.fetch); } ] ); }); define('controllers/showcase',['app'], function(app) { app.controller("showcase", ["$rootScope", "$scope", "$controller", "$q", "$location", "$timeout", "api", "permissions", "alert", function ($rootScope, $scope, $controller, $q, $location, $timeout, api, permissions, alert) { var showcases = window.PAGE.showcase; if(!showcases.total_unapproved) $location.path('/'); $scope.showcases = {}; $scope.features = {}; for (var i = 0 ; i < showcases.total; i++) { if(showcases.features[i].approved) continue; var controllerName = showcases.features[i].feature + showcases.features[i].order; $scope.showcases[controllerName] = showcases.features[i]; app.registerShowcaseController(showcases.features[i], function (path, controllerName) { $scope.features[controllerName] = $scope.showcases[controllerName]; }); } $scope.checkFeatures = function() { if(window.PAGE.showcase.total_unapproved > 0) return false; permissions.init(window.PAGE.permissions); $location.path('/'); }; $scope.setStatus = function(message) { alert.error(message); }; $rootScope.$on('approve', function(event, feature) { var controllerName = feature.feature + feature.order; api.approveShowcase({ data: { _id: feature._id }, success: function () { window.PAGE.showcase.total_unapproved--; $scope.features[controllerName].approved = true; $scope.checkFeatures(); }, failed: function (message) { $scope.setStatus(message); } }); }); $rootScope.$on('error', function(event, error) { $scope.setStatus(error); }); $scope.saveChanges = function() { $rootScope.$broadcast('save'); }; } ] ); }); define('controllers/plugin',['app'], function(app) { app.controller("plugin", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "lang", "api", "util", "consts", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, lang, api, util, consts, alert) { if(!$routeParams.plugin) { $location.path('/'); return; } $rootScope.$emit('menuItem', 'Plugin' + $routeParams.plugin); $scope.plugin = {}; $scope.saveData = {}; $scope.saveing = false; $scope.pluginView = ''; $scope.publicDir = ''; api.getPlugin({ data: { code: $routeParams.plugin, type: consts.PLUGIN_TYPE_ADDON }, success: function (data) { if(data.disabled || !data.visible) { $location.path('/'); return; } $scope.plugin = data; $scope.saveData = util.duplicateObject($scope.plugin); lang.setDefaultNS('plugins-addon-' + $scope.plugin.code); app.registerPluginController($scope.plugin, function(path) { $scope.publicDir = path; $scope.pluginView = $scope.publicDir + '/view.htm?v=' + $scope.plugin.version; }); }, failed: function () { $location.path('/'); } }); $scope.saveChanges = function(callback) { if($scope.saveing) return; if(callback !== undefined || typeof callback !== 'function') callback = function() {}; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.plugin); api.managePlugin({ data: apiParams, success: function(data, message) { $scope.saveing = false; callback(); alert.success(message); }, failed: function (message) { $scope.saveing = false; callback(); alert.error(message); } }); }; } ] ); }); define('controllers/pluginManage',['app'], function(app) { app.controller("pluginManage", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "filter", "confirm", "alert", "lang", "consts", function ($rootScope, $scope, $location, $timeout, api, meta, filter, confirm, alert, lang, consts) { $rootScope.$emit('menuItem', 'Plugins'); $scope.plugins = []; $scope.loadingPlugins = false; $scope.filter = ''; $scope.filterOptions = [ { value: '', label: lang.t("All Plugins") }, { value: consts.PLUGIN_TYPE_DESTINATION, label: lang.t("Destination Plugins") }, { value: consts.PLUGIN_TYPE_NOTIFICATION, label: lang.t("Notification Plugins") }, { value: consts.PLUGIN_TYPE_SECURITY, label: lang.t("Security Plugins") }, { value: consts.PLUGIN_TYPE_ADDON, label: lang.t("Addon Plugins") } ]; $scope.loaders = { state: false, update: false, visible: false, autoupdate: false, uninstall: false }; $scope.permissions = [ { value: consts.PLUGIN_PERMISSION_ROOT, name: lang.t("Root Access") }, { value: consts.PLUGIN_PERMISSION_RESELLER, name: lang.t("Root & Reseller Access") }, { value: consts.PLUGIN_PERMISSION_USER, name: lang.t("Root, Reseller & User Access") } ]; meta = meta.new("plugins_manage"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["created"]); meta.setTotalItems($scope.plugins.length); $scope.savePermissions = function(plugin) { api.managePlugin({ data: { _id: plugin._id, permissions: plugin.permissions }, success: function (data) { $scope.updatePlugin(data); }, failed: function (message) { alert.error(message); } }); }; $scope.updatePlugin = function(plugin) { if($rootScope.plugins[plugin._id] === undefined) return; for(var key in $rootScope.plugins[plugin._id]) $rootScope.plugins[plugin._id][key] = plugin[key]; }; $scope.uninstall = function(plugin) { if($scope.loaders.uninstall) return; $scope.loaders.uninstall = true; confirm.open({ message: lang.t("This plugin and all his settings will be permanently deleted!"), confirm: function () { api.uninstallPlugin({ data: { _id: plugin._id }, success: function(data, message) { $scope.loaders.uninstall = false; if($rootScope.plugins[plugin._id] !== undefined) { $rootScope.plugins[plugin._id].visible = false; $rootScope.plugins[plugin._id].disabled = true; } $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.uninstall = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.uninstall = false; } }); }; $scope.toggleStatus = function(plugin) { $scope.loaders.state = true; api.managePlugin({ data: { _id: plugin._id, disabled: !plugin.disabled }, success: function(data) { $scope.loaders.state = false; plugin.disabled = data.disabled; $scope.updatePlugin(data); }, failed: function (message) { $scope.loaders.state = false; alert.error(message); } }); }; $scope.toggleVisible = function(plugin) { $scope.loaders.visible = true; api.managePlugin({ data: { _id: plugin._id, visible: !plugin.visible }, success: function(data) { $scope.loaders.visible = false; plugin.visible = data.visible; $scope.updatePlugin(data); }, failed: function (message) { $scope.loaders.visible = false; alert.error(message); } }); }; $scope.autoupdate = function(plugin) { if(plugin.updating) return; $scope.loaders.update = true; confirm.open({ message: lang.t("This plugin will be updated to version %s", plugin.available_package), confirm: function () { plugin.updating = true; api.updatePlugin({ data: { _id: plugin._id }, success: function(data) { plugin.updating = false; $scope.loaders.update = false; plugin.version = data.version; plugin.available_package = data.available_package; $scope.updatePlugin(data); }, failed: function (message) { $scope.loaders.update = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.update = false; } }); }; $scope.fetch = function() { $scope.loadingPlugins = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); if($scope.filter) apiParams.find.type = $scope.filter; $scope.plugins = []; api.listPlugins({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.plugins); $scope.plugins = data.plugins; $scope.loadingPlugins = false; } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/logs',['app'], function(app) { app.controller("logs", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "filter", "confirm", "$interval", "lang", "consts", "alert", "popup", function ($rootScope, $scope, $location, $timeout, api, meta, filter, confirm, $interval, lang, consts, alert, popup) { $rootScope.$emit('menuItem', 'Logs'); $scope.logs = []; $scope.logsProcessingList = {}; $scope.checkTimeout = undefined; $scope.loadingLogs = false; $scope.showPager = true; $scope.checkall = false; $scope.checked = false; var logsFilter = filter.new("logs_filter"); if(!logsFilter.getFilter()) logsFilter.setFilter(0); var filterSession = logsFilter.getFilter(); $scope.filter = filterSession; // removed selected after first display logsFilter.setFilter(0); var logsSubFilter = filter.new("logs_subfilter"); $scope.subfilter = logsSubFilter.getFilter(); $scope.statusfilter = 0; // removed selected after first display logsSubFilter.setFilter(""); $scope.subfilterTitle = ''; $scope.subfilterOptions = []; $scope.filterOptions = [ { label: lang.t('All Logs'), value: 0 }, { label: lang.t('Backup Logs'), value: consts.LOG_TYPE_BACKUP }, { label: lang.t('Clone Logs'), value: consts.LOG_TYPE_CLONE }, { label: lang.t('Backup on Demand Logs'), value: consts.LOG_TYPE_BACKUP_ON_DEMAND }, { label: lang.t('Download Logs'), value: consts.LOG_TYPE_DOWNLOAD }, { label: lang.t('Restore Logs'), value: consts.LOG_TYPE_RESTORE }, { label: lang.t('Reindex Logs'), value: consts.LOG_TYPE_REINDEX }, { label: lang.t('System Logs'), value: consts.LOG_TYPE_SYSTEM }, { label: lang.t('Extension Installation Logs'), value: consts.LOG_TYPE_EXTENSION } ]; $scope.statusFilterOptions = [ { label: lang.t('All Statuses'), value: 0 } ]; for(var status in consts.LOG_STATUS_NAMES) { $scope.statusFilterOptions.push({ label: consts.LOG_STATUS_NAMES[status], value: status }); } $scope.loaders = { stop: false, delete: false, view: false, summary: false }; $scope.$watch("filter", function (newVal) { $scope.subfilterTitle = ''; $scope.subfilterOptions = []; if(!filterSession) $scope.subfilter = ""; filterSession = 0; if( $scope.filter !== consts.LOG_TYPE_BACKUP && $scope.filter !== consts.LOG_TYPE_CLONE && $scope.filter !== consts.LOG_TYPE_BACKUP_ON_DEMAND ) return; switch($scope.filter) { case consts.LOG_TYPE_BACKUP: $scope.subfilterTitle = 'Backup Job'; $scope.subfilterOptions.push({ label: lang.t("All Backup Jobs"), value: "" }); api.listBackupJobs({ data: { list_hidden: true }, success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.subfilterOptions.push({ label: data.jobs[i].name, value: data.jobs[i]._id }); } } }); break; case consts.LOG_TYPE_CLONE: $scope.subfilterTitle = 'Clone Job'; $scope.subfilterOptions.push({ label: lang.t("All Clone Jobs"), value: "" }); api.listCloneJobs({ data: { list_hidden: true }, success: function (data) { for(var i = 0; i < data.jobs.length; i++) { $scope.subfilterOptions.push({ label: data.jobs[i].name, value: data.jobs[i]._id }); } } }); break; } }, true); meta = meta.new("logs"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("start_time"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["pid", "type", "start_time", "end_time", "status"]); meta.setTotalItems($scope.logs.length); $scope.onClickDownload = function(log) { window.location = $scope.downloadURL('log_id=' + log._id); }; $scope.onClickDelete = function(log) { $scope.loaders.delete = true; confirm.open({ message: lang.t("The selected log will be permanently deleted!"), confirm: function () { api.deleteLog({ data: { _id: [log._id] }, success: function(data, message) { $scope.loaders.delete = false; $scope.checkall = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.loaders.delete = false; } }); }; $scope.onClickView = function(log) { $scope.loaders.view = true; api.getLog({ data: { _id: log._id, content: 1 }, success: function (data) { $scope.loaders.view = false; if(!data.content) { alert.error(lang.t("No log content found")); return; } popup.open({ size: "lg", template: 'logViewer', scope: $scope, resolve: { log: function() { return data; }, reload: function () { return function(callback) { api.getLog({ data: { _id: log._id, content: 1 }, success: function (data) { if(callback !== undefined) callback(data); } }); } } } }).result.then(function() {}, function () {}); }, failed: function (message) { $scope.loaders.view = false; alert.error(message); } }); }; $scope.onClickSummary = function(log) { //$scope.loaders.summary = true; popup.open({ size: "lg", template: 'logItems', scope: $scope, resolve: { log: function() { return log; } } }).result.then(function() {}, function () {}); }; $scope.checkChanged = function () { for(var i = 0; i < $scope.logs.length; i++) { if($scope.logs[i].checked && $scope.logs[i].status != consts.LOG_STATUS_PROCESSING) { $scope.checked = true; return; } } $scope.checked = false; }; $scope.setCheckAll = function() { for(var i = 0; i < $scope.logs.length; i++) { var log = $scope.logs[i]; if(log.status != consts.LOG_STATUS_PROCESSING && $scope.permissions[log.type]) log.checked = $scope.checkall; } $scope.checkChanged(); }; $scope.deleteSelected = function() { var ids = []; for(var i in $scope.logs) { if($scope.logs[i].checked) ids.push($scope.logs[i]._id); } if(!ids.length) { alert.error(lang.t("No log IDs selected")); return false; } confirm.open({ message: lang.t("The selected logs will be permanently deleted!"), confirm: function () { api.deleteLog({ data: { _id: ids }, success: function(data, message) { $scope.checkall = false; $scope.checked = false; $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }, cancel: function () { $scope.saveing = false; } }); }; $scope.updateAlert = function(alert) { for(var i in $scope.logs) { if($scope.logs[i]._id === alert._id) { $scope.logs[i] = alert; return false; } } }; $scope.fetch = function() { $scope.loadingLogs = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; if($scope.filter) apiParams.find.type = $scope.filter; if($scope.statusfilter) apiParams.find.status = $scope.statusfilter; if($scope.subfilter) { switch($scope.filter) { case consts.LOG_TYPE_BACKUP: case consts.LOG_TYPE_CLONE: apiParams.find["info.ID"] = $scope.subfilter; break; } } apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.logs = []; $scope.logsProcessingList = []; api.listLogs({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.logs); $scope.logs = data.logs; for(var i in $scope.logs) { if($scope.logs[i].status === consts.LOG_STATUS_PROCESSING) $scope.logsProcessingList.push($scope.logs[i]); $scope.logs[i].information = []; for(var a in $scope.logs[i].info) $scope.logs[i].information.push({ key: a, value: $scope.logs[i].info[a] }); //if(!data[i].information) data[i].information = '-'; } checkProcessingStatus(); $scope.loadingLogs = false; } }); }; var checkProcessingStatus = function() { if($scope.checkTimeout !== undefined || !$scope.logsProcessingList.length) return; $scope.checkTimeout = setTimeout(function () { $scope.checkTimeout = undefined; var fetch = false, timeout = false, params = {}; params._id = []; for(var i = 0; i < $scope.logsProcessingList.length; i++) params._id.push($scope.logsProcessingList[i]._id); api.listLogs({ data: params, success: function(data) { var logs = data.logs; for(var i=0; i < logs.length; i++) { if(logs[i].status === consts.LOG_STATUS_PROCESSING) timeout = true; else if(logs[i].status !== consts.LOG_STATUS_PROCESSING) fetch = true; for(var j = 0; j < $scope.logsProcessingList.length; j++) { if($scope.logsProcessingList[j]._id != logs[i]._id) continue; $scope.logsProcessingList[j].start_time = logs[i].start_time; $scope.logsProcessingList[j].end_time = logs[i].end_time; $scope.logsProcessingList[j].execution_time = logs[i].execution_time; } } if(fetch) $scope.fetch(); if(timeout) checkProcessingStatus(); } }); }, 3000); }; $scope.$on("$destroy", function() { if($scope.checkTimeout === undefined) return; clearTimeout($scope.checkTimeout); $scope.checkTimeout = undefined; }); $timeout($scope.fetch); } ] ); }); define('controllers/logViewer',['app'], function(app) { app.controller('logViewer', ["$uibModalInstance", "$scope", "$timeout", "consts", "log", "reload", function($uibModalInstance, $scope, $timeout, consts, log, reload) { $scope.log = log; $scope.log.information = []; for(var a in $scope.log.info) $scope.log.information.push({ key: a, value: $scope.log.info[a] }); $scope.autoScroll = true; $scope.logContent = null; $scope.timeout = null; $timeout(function () { $scope.logContent = document.getElementById('logContent'); $scope.logContent.scrollTop = $scope.logContent.scrollHeight $scope.logContent.addEventListener('scroll', function () { $scope.autoScroll = Math.abs($scope.logContent.scrollHeight - $scope.logContent.scrollTop - $scope.logContent.clientHeight) < 1; }); }); $scope.reloadLog = function () { $scope.timeout = null; reload(function(data) { $scope.log = data; $timeout(function () { if ($scope.autoScroll && $scope.logContent) $scope.logContent.scrollTop = $scope.logContent.scrollHeight; }); if($scope.log.status == consts.LOG_STATUS_PROCESSING) $scope.timeout = setTimeout($scope.reloadLog, 2000); }); } if($scope.log.status == consts.LOG_STATUS_PROCESSING) $scope.reloadLog(); $scope.ok = function () { $uibModalInstance.close(); }; $scope.$on('$destroy', function () { if($scope.timeout) clearTimeout($scope.timeout); $scope.timeout = null; }); } ] ); }); define('controllers/logItems',['app'], function(app) { app.controller('logItems', ["$uibModalInstance", "$scope", "$timeout", "lang", "meta", "consts", "api", "alert", "log", "popup", function($uibModalInstance, $scope, $timeout, lang, meta, consts, api, alert, log, popup) { $scope.log = log; $scope.items = []; $scope.loadingItems = false; $scope.loaders = { view: false }; meta = meta.new("log_items"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("priority"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["priority","started","ended","execution_time","owner","status"]); meta.setTotalItems($scope.items.length); meta.setPageSizes([5,10]); meta.setPageSize(5); meta.setLimit(5); $scope.downloadLogItem = function(item) { window.location = $scope.downloadURL('log_id=' + $scope.log._id + ':' + item._id); }; $scope.viewLogItem = function(item) { $scope.loaders.view = true; api.getLogItem({ data: { _id: item._id, log_id: $scope.log._id, content: 1 }, success: function (data) { $scope.loaders.view = false; if(!data.content) { alert.error(lang.t("No log content found")); return; } popup.open({ size: "lg", template: 'logViewer', scope: $scope, resolve: { log: function() { var info = {}; if(data.data.account) info.account = data.data.account; info.priority = data.priority; //info.owner = response.data.owner_name + " (#" + response.data.owner + ")"; info.created = lang.d(data.created); //info.message = response.data.message; return { _id: data._id, type: data.type, file: data.file, content: data.content, start_time: data.started, end_time: data.ended, execution_time: data.execution_time, status: consts.QUEUE_STATUS_TO_LOG[data.status] === undefined ? consts.LOG_STATUS_PROCESSING : consts.QUEUE_STATUS_TO_LOG[data.status], info: info }; }, reload: function () { return function(callback) { api.getLogItem({ data: { _id: item._id, log_id: $scope.log._id, content: 1 }, success: function (data) { var info = {}; if(data.data.account) info.account = data.data.account; info.priority = data.priority; //info.owner = response.data.owner_name + " (#" + response.data.owner + ")"; info.created = lang.d(data.created); //info.message = response.data.message; if(callback !== undefined) callback({ _id: data._id, type: data.type, file: data.file, content: data.content, start_time: data.started, end_time: data.ended, execution_time: data.execution_time, status: consts.QUEUE_STATUS_TO_LOG[data.status] === undefined ? consts.LOG_STATUS_PROCESSING : consts.QUEUE_STATUS_TO_LOG[data.status], info: info }); } }); } } } }).result.then(function() {}, function () {}); }, failed: function (message) { $scope.loaders.view = false; alert.error(message); } }); }; $scope.fetch = function() { $scope.loadingItems = true; var apiParams = { skip: meta.getSkip(), limit: meta.getPageSize(), sort: {}, filter: meta.getFilter(), "log_id": $scope.log._id }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.items = []; api.listLogItems({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.items); $scope.items = data.items; $scope.loadingItems = false; }, failed: function (message) { alert.error(message); $uibModalInstance.close(); } }); }; $timeout($scope.fetch); $scope.close = function () { $uibModalInstance.close(); }; }]); }); define('controllers/settings',['app'], function(app) { app.controller("settings", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "meta", "confirm", "util", "permissions", "cfpLoadingBar", "lang", "alert", function ($rootScope, $scope, $routeParams, $location, $timeout, api, meta, confirm, util, permissions, cfpLoadingBar, lang, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.saveing = false; $scope.changed = false; $scope.loading = false; $scope.sectionChanged = false; $rootScope.noSaveButton = false; $scope.details = {}; $scope.saveData = {}; $scope.sections = [ { _id: 'general', name: lang.t('General'), template: 'general', icon: 'fa-cogs', docs:'/Settings/general.html' }, { _id: 'performance', name: lang.t('Performance'), template: 'performance', icon: 'fa-sliders-h', docs:'/Settings/performance.html' }, { _id: 'resource', name: lang.t('Resource'), template: 'resource', icon: 'fa-microchip', docs:'/Settings/resource.html' }, { _id: 'restore', name: lang.t('Restore'), template: 'restore', icon: 'fa-sync', docs:'/Settings/restore.html' }, { _id: 'privacy', name: lang.t('Privacy & Security'), template: 'privacy', icon: 'fa-lock', docs:'/Settings/privacyAndSecurity.html' }, { _id: 'panel', name: lang.t('Panel'), template: 'panel', icon: 'fa-solar-panel', docs:'/Settings/Panel.html' }, { _id: 'snapshots', name: lang.t('Backup on Demand'), template: 'snapshots', icon: 'fa-cubes', docs:'/Settings/snapshots.html' }, { _id: 'notification', name: lang.t('Notification'), template: 'notification', icon: 'fa-bell', docs:'/Settings/notification.html' }, { _id: 'update', name: lang.t('Update Preferences'), template: 'update', icon: 'fa-list', docs:'/Settings/update.html' }, { _id: 'binary', name: lang.t('Binary Locations'), template: 'binary', icon: 'fa-terminal', docs:'/Settings/binaryLocations.html' } ]; $scope.getSection = function (section_id) { for(var i = 0; i < $scope.sections.length; i++) { if($scope.sections[i]._id === section_id) { return $scope.sections[i]; } } return $scope.sections[0]; }; $scope.changeSection = function (section) { if(!$scope.changed) { $location.path('/settings/' + section._id); return; } $scope.sectionChanged = true; confirm.open({ message: lang.t("You didn't saved your changes"), confirm: function () {}, cancel: function () { $location.path('/settings/' + section._id); }, cancelLabel: lang.t("Leave Section"), confirmLabel: lang.t("Stay On Section"), }); }; $scope.validateOptions = {}; $scope.$on('validateOptions', function (e, data) { $scope.validateOptions = data; }); $scope.$on('$destroy', function() { if(!$scope.changed) return; if($scope.sectionChanged) { $scope.sectionChanged = false; return; } confirm.open({ message: lang.t("You didn't saved your changes"), confirmLabel: lang.t("Save"), cancelLabel: lang.t("Disregard Changes"), confirm: $scope.saveChanges }); }); $scope.loadSection = function (section) { $scope.currentSection = section; if(section._id === 'panel') { $scope.settingsSection = ''; app.registerController( 'panelSettings', 'plugins/panel', function(path) { $scope.settingsSection = $scope.includePath('panel/view', 'plugins'); }); } else { $scope.settingsSection = $scope.includePath('settings/' + section.template); } }; $scope.loadSection($scope.getSection($routeParams.section ? $routeParams.section : 'general')); $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details); }, true); $scope.$on('noSaveButtonChange', function (event, value) { $scope.noSaveButton = value; }); $scope.saveChanges = function(callback) { cfpLoadingBar.start(); if($scope.saveing) return; $scope.saveing = true; for (var key in $scope.saveData.options) { if($scope.validateOptions[key] === undefined) continue; if(!$scope.validateOptions[key].validation($scope.saveData.options[key])) { alert.error(lang.t("Invalid value provided for %s", $scope.validateOptions[key].name)); cfpLoadingBar.complete(); $scope.saveing = false; return; } } var apiParams = util.saveParams($scope.saveData, $scope.details, undefined, function (key) { return key == 'mustagree' || key == 'suspendbackups'; }); apiParams.section = $scope.currentSection._id; api.manageSettings({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(callback !== undefined) callback(); if(apiParams.section === 'snapshots') { $rootScope.info.bod_disabled = !data.backup; } $scope.$broadcast('saveChanges', { success: true, message: message, data: data }); alert.success(message); }, failed: function(message) { $scope.saveing = false; $scope.$broadcast('saveChanges', { success: false, message: message }); alert.error(message); } }); }; $scope.fetch = function() { $scope.loading = true; api.getSettings({ data: { section: $scope.currentSection._id }, success: function(data) { $scope.loading = false; $scope.details = {}; $scope.saveData = {}; if(util.countObj(data)) { $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); } }, failed: function (message) { alert.error(message); } }); }; $timeout($scope.fetch); }]); }); define('controllers/settings/binary',['app'], function(app) { app.controller("binarySettings", ["$rootScope", "$scope", function ($rootScope, $scope) { $scope.$on('saveChanges', function (event, data) { for(var key in data.data) $scope.saveData[key] = data.data[key]; }); } ]); }); define('controllers/settings/general',['app'], function(app) { app.controller("generalSettings", ["$rootScope", "$scope", "api", "lang", function ($rootScope, $scope, api, lang) { $scope.time_formats = [ { value: 12, label: lang.t('12 hours based (e.g. 11:00 PM)') }, { value: 24, label: lang.t('24 hours based (e.g. 23:00)') } ]; $scope.email_integrations = [ { value: '', label: '- ' + lang.t('Disabled') + ' -' }, ]; api.listNotificationIntegrations({ data: { find: { type: 'Email' } }, success: function (data) { for(var i = 0; i < data.notifications.length; i++) { $scope.email_integrations.push({ value: data.notifications[i]._id, label: data.notifications[i].name }); } } }); $scope.$on('saveChanges', function (event, data) { window.PAGE.timeformat = data.data.time_format; }); } ]); }); define('controllers/settings/notification',['app'], function(app) { app.controller("notificationSettings", ["$rootScope", "$scope", "$timeout", "lang", "consts", "api", "confirm", "alert", "meta", function ($rootScope, $scope, $timeout, lang, consts, api, confirm, alert, meta) { $scope.loadingNotifications = false; $scope.notifications = []; $scope.filter = ''; $scope.filterOptions = [{ label: lang.t('All Notifications'), value: '' }]; $scope.saveing = false; $scope.loaders = { state: false, delete: false }; meta = meta.new("notifications"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("asc"); meta.setSortFields(["name","type","owner","disabled"]); meta.setTotalItems($scope.notifications.length); $scope.onClickDelete = function(notification) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This notification will be permanently deleted!"), confirm: function () { api.deleteNotificationIntegration({ data: { _id: notification._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.toggleStatus = function(notification) { if($scope.saveing) return; $scope.saveing = true; $scope.loaders.state = true; var disabled = !notification.disabled; api.manageNotificationIntegration({ data: { _id: notification._id, action: 'modify', disabled: disabled }, success: function(data, message) { $scope.saveing = false; $scope.loaders.state = false; notification.disabled = disabled; alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.state = false; alert.error(message); } }); }; $scope.listNotifications = function(callback) { if(callback === undefined || typeof callback != 'function') callback = function(){}; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; if($scope.filter) apiParams.find.type = $scope.filter; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listNotificationIntegrations({ data: apiParams, success: function (data, message) { callback({ success: true, data: data, message: message}); }, failed: function (data, message) { callback({ success: false, data: data, message: message}); } }); }; $scope.fetch = function() { if($scope.loadingNotifications) return; $scope.loadingNotifications = true; $scope.listNotifications(function (response) { $scope.notifications = response.data.notifications; $scope.loadingNotifications = false; meta.setTotalItems(response.data.total); meta.calculate($scope.notifications); }); }; api.listNotificationIntegrationTypes({ success: function (data) { $scope.types = data; for(var i = 0; i < data.types.length; i++) { $scope.filterOptions.push({ label: data.types[i].name, value: data.types[i].key }); } } }); $timeout($scope.fetch); }]); }); define('controllers/settings/notificationManage',['app'], function(app) { app.controller("notificationManage", ["$rootScope", "$scope", "$routeParams", "$q", "$location", "$timeout", "api", "meta", "util", "confirm", "permissions", "lang", "consts", "alert", function ($rootScope, $scope, $routeParams, $q, $location, $timeout, api, meta, util, confirm, permissions, lang, consts, alert) { $rootScope.$emit('menuItem', 'Settings'); $scope.details = { type: '', frequency: {}, owner: $scope.loggedAccount._id, owner_name: $scope.loggedAccount.username, options: {} }; $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete = { accountText: $scope.saveData.owner_name }; $scope.saveing = false; $scope.sending = false; $scope.changed = true; $scope.cancelled = false; $scope.types = []; $scope.plugin = {}; $scope.plugin_available = {}; $scope.plugins_available = {}; $scope.installing = false; $scope.frequencies = [ { value: 0, label: lang.t("Frequency") + " - " + lang.t("Disabled") }, { value: consts.NOTIFICATION_FREQUENCY_REALTIME, label: lang.t("Frequency") + " - " + lang.t("Real Time") }, { value: consts.NOTIFICATION_FREQUENCY_ONCEADAY, label: lang.t("Frequency") + " - " + lang.t("Once a Day") } ]; $scope.resetFrequency = function() { if($scope.saveData.frequency[consts.ALERT_LEVEL_INFO] === undefined) $scope.saveData.frequency[consts.ALERT_LEVEL_INFO] = consts.NOTIFICATION_FREQUENCY_REALTIME; if($scope.saveData.frequency[consts.ALERT_LEVEL_WARNING] === undefined) $scope.saveData.frequency[consts.ALERT_LEVEL_WARNING] = consts.NOTIFICATION_FREQUENCY_REALTIME; if($scope.saveData.frequency[consts.ALERT_LEVEL_CRITICAL] === undefined) $scope.saveData.frequency[consts.ALERT_LEVEL_CRITICAL] = consts.NOTIFICATION_FREQUENCY_REALTIME; }; $scope.resetFrequency(); $scope.isAvailableNotificationIntegration = function() { return $scope.saveData.type && $scope.saveData.type.indexOf('AvailableNotificationIntegrations') >= 0; }; $scope.selectAccount = function(account) { if(account === undefined) return; $scope.saveData.owner = account._id; $scope.saveData.owner_name = account.username; $scope.autocomplete.accountText = account.username; var activeElement = document.activeElement; if (activeElement) activeElement.blur(); }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.resetOptions = function () { $scope.options = {}; }; $scope.loadTemplate = function(type) { if(!type) return; if(type.indexOf('::') >= 0) { var parts = type.split('::'); type = parts[0]; $scope.plugin_available = $scope.plugins_available[parts[1]]; } $scope.resetOptions(); switch(type) { case 'AvailableNotificationIntegrations': $scope.notificationIntegrationType = $scope.includePath('notifications/' + type); $scope.experimental = $scope.plugin_available.experimental !== undefined ? $scope.plugin_available.experimental : ''; break; default: if($scope.plugin[type] === undefined) return; lang.setDefaultNS('plugins-notification-' + type); app.registerPluginController($scope.plugin[type], function(path) { $scope.publicDir = path; $scope.notificationIntegrationType = $scope.publicDir + '/view.htm?v=' + $scope.plugin[type].version; $scope.experimental = $scope.plugin[type].experimental; }); break; } }; $scope.loadNotificationIntegrationType = function() { $scope.loadTemplate($scope.saveData.type); }; $scope.resetOptions(); $scope.$on('options', function (event, options) { for(var key in options) $scope.options[key] = options[key]; }); $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('$destroy', function() { if(!$scope.changed || $scope.cancelled) return; confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/settings/notification'); }; $scope.sendTest = function () { if(!$scope.details._id) { alert.error(lang.t("You can't send test message on unconfigured notification integration")); return; } if($scope.sending) return; $scope.sending = true; api.sendNotificationIntegrationTest({ data: { _id: $scope.details._id }, success: function(data, message) { $scope.sending = false; alert.success(message); }, failed: function (message) { $scope.sending = false; alert.error(message); } }); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, [], function(key) { return ($scope.details._id === undefined && key === 'type'); }); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageNotificationIntegration({ data: apiParams, success: function(data, message) { $scope.saveing = false; $scope.details = data; $scope.saveData = util.duplicateObject($scope.details); $scope.changed = false; if(callback === undefined) { if(apply) $location.path('/settings/notification/manage/' + data._id); else $location.path('/settings/notification'); alert.success(message); } if(callback !== undefined && typeof callback === 'function') callback(); }, failed: function (message) { $scope.saveing = false; alert.error(message); if(callback !== undefined && typeof callback === 'function') callback(); } }); }; $scope.installNotificationIntegration = function() { if($scope.installing) return; $scope.installing = true; confirm.open({ message: lang.t("This notification integration will be installed on this server!"), confirm: function () { api.installPlugin({ data: { package_id: $scope.plugin_available._id, disabled: 0 }, success: function (data, message) { $scope.installing = false; //$scope.installed_plugin = data; $scope.plugin_available = {}; $scope.loadNotificationIntegrations(function () { $scope.saveData.type = data.code; $scope.loadNotificationIntegrationType(); alert.success(message); }); }, failed: function (message) { $scope.installing = false; alert.error(message); } }); }, cancel: function () { $scope.installing = false; } }); }; $scope.loadNotificationIntegrations = function(callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; $scope.types = []; $scope.plugins_available = {}; api.listNotificationIntegrationTypes({ success: function (data) { for(var i = 0; i < data.types.length; i++) { var type = data.types[i]; $scope.types.push({ label: type.name, value: type.key, group: lang.t('Installed Integrations') }); $scope.plugin[type.key] = { type: consts.PLUGIN_TYPE_NOTIFICATION, code: type.key, version: type.version }; if(!$scope.details.type && !$routeParams.id) { $scope.details.type = type.key; $scope.saveData.type = type.key; $scope.loadNotificationIntegrationType(); } } api.listPackagesAvailable({ data: { find: { type: consts.PLUGIN_TYPE_NOTIFICATION } }, success: function(data) { for(var i = 0; i < data.packages.length; i++) { var pkg = data.packages[i]; $scope.plugins_available[pkg.code] = pkg; $scope.types.push({ label: lang.t("%s via %s", pkg.name, pkg.repo_name), value: "AvailableNotificationIntegrations::" + pkg.code, group: lang.t('Available Integrations') }); } callback(); }, failed: function () { callback(); } }); } }); }; $scope.loadNotificationIntegrations(function () { if($routeParams.id) { api.getNotificationIntegration({ data: { _id: $routeParams.id }, success: function(data) { $scope.details = data; if({}.toString.apply($scope.details.options) !== '[object Object]') { $scope.details.options = {}; } $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete.accountText = $scope.saveData.owner_name; //delete $scope.details.options; $scope.loadNotificationIntegrationType(); } }); } }); }]); }); define('controllers/settings/performance',['app'], function(app) { app.controller("performanceSettings", ["$rootScope", "$scope", "api", "lang", function ($rootScope, $scope, api, lang) { $scope.queuePriorities = [ { _id: '', name: lang.t('Default') } ]; $scope.fetchQueuePriorities = function() { api.listQueuePriorities({ success: function (data) { var priorities = data.priorities; for(var i=0; i< priorities.length; i++ ){ $scope.queuePriorities.push({ _id: priorities[i]._id, name: priorities[i].name }); } } }); }; $scope.fetchQueuePriorities(); $scope.mysqlpackets_options = [ { label: lang.t("Default"), value: 0 }, { label: "32 MB", value: 32 }, { label: "64 MB", value: 64 }, { label: "128 MB", value: 128 }, { label: "256 MB", value: 256 }, { label: "512 MB", value: 512 }, { label: "1 GB", value: 1024 } ]; $scope.gtidpurged_options = [ { label: lang.t("Default"), value: "" }, { label: "Auto", value: "AUTO" }, { label: "Off", value: "OFF" }, { label: "On", value: "ON" }, { label: "Commented", value: "COMMENTED" } ]; }]); }); define('controllers/settings/resource',['app'], function(app) { app.controller("resourceSettings", ["$rootScope", "$scope", "lang", function ($rootScope, $scope, lang) { }]); }); define('controllers/settings/privacy',['app'], function(app) { app.controller("privacySettings", ["$rootScope", "$scope", "confirm", "lang", "api", function ($rootScope, $scope, confirm, lang, api) { $scope.encryption_key = ''; api.getMasterEncryptionKey({ success: function (data) { $scope.encryption_key = data.encryption_key; } }); $scope.$watch('saveData.encryption_selection', function () { if( $scope.details.encryption_selection === undefined || $scope.details.encryption_selection == 0 || $scope.saveData.encryption_selection === undefined || $scope.saveData.encryption_selection == 1 ) return; confirm.open({ message: lang.t("WARNING! All encrypted backups for accounts that are using *remote* encryption key will be deleted and lost forever!"), confirmLabel: lang.t("OK, I understand the risks"), confirm: function () { $scope.saveData.condition = 1; }, cancel: function () { $scope.saveData.condition = 0; $scope.saveData.encryption_selection = 1; } }); }); } ] ); }); define('controllers/settings/restore',['app'], function(app) { app.controller("restoreSettings", ["$rootScope", "$scope", "$timeout", "api", "consts", "lang", function ($rootScope, $scope, $timeout, api, consts, lang) { $scope.ownership_types = ['nobody','user']; /* $scope.destinations = [{_id: '', name: lang.t('- Disable Safety Backups -') }]; $scope.fetchDestinations = function() { api.listDestinations({}, function(response) { for(var i = 0; i < response.data.destinations.length; i++) { if( response.data.destinations[i].clone_destination || response.data.destinations[i].engine != consts.DESTINATION_ENGINE_JETBACKUP || !response.data.destinations[i].incremental_ability ) continue; $scope.destinations.push(response.data.destinations[i]); } }); }; $timeout($scope.fetchDestinations()); */ } ] ); }); define('controllers/settings/snapshots',['app'], function(app) { app.controller("snapshotsSettings", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "lang", "consts", function ($rootScope, $scope, $routeParams, $location, $timeout, api, lang, consts) { $scope.backups = [{_id: '', name: lang.t('- Disable Backup on Demand System -') }]; $scope.sizes = ['MB','GB','TB']; $scope.fetchBackupJobs = function() { var params = {find:{}}; params.find.type = consts.BACKUP_TYPE_ACCOUNT; params.find.contains = consts.BACKUP_TYPE_ACCOUNT_FULL; api.listBackupJobs({ data: params, success: function(data) { for(var i = 0; i < data.jobs.length; i++) $scope.backups.push(data.jobs[i]); } }); }; $timeout($scope.fetchBackupJobs()); }]); }); define('controllers/settings/update',['app'], function(app) { app.controller("updateSettings", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "lang", "consts", function ($rootScope, $scope, $routeParams, $location, $timeout, api, lang, consts) { $scope.tiers = [ { key: "release", name: "RELEASE", description: lang.t("Receives well-tested updates directly from the JetApps repository, ensuring optimal reliability and minimal risk. Ideal for production environments where stability and consistency is paramount.") }, { key: "rc", name: "RELEASE CANDIDATE (RC)", description: lang.t("Pre-release versions that are close to the final stable release, with updates from our repository servers. These versions are intended for final testing before the official release. Recommended for users who wish to test the upcoming stable version and provide feedback.") }, { key: "edge", name: "EDGE", description: lang.t("Cutting-edge updates with the latest features and improvements, provided from our repository servers. Should be more stable than ALPHA but still may contain bugs or other issues. Great for users who prefer to stay at the forefront of development.") }, { key: "alpha", name: "ALPHA", description: lang.t("Early access to features still in development, sourced from our repository servers. Expect frequent updates and potential instability. Suitable for developers and testers who want to explore new features.") }, ]; $scope.getVersion = function (tier) { if($scope.saveData.versions === undefined || $scope.saveData.versions[tier] === undefined) return ''; return $scope.saveData.versions[tier]; }; $scope.$on('saveChanges', function (event, data) { $rootScope.info.tier = data.data.tier.toUpperCase(); }); }]); }); define('controllers/fileManager',['app'], function(app) { app.controller("fileManager", ["$rootScope", "$scope", "$interval", "$timeout", "api", "meta", "$window", "$routeParams", "$location", "permissions", "consts", "lang", "alert", "pathManager", function($rootScope, $scope, $interval, $timeout, api, meta, $window, $routeParams, $location, permissions, consts, lang, alert, pathManager) { $rootScope.$emit('menuItem', 'BackupManager'); $scope.manager = pathManager.new($scope.listPathes !== undefined ? $scope.listPathes : []); $scope.type = $routeParams.type; $scope.typeId = $routeParams.id; $scope.typeDetails = { name: '' }; $scope.files = []; $scope.loadingFiles = false; $scope.currentPath = ''; $scope.breadcrumbs = []; $scope.filesIndex = {}; $scope.actionModule = undefined; //$scope.config = {}; $scope.backup_type = 2; $scope.restoringBackup = false; $scope.downloadingBackup = false; $scope.downloads = []; $scope.restores = []; $scope.downloadsTmp = []; $scope.queues = []; $scope.isDirectories = false; $scope.showhidden = true; $scope.checkedAll = false; var statusInterval; $scope.clearStatus = function() { }; $scope.cancelAction = function() { $scope.actionModule = undefined; }; $scope.changeView = function(view){ $location.path(view); // path not hash }; $scope.onClickRestore = function() { var selected = getSelected(); if(!selected.length) { alert.error("Please select files to restore"); return; } $scope.actionModule = ($scope.actionModule === 'restore') ? undefined : 'restore'; }; /* $scope.onClickRestoreConfirm = function() { $scope.restoringBackup = true; var apiParams = {}; apiParams['_id'] = $scope.typeId; apiParams['files'] = getSelected(); api.addQueueItems({ data: apiParams, success: function(data, message) { $scope.queues.push(data._id); $scope.restoringBackup = false; $scope.actionModule = undefined; $scope.uncheckAll(); $scope.getRestores(); alert.success(message); return true; }, failed: function (message) { alert.error(message); $scope.restoringBackup = false; } }); }; */ $scope.onClickDownload = function() { var selected = getSelected(); if(!selected.length) { alert.error("Please select files to download"); return; } $scope.actionModule = ($scope.actionModule === 'download') ? undefined : 'download'; }; /* $scope.onClickDownloadConfirm = function() { $scope.downloadingBackup = true; var apiParams = {}; apiParams._id = $scope.typeId; apiParams.type = $scope.type; apiParams.files = getSelected(); api.addQueueDownload(apiParams, function(response) { if(!response.success) { alert.error(response.message); $scope.downloadingBackup = false; return false; } $scope.queues.push(response.data._id); $scope.downloadingBackup = false; $scope.actionModule = undefined; $scope.uncheckAll(); $scope.getDownloads(); alert.success(response.message); return true; }); }; */ /* $scope.isConditionsAgreed = function() { for(var i in $scope.config.restore_conditions) { if($scope.config.restore_conditions[i].type !== 0 && $scope.config.restore_conditions[i].type !== $scope.backup_type) continue; if(!$scope.config.restore_conditions[i].checked) return true } return false; }; */ var getSelected = function() { var selected = []; for(var i in $scope.filesIndex) { for(var j in $scope.filesIndex[i].files) { if($scope.filesIndex[i].files[j] != null && $scope.filesIndex[i].files[j].checked !== undefined && $scope.filesIndex[i].files[j].checked) { selected.push($scope.filesIndex[i].files[j].path); } } } return selected; }; $scope.canPerformAction = function () { for(var i in $scope.filesIndex) { for(var j in $scope.filesIndex[i].files) { if($scope.filesIndex[i].files[j] != null && $scope.filesIndex[i].files[j].checked !== undefined && $scope.filesIndex[i].files[j].checked) { return false; } } } return true; }; $scope.emitSelected = function() { var output = {}; var selected = $scope.manager.getSelected(); for(var i = 0; i < selected.length; i++) { var path = selected[i]; var name = path.replace(/.*\//, ''); var parent = path.match(/.*\//).join(''); if(parent !== '/') parent = parent.replace(/\/$/, ''); if($scope.filesIndex[parent] === undefined) { output[path] = {empty:true}; continue; } var files = $scope.filesIndex[parent].files; for(var j = 0; j < files.length; j++) { if(files[j].name !== name) continue; output[path] = files[j]; break; } } $rootScope.$emit('filesChanged', output); }; $scope.toggleFile = function(file) { if($scope.manager.isExists(file.path)) $scope.manager.removePath(file.path); else $scope.manager.addPath(file.path); $scope.emitSelected(); $scope.calculateCheckedAll(); }; $scope.isDisabled = function(file) { return $scope.manager.isChildren(file.path); }; $scope.isChecked = function(file) { file.checked = ($scope.manager.isExists(file.path) || $scope.manager.isChildren(file.path)); return file.checked; }; $scope.isChildrenChecked = function(file) { return $scope.manager.isParent(file.path); }; var manageBreadcrumbs = function(file) { if(file.path === '/') file.name = '/' + $scope.type + '-root'; $scope.breadcrumbs.unshift(file); if(file.parent !== undefined) manageBreadcrumbs(file.parent); }; var handleResponse = function(data, file) { $scope.filesIndex[file.path] = data; $scope.files = data.files; /* $scope.files.sort(function(a, b){ if(a.type == 'Directory' && b.type != 'Directory') return -1; if(b.type == 'Directory' && a.type != 'Directory') return 1; return a.name < b.name ? -1 : 1; }); */ $scope.loadingFiles = false; }; $scope.toggleHidden = function() { $scope.showhidden = !$scope.showhidden; $scope.calculateCheckedAll(); }; var metaFiles = meta.new("file_manager"); $scope.meta = metaFiles; $scope.metaData = metaFiles.getData(); if(!metaFiles.getSortBy()) metaFiles.setSortBy("type"); if(!metaFiles.getSortDirection()) metaFiles.setSortDirection("asc"); metaFiles.setSortFields(["name","type","size","created"]); metaFiles.setPageSize(50); metaFiles.setPageSizes([10,25,50,100]); metaFiles.setTotalItems($scope.files.length); $scope.currentFile = undefined; $scope.fetch = function(file, resetPagination) { if(file === undefined) file = $scope.currentFile; else $scope.currentFile = file; if(file.path === undefined) file.path = '/'; $scope.loadingFiles = true; $scope.files = []; $scope.breadcrumbs = []; manageBreadcrumbs(file); if(resetPagination) metaFiles.setCurrentPage(1); //if($scope.filesIndex[file.path] !== undefined) { // handleResponse($scope.filesIndex[file.path], file); // return; //} var apiParams = { sort: {}, skip: metaFiles.getSkip(), limit: metaFiles.getPageSize(), find: {}, filter: '' }; apiParams._id = $scope.typeId; apiParams.type = $scope.type; apiParams.path = file.path; apiParams.file_id = file.id; apiParams.sort[metaFiles.getSortBy()] = metaFiles.getSortDirectionInt(); api.fileManager({ data: apiParams, success: function(data) { for(var i = 0; i < data.files.length; i++) { data.files[i].path = file.path + (file.path === '/' ? '' : '/') + data.files[i].name; data.files[i].parent = file; data.files[i].hidden = data.files[i].name.substr(0, 1) === '.'; } metaFiles.setTotalItems(data.total); metaFiles.calculate(data.files); handleResponse(data, file); $scope.calculateCheckedAll(); }, failed: function (message) { alert.error(message); } }); }; $scope.hideCheckAll = function() { return $scope.manager.isExists($scope.currentFile.path) || $scope.manager.isChildren($scope.currentFile.path); }; $scope.calculateCheckedAll = function () { for(var i = 0; i < $scope.files.length; i++) { var file = $scope.files[i]; if( !(file.type === 'File' || file.type === 'Directory') || (file.hidden && !$scope.showhidden && $scope.checkedAll) ) continue; var exists = $scope.manager.isExists(file.path); if(!exists) { $scope.checkedAll = false; return; } } $scope.checkedAll = true; }; $scope.toggleCheckAll = function() { $scope.checkedAll = !$scope.checkedAll; for(var i = 0; i < $scope.files.length; i++) { var file = $scope.files[i]; if( !(file.type === 'File' || file.type === 'Directory') || (file.hidden && !$scope.showhidden && $scope.checkedAll) ) continue; var exists = $scope.manager.isExists(file.path); if($scope.checkedAll && !exists) $scope.manager.addPath(file.path); else if(!$scope.checkedAll && exists) $scope.manager.removePath(file.path); } $scope.emitSelected(); }; $scope.uncheckAll = function () { for(var i in $scope.filesIndex) { for(var j in $scope.filesIndex[i].files) { if($scope.filesIndex[i].files[j] != null && $scope.filesIndex[i].files[j].checked !== undefined && $scope.filesIndex[i].files[j].checked) { $scope.filesIndex[i].files[j].checked = false; } } } }; $scope.directDownload = function(download) { window.location = $scope.downloadURL('download_id=' + download.download_id); }; /* $scope.getDownloads = function () { $scope.downloads = []; $scope.loadingDownloads = true; var apiParams = {}; apiParams._id = $scope.typeId; apiParams.type = $scope.type; api.getBackupDownloads(apiParams, function(response) { if (!response.success) { $scope.downloads = []; alert.error(response.message); $scope.loadingDownloads = false; return false; } for(var i = 0; i < response.data.downloads.length; i++) { $scope.downloads.push(response.data.downloads[i]); if ($scope.downloads[i].ready) $scope.downloads[i].status = 100; else $scope.downloads[i].status = 1; } var find = {status:{'$gt':100}}; api.listQueueItems({ type: consts.QUEUE_TYPE_DOWNLOAD, snap_item_id: $scope.typeId, find: find }, function(response) { if(!response.success) { alert.error(response.message); $scope.loadingRestores = false; return false; } for(var i = 0; i < response.data.queue.length; i++) { var data = response.data.queue[i]; var filename = ''; if(data.status > 100) filename = lang.t("Download Failed"); else filename = lang.t("Download in Progress"); $scope.downloads.push({ queue_id: data._id, status: data.status, ready: !(parseInt(data.status) > 100 || parseInt(data.status) < 100), filename: filename, download_id: data.download_id }); } $scope.loadingDownloads = false; return true; }); return true; }); }; */ /* $scope.getRestores = function () { $scope.loadingRestores = true; api.listQueueItems({ type: consts.QUEUE_ITEM_TYPE_RESTORE, snap_item_id: $scope.typeId }, function(response) { $scope.restores = []; if(!response.success) { alert.error(response.message); $scope.loadingRestores = false; return false; } for(var i = 0; i < response.data.queue.length; i++) { var data = response.data.queue[i]; var text = ''; if(data.status === 100) text = lang.t("Restore Completed"); else if(data.status > 100) text = lang.t("Restore Failed"); else text = lang.t("Restore in Progress"); $scope.restores.push({ _id: data._id, ready: data.status >= 100, status: data.status, created: data.created, text: text }); } $scope.loadingRestores = false; return true; }); }; */ $scope.inQueues = function(_id) { for(var i = 0; i < $scope.queues.length; i++) { if($scope.queues[i] == _id) return i; } return null; }; $scope.checkStatus = function () { statusInterval = $interval(function() { api.listQueueItems({ data: { snap_item_id: $scope.typeId }, success: function(data) { var reload = false; for(var i = 0; i < data.queue.length; i++) { var item = data.queue[i]; var index = $scope.inQueues(item._id); if(index !== null) { if(item.status >= 100) { $scope.queues.splice(index, 1); reload = true; } } else if(item.status < 100) { $scope.queues.push(item._id); } } /* if(reload) { $scope.getDownloads(); $scope.getRestores(); } */ }, failed: function (message) { alert.error(message); } }); }, 3000); }; $scope.getDestination = function() { api.getDestination({ data: { _id: $scope.typeId }, success: function(data) { $scope.typeDetails = data; }, failed: function (message) { alert.error(message); $location.path('/destinations'); } }); }; $scope.getBackup = function() { api.getBackupItem({ data: { _id: $scope.typeId }, success: function(data) { $scope.typeDetails = data; //$scope.isDirectories = consts.BACKUP_TYPE_DIRECTORY == $scope.typeDetails.type; }, failed: function (message) { alert.error(message); } }); }; $scope.$on('$destroy', function() { if(angular.isDefined(statusInterval)) $interval.cancel(statusInterval); }); $scope.init = function () { //$scope.checkStatus(); switch($scope.type) { default: $location.path('/'); break; case 'backup': if(!permissions.canManageFileBackups) $location.path('/'); $scope.getBackup(); //$scope.getRestores(); break; case 'destination': if(!permissions.canManageDestinations) $location.path('/'); $scope.isDirectories = true; $scope.getDestination(); break; } //$scope.getDownloads(); $scope.fetch({path: '/'}); $scope.calculateCheckedAll(); }; $timeout($scope.init()); }] ); } ); define('controllers/fileManagerPopup',['app'], function(app) { app.controller("fileManagerPopup", ["$uibModalInstance", "$rootScope", "$scope", "$routeParams", "$interval", "$timeout", "api", "meta", "lang", "pathManager", "files", "backup", function($uibModalInstance, $rootScope, $scope, $routeParams, $interval, $timeout, api, meta, lang, pathManager, files, backup) { $routeParams.type = 'backup'; $routeParams.id = backup._id; $scope.files = files; $scope.listPathes = []; for(var path in files) $scope.listPathes.push(path); $rootScope.$on('filesChanged', function (event, files) { $scope.files = {}; for(var path in files) { if($scope.files[path] !== undefined) continue; $scope.files[path] = files[path].empty !== undefined && files[path].empty ? "Unknown" : files[path].type; } }); $scope.ok = function () { $uibModalInstance.close($scope.files); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }]); } ); define('controllers/fileBrowse',['app'], function(app) { app.controller("fileBrowse", ["$uibModalInstance", "$scope", "$interval", "$timeout", "api", "meta", "lang", "alert", "util", "pathManager", "listPaths", function($uibModalInstance, $scope, $interval, $timeout, api, meta, lang, alert, util, pathManager, listPaths) { $scope.manager = pathManager.new(listPaths); $scope.files = []; $scope.selectedTree = {}; $scope.loadingFiles = false; $scope.breadcrumbs = []; $scope.filesIndex = {}; $scope.filesPageIndex = {}; $scope.currentFile = {path: '/'}; $scope.toggleFile = function(file) { if($scope.manager.isExists(file.path)) $scope.manager.removePath(file.path); else $scope.manager.addPath(file.path); }; $scope.noParentDirectory = function() { return $scope.breadcrumbs.length <= 1; }; $scope.goParentDirectory = function() { if($scope.noParentDirectory()) return; $scope.fetch($scope.breadcrumbs[$scope.breadcrumbs.length-2], false, true); }; $scope.isDisabled = function(file) { return $scope.manager.isChildren(file.path); }; $scope.isChecked = function(file) { return $scope.manager.isExists(file.path) || $scope.manager.isChildren(file.path); }; $scope.isChildrenChecked = function(file) { return $scope.manager.isParent(file.path); }; var calculateBreadcrumbs = function(file) { var path = file.path; if(path.substr(-1) === '/') path = path.substr(0, path.length-1); if(path.substr(0, 1) === '/') path = path.substr(1); var parts = path ? path.split('/') : []; $scope.breadcrumbs = [{name:"", path:"/"}]; var fullpath = ''; for(var i = 0; i < parts.length; i++) { fullpath += '/' + parts[i]; $scope.breadcrumbs.push({name: parts[i], path: fullpath}); } }; var handleResponse = function(data, file) { $scope.filesIndex[file.path] = data; $scope.filesPageIndex[file.path] = metaFiles.getCurrentPage(); $scope.files = data.files; for(var i = 0; i < $scope.files.length; i++) { $scope.files[i].checked = $scope.manager.isExists($scope.files[i].path); } /* $scope.files.sort(function(a, b){ if(a.type == 'Directory' && b.type != 'Directory') return -1; if(b.type == 'Directory' && a.type != 'Directory') return 1; return a.name < b.name ? -1 : 1; }); */ $scope.loadingFiles = false; }; var metaFiles = meta.new("file_browse"); $scope.meta = metaFiles; $scope.metaData = metaFiles.getData(); if(!metaFiles.getSortBy()) metaFiles.setSortBy("type"); if(!metaFiles.getSortDirection()) metaFiles.setSortDirection("asc"); metaFiles.setSortFields(["name","type","size","created"]); metaFiles.setPageSize(25); metaFiles.setPageSizes([5,10,25,50]); metaFiles.setTotalItems($scope.files.length); $scope.fetch = function(file, resetPagination, restorePagination) { if(file === undefined || file.path === undefined) file = $scope.currentFile; $scope.currentFile = file; $scope.loadingFiles = true; $scope.files = []; calculateBreadcrumbs(file); /* if($scope.filesIndex[file.path] !== undefined) { handleResponse($scope.filesIndex[file.path], file); return; } */ if(resetPagination) { metaFiles.setCurrentPage(1); } else if(restorePagination) { var page = $scope.filesPageIndex[file.path] === undefined ? 1 : $scope.filesPageIndex[file.path]; metaFiles.setCurrentPage(page); } var apiParams = { sort: {}, skip: metaFiles.getSkip(), limit: metaFiles.getPageSize(), find: {}, filter: '' }; apiParams._id = $scope.typeId; apiParams.type = $scope.type; apiParams.path = file.path; apiParams.sort[metaFiles.getSortBy()] = metaFiles.getSortDirectionInt(); api.fileBrowse({ data: apiParams, success: function(data) { for(var i = 0; i < data.files.length; i++) { data.files[i].path = file.path + (file.path === '/' ? '' : '/') + data.files[i].name; } handleResponse(data, file); metaFiles.setTotalItems(data.total); metaFiles.calculate(data.files); }, failed: function (message) { alert.error(message); } }); }; $timeout($scope.fetch({path: '/'})); $scope.ok = function () { $uibModalInstance.close($scope.manager.getSelected()); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }] ); } ); define('controllers/downloads',['app'], function(app) { app.controller("downloads", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "alert", function ($rootScope, $scope, $location, $timeout, api, meta, alert) { $rootScope.$emit('menuItem', 'Downloads'); $scope.loading = false; $scope.downloads = []; meta = meta.new("downloads"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["created", "size"]); meta.setTotalItems($scope.downloads.length); $scope.directDownload = function(download) { window.location = window.PAGE.path.download + "&download_id=" + download._id; }; $scope.saveNotes = function (download, keyEvent) { if(keyEvent && keyEvent.which !== 13) return; api.manageDownloadNotes({ data: { _id: download._id, notes: download.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); } }); download.editing = false; }; $scope.fetch = function () { if($scope.loading) return; $scope.loading = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.downloads = []; api.listDownloads({ data: apiParams, success: function(data) { $scope.loading = false; meta.setTotalItems(data.total); meta.calculate(data.downloads); $scope.downloads = data.downloads; } }); }; $timeout($scope.fetch()); } ] ); }); define('controllers/accountSelection',['app'], function(app) { app.controller('accountSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "lang", "account", function($uibModalInstance, $scope, $timeout, api, lang, account) { $scope.loading = false; $scope.accounts = []; $scope.selectedAccount = {}; $scope.selectAccount = function(account) { $scope.selectedAccount = account; }; $scope.fetch = function () { $scope.loading = true; api.listAccounts({ data: { login_only: 0, sort: { username: 1 }, limit: 9999999 }, success: function (data) { for (var i = 0; i < data.accounts.length; i++) { if(account === data.accounts[i].username) $scope.selectedAccount = data.accounts[i]; $scope.accounts.push(data.accounts[i]); } $scope.loading = false; } }); }; $timeout($scope.fetch()); $scope.ok = function () { $uibModalInstance.close($scope.selectedAccount); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/restore',['app'], function(app) { app.controller("restore", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "permissions", "confirm", "alert", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, permissions, confirm, alert, consts, lang, popup) { $rootScope.$emit('menuItem', 'Restore'); $scope.changed = false; $scope.restoreSectionChanged = false; $scope.hideTabs = !permissions.canManageAccounts && !permissions.canManageDirectoryBackups; $scope.restoreSections = [ { _id: 'singleaccount', name: lang.t('Single Account'), template: 'restoreSingleAccount', icon: 'fa-user', hidden: false }, { _id: 'multiaccount', name: lang.t('Multi Account'), template: 'restoreMultiAccount', icon: 'fa-users', hidden: !permissions.canManageAccounts }, { _id: 'directories', name: lang.t('Directories'), template: 'restoreDirectories', icon: 'fa-folder', hidden: !permissions.canManageDirectoryBackups }, { _id: 'disasterrecovery', name: lang.t('ISO Images'), template: 'restoreDisasterRecovery', icon: 'fa-compact-disc', hidden: !permissions.canManageDisasterRecoveryBackups } ]; $scope.getRestoreSection = function (section_id) { for(var i = 0; i < $scope.restoreSections.length; i++) { if($scope.restoreSections[i]._id === section_id) { return $scope.restoreSections[i]; } } return $scope.restoreSections[0]; }; $scope.changeRestoreSection = function (section) { if(!$scope.changed) { $location.path('/restore/' + section._id); return; } $scope.restoreSectionChanged = true; }; $scope.loadRestoreSection = function (section) { $scope.currentRestoreSection = section; $scope.restoreSection = $scope.includePath(section.template); }; $scope.loadRestoreSection($scope.getRestoreSection($routeParams.section ? $routeParams.section : 'singleaccount')); } ] ); }); define('controllers/restoreMultiAccount',['app'], function(app) { app.controller("restoreMultiAccount", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "permissions", "confirm", "alert", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, permissions, confirm, alert, consts, lang, popup) { $scope.today = new Date(); $scope.loadingAccounts = false; $scope.destinations = [{label:lang.t("Any Destination"),value:''}]; $scope.action = 'restore'; $scope.accounts = []; $scope.account_details = {}; $scope.owner_details = {}; $scope.excluded = []; $scope.restore_conditions = []; $scope.conditions = {}; $scope.exclude_type = 0; $scope.exclude_loading = false; $scope.encryption_keys = {}; $scope.total_accounts = 0; $scope.backup_contains = consts.BACKUP_TYPE_ACCOUNT_FULL; $scope.options = {}; $scope.tags = {}; $scope.autocomplete = { accountText: '', ownerText: '', tagText: '' }; $scope.filters = { accounts: [], show_oldest: 0, date_start: '', date_end: '', account_status: 0, account_suspended: 0, locked: 0, encrypted: 0, backup_structure: 0, backup_contains: 0, destination: '', owned_by: [], tags: [], use_damaged: 0 }; $scope.$watch('action', function () { $scope.options = {allbackups:0}; if($scope.action == 'unlock') $scope.filters.locked = 1; else if($scope.action == 'lock') $scope.filters.locked = 2; else $scope.filters.locked = 0; }); $scope.account_types_disabled = {}; $scope.account_types_disabled[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = true; $scope.account_types = [ { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG], value: consts.BACKUP_TYPE_ACCOUNT_CONFIG }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR], value: consts.BACKUP_TYPE_ACCOUNT_HOMEDIR }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES], value: consts.BACKUP_TYPE_ACCOUNT_DATABASES }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS], value: consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS], value: consts.BACKUP_TYPE_ACCOUNT_EMAILS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FTP], value: consts.BACKUP_TYPE_ACCOUNT_FTP }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS], value: consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS], value: consts.BACKUP_TYPE_ACCOUNT_DOMAINS }, { label: consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES], value: consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES } ]; var metaAcct = meta.new("restore_and_download"); $scope.meta = metaAcct; $scope.metaData = metaAcct.getData(); metaAcct.setSortReverse(false); if(!metaAcct.getSortBy()) metaAcct.setSortBy("username"); if(!metaAcct.getSortDirection()) metaAcct.setSortDirection("asc"); metaAcct.setSortFields(["username", "owner"]); metaAcct.setTotalItems($scope.accounts.length); $scope.containsChecked = function(type, contains) { if(contains === undefined) contains = $scope; return ( type & contains.backup_contains ); }; $scope.toggleContains = function(type, contains) { if(contains === undefined) contains = $scope; if($scope.containsChecked(type, contains)) contains.backup_contains ^= type; else contains.backup_contains |= type; }; $scope.isExcluded = function(account) { return $scope.excluded.indexOf(account.username) >= 0; }; $scope.toggleExclude = function(account) { if(!$scope.isExcluded(account)) $scope.excluded.push(account.username); else { var index = $scope.excluded.indexOf(account.username); $scope.excluded.splice(index, 1); } }; $scope.toggleExcludeAll = function() { if($scope.exclude_loading) return; $scope.exclude_loading = true; if($scope.exclude_type === 0) { $scope.exclude_type = 1; api.listAccountsByFilters({ data: { filters: $scope.filters, limit: 9999999 }, success: function(data) { $scope.excluded = []; for(var i = 0; i < data.accounts.length; i++) { var account = data.accounts[i].account; $scope.excluded.push(account.username); } $scope.exclude_loading = false; } }); } else { $scope.exclude_loading = false; $scope.exclude_type = 0; $scope.excluded = []; } }; $scope.gotItems = function(types) { var check = 0; for(var i = 0; i < types.length; i++) check |= types[i]; return $scope.backup_contains & check; }; $scope.fetchNoResetExcludes = function (callback) { $scope.fetch(callback, true); }; $scope.fetch = function(callback, dontReset) { if($scope.loadingAccounts) return; if(callback === undefined || typeof callback !== 'function') callback = function(){}; $scope.loadingAccounts = true; $scope.exclude_type = 0; if(dontReset === undefined || !dontReset) $scope.excluded = []; var apiParams = { skip: metaAcct.getSkip(), limit: metaAcct.getPageSize(), filters: $scope.filters }; if(window.PAGE.info.utcOffset){ if(apiParams.filters.date_start) apiParams.filters.date_start.utcOffset(window.PAGE.info.utcOffset, true); if(apiParams.filters.date_end) apiParams.filters.date_end.utcOffset(window.PAGE.info.utcOffset, true); } $scope.accounts = []; api.listAccountsByFilters({ data: apiParams, success: function(data) { metaAcct.setTotalItems(data.total); metaAcct.calculate(data.accounts); $scope.accounts = data.accounts; $scope.total_accounts = data.total; $scope.loadingAccounts = false; callback(); } }); }; $scope.tagsSelection = function () { popup.open({ template: 'tagsSelection', scope: $scope, resolve: { tags: function() { return $scope.filters.tags; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }).result.then(function(selected) { $scope.filters.tags = selected; }, function () {}); }; $scope.ownersSelection = function () { popup.open({ template: 'accountsSelection', scope: $scope, resolve: { accounts: function() { return $scope.filters.owned_by; }, includeOrphan: function () { return 0; }, callParams: function () { return ''; } } }).result.then(function(selected) { $scope.filters.owned_by = selected; }, function () {}); }; $scope.accountsSelection = function () { popup.open({ template: 'accountsSelection', scope: $scope, resolve: { accounts: function() { return $scope.filters.accounts; }, includeOrphan: function () { return 1; }, callParams: function () { return ''; } } }).result.then(function(selected) { $scope.filters.accounts = selected; }, function () {}); }; $scope.searchTags = function(query) { if(!query) return []; var deferred = $q.defer(); api.listTags({ data: { filter: query, sort: { name: 1 }, find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function(data) { var results = []; for(var i = 0; i < data.tags.length; i++) { var tag = data.tags[i]; if($scope.filters.tags.indexOf(tag._id) >= 0) continue; results.push(tag); } deferred.resolve( results ); } }); return deferred.promise; }; $scope.searchOwners = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) { var account = data.accounts[i]; if($scope.filters.owned_by.indexOf(account.username) >= 0) continue; results.push(account); } deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { include_orphan: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) { var account = data.accounts[i]; if($scope.filters.accounts.indexOf(account.username) >= 0) continue; results.push(account); } deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.selectTag = function(tag) { if(tag === undefined) return; $scope.filters.tags.push(tag._id); $scope.autocomplete.tagText = ''; }; $scope.selectOwner = function(account) { if(account === undefined) return; $scope.filters.owned_by.push(account.username); $scope.owner_details[account.username] = account; $scope.autocomplete.ownerText = ''; }; $scope.selectAccount = function(account) { if(account === undefined) return; $scope.filters.accounts.push(account.username); $scope.account_details[account.username] = account; $scope.autocomplete.accountText = ''; }; $scope.isContainsDisabled = function(type) { return $scope.account_types_disabled[type] !== undefined && $scope.account_types_disabled[type]; }; $scope.manageBackupLock = function() { var totalAccounts = $scope.total_accounts-$scope.excluded.length; if(totalAccounts <= 0) { alert.error(lang.t("Your filters didn't result with any account")); return; } var locked = $scope.action == 'lock' ? 1 : 0; confirm.open({ message: lang.t("Total of %s accounts backups will be " + (locked ? "locked" : "unlocked"), totalAccounts), confirm: function () { api.manageMultiBackupLock({ data: { locked: locked, filters: $scope.filters, options: $scope.options, excluded: $scope.excluded }, success: function (data, message) { alert.success(message); $scope.fetch(); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.addToQueue = function() { var totalAccounts = $scope.total_accounts-$scope.excluded.length; if(totalAccounts <= 0) { alert.error(lang.t("Your filters didn't result with any account")); return; } var confirmMessage = ''; var type = ''; switch($scope.action) { case 'restore': type = consts.QUEUE_ITEM_TYPE_RESTORE; confirmMessage = lang.t("Total of %s accounts will be restored", totalAccounts); for(var i = 0; i < $scope.restore_conditions.length; i++) { var condition = $scope.restore_conditions[i]; if($scope.conditions[condition._id] === undefined || !$scope.conditions[condition._id]) { alert.error(lang.t("Please accept all restore conditions")); return; } } break; case 'download': type = consts.QUEUE_ITEM_TYPE_DOWNLOAD; confirmMessage = lang.t("Total of %s accounts backups will be downloaded", totalAccounts); break; } confirm.open({ message: confirmMessage, confirm: function () { api.addMultiAccountQueueItems({ data: { type: type, filters: $scope.filters, options: $scope.options, backup_contains: $scope.backup_contains, encryption_keys: $scope.encryption_keys, excluded: $scope.excluded }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); } }); } }); }; $scope.setActionMessage = function() { var message = ''; var total = $scope.total_accounts-$scope.excluded.length; switch($scope.action) { case 'restore': message = lang.t("Total of %s filtered accounts will be restored", total); break; case 'download': message = lang.t("Total of %s backups will be downloaded (one backup for each filtered account)", total); break; case 'lock': if($scope.options.allbackups) message = lang.t("All backups related to %s filtered accounts will be locked", total); else message = lang.t("Total of %s backups will be locked (one backup for each filtered account)", total); break; case 'unlock': if($scope.options.allbackups) message = lang.t("All backups related to %s filtered accounts will be unlocked", total); else message = lang.t("Total of %s backups will be unlocked (one backup for each filtered account)", total); break; } if(!message) return; $scope.actionMessage = { message: message, type: "warning" }; }; $scope.filteredMessage = function() { $scope.filteredAccountsStatus = { message: lang.t("Total of %s accounts will be affected using selected filters", $scope.total_accounts-$scope.excluded.length), type: "info" }; }; $scope.deleteSnapshot = function(backup) { confirm.open({ message: lang.t("Are you sure you want to delete this snapshot?"), confirm: function () { api.deleteSnapshot({ data: { _id: backup._id }, success: function (data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }, cancel: function () { } }); }; $scope.$watch('excluded', function () { $scope.filteredMessage(); $scope.setActionMessage(); }, true); $scope.$watch('total_accounts', function () { $scope.filteredMessage(); $scope.setActionMessage(); }, true); $scope.$watch('options', function () { $scope.filteredMessage(); $scope.setActionMessage(); }, true); $scope.$watch('filters', function () { if($scope.filters.account_status != 1) { if(!$scope.containsChecked(consts.BACKUP_TYPE_ACCOUNT_CONFIG, $scope.filters)) $scope.toggleContains(consts.BACKUP_TYPE_ACCOUNT_CONFIG, $scope.filters); if(!$scope.containsChecked(consts.BACKUP_TYPE_ACCOUNT_CONFIG)) $scope.toggleContains(consts.BACKUP_TYPE_ACCOUNT_CONFIG); $scope.account_types_disabled[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = true; } else { $scope.account_types_disabled[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = false; } $scope.fetch(function () { $scope.filteredMessage(); $scope.setActionMessage(); }); }, true); if(permissions.canManageDestinations) { api.listDestinations({ success: function (data) { for(var i = 0; i < data.destinations.length; i++) { var destination = data.destinations[i]; $scope.destinations.push({label: destination.name,value:destination._id}); } } }); } api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) $scope.tags[data.tags[i]._id] = data.tags[i]; } }); api.listRestoreConditions({ data: { find: { disabled: false } }, success: function (data) { $scope.restore_conditions = data.conditions; } }); $timeout($scope.fetch); } ] ); }); define('controllers/restoreSingleAccount',['app'], function(app) { app.controller("restoreSingleAccount", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "permissions", "confirm", "alert", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, permissions, confirm, alert, consts, lang, popup) { if(!permissions.canManageAccounts) { $scope.$emit("accountChanged", $rootScope.loggedAccount); } $scope.autocomplete = {accountText:''}; $scope.selectAccount = function(account) { if(account === undefined) return; //$scope.selectedAccount = account.username; //$scope.autocomplete.accountText = account.username; $scope.$emit("accountChanged", account); }; $scope.clearAccount = function () { $scope.autocomplete = {accountText:''}; $scope.$emit("accountChanged", {}); } $scope.searchAccounts = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; } ] ); }); define('controllers/restoreDirectories',['app'], function(app) { app.controller("restoreDirectories", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "permissions", "confirm", "alert", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, permissions, confirm, alert, consts, lang, popup) { $scope.isAllChecked = false; $scope.backups = []; $scope.backups_selected = []; $scope.files = {}; $scope.filter = ''; var changeBackupSelected = function (backup) { var position = -1; for (var i = 0; i < $scope.backups_selected.length; i++) { if(backup.backup._id === $scope.backups_selected[i].backup._id) { position = i; break; } } if(backup.checked) { if(position >= 0) return; $scope.backups_selected.push(backup); } else { if(position < 0) return; $scope.backups_selected.splice(position, 1); } }; $scope.fileBrowse = function(backup) { popup.open({ size: "xl", template: 'fileManagerPopup', scope: $scope, resolve: { files: function() { return $scope.files[backup.backup._id] !== undefined ? $scope.files[backup.backup._id] : {}; }, backup: function() { return backup.backup; } } }).result.then(function(files) { $scope.files[backup.backup._id] = files; }, function(){}); }; $scope.totalFiles = function(backup) { if($scope.files[backup.backup._id] === undefined) return null; var output = 0; for(var path in $scope.files[backup.backup._id]) output++; if(!output) { delete $scope.files[backup.backup._id]; return null; } return output; }; $scope.changeBackup = function(backup) { backup.options = []; if(backup.new_id === backup.backup._id) { backup.options_real = {}; backup.new_id = ''; return; } delete $scope.files[backup.backup._id]; var newBackup = backup.options_real[backup.new_id]; for(var key in newBackup) backup.backup[key] = newBackup[key]; //$scope.selected_full = ''; //$scope.selected_full_items = []; backup.options_real = {}; backup.new_id = ''; }; $scope.selectBackup = function(backup) { backup.new_id = backup.backup._id; backup.options = []; backup.options_real = {}; var apiParams = { type: backup.backup.backup_type, contains: backup.backup.backup_contains, name: backup.backup.name, sort: { created: -1 } }; api.listBackupForTypeName({ data: apiParams, success: function (data) { for(var i = 0; i < data.backups.length; i++) { backup.options.push({ _id: data.backups[i]._id, display: lang.d(data.backups[i].created, 'shorttime') }); backup.options_real[data.backups[i]._id] = data.backups[i]; } } }); }; $scope.checkAll = function () { //$scope.isAllChecked = !$scope.isAllChecked; for (var i = 0; i < $scope.backups.length; i++) { var backup = $scope.backups[i]; backup.checked = $scope.isAllChecked; changeBackupSelected(backup); } }; $scope.unCheckAll = function () { $scope.isAllChecked = false; for (var i = 0; i < $scope.backups.length; i++) { var backup = $scope.backups[i]; backup.checked = false; changeBackupSelected(backup); } $scope.files = {}; }; $scope.checkChanged = function (backup) { if(backup !== undefined) changeBackupSelected(backup); var state = ($scope.backups.length > 0); for (var i = 0; i < $scope.backups.length; i++) { var cbackup = $scope.backups[i]; if(!cbackup.checked) { $scope.isAllChecked = false; delete $scope.files[cbackup.backup._id]; state = false; } } $scope.isAllChecked = state; }; $scope.saveNotes = function (backup, keyEvent) { backup.backup.notes = backup.backup.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageBackupNotes({ data: { _id: backup.backup._id, notes: backup.backup.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); }, }); backup.editing = false; }; $scope.getChecked = function () { var ids = []; for(var i = 0; i < $scope.backups_selected.length; i++) ids.push($scope.backups_selected[i].backup._id); return ids; }; $scope.getCheckedParents = function () { var ids = []; for(var i = 0; i < $scope.backups_selected.length; i++) ids.push($scope.backups_selected[i].backup.parent_id); return ids; }; $scope.restore = function() { var ids = $scope.getChecked(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } confirm.open({ title: lang.t("RESTORE NOTICE"), message: lang.t("To guarantee the safety and integrity of your system, the Files and/or Directories selected will be restored with a temporary file/directory name at its original location.") + "<br />" + lang.t("For example, when restoring %s folder, JetBackup will restore it at %s", "<strong>/etc</strong>", "<strong>/etc.jetbackup.xxxx</strong>") + "<br /><br />" + "<strong>" + lang.t("YOU ARE RESPONSIBLE") + "</strong> " + lang.t("for completing the restoration process manually.") + "<br /><br />" + lang.t("Please take necessary precautions before restoring core system files and/or directories to avoid any unintended issues with your server.") + "<br /><br />" + lang.t("For more information, please visit") + " <a style='color: #fd6b2b;' href='https://docs.jetbackup.com/v5.2/adminpanel/restoreAndDownload.html#directories' target='_blank'>" + lang.t("Directory Restore Documentation") + "</a>.", //cancelLabel: lang.t("No, let me set schedules"), confirmLabel: lang.t("Restore Selected Items"), confirm: function () { api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_RESTORE, items: ids, files: $scope.files }, success: function (data, message) { alert.success(message); $scope.unCheckAll(); $scope.files = {}; }, failed: function (message) { alert.error(message); } }); } }); }; $scope.download = function() { var ids = $scope.getChecked(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_DOWNLOAD, items: ids, files: $scope.files }, success: function (data, message) { alert.success(message); $scope.unCheckAll(); $scope.files = {}; }, failed: function (message) { alert.error(message); } }); }; $scope.lock = function() { var ids = $scope.getCheckedParents(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } popup.open({ size: "lg", template: 'backupLockSelection', scope: $scope, }).result.then(function(ttl) { api.manageBackupLock({ data: { _id: ids, lock_ttl: ttl, locked: 1 }, success: function(data, message) { var parents = []; for(var i = 0; i < $scope.backups.length; i++) { if(!$scope.backups[i].checked) continue; if(!parents.includes($scope.backups[i].backup.parent_id)) parents.push($scope.backups[i].backup.parent_id); } if(ttl) { var ttlDate = new Date(); ttlDate.setDate(ttlDate.getDate() + ttl); } for(var i = 0; i < $scope.backups.length; i++) { if(!parents.includes($scope.backups[i].backup.parent_id)) continue; $scope.backups[i].backup.lock = true; $scope.backups[i].backup.lock_ttl = ttl ? moment(ttlDate) : 0; } alert.success(message); }, failed: function (message) { alert.error(message); } }); }); }; $scope.unlock = function() { var ids = $scope.getCheckedParents(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } api.manageBackupLock({ data: { _id: ids, locked: 0 }, success: function(data, message) { var parents = []; for(var i = 0; i < $scope.backups.length; i++) { if(!$scope.backups[i].checked) continue; if(!parents.includes($scope.backups[i].backup.parent_id)) parents.push($scope.backups[i].backup.parent_id); } for(var i = 0; i < $scope.backups.length; i++) { if(!parents.includes($scope.backups[i].backup.parent_id)) continue; $scope.backups[i].backup.lock = false; $scope.backups[i].backup.lock_ttl = 0; } alert.success(message); }, failed: function (message) { alert.error(message); } }); }; var getBackupData = function (backup) { for(var j = 0; j < $scope.backups_selected.length; j++) if(backup.backup._id === $scope.backups_selected[j].backup._id) return $scope.backups_selected[j]; return backup; }; $scope.deleteSnapshot = function(backup) { confirm.open({ message: lang.t("Are you sure you want to delete this snapshot? Please note that this will affect all other snapshot items related to this snapshot item"), confirm: function () { api.deleteSnapshot({ data: { _id: backup.parent_id }, success: function (data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }, cancel: function () { } }); }; $scope.fetch = function () { api.listBackupForDirectories({ data: { filter: $scope.filter }, success: function (data) { var backups = []; for(var i = 0; i < data.directories.length; i++) { var backup = data.directories[i]; backups.push(getBackupData(backup)); } $scope.backups = backups; $scope.checkChanged(); }, fail: function (message) { alert.error(message); } }); }; $scope.fetch(); } ] ); }); define('controllers/restoreDisasterRecovery',['app'], function(app) { app.controller("restoreDisasterRecovery", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "meta", "permissions", "confirm", "alert", "consts", "lang", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, meta, permissions, confirm, alert, consts, lang, popup) { $scope.isAllChecked = false; $scope.backups = []; $scope.backups_selected = []; $scope.files = {}; $scope.filter = ''; $scope.lock_options = { ttl: 0 } var changeBackupSelected = function (backup) { var position = -1; for (var i = 0; i < $scope.backups_selected.length; i++) { if(backup._id === $scope.backups_selected[i]._id) { position = i; break; } } if(backup.checked) { if(position >= 0) return; $scope.backups_selected.push(backup); } else { if(position < 0) return; $scope.backups_selected.splice(position, 1); } }; $scope.checkAll = function () { //$scope.isAllChecked = !$scope.isAllChecked; for (var i = 0; i < $scope.backups.length; i++) { var backup = $scope.backups[i]; backup.checked = $scope.isAllChecked; changeBackupSelected(backup); } }; $scope.unCheckAll = function () { $scope.isAllChecked = false; for (var i = 0; i < $scope.backups.length; i++) { var backup = $scope.backups[i]; backup.checked = false; changeBackupSelected(backup); } $scope.files = {}; }; $scope.checkChanged = function (backup) { if(backup !== undefined) changeBackupSelected(backup); var state = ($scope.backups.length > 0); for (var i = 0; i < $scope.backups.length; i++) { var cbackup = $scope.backups[i]; if(!cbackup.checked) { $scope.isAllChecked = false; delete $scope.files[cbackup._id]; state = false; } } $scope.isAllChecked = state; }; $scope.saveNotes = function (backup, keyEvent) { backup.notes = backup.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageBackupNotes({ data: { _id: backup._id, notes: backup.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); }, }); backup.editing = false; }; $scope.getChecked = function () { var ids = []; for(var i = 0; i < $scope.backups_selected.length; i++) ids.push($scope.backups_selected[i]._id); return ids; }; $scope.getCheckedParents = function () { var ids = []; for(var i = 0; i < $scope.backups_selected.length; i++) ids.push($scope.backups_selected[i].parent_id); return ids; }; $scope.download = function() { var ids = $scope.getChecked(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_DOWNLOAD, items: ids, files: $scope.files }, success: function (data, message) { alert.success(message); $scope.unCheckAll(); $scope.files = {}; }, failed: function (message) { alert.error(message); } }); }; $scope.lock = function() { var ids = $scope.getCheckedParents(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } api.manageBackupLock({ data: { _id: ids, lock_ttl: $scope.lock_options.ttl, locked: 1 }, success: function(data, message) { for(var i = 0; i < $scope.backups.length; i++) { if(!$scope.backups[i].checked) continue; $scope.backups[i].lock = 1; $scope.backups[i].lock_ttl = $scope.lock_options.ttl; } alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.unlock = function() { var ids = $scope.getCheckedParents(); if(ids.length <= 0 ) { alert.error(lang.t("You must select at least one backup")); return; } api.manageBackupLock({ data: { _id: ids, locked: 0 }, success: function(data, message) { for(var i = 0; i < $scope.backups.length; i++) { if(!$scope.backups[i].checked) continue; $scope.backups[i].lock = 0; $scope.backups[i].lock_ttl = 0; } alert.success(message); }, failed: function (message) { alert.error(message); } }); }; var getBackupData = function (backup) { for(var j = 0; j < $scope.backups_selected.length; j++) if(backup._id === $scope.backups_selected[j]._id) return $scope.backups_selected[j]; return backup; }; $scope.deleteSnapshot = function(backup) { confirm.open({ message: lang.t("Are you sure you want to delete this snapshot?"), confirm: function () { api.deleteSnapshot({ data: { _id: backup.parent_id }, success: function (data, message) { $scope.fetch(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }, cancel: function () { } }); }; $scope.fetch = function () { api.listBackupForDisasterRecovery({ success: function (data) { var backups = []; for(var i = 0; i < data.images.length; i++) { var backup = data.images[i]; backups.push(getBackupData(backup)); } $scope.backups = backups; $scope.checkChanged(); }, fail: function (message) { alert.error(message); } }); }; $scope.fetch(); } ] ); }); define('controllers/accountBackups',['app'], function(app) { app.controller("accountBackups", ["$uibModalInstance","$rootScope", "$scope", "$q", "$location", "$timeout", "$window", "api", "meta", "util", "permissions", "confirm", "consts", "lang", "alert", "popup", "account", function ($uibModalInstance, $rootScope, $scope, $q, $location, $timeout, $window, api, meta, util, permissions, confirm, consts, lang, alert, popup, account) { $rootScope.$emit('menuItem', 'Restore'); $scope.accountData = account; if(!$scope.accountData) $scope.accountData = {}; $scope.reset = function () { $scope.loading = false; $scope.list = {}; $scope.list_loaded = {}; $scope.backups = []; $scope.searchFilterValue = ''; $scope.static = { isAllChecked: false }; $scope.advanced = false; $scope.selected = {full:'',full_items:[]}; $scope.summary = { enabled: false, type: '', tpl: '', gotoqueue: true }; //$scope.summary_type = ''; //$scope.summary_tpl = ''; $scope.list_checked = {}; $scope.list_checked_parents = {}; $scope.fulls = []; $scope.fulls_list = {}; $scope.conditions = {restore:{}}; $scope.options = { owner: '', exclude: [] }; $scope.owner = {}; $scope.autocomplete = { accountText: '' }; $scope.files = {}; $scope.lock_options = { ttl: 0 }; $scope.encryption = { encrypted: false, key: '' }; $scope.panelConfig = {}; $scope.require = { owner: true }; $scope.localOptions = {chown:false}; }; $scope.reset(); $scope.restore_conditions = []; $scope.currentSection = undefined; $scope.sections = [ //{ _id: consts.BACKUP_TYPE_ACCOUNT_FULL, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_SHORT[consts.BACKUP_TYPE_ACCOUNT_FULL], icon: "fa-box" }, { _id: consts.BACKUP_TYPE_ACCOUNT_CONFIG, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CONFIG], icon: "fa-cog", permissions: permissions.canManageConfigBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_HOMEDIR, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR], icon: "fa-folder", permissions: permissions.canManageFileBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS], icon: "fa-clock", permissions: permissions.canManageCronBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_DATABASES, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DATABASES], icon: "fa-database", permissions: permissions.canManageDatabaseBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS], icon: "fa-user-tie", permissions: permissions.canManageDatabaseBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_DOMAINS, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DOMAINS], icon: "fa-map-marker-alt", permissions: permissions.canManageDNSZoneBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES], icon: "fa-lock", permissions: permissions.canManageCertificateBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_EMAILS, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_EMAILS], icon: "fa-envelope", permissions: permissions.canManageEmailBackups }, { _id: consts.BACKUP_TYPE_ACCOUNT_FTP, name: consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_FTP], icon: "fa-file-alt", permissions: permissions.canManageFTPBackups } ]; $scope.$on("accountChanged", function(evt,data){ $scope.accountData = data; $scope.reset(); $scope.fetchFulls(function () { $scope.changeSection($scope.sections[0]); }); }); $scope.$watch('summary.type', function () { if(!$scope.summary.type) $scope.summary.tpl = ''; else $scope.summary.tpl = 'accountBackups' + $scope.summary.type + 'Summary'; }); $scope.isTooltipEnabled = function() { return $window.innerWidth <= 928; }; var metaAcct = meta.new("account_backups"); $scope.meta = metaAcct; $scope.metaData = metaAcct.getData(); metaAcct.setSortReverse(false); if(!metaAcct.getSortBy()) metaAcct.setSortBy("username"); if(!metaAcct.getSortDirection()) metaAcct.setSortDirection("asc"); metaAcct.setPageSizes([5,10,25,50]); metaAcct.setPageSize(5); metaAcct.setSortFields(["username", "owner"]); metaAcct.setTotalItems($scope.list.length); var replaceItem = function(item) { if($scope.list[item.backup_contains] === undefined) $scope.list[item.backup_contains] = []; for(var i = 0; i < $scope.list[item.backup_contains].length; i++) { if( $scope.list[item.backup_contains][i].name === item.name && ( item.params.engine === undefined || $scope.list[item.backup_contains][i].params.engine == item.params.engine ) ) { //if($scope.list[item.backup_contains][i]._id === item._id) return; for(var key in item) $scope.list[item.backup_contains][i][key] = item[key]; return; } } $scope.list[item.backup_contains].push(item); }; var checkFull = function(contains) { if(!$scope.selected.full_items.length) return; for(var i = 0; i < $scope.selected.full_items.length; i++) { var item = $scope.selected.full_items[i]; if(contains !== undefined && item.backup_contains !== contains) continue; item.checked = true; replaceItem(item); } }; $scope.checkAll = function() { for(var i = 0; i < $scope.list[$scope.currentSection._id].length; i++) { var backup = $scope.list[$scope.currentSection._id][i]; backup.checked = $scope.static.isAllChecked; if(!backup.checked && $scope.files[backup._id] !== undefined) delete $scope.files[backup._id]; } }; $scope.uncheckAll = function() { for(var contains in $scope.list) for(var i = 0; i < $scope.list[contains].length; i++) { var backup = $scope.list[contains][i]; backup.checked = false; if($scope.files[backup._id] !== undefined) delete $scope.files[backup._id]; } }; $scope.isChecked = function() { for(var contains in $scope.list) for(var i = 0; i < $scope.list[contains].length; i++) if($scope.list[contains][i].checked) return true; return false; }; $scope.getChecked = function() { var checked = []; if($scope.currentSection === undefined || $scope.list[$scope.currentSection._id] === undefined) return checked; for(var i = 0; i < $scope.list[$scope.currentSection._id].length; i++) if($scope.list[$scope.currentSection._id][i].checked) checked.push($scope.list[$scope.currentSection._id][i]._id); return checked; }; $scope.getCheckedAll = function() { var checked = []; for(var contains in $scope.list) for(var i = 0; i < $scope.list[contains].length; i++) if($scope.list[contains][i].checked) checked.push($scope.list[contains][i]); return checked; }; $scope.searchAccounts = function(query) { if(!query) return []; var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) { var account = data.accounts[i]; if(($scope.options.reseller && account.root) || (!$scope.options.reseller && account.reseller)) { results.push(account); } } deferred.resolve( results ); } }); return deferred.promise; }; $scope.selectNewOwner = function(account) { if(account === undefined) return; $scope.options.owner = account.username; $scope.owner = account; }; $scope.resetNewOwner = function() { $scope.options.owner = ''; $scope.autocomplete.accountText = ''; $scope.owner = {}; }; $scope.changeBackup = function(backup) { backup.options = []; if(backup.new_id === backup._id) { backup.options_real = {}; backup.new_id = ''; return; } delete $scope.files[backup._id]; var newBackup = backup.options_real[backup.new_id]; for(var key in newBackup) backup[key] = newBackup[key]; $scope.selected.full = ''; $scope.selected.full_items = []; backup.options_real = {}; backup.new_id = ''; }; $scope.selectBackup = function(backup) { backup.new_id = backup._id; backup.options = []; backup.options_real = {}; var apiParams = { account_id: backup.account_id, type: backup.backup_type, contains: backup.backup_contains, name: backup.name, sort: { created: -1 }, limit: 9999999 }; if(backup.params.engine !== undefined) apiParams.engine = backup.params.engine; api.listBackupForTypeName({ data: apiParams, success: function (data) { for(var i = 0; i < data.backups.length; i++) { backup.options.push({ _id: data.backups[i]._id, display: lang.d(data.backups[i].created, 'shorttime') }); backup.options_real[data.backups[i]._id] = data.backups[i]; } } }); }; $scope.checkChanged = function() { $scope.selected.full = ''; $scope.selected.full_items = []; }; $scope.$watch('list', function() { var checked = $scope.getChecked(); $scope.static.isAllChecked = checked.length === metaAcct.getTotalItems(); },true); $scope.askForEncryptionKey = function() { return $scope.encryption.encrypted && $scope.accountData.backup_type == 1 && $scope.accountData.encryption_key_type == 1; }; $scope.lock = function() { var ids = []; for(var id in $scope.list_checked_parents) ids.push(id); api.manageBackupLock({ data: { _id: ids, lock_ttl: $scope.lock_options.ttl, locked: 1 }, success: function(data, message) { for(var contains in $scope.list) { for(var i = 0; i < $scope.list[contains].length; i++) { var item = $scope.list[contains][i]; if(ids.indexOf(item.parent_id) >= 0) { item.lock = 1; item.lock_ttl = $scope.lock_options.ttl; } } } $uibModalInstance.close(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.unlock = function() { var ids = []; for(var id in $scope.list_checked_parents) ids.push(id); api.manageBackupLock({ data: { _id: ids, locked: 0 }, success: function(data, message) { for(var contains in $scope.list) { for(var i = 0; i < $scope.list[contains].length; i++) { var item = $scope.list[contains][i]; if(ids.indexOf(item.parent_id) >= 0) { item.lock = 0; } } } $uibModalInstance.close(); alert.success(message); }, failed: function (message) { alert.error(message); } }); }; $scope.saveNotes = function (backup, keyEvent) { backup.notes = backup.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageBackupNotes({ data: { _id: backup._id, notes: backup.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); }, }); backup.editing = false; }; $scope.fileBrowse = function(backup) { popup.open({ size: "xl", template: 'fileManagerPopup', scope: $scope, resolve: { files: function() { return $scope.files[backup._id] !== undefined ? $scope.files[backup._id] : {}; }, backup: function() { return backup; } } }).result.then(function(files) { $scope.files[backup._id] = files; }, function(){}); }; $scope.totalFiles = function(backup) { if($scope.files[backup._id] === undefined) return null; var output = 0; for(var path in $scope.files[backup._id]) output++; if(!output) { delete $scope.files[backup._id]; return null; } return output; }; $scope.fetchReal = function(callback) { if(callback === undefined) callback = function() {}; if($scope.loading) return; if($scope.list_loaded[$scope.currentSection._id] !== undefined) { callback(); return; } $scope.list_loaded[$scope.currentSection._id] = true; $scope.loading = true; $scope.list[$scope.currentSection._id] = []; $scope.backups = []; $scope.searchFilterValue = ''; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: $scope.currentSection._id, account_id: $scope.accountData._id, limit: 9999999 }; api.listBackupForType({ data: apiParams, success: function (data) { $scope.loading = false; for(var i = 0; i < data.backups.length; i++) { data.backups[i].options = []; replaceItem(data.backups[i]); } $scope.selected.full_items = data.backups; checkFull($scope.currentSection._id); callback(); }, failed: function () { $scope.loading = false; callback(); } }); }; $scope.fetch = function () { $scope.backups = []; $scope.backupsFiltered = []; var records = []; if($scope.searchFilterValue) { for(var i = 0; i < $scope.list[$scope.currentSection._id].length; i++) { if(!(new RegExp($scope.searchFilterValue)).test($scope.list[$scope.currentSection._id][i].name)) continue; records.push($scope.list[$scope.currentSection._id][i]); } } else { records = $scope.list[$scope.currentSection._id]; } metaAcct.setTotalItems(records.length); var skipped = 0; for(var i = 0; i < records.length; i++) { if($scope.backups.length >= metaAcct.getPageSize()) break; if(skipped < metaAcct.getSkip()) { skipped++; continue; } $scope.backups.push(records[i]); } metaAcct.calculate($scope.backups); }; $scope.ok = function () { $uibModalInstance.close(); }; $scope.changeSection = function (section) { $scope.currentSection = section; $scope.fetchReal(function () { //metaAcct.setTotalItems($scope.list[$scope.currentSection._id].length); $scope.static.isAllChecked = $scope.getChecked().length === metaAcct.getTotalItems(); $scope.fetch(); }); }; $scope.changeFullBackup = function() { if($scope.selected.full === '') return; $scope.uncheckAll(); api.getBackupItems({ data: { _id: $scope.selected.full, limit: 999999 }, success: function(data) { if(!data.backups.length) return; $scope.selected.full_items = data.backups; checkFull(); } }); }; $scope.calculateSummary = function() { var gotData = false; $scope.encryption.encrypted = false; $scope.list_checked = {}; $scope.list_checked_parents = {}; for(var contains in $scope.list) { for(var i = 0; i < $scope.list[contains].length; i++) { if($scope.list[contains][i].checked) { if(!$scope.encryption.encrypted && $scope.list[contains][i].encrypted) $scope.encryption.encrypted = true; if($scope.list_checked[contains] === undefined) $scope.list_checked[contains] = []; $scope.list_checked[contains].push($scope.list[contains][i]); if($scope.list_checked_parents[$scope.list[contains][i].parent_id] === undefined) $scope.list_checked_parents[$scope.list[contains][i].parent_id] = $scope.list[contains][i].created; gotData = true; } } } $scope.summary.enabled = gotData; }; $scope.checkOwnerRequire = function () { if(!permissions.isRoot || !$scope.panelConfig.account_data.owner_id) { $scope.require.owner = false; return; } $scope.validateOwner($scope.panelConfig.account_data.owner_id, function (exists, account) { if(!account.root && $scope.options.reseller) exists = false; if(exists) { $scope.autocomplete.accountText = account.username; $scope.selectNewOwner(account); } $scope.require.owner = !exists; }); }; $scope.showSummary = function(type) { if(type === 'Restore') { $scope.getPanelConfig(); $scope.options.suspend = $scope.panelConfig.account_data.suspended; $scope.options.reseller = $scope.panelConfig.account_data.reseller; $scope.options.exclude = []; $scope.checkOwnerRequire(); } if(!$scope.checkOrphanConfig()) return; $scope.summary.type = type; $scope.calculateSummary(); }; $scope.gotItems = function(types) { var list = $scope.getCheckedAll(); for(var i = 0; i < list.length; i++) { if(types.indexOf(list[i].backup_contains) >= 0) return true; } return false; }; $scope.getPanelConfig = function() { var list = $scope.getCheckedAll(); for(var i = 0; i < list.length; i++) { if(list[i].backup_contains === consts.BACKUP_TYPE_ACCOUNT_CONFIG) { $scope.panelConfig = list[i]; return $scope.panelConfig; } } $scope.panelConfig = { account_data: {} }; return null; }; $scope.checkOrphanConfig = function() { if(!$scope.accountData.orphan) return true; if($scope.getPanelConfig() === null) { alert.error(lang.t("You must select \"Panel Configurations\" item in order to restore orphan account")); return false; } return true; }; $scope.validateOwner = function(owner_id, callback) { if(callback === undefined) callback = function() {}; api.getAccount({ data: { _id: owner_id }, success: function (data) { callback(data.reseller, data); }, failed: function () { callback(false, {}); } }); }; $scope.exclude = { row: '' }; $scope.validateListPath = function (path) { if(!path.trim()) return false; return !consts.PATH_FILTER_PATTERNS.test(path); }; $scope.addExcludeRow = function () { if($scope.exclude.row === undefined || !$scope.exclude.row.trim()) return; if($scope.validateListPath($scope.exclude.row.trim())) $scope.options.exclude.push($scope.exclude.row.trim()); else alert.error(lang.t('The provided path ("%s") is invalid. The path must start with a "/".', $scope.exclude.row.trim() )); $scope.exclude.row = ''; }; $scope.addMultiExcludeRow = function() { $scope.listTitle = lang.t("Directories and Files to exclude"); $scope.listData = $scope.options.exclude.join("\n"); $scope.listUIB = popup.open({ template: 'listSelection', noController: true, scope: $scope }); $scope.listUIB.result.then(function(records) { while($scope.options.exclude.length) $scope.options.exclude.pop(); records = records.split("\n"); var invalidPaths = []; for(var i = 0; i < records.length; i++) { if($scope.validateListPath(records[i])) { if ($scope.options.exclude.indexOf(records[i]) < 0 ) $scope.options.exclude.push(records[i]); } else invalidPaths.push(records[i]); } if(invalidPaths.length) alert.error(lang.t('The following paths ("%s") is invalid. The path must start with a "/" and can\'t have trailing "/"' + (type === 'include' ? ', also patterns are not allowed.' : '.'), invalidPaths.join(", ") )) }, function () {}); }; $scope.$watch('options.reseller', function() { $scope.getPanelConfig(); if(!$scope.owner.root && $scope.options.reseller) { $scope.require.owner = true; $scope.resetNewOwner(); } }); $scope.restore = function() { if($scope.getPanelConfig() === null) { $scope.options.terminate = false; $scope.options.reseller = false; $scope.options.suspend = false; $scope.options.owner = ''; } if(!$scope.checkOrphanConfig()) return; var liveAccount = !($scope.options.terminate || $scope.accountData.orphan); if(!liveAccount && $scope.require.owner && !$scope.options.owner) { alert.error(lang.t("You must select new owner")); return; } for(var i = 0; i < $scope.restore_conditions.length; i++) { var condition = $scope.restore_conditions[i]; if($scope.conditions.restore[condition._id] === undefined || !$scope.conditions.restore[condition._id]) { alert.error(lang.t("Please accept all restore conditions")); return; } } if($scope.askForEncryptionKey() && !$scope.encryption.key) { alert.error(lang.t("You must provide \"Backups Private Encryption Key\"")); return; } var list = $scope.getCheckedAll(); var ids = []; for(var i = 0; i < list.length; i++) ids.push(list[i]._id); var options = util.duplicateObject($scope.options); if(liveAccount) { delete options.reseller; delete options.owner; } else { if(options.terminate) delete options.merge; } if(!permissions.isRoot) { delete options.reseller; delete options.owner; } if(!permissions.isReseller) { delete options.suspend; } api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_RESTORE, items: ids, files: $scope.files, options: options, encryption_key: $scope.encryption.key }, success: function (data, message) { $scope.encryption.key = ''; alert.success(message); $uibModalInstance.close(); if($scope.summary.gotoqueue) $location.path("/queue"); }, failed: function (message) { alert.error(message); } }); }; $scope.download = function() { if($scope.askForEncryptionKey() && !$scope.encryption.key) { alert.error(lang.t("You must provide \"Backups Private Encryption Key\"")); return; } var options = util.duplicateObject($scope.options); var list = $scope.getCheckedAll(); var ids = []; for(var i = 0; i < list.length; i++) ids.push(list[i]._id); api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_DOWNLOAD, items: ids, files: $scope.files, options: options, encryption_key: $scope.encryption.key }, success: function (data, message) { $scope.encryption.key = ''; alert.success(message); $uibModalInstance.close(); if($scope.summary.gotoqueue) $location.path("/queue"); }, failed: function (message) { alert.error(message); } }); }; $scope.removeItems = function(contains) { $scope.selected.full = ''; $scope.selected.full_items = []; for(var i = 0; i < $scope.list[contains].length; i++) { var backup = $scope.list[contains][i]; backup.checked = false; if($scope.files[backup._id] !== undefined) delete $scope.files[backup._id]; } $scope.calculateSummary(); }; $scope.removeSnapshot = function(id) { $scope.selected.full = ''; $scope.selected.full_items = []; for(var contains in $scope.list) { for(var i = 0; i < $scope.list[contains].length; i++) { var backup = $scope.list[contains][i]; if(backup.parent_id !== id) continue; backup.checked = false; if($scope.files[backup._id] !== undefined) delete $scope.files[backup._id]; } } $scope.calculateSummary(); }; $scope.$watch('require', function () { var require = $scope.require.owner; $scope.localOptions.chown = require; $scope.chownDisabled = require; }, true); api.listRestoreConditions({ data: { find: { disabled: false } }, success: function (data) { $scope.restore_conditions = data.conditions; } }); $scope.deleteSnapshot = function() { if(!$scope.selected.full) return; confirm.open({ message: lang.t("Are you sure you want to delete this snapshot?"), confirm: function () { api.deleteSnapshot({ data: { _id: $scope.selected.full }, success: function (data, message) { $scope.reset(); $scope.fetchFulls(); $scope.changeSection($scope.sections[0]); alert.success(message); }, failed: function (message) { alert.error(message); } }); }, cancel: function () { } }); }; $scope.fetchFulls = function (callback) { if(callback === undefined || typeof callback !== 'function') callback = function(){}; api.listBackupForTypeName({ data: { name: $scope.accountData.username, type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_FULL, account_id: $scope.accountData._id, sort: { created: -1 }, limit: 9999999 }, success: function (data) { for(var i = 0; i < data.backups.length; i++) { if(i === 0) $scope.selected.full = data.backups[i].parent_id; var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.fulls.push({ _id: data.backups[i].parent_id, display: lang.d(data.backups[i].created, 'shorttime') }); $scope.fulls_list[data.backups[i].parent_id] = data.backups[i]; } $scope.fulls.push({ _id: '', display: lang.t("Custom") }); $scope.changeFullBackup(); callback(); } }); }; $scope.fetchFulls(); $scope.changeSection($scope.sections[0]); } ] ); }); define('controllers/accountDownloads',['app'], function(app) { app.controller("accountDownloads", ["$uibModalInstance", "$rootScope", "$scope", "$location", "$timeout", "api", "meta", "util", "consts", "lang", "account", "alert", function ($uibModalInstance, $rootScope, $scope, $location, $timeout, api, meta, util, consts, lang, account, alert) { $scope.loading = false; $scope.account = account; $scope.downloads = []; meta = meta.new("account_downloads"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([5]); meta.setPageSize(5); meta.setSortFields(["created", "size"]); meta.setTotalItems($scope.downloads.length); $scope.close = function () { $uibModalInstance.close(); }; $scope.directDownload = function(download) { window.location = window.PAGE.path.download + "&download_id=" + download._id; }; $scope.saveNotes = function (download, keyEvent) { download.notes = download.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageDownloadNotes({ data: { _id: download._id, notes: download.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); } }); download.editing = false; }; $scope.fetch = function () { if($scope.loading) return; $scope.loading = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter(), account_id: $scope.account._id }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.downloads = []; api.listDownloads({ data: apiParams, success: function(data) { $scope.loading = false; meta.setTotalItems(data.total); meta.calculate(data.downloads); $scope.downloads = data.downloads; } }); }; $timeout($scope.fetch()); } ] ); }); define('controllers/accountFilters',['app'], function(app) { app.controller("accountFilters", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "confirm", "consts", "lang", "alert", function ($rootScope, $scope, $location, $timeout, api, meta, confirm, consts, lang, alert) { $rootScope.$emit('menuItem', 'AccountFilters'); $scope.filters = []; $scope.groups = {}; $scope.loadingFilters = false; $scope.saveing = false; $scope.filter = 0; $scope.filterOptions = [ { label: lang.t("All Filter Types"), value: 0 }, { label: lang.t("Accounts Filter"), value: consts.ACCOUNT_FILTER_TYPE_ACCOUNT }, { label: lang.t("Account Tags Filter"), value: consts.ACCOUNT_FILTER_TYPE_ACCOUNT_TAG }, { label: lang.t("Owned By Filter"), value: consts.ACCOUNT_FILTER_TYPE_OWNEDBY }, { label: lang.t("Resellers Filter"), value: consts.ACCOUNT_FILTER_TYPE_RESELLER }, { label: lang.t("Suspension Filter"), value: consts.ACCOUNT_FILTER_TYPE_SUSPENSION }, { label: lang.t("Encryption Filter"), value: consts.ACCOUNT_FILTER_TYPE_ENCRYPTION }, { label: lang.t("Disk Space Usage Filter"), value: consts.ACCOUNT_FILTER_TYPE_DISK_USAGE }, { label: lang.t("Inodes Usage Filter"), value: consts.ACCOUNT_FILTER_TYPE_INODE_USAGE }, { label: lang.t("Packages Filter"), value: consts.ACCOUNT_FILTER_TYPE_PACKAGE }, { label: lang.t("Characters Range Filter"), value: consts.ACCOUNT_FILTER_TYPE_RANGE }, { label: lang.t("Regular Expression Filter"), value: consts.ACCOUNT_FILTER_TYPE_REGEX } ]; $scope.types = {}; for(var i = 0; i < $scope.filterOptions.length; i++) if($scope.filterOptions[i].value > 0) $scope.types[$scope.filterOptions[i].value] = $scope.filterOptions[i].label; $scope.loaders = { delete: false }; meta = meta.new("filters"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["name","type","owner"]); meta.setTotalItems($scope.filters.length); $scope.onClickDelete = function(filter) { if($scope.saveing) return; if(filter.groups_count > 0) { alert.error(lang.t("This filter has an assigned filter groups, Please remove those groups before deleting this filter.")); return false; } $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This filter will be permanently deleted!"), confirm: function () { api.deleteAccountFilter({ data: { _id: filter._id }, success: function(data, message) { $scope.saveing = false; $scope.loaders.delete = false; $scope.fetch(); alert.success(message); }, failed: function (message) { $scope.saveing = false; $scope.loaders.delete = false; alert.error(message); } }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.listGroups = function(callback) { api.listAccountFilterGroups({ success: function(data) { for(var i = 0; i < data.groups.length; i++) { if($scope.groups[data.groups[i]._id] === undefined) $scope.groups[data.groups[i]._id] = []; $scope.groups[data.groups[i]._id].push(data.groups[i]); } if(callback !== undefined) callback(); }, failed: function () { if(callback !== undefined) callback(); } }); }; $scope.fetch = function() { $scope.loadingFilters = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); if($scope.filter) apiParams.find.type = $scope.filter; $scope.filters = []; api.listAccountFilters({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.filters); $scope.filters = data.filters; for(var i = 0; i < $scope.filters.length; i++) $scope.groups[$scope.filters[i]._id] = []; $scope.listGroups(function () { $scope.loadingFilters = false; }); } }); }; $timeout($scope.fetch); } ] ); }); define('controllers/accountFilterManage',['app'], function(app) { app.controller("accountFilterManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$q", "api", "lang", "util", "confirm", "consts", "alert", "permissions", "popup", function ($rootScope, $scope, $routeParams, $location, $timeout, $q, api, lang, util, confirm, consts, alert, permissions, popup) { $rootScope.$emit('menuItem', 'AccountFilters'); $scope.details = { name: '', owner: $scope.loggedAccount._id, owner_name: $scope.loggedAccount.username }; $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete = { accountText: $scope.saveData.owner_name }; $scope.saveing = false; $scope.changed = false; $scope.cancelled = false; $scope.range = "0123456789_abcdefghijklmnopqrstuvwxyz"; $scope.tags = {}; $scope.item = { package: '' }; $scope.accounts = {}; $scope.conditions = [ { label: lang.t("Include"), value: consts.ACCOUNT_FILTER_CONDITION_INCLUDE }, { label: lang.t("Exclude"), value: consts.ACCOUNT_FILTER_CONDITION_EXCLUDE } ]; $scope.types = [ { label: lang.t("Accounts Filter"), value: consts.ACCOUNT_FILTER_TYPE_ACCOUNT, template: 'account' }, { label: lang.t("Owned By Filter"), value: consts.ACCOUNT_FILTER_TYPE_OWNEDBY, template: 'reseller' }, { label: lang.t("Resellers Filter"), value: consts.ACCOUNT_FILTER_TYPE_RESELLER, template: 'reseller' }, { label: lang.t("Suspension Filter"), value: consts.ACCOUNT_FILTER_TYPE_SUSPENSION, template: 'suspension' }, { label: lang.t("Encryption Filter"), value: consts.ACCOUNT_FILTER_TYPE_ENCRYPTION, template: 'encryption' }, { label: lang.t("Disk Space Usage Filter"), value: consts.ACCOUNT_FILTER_TYPE_DISK_USAGE, template: 'diskusage' }, { label: lang.t("Inodes Usage Filter"), value: consts.ACCOUNT_FILTER_TYPE_INODE_USAGE, template: 'inodeusage' }, { label: lang.t("Packages Filter"), value: consts.ACCOUNT_FILTER_TYPE_PACKAGE, template: 'package' }, { label: lang.t("Characters Range Filter"), value: consts.ACCOUNT_FILTER_TYPE_RANGE, template: 'range' }, { label: lang.t("Regular Expression Filter"), value: consts.ACCOUNT_FILTER_TYPE_REGEX, template: 'regex' } ]; if(permissions.isRoot) $scope.types.push({ label: lang.t("Account Tags Filter"), value: consts.ACCOUNT_FILTER_TYPE_ACCOUNT_TAG, template: 'accounttags' }); $scope.selectCreator = function(account) { if(account === undefined) return; $scope.saveData.owner = account._id; $scope.saveData.owner_name = account.username; $scope.autocomplete.accountText = account.username; var activeElement = document.activeElement; if (activeElement) activeElement.blur(); }; $scope.searchCreators = function(query) { if(query) { var deferred = $q.defer(); api.listAccounts({ data: { login_only: 1, filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) results.push(data.accounts[i]); deferred.resolve( results ); } }); return deferred.promise; } return []; }; $scope.loadFilterType = function(type, defaults) { $scope.saveData = util.duplicateObject($scope.details); $scope.autocomplete.accountText = $scope.saveData.owner_name; if(defaults) { $scope.saveData.condition = consts.ACCOUNT_FILTER_CONDITION_INCLUDE; $scope.saveData.type = type; switch(type) { case consts.ACCOUNT_FILTER_TYPE_ACCOUNT: case consts.ACCOUNT_FILTER_TYPE_ACCOUNT_TAG: case consts.ACCOUNT_FILTER_TYPE_RESELLER: case consts.ACCOUNT_FILTER_TYPE_OWNEDBY: case consts.ACCOUNT_FILTER_TYPE_PACKAGE: $scope.saveData.list = []; break; case consts.ACCOUNT_FILTER_TYPE_INODE_USAGE: case consts.ACCOUNT_FILTER_TYPE_DISK_USAGE: $scope.saveData.usage = 0; break; case consts.ACCOUNT_FILTER_TYPE_RANGE: $scope.saveData.range_start = '0'; $scope.saveData.range_end = 'z'; break; case consts.ACCOUNT_FILTER_TYPE_REGEX: $scope.saveData.regex = ''; break; } } if($scope.saveData.type == consts.ACCOUNT_FILTER_TYPE_DISK_USAGE || $scope.saveData.type == consts.ACCOUNT_FILTER_TYPE_INODE_USAGE) { $scope.conditions[0].label = lang.t("Include Below (or equals)"); $scope.conditions[1].label = lang.t("Include Above (or equals)"); } else { $scope.conditions[0].label = lang.t("Include"); $scope.conditions[1].label = lang.t("Exclude"); } for(var i = 0; i < $scope.types.length; i++) { if($scope.types[i].value === type) { $scope.filterType = $scope.includePath('accountFilters/' + $scope.types[i].template); return; } } }; $scope.itemsSelection = function () { var types = {}; types[consts.ACCOUNT_FILTER_TYPE_ACCOUNT] = { size: 'lg', template: 'accountsSelection', resolve: { accounts: function() { return $scope.saveData.list; }, includeOrphan: function () { return 0; }, callParams: function () { return ''; } } }; types[consts.ACCOUNT_FILTER_TYPE_RESELLER] = { size: 'lg', template: 'accountsSelection', controller: 'resellersSelection', resolve: { accounts: function() { return $scope.saveData.list; }, includeOrphan: function () { return 0; } } }; types[consts.ACCOUNT_FILTER_TYPE_OWNEDBY] = { size: 'lg', template: 'accountsSelection', controller: 'resellersSelection', resolve: { accounts: function() { return $scope.saveData.list; }, includeOrphan: function () { return 0; } } }; types[consts.ACCOUNT_FILTER_TYPE_PACKAGE] = { size: 'lg', template: 'accountPackagesSelection', resolve: { packages: function() { return $scope.saveData.list; }, account: function () { return null; } } }; types[consts.ACCOUNT_FILTER_TYPE_ACCOUNT_TAG] = { size: 'lg', template: 'tagsSelection', resolve: { tags: function() { return $scope.saveData.list; }, type: function () { return consts.TAG_TYPE_ACCOUNT; } } }; popup.open(types[$scope.saveData.type]).result.then(function(selected) { $scope.saveData.list = selected; }, function () {}); }; $scope.searchTags = function(query) { if(!query) return []; var deferred = $q.defer(); api.listTags({ data: { filter: query, sort: { name: 1 }, find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function(data) { var results = []; for(var i = 0; i < data.tags.length; i++) { var tag = data.tags[i]; if($scope.saveData.list.indexOf(tag._id) >= 0) continue; results.push(tag); } deferred.resolve( results ); }, failed: function (message) { } }); return deferred.promise; }; $scope.searchAccountPackages = function(query) { if(!query) return []; var deferred = $q.defer(); api.listAccountPackages({ data: { all: 1, filter: query, sort: { name: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.packages.length; i++) { var packageData = data.packages[i]; if($scope.saveData.list.indexOf(packageData.name) >= 0) continue; results.push(packageData); } deferred.resolve( results ); } }); return deferred.promise; }; $scope.searchAccounts = function(query) { if(!query) return []; var reseller = $scope.saveData.type === consts.ACCOUNT_FILTER_TYPE_RESELLER || $scope.saveData.type === consts.ACCOUNT_FILTER_TYPE_OWNEDBY; var deferred = $q.defer(); api.listAccounts({ data: { filter: query, sort: { username: 1 } }, success: function(data) { var results = []; for(var i = 0; i < data.accounts.length; i++) { var account = data.accounts[i]; if( (!reseller && $scope.saveData.list.indexOf(account.username) >= 0) || (reseller && (!account.reseller || $scope.saveData.list.indexOf(account.username) >= 0)) ) continue; results.push(account); } deferred.resolve( results ); } }); return deferred.promise; }; $scope.addPackage = function() { var value = $scope.item.package.trim(); if(!value) return; if($scope.saveData.list.indexOf(value) >= 0) { $scope.item.package = ''; return; } $scope.saveData.list.push(value); $scope.item.package = ''; }; $scope.addMultiplePackages = function() { $scope.listData = $scope.saveData.list.join("\n"); $scope.listUIB = popup.open({ template: 'listSelection', scope: $scope, noController: true }); $scope.listUIB.result.then(function(records) { while($scope.saveData.list.length) $scope.saveData.list.pop(); records = records.split("\n"); for(var i = 0; i < records.length; i++) { if($scope.saveData.list.indexOf(records[i]) >= 0) continue; $scope.saveData.list.push(records[i]); } }, function () {}); }; $scope.selectItem = function(item) { if(item === undefined) return; $scope.saveData.list.push(item); $scope.autocomplete.filterText = ''; }; $scope.rangeStartValueCheck = function (char) { return char <= $scope.saveData.range_end; }; $scope.rangeEndValueCheck = function (char) { return char >= $scope.saveData.range_start; }; $scope.fetchFilterData = function(filter_id) { api.getAccountFilter({ data: { _id: filter_id }, success: function(data) { $scope.details = data; if($scope.details.type == consts.ACCOUNT_FILTER_TYPE_DISK_USAGE && $scope.details.usage > 0) { $scope.details.usage = (($scope.details.usage / 1024) / 1024); } $scope.loadFilterType($scope.details.type); } }); }; $scope.$watch("saveData", function(){ $scope.changed = util.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('createFilter', function () { $scope.saveChanges(true, function(response) { $scope.$emit('filterResponse', response); }); }); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled && !$scope.popup && !$scope.wizardData) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/accountFilters'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = util.saveParams($scope.saveData, $scope.details, [], function(key) { return ($scope.details._id === undefined && key === 'type'); }); apiParams.action = $scope.details._id ? 'modify' : 'create'; if(apiParams.usage !== undefined && $scope.saveData.type == consts.ACCOUNT_FILTER_TYPE_DISK_USAGE && apiParams.usage > 0) { apiParams.usage = ((apiParams.usage * 1024) * 1024); } api.manageAccountFilter({ data: apiParams, success: function(data, message) { $scope.saveing = false; if(callback !== undefined && typeof callback === 'function') { callback({ success: true, data: data, message: message }); return; } $scope.changed = false; $scope.saveData._id = data._id; $scope.details = util.duplicateObject($scope.saveData); if(apply) $location.path('/accountFilterManage/' + data._id); else $location.path('/accountFilters'); alert.success(message); }, failed: function (message) { $scope.saveing = false; if(callback !== undefined && typeof callback === 'function') { callback({ success: false, data: {}, message: message }); return; } alert.error(message); } }); }; $scope.loadAccounts = function () { api.listAccounts({ success: function(data) { for(var i = 0; i < data.accounts.length; i++) { $scope.accounts[data.accounts[i].username] = data.accounts[i]; } } }); }; $scope.loadData = function () { var filter_id = $routeParams.id; if(filter_id) $timeout($scope.fetchFilterData(filter_id)); else $scope.loadFilterType(consts.ACCOUNT_FILTER_TYPE_ACCOUNT, true); $scope.loadAccounts(); }; if(permissions.isRoot) { api.listTags({ data: { find: { type: consts.TAG_TYPE_ACCOUNT } }, success: function (data) { for(var i = 0; i < data.tags.length; i++) $scope.tags[data.tags[i]._id] = data.tags[i]; $scope.loadData(); } }); } else { $scope.loadData(); } }]); }); define('controllers/accountFilterManagePopup',['app'], function(app) { app.controller('accountFilterManagePopup', ["$uibModalInstance", "$routeParams", "$rootScope", "$scope", "api", "consts", "lang", "alert", function($uibModalInstance, $routeParams, $rootScope, $scope, api, consts, lang, alert) { $scope.popup = true; $routeParams.id = null; $scope.details = { name: '' }; $scope.saveData = { name: '', type: consts.ACCOUNT_FILTER_TYPE_ACCOUNT, list: [], condition: consts.ACCOUNT_FILTER_CONDITION_INCLUDE }; $scope.$on('filterResponse', function (event, response) { if(!response.success) { alert.error(response.message); return; } api.getAccountFilterGroup({ data: { _id: response.data.group_id }, success: function(data) { alert.success(response.message); $uibModalInstance.close(data); }, failed: function (message) { alert.error(message); } }); }); $scope.ok = function () { $rootScope.$broadcast('createFilter'); }; $scope.cancel = function () { $uibModalInstance.dismiss(); }; }]); }); define('controllers/accountFilterGroupManage',['app'], function(app) { app.controller("accountFilterGroupManage", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "api", "consts", "lang", "meta", "utils", "alert", "confirm", function ($rootScope, $scope, $routeParams, $location, $timeout, api, consts, lang, meta, utils, alert, confirm) { $rootScope.$emit('menuItem', 'AccountFilters'); $scope.details = { name: '', filters: [] }; $scope.saveData = utils.duplicateObject($scope.details); $scope.filters = {}; $scope.saveing = false; $scope.changed = false; $scope.types = {}; $scope.types[consts.ACCOUNT_FILTER_TYPE_ACCOUNT] = lang.t("Accounts Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_OWNEDBY] = lang.t("Owned By Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_RESELLER] = lang.t("Resellers Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_SUSPENSION] = lang.t("Suspension Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_ENCRYPTION] = lang.t("Encryption Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_DISK_USAGE] = lang.t("Disk Space Usage Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_INODE_USAGE] = lang.t("Inodes Usage Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_PACKAGE] = lang.t("Packages Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_RANGE] = lang.t("Characters Range Filter"); $scope.types[consts.ACCOUNT_FILTER_TYPE_REGEX] = lang.t("Regular Expression Filter"); $scope.toggleFilter = function (filter) { var idx = $scope.saveData.filters.indexOf(filter._id); if (idx > -1) $scope.saveData.filters.splice(idx, 1); else $scope.saveData.filters.push(filter._id); }; $scope.fetchGroupData = function(group_id) { api.getAccountFilterGroup({ data: { _id: group_id }, success: function(data) { $scope.details = data; $scope.saveData = utils.duplicateObject($scope.details); } }); }; $scope.$watch("saveData", function(){ $scope.changed = utils.isChanged($scope.saveData, $scope.details, ['_id']); }, true); $scope.$on('createFilter', function (event) { $scope.saveChanges(true, function(response) { $scope.$emit('filterResponse', response); }); }); $scope.$on('$destroy', function() { if($scope.changed && !$scope.cancelled) { confirm.open({ message: lang.t("You didn't saved your changes"), confirm: $scope.saveChanges, cancelLabel: lang.t("Disregard Changes"), confirmLabel: lang.t("Save"), }); } }); $scope.cancel = function() { $scope.cancelled = true; $location.path('/accountFilterGroups'); }; $scope.saveChanges = function(apply, callback) { if($scope.saveing) return; $scope.saveing = true; var apiParams = utils.saveParams($scope.saveData, $scope.details); apiParams.action = $scope.details._id ? 'modify' : 'create'; api.manageAccountFilterGroup({ data: apiParams, success: function(data, message) { $scope.saveing = false; if(callback !== undefined) { callback({ success: true, data: data, message: message }); return; } $scope.changed = false; $scope.saveData._id = data._id; $scope.details = utils.duplicateObject($scope.saveData); if(apply) $location.path('/accountFilterGroupManage/' + data._id); else $location.path('/accountFilterGroups'); alert.success(message); }, failed: function (message) { $scope.saveing = false; if(callback !== undefined) { callback({ success: false, data: {}, message: message }); return; } alert.error(message); } }); }; $scope.fetchFilters = function (callback) { $scope.filters = {}; api.listAccountFilters({ success: function (data) { for(var i = 0; i < data.filters.length; i++) { $scope.filters[data.filters[i]._id] = data.filters[i]; } if(callback !== undefined) callback(); } }); }; $timeout($scope.fetchFilters(function() { var group_id = $routeParams.id; if(group_id) $timeout($scope.fetchGroupData(group_id)); })); } ] ); }); define('controllers/accountFilterGroupManagePopup',['app'], function(app) { app.controller('accountFilterGroupManagePopup', ["$uibModalInstance", "$rootScope", "$scope", "api", "lang", "alert", function($uibModalInstance, $rootScope, $scope, api, lang, alert) { $scope.saveData = { name: '', filters: [] }; $scope.$on('filterResponse', function (event, response) { if(!response.success) { alert.error(response.message); return; } api.getAccountFilterGroup({ data: { _id: response.data._id }, success: function(data) { alert.success(response.message); $uibModalInstance.close(data); }, failed: function (message) { alert.error(message); } }); }); $scope.ok = function () { $rootScope.$broadcast('createFilter'); }; $scope.cancel = function () { $uibModalInstance.dismiss(); }; }]); }); define('controllers/accountFilterGroups',['app'], function(app) { app.controller("accountFilterGroups", ["$rootScope", "$scope", "$location", "$timeout", "api", "meta", "confirm", "lang", function ($rootScope, $scope, $location, $timeout, api, meta, confirm, lang) { $rootScope.$emit('menuItem', 'AccountFilters'); $scope.groups = []; $scope.filters = {}; $scope.loadingGroups = false; $scope.saveing = false; $scope.loaders = { delete: false }; meta = meta.new("filter_groups"); $scope.meta = meta; $scope.metaData = meta.getData(); if(!meta.getSortBy()) meta.setSortBy("name"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setSortFields(["name","type","owner","count"]); meta.setTotalItems($scope.groups.length); $scope.onClickDelete = function(group) { if($scope.saveing) return; if(group.count > 0) { alert.error(lang.t("This account filter group has an assigned jobs, Please remove those jobs before deleting this account filter group.")); return false; } $scope.saveing = true; $scope.loaders.delete = true; confirm.open({ message: lang.t("This group will be permanently deleted!"), confirm: function () { api.deleteAccountFilterGroup({ _id: group._id }, function(response) { $scope.saveing = false; $scope.loaders.delete = false; if(response.success) { $scope.fetchData(); alert.success(response.message); return; } alert.error(response.message); }); }, cancel: function () { $scope.saveing = false; $scope.loaders.delete = false; } }); }; $scope.fetchFilters = function (callback) { $scope.filters = {}; api.listAccountFilters({ success: function (data) { for(var i = 0; i < data.filters.length; i++) { $scope.filters[data.filters[i]._id] = data.filters[i]; } if(callback !== undefined) callback(); } }); }; $scope.fetch = function() { $scope.loadingGroups = true; var apiParams = { sort: {}, skip: meta.getSkip(), limit: meta.getPageSize(), find: {}, filter: meta.getFilter() }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); $scope.groups = []; api.listAccountFilterGroups({ data: apiParams, success: function(data) { meta.setTotalItems(data.total); meta.calculate(data.groups); $scope.groups = data.groups; $scope.loadingGroups = false; } }); }; $timeout($scope.fetchFilters(function() { $scope.fetch(); })); } ] ); }); define('controllers/accountFilterGroupSelection',['app'], function(app) { app.controller('accountFilterGroupSelection', ["$uibModalInstance", "$scope", "filters", "details", "alert", "lang", "popup", function($uibModalInstance, $scope, filters, details, alert, lang, popup) { $scope.filters = []; $scope.allFilters = filters; $scope.newFilter = function () { popup.open({ size: "lg", template: 'accountFilterManagePopup', scope: $scope, }).result.then(function(filterDetails) { if(!filterDetails._id) { alert.error(lang.t("Failed to create filter")); return; } $scope.allFilters[filterDetails._id] = filterDetails; $scope.selectedFilter = filterDetails._id; $scope.ok(); /* //$scope.allFilters[filterDetails._id] = filterDetails; $scope.allFilters[filterDetails._id] = filterDetails; $scope.setFilters(); */ }, function () { //$log.info('Modal dismissed at: ' + new Date()); }); }; $scope.setFilters = function () { for(var i in $scope.allFilters) { $scope.filters.push($scope.allFilters[i]); } }; $scope.setFilters(); $scope.selectedFilter = $scope.filters.length ? $scope.filters[0]._id : ''; $scope.ok = function () { $uibModalInstance.close( $scope.selectedFilter ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; }]); }); define('controllers/accountsSelection',['app'], function(app) { app.controller('accountsSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "meta", "accounts", "includeOrphan", "callParams", "lang", function($uibModalInstance, $scope, $timeout, api, meta, accounts, includeOrphan, callParams, lang) { $scope.loading = false; $scope.accounts = []; $scope.fetchAccounts = function () { $scope.loading = true; api.listAccounts({ data: { include_orphan: includeOrphan, sort: { username: 1 }, limit: 9999999 }, success: function (data) { for (var i = 0; i < data.accounts.length; i++) { data.accounts[i].checked = accounts !== undefined && accounts.length ? accounts.indexOf(data.accounts[i].username) >= 0 : false; } $scope.accounts = data.accounts; $scope.loading = false; } }); }; $timeout($scope.fetchAccounts); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.accounts.length; i++) { if($scope.accounts[i].checked) selected.push($scope.accounts[i].username); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/accountPackagesSelection',['app'], function(app) { app.controller('accountPackagesSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "meta", "packages", "account", "lang", function($uibModalInstance, $scope, $timeout, api, meta, packages, account, lang) { $scope.loading = false; $scope.packages = []; $scope.fetchAccountPackages = function () { if($scope.loading) return; $scope.loading = true; $scope.packages = []; var apiParams = {all: 1, sort: { name: 1 }}; if(account) apiParams._id = account._id; var added = []; api.listAccountPackages({ data: apiParams, success: function (data) { for (var i = 0; i < data.packages.length; i++) { data.packages[i].checked = packages !== undefined && packages.length ? packages.indexOf(data.packages[i].name) >= 0 : false; if(added.indexOf(data.packages[i].name) < 0) { $scope.packages.push(data.packages[i]); added.push(data.packages[i].name); } } $scope.loading = false; } }); }; $timeout($scope.fetchAccountPackages); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.packages.length; i++) { if($scope.packages[i].checked) selected.push($scope.packages[i].name); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/resellersSelection',['app'], function(app) { app.controller('resellersSelection', ["$uibModalInstance", "$scope", "$timeout", "api", "meta", "lang", "accounts", function($uibModalInstance, $scope, $timeout, api, meta, lang, accounts) { $scope.loading = false; $scope.accounts = []; $scope.fetchAccounts = function () { $scope.loading = true; api.listAccounts({ data: { limit: 9999999, find: { reseller: true } }, success: function (data) { for (var i = 0; i < data.accounts.length; i++) { data.accounts[i].checked = accounts !== undefined && accounts.length ? accounts.indexOf(data.accounts[i].username) >= 0 : false; $scope.accounts.push(data.accounts[i]); } $scope.loading = false; } }); }; $timeout($scope.fetchAccounts); $scope.ok = function () { var selected = []; for (var i = 0; i < $scope.accounts.length; i++) { if($scope.accounts[i].checked) selected.push($scope.accounts[i].username); } $uibModalInstance.close( selected ); }; $scope.cancel = function () { $uibModalInstance.dismiss(lang.t('cancel')); }; } ] ); }); define('controllers/confirm',['app'], function(app) { app.controller('confirm', ["$uibModalInstance", "$scope", "$timeout", "$sce", "api", "lang", "meta", "title", "message", "buttons", "labels", function($uibModalInstance, $scope, $timeout, $sce, api, lang, meta, title, message, buttons, labels) { $scope.title = title; $scope.message = $sce.trustAsHtml(message); $scope.buttons = buttons; $scope.labels = labels; $scope.close = function () { $uibModalInstance.close(); }; $scope.dismiss = function () { $uibModalInstance.dismiss(); }; } ] ); }); define('controllers_enduser/dashboard',[ 'app', ], function(app) { app.controller("dashboard_enduser", ["$rootScope", "$scope", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "confirm", function($rootScope, $scope, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, confirm) { $rootScope.$emit('menuItem', 'Dashboard'); $scope.stats = { alerts: 0, accounts: 0, jobs: 0, backups: 0, over_quota: 0, jobs_running: 0 }; $scope.loadingStatistics = true; $scope.createBackupOnDemand = function () { confirm.open({ message: lang.t("Are you sure you want to create backup on demand?"), confirm: function () { api.createBackupOnDemand({ data: { account_id: $scope.loggedAccount._id }, success: function(data, message) { alert.success(message); }, failed: function(message) { alert.error(message); } }); }, cancel: function () {} }); }; $scope.fetch = function(callback) { if(callback === undefined | typeof callback !== 'function') callback = function() {}; api.getDashboardDetails({ success: function(data) { $scope.stats.alerts = data.statistics.total_new_alerts; $scope.stats.accounts = data.statistics.total_accounts; $scope.stats.backups = data.statistics.total_account_backups; $scope.stats.disk_usage = data.statistics.total_disk_usage; $scope.loadingStatistics = false; callback(); }, failed: function (message) { alert.error(message); $scope.loadingStatistics = false; callback(); } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore',[ 'app', ], function(app) { app.controller("restore_enduser", ["$rootScope", "$scope", "$routeParams", "$window", "$location", "$timeout", "$interval", "api", "meta", "lang", "popup", "permissions", "consts", function($rootScope, $scope, $routeParams, $window, $location, $timeout, $interval, api, meta, lang, popup, permissions, consts) { $rootScope.$emit('menuItem', 'Restore'); $scope.currentSection = {}; $scope.selected = {}; $scope.sectionTemplate = ''; $scope.sections = [ {_id: 'full', name: lang.t("Full Account"), icon: 'fa-cubes', hidden: !permissions.canManageFullBackups}, {_id: 'files', name: lang.t("Home Directory"), icon: 'fa-folder', hidden: !permissions.canManageFileBackups}, {_id: 'cron', name: lang.t("Cron Jobs"), icon: 'fa-user-clock', hidden: !permissions.canManageCronBackups}, {_id: 'db', name: lang.t("Databases"), icon: 'fa-database', hidden: !permissions.canManageDatabaseBackups}, {_id: 'dbuser', name: lang.t("Database Users"), icon: 'fa-user-tie', hidden: !permissions.canManageDatabaseBackups}, {_id: 'dns', name: lang.t("Domains"), icon: 'fa-map-marker-alt', hidden: !permissions.canManageDNSZoneBackups}, {_id: 'ssl', name: lang.t("Certificates"), icon: 'fa-lock', hidden: !permissions.canManageCertificateBackups}, {_id: 'email', name: lang.t("Email Accounts"), icon: 'fa-envelope', hidden: !permissions.canManageEmailBackups}, {_id: 'ftp', name: lang.t("FTP Accounts"), icon: 'fa-file', hidden: !permissions.canManageFTPBackups} ]; $scope.saveNotes = function (backup, keyEvent) { backup.notes = backup.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageBackupNotes({ data: { _id: backup._id, notes: backup.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); }, }); backup.editing = false; }; $scope.isSelected = function () { for(var id in $scope.selected) return true; return false; }; $scope.isSelectedBackup = function (backup) { return $scope.selected[backup._id] !== undefined; }; $scope.selectedBackup = function(backup) { if($scope.selected[backup._id] !== undefined) delete $scope.selected[backup._id]; else $scope.selected[backup._id] = backup; }; $scope.prepareSummary = function (type) { var backups = []; for(var id in $scope.selected) backups.push($scope.selected[id]); $scope.showSummary(type, backups); }; $scope.changeBackup = function(backup) { backup.options = []; if(backup.new_id === backup._id) { backup.options_real = {}; backup.new_id = ''; return; } var oldId = backup._id; var newBackup = backup.options_real[backup.new_id]; for(var key in newBackup) backup[key] = newBackup[key]; if($scope.selected[oldId] !== undefined) { delete $scope.selected[oldId]; $scope.selected[backup._id] = backup; } backup.options_real = {}; backup.new_id = ''; }; $scope.selectBackup = function(backup) { backup.new_id = backup._id; backup.options = []; backup.options_real = {}; var apiParams = { account_id: backup.account_id, type: backup.backup_type, contains: backup.backup_contains, name: backup.name, sort: { created: -1 }, limit: 9999999 }; if(backup.params.engine !== undefined) apiParams.engine = backup.params.engine; api.listBackupForTypeName({ data: apiParams, success: function (data) { for(var i = 0; i < data.backups.length; i++) { backup.options.push({ _id: data.backups[i]._id, display: lang.d(data.backups[i].created, 'shorttime') }); backup.options_real[data.backups[i]._id] = data.backups[i]; } } }); }; $scope.isTooltipEnabled = function() { return $window.innerWidth <= 928; }; $scope.showSummary = function (type, items, files) { popup.open({ size: "xl", template: 'backups', templateViews: 'views_enduser', controller: 'backups_enduser', resolve: { section: function () { return $scope.currentSection; }, summary: function () { return type; }, items: function() { return items; }, files: function () { return files !== undefined ? files : {}; } } }).result.then(function(refresh) { if(refresh) $scope.fetch(); }, function(){}); }; $scope.changeSection = function (section) { $scope.changeView('restore/' + section._id); }; $scope.loadSection = function (type) { for(var i = 0; i < $scope.sections.length; i++) { var section = $scope.sections[i]; if(section._id !== type || section.hidden) continue; $scope.currentSection = section; $scope.sectionTemplate = $scope.includePath('restore/' + section._id, 'views_enduser'); return; } for(var i = 0; i < $scope.sections.length; i++) { var section = $scope.sections[i]; if(section.hidden) continue; $scope.currentSection = section; $scope.sectionTemplate = $scope.includePath('restore/' + section._id, 'views_enduser'); return; } }; $scope.loadSection($routeParams.type); } ] ); }); define('controllers_enduser/restore/full',[ 'app', ], function(app) { app.controller("restore_full_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert) { $scope.backups = []; $scope.selected = ''; meta = meta.new("enduser_full_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.selectedBackup = function(backup) { if($scope.selected === backup.parent_id) $scope.selected = ''; else $scope.selected = backup.parent_id; }; $scope.prepareSummary = function (type) { api.getBackupItems({ data: { _id: $scope.selected, limit: 999999 }, success: function (data) { $scope.showSummary(type, data.backups); }, failed: function (message) { alert.error(message); } }) }; $scope.fetch = function () { $scope.backups = []; $scope.selected = ''; var apiParams = { name: $scope.loggedAccount.username, type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_FULL, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForTypeName({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/files',[ 'app', ], function(app) { app.controller("restore_files_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {_id:''}; $scope.files = undefined; meta = meta.new("enduser_files_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.selectedBackup = function(backup) { $scope.files = undefined; if($scope.selected._id !== backup._id) $scope.selected = backup; else $scope.selected = {_id:''}; }; $scope.totalFiles = function() { if($scope.files === undefined) return null; var output = 0; for(var path in $scope.files) output++; if(!output) return null; return output; }; $scope.fileBrowse = function() { popup.open({ size: "xl", template: 'fileManagerPopup', scope: $scope, resolve: { files: function() { return $scope.files; }, backup: function() { return $scope.selected; } } }).result.then(function(files) { var total = 0; for(var path in files) total++; $scope.files = total ? files : undefined; }, function(){}); }; $scope.prepareSummary = function (type) { var files = {}; if($scope.files !== undefined) files[$scope.selected._id] = $scope.files; $scope.showSummary(type, [$scope.selected], files); }; $scope.fetch = function () { $scope.backups = []; $scope.selected = {_id:''}; $scope.files = undefined; var apiParams = { name: $scope.loggedAccount.username, type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_HOMEDIR, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForTypeName({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/cron',[ 'app', ], function(app) { app.controller("restore_cron_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {_id:''}; $scope.files = {}; meta = meta.new("enduser_cron_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.saveNotes = function (backup, keyEvent) { backup.notes = backup.notes.substr(0, 40); if(keyEvent && keyEvent.which !== 13) return; api.manageBackupNotes({ data: { _id: backup._id, notes: backup.notes }, success: function (data, message) { alert.success(message); }, failed: function (message) { alert.error(message); }, }); backup.editing = false; }; $scope.selectedBackup = function(backup) { if($scope.selected._id === backup._id) $scope.selected = {_id:''}; else $scope.selected = backup; }; $scope.prepareSummary = function (type) { $scope.showSummary(type, [$scope.selected]); }; $scope.fetch = function () { $scope.backups = []; $scope.selected = {_id:''}; var apiParams = { name: $scope.loggedAccount.username, type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForTypeName({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/dns',[ 'app', ], function(app) { app.controller("restore_dns_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_dns_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_DOMAINS, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/email',[ 'app', ], function(app) { app.controller("restore_email_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_email_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_EMAILS, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/db',[ 'app', ], function(app) { app.controller("restore_db_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_db_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_DATABASES, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/dbuser',[ 'app', ], function(app) { app.controller("restore_dbuser_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_dbuser_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/ftp',[ 'app', ], function(app) { app.controller("restore_ftp_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", "permissions", "alert", "popup", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts, permissions, alert, popup) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_ftp_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_FTP, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/restore/ssl',[ 'app', ], function(app) { app.controller("restore_ssl_enduser", ["$rootScope", "$scope", "$routeParams", "$location", "$timeout", "$interval", "api", "meta", "lang", "consts", function($rootScope, $scope, $routeParams, $location, $timeout, $interval, api, meta, lang, consts) { $scope.backups = []; $scope.selected = {}; $scope.files = {}; meta = meta.new("enduser_ssl_backups"); $scope.meta = meta; $scope.metaData = meta.getData(); meta.setSortReverse(false); if(!meta.getSortBy()) meta.setSortBy("created"); if(!meta.getSortDirection()) meta.setSortDirection("desc"); meta.setPageSizes([10,25,50,100]); meta.setPageSize(10); meta.setSortFields(["username", "owner"]); meta.setTotalItems($scope.backups.length); $scope.fetch = function () { $scope.backups = []; $scope.selected = {}; var apiParams = { type: consts.BACKUP_TYPE_ACCOUNT, contains: consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES, account_id: $scope.loggedAccount._id, skip: meta.getSkip(), limit: meta.getPageSize(), filter: meta.getFilter(), sort: {}, find: {} }; apiParams.sort[meta.getSortBy()] = meta.getSortDirectionInt(); api.listBackupForType({ data: apiParams, success: function (data) { meta.setTotalItems(data.total); meta.calculate(data.backups); for(var i = 0; i < data.backups.length; i++) { var names = []; for(var j = 0; j < data.backups[i].schedules.length; j++) names.push(consts.SCHEDULE_TYPES[data.backups[i].schedules[j]]); data.backups[i].schedules_names = names.join(","); $scope.backups.push(data.backups[i]); } } }); }; $timeout($scope.fetch); } ] ); }); define('controllers_enduser/backups',['app'], function(app) { app.controller("backups_enduser", ["$uibModalInstance","$rootScope", "$scope", "$q", "$location", "$timeout", "api", "meta", "util", "permissions", "consts", "lang", "alert", "popup", "summary", "items", "files", "section", function ($uibModalInstance, $rootScope, $scope, $q, $location, $timeout, api, meta, util, permissions, consts, lang, alert, popup, summary, items, files, section) { $scope.loading = false; $scope.accountData = $scope.loggedAccount; $scope.items = items; $scope.files = files; $scope.list = {}; $scope.list_checked = {}; $scope.summary_gotoqueue = true; $scope.summary_type = summary; $scope.summary_tpl = $scope.includePath('backups' + summary + 'Summary', 'views_enduser'); $scope.restore_conditions = []; $scope.conditions = {}; $scope.options = { package: '' }; $scope.encryption = { encrypted: false, key: '' }; $scope.noPermissions = []; if(section._id === 'full') { if(!permissions.canManageFileBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_HOMEDIR); if(!permissions.canManageCronBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS); if(!permissions.canManageDatabaseBackups) { $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_DATABASES); $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS); } if(!permissions.canManageDNSZoneBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_DOMAINS); if(!permissions.canManageCertificateBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES); if(!permissions.canManageEmailBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_EMAILS); if(!permissions.canManageFTPBackups) $scope.noPermissions.push(consts.BACKUP_TYPE_ACCOUNT_FTP); } for (var i = 0; i < $scope.items.length; i++) { var backup = $scope.items[i]; backup.checked = true; if($scope.list[backup.backup_contains] === undefined) $scope.list[backup.backup_contains] = []; $scope.list[backup.backup_contains].push(backup); } $scope.close = function () { $uibModalInstance.dismiss(); }; $scope.askForEncryptionKey = function() { return $scope.encryption.encrypted && $scope.accountData.backup_type == 1 && $scope.accountData.encryption_key_type == 1; }; $scope.ok = function () { $uibModalInstance.close(); }; $scope.calculateSummary = function() { var gotData = false; $scope.encryption.encrypted = false; $scope.list_checked = {}; for(var contains in $scope.list) { for(var i = 0; i < $scope.list[contains].length; i++) { var backup = $scope.list[contains][i]; if(!backup.checked) continue; if(!$scope.encryption.encrypted && backup.encrypted) $scope.encryption.encrypted = true; if($scope.list_checked[contains] === undefined) $scope.list_checked[contains] = []; $scope.list_checked[contains].push($scope.list[contains][i]); gotData = true; } } if(!gotData) $uibModalInstance.dismiss(); }; $scope.gotItems = function(types) { for(var i = 0; i < types.length; i++) { if($scope.list_checked[types[i]] !== undefined) return true; } return false; }; $scope.restore = function() { for(var i = 0; i < $scope.restore_conditions.length; i++) { var condition = $scope.restore_conditions[i]; if($scope.conditions[condition._id] === undefined || !$scope.conditions[condition._id]) { alert.error(lang.t("Please accept all restore conditions")); return; } } if($scope.askForEncryptionKey() && !$scope.encryption.key) { alert.error(lang.t("You must provide \"Backups Private Encryption Key\"")); return; } var list = $scope.items; var ids = []; for(var i = 0; i < list.length; i++) if(list[i].checked) ids.push(list[i]._id); var options = util.duplicateObject($scope.options); api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_RESTORE, items: ids, files: $scope.files, options: options, encryption_key: $scope.encryption.key }, success: function (data, message) { $scope.encryption.key = ''; alert.success(message); $uibModalInstance.close(); if($scope.summary_gotoqueue) $location.path("/queue"); }, failed: function (message) { alert.error(message); } }); }; $scope.download = function() { if($scope.askForEncryptionKey() && !$scope.encryption.key) { alert.error(lang.t("You must provide \"Backups Private Encryption Key\"")); return; } var list = $scope.items; var ids = []; for(var i = 0; i < list.length; i++) if(list[i].checked) ids.push(list[i]._id); api.addQueueItems({ data: { type: consts.QUEUE_ITEM_TYPE_DOWNLOAD, items: ids, files: $scope.files, encryption_key: $scope.encryption.key }, success: function (data, message) { $scope.encryption.key = ''; alert.success(message); $uibModalInstance.close(); if($scope.summary_gotoqueue) $location.path("/queue"); }, failed: function (message) { alert.error(message); } }); }; $scope.removeItems = function(contains) { for(var i = 0; i < $scope.list[contains].length; i++) { var backup = $scope.list[contains][i]; backup.checked = false; } $scope.calculateSummary(); }; api.listRestoreConditions({ data: { find: { disabled: 0 } }, success: function (data) { $scope.restore_conditions = data.conditions; } }); $scope.calculateSummary(); } ] ); }); define('filters/html',["app"], function(app) { app.filter("html", ["$sce", function ($sce){ return function(html) { return $sce.trustAs('html', html); }; }]); }); define('filters/capitalize',["app"], function(app) { app.filter("capitalize", function (){ return function(input, all) { return (!!input) ? input.replace((all ? /([^\W_]+[^\s-]*) */g : /([^\W_]+[^\s-]*)/), function(txt){ return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); }) : ''; }; }); }); define('filters/executionTime',["app"], function(app) { app.filter("executionTime", ["$sce", "lang", function ($sce, lang){ return function(seconds) { seconds = parseInt(seconds); if(seconds < 0) return "-"; if(seconds === 0) return lang.t("Under a Second"); var time = { Day: Math.floor(seconds / 86400), Hour: Math.floor(seconds / 3600) % 24, Minute: Math.floor(seconds / 60) % 60, Second: (seconds % 60) }; if(time['Day']) return lang.t("%s Days and %s Hours and %s Minutes and %s Seconds", time['Day'], time['Hour'], time['Minute'], time['Second']) if(time['Hour']) return lang.t("%s Hours and %s Minutes and %s Seconds", time['Hour'], time['Minute'], time['Second']) if(time['Minute']) return lang.t("%s Minutes and %s Seconds", time['Minute'], time['Second']) if(time['Second']) return lang.t("%s Seconds", time['Second']) }; }]); }); define('filters/numberFormat',["app"], function(app) { app.filter("numberFormat", [function (){ return function(n, c, d, t) { c = isNaN(c = Math.abs(c)) ? 2 : c; d = d == undefined ? "." : d; t = t == undefined ? "," : t; var s = n < 0 ? "-" : ""; var i = parseInt(n = Math.abs(+n || 0).toFixed(c)) + ""; var j = (j = i.length) > 3 ? j % 3 : 0; return s + (j ? i.substring(0, j) + t : "") + i.substring(j).replace(/(\d{3})(?=\d)/g, "$1" + t) + (c ? d + Math.abs(n - i).toFixed(c).slice(2) : ""); }; }]); }); define('services/api',['app'], function (app) { app.factory('api', ["$rootScope", "$http", "$location", "cfpLoadingBar", "permissions", "lang", "util", function ($rootScope, $http, $location, cfpLoadingBar, permissions, lang, util) { function _exec(cmd, options) { if(options.success === undefined || typeof options.success !== 'function') options.success = function(data, message, system) {}; if(options.failed === undefined || typeof options.failed !== 'function') options.failed = function(message, system) {}; if(options.withLoader === undefined) options.withLoader = true; if(options.data === undefined) options.data = {}; options.data.function = cmd; if(options.withLoader) cfpLoadingBar.start(); $http.post(window.PAGE.path.api, options.data).then(function(response) { if(response.data.success === undefined && response.data.includes('<html')) window.location.reload(); if(response.data.system.retry_ms > 0) { util.sleep(response.data.system.retry_ms); _exec(cmd, options); return; } if (response.data.message) { var args = []; args.push('exceptions|:|' + response.data.message); if(!response.data.success && response.data.data.length) for(var i = 0; i < response.data.data.length; i++) args.push(response.data.data[i]); response.data.message = lang.t.apply(lang, args); } if(response.data.system.licenseIssue || response.data.system.agreement || response.data.system.dr || response.data.system.agreement_panel) { var location = ''; window.PAGE.system = response.data.system; if(response.data.system.agreement_panel) location = '/agreementPanel'; if(response.data.system.dr) location = '/disasterRecovery'; if(response.data.system.agreement) location = '/agreement'; if(response.data.system.licenseIssue && !response.data.system.dr) { if($rootScope.license.status === 'Active') { window.PAGE.license = {status:'Invalid',message: response.data.message}; $rootScope.license = window.PAGE.license; } location = '/license'; } permissions.init(window.PAGE.permissions); $location.path(location); } if(options.withLoader) cfpLoadingBar.complete(); if(response.data.success) options.success(response.data.data, response.data.message, response.data.system); else options.failed(response.data.message, response.data.system); }, function () { if(options.withLoader) cfpLoadingBar.complete(); }); } return { panel: function (func, options) { func = String(func).charAt(0).toUpperCase() + String(func).slice(1); return _exec('panel/' + func, options); }, custom: function(func, options) { return _exec(func, options); }, getSettings: function (options) { var cmd = 'getSettings' + options.data.section[0].toUpperCase()+options.data.section.substr(1); delete options.section; return _exec(cmd, options); }, manageSettings: function (options) { var cmd = 'manageSettings' + options.data.section[0].toUpperCase()+options.data.section.substr(1); delete options.section; return _exec(cmd, options); }, factoryReset: function (options) { _exec('factoryReset', options); }, panelPreload: function (options) { _exec('panelPreload', options); }, exitDisasterRecovery: function (options) { _exec('exitDisasterRecovery', options); }, manageRestoreCondition: function (options) { _exec('manageRestoreCondition', options); }, getRestoreCondition: function (options) { _exec('getRestoreCondition', options); }, listRestoreConditions: function (options) { _exec('listRestoreConditions', options); }, deleteRestoreCondition: function (options) { _exec('deleteRestoreCondition', options); }, createSupportTicketKey: function (options) { _exec('createSupportTicketKey', options); }, getMyAccount: function (options) { _exec('getMyAccount', options); }, manageMyAccount: function (options) { _exec('manageMyAccount', options); }, approveAgreement: function (options) { _exec('approveAgreement', options); }, getProcessStatus: function (options) { _exec('getProcessStatus', options); }, fileManager: function (options) { _exec('fileManager', options); }, getDashboardDetails: function (options) { _exec('getDashboardDetails', options); }, fileBrowse: function (options) { _exec('fileBrowse', options); }, getDownload: function (options) { _exec('getDownload', options); }, listDownloads: function (options) { _exec('listDownloads', options); }, manageDownloadNotes: function (options) { _exec('manageDownloadNotes', options); }, createBackupOnDemand: function (options) { _exec('createBackupOnDemand', options); }, manageSecurityPlugin: function (options) { _exec('manageSecurityPlugin', options); }, managePlugin: function (options) { _exec('managePlugin', options); }, getPlugin: function (options) { _exec('getPlugin', options); }, listPlugins: function (options) { _exec('listPlugins', options); }, installPlugin: function (options) { _exec('installPlugin', options); }, uninstallPlugin: function (options) { _exec('uninstallPlugin', options); }, updatePlugin: function (options) { _exec('updatePlugin', options); }, listAvailablePlugins: function (options) { _exec('listAvailablePlugins', options); }, listNotificationIntegrationTypes: function (options) { _exec('listNotificationIntegrationTypes', options); }, listNotificationIntegrations: function (options) { _exec('listNotificationIntegrations', options); }, manageNotificationIntegration: function (options) { _exec('manageNotificationIntegration', options); }, sendNotificationIntegrationTest: function (options) { _exec('sendNotificationIntegrationTest', options); }, deleteNotificationIntegration: function (options) { _exec('deleteNotificationIntegration', options); }, getNotificationIntegration: function (options) { _exec('getNotificationIntegration', options); }, manageHook: function (options) { _exec('manageHook', options); }, getHook: function (options) { _exec('getHook', options); }, listHooks: function (options) { _exec('listHooks', options); }, deleteHook: function (options) { _exec('deleteHook', options); }, manageTag: function (options) { _exec('manageTag', options); }, getTag: function (options) { _exec('getTag', options); }, listTags: function (options) { _exec('listTags', options); }, deleteTag: function (options) { _exec('deleteTag', options); }, manageSchedule: function (options) { _exec('manageSchedule', options); }, getSchedule: function (options) { _exec('getSchedule', options); }, listSchedules: function (options) { _exec('listSchedules', options); }, deleteSchedule: function (options) { _exec('deleteSchedule', options); }, manageQueuePriority: function (options) { _exec('manageQueuePriority', options); }, getQueuePriority: function (options) { _exec('getQueuePriority', options); }, listQueuePriorities: function (options) { _exec('listQueuePriorities', options); }, deleteQueuePriority: function (options) { _exec('deleteQueuePriority', options); }, getFilePermissions: function (options) { _exec('getFilePermissions', options); }, listFilePermissions: function (options) { _exec('listFilePermissions', options); }, manageFilePermissions: function (options) { _exec('manageFilePermissions', options); }, deleteFilePermissions: function (options) { _exec('deleteFilePermissions', options); }, getRepository: function (options) { _exec('getRepository', options); }, listRepositories: function (options) { _exec('listRepositories', options); }, manageRepository: function (options) { _exec('manageRepository', options); }, deleteRepository: function (options) { _exec('deleteRepository', options); }, reloadRepository: function (options) { _exec('reloadRepository', options); }, getPackage: function (options) { _exec('getPackage', options); }, listPackages: function (options) { _exec('listPackages', options); }, listPackagesAvailable: function (options) { _exec('listPackagesAvailable', options); }, deleteAccountFilter: function (options) { _exec('deleteAccountFilter', options); }, getAccountFilter: function (options) { _exec('getAccountFilter', options); }, listAccountFilters: function (options) { _exec('listAccountFilters', options); }, manageAccountFilter: function (options) { _exec('manageAccountFilter', options); }, getAccountFilterGroup: function (options) { _exec('getAccountFilterGroup', options); }, listAccountFilterGroups: function (options) { _exec('listAccountFilterGroups', options); }, //listPackages: function (options) { _exec('listPackages', options); }, getAlert: function (options) { _exec('getAlert', options); }, listAlerts: function (options) { _exec('listAlerts', options); }, clearAlerts: function (options) { _exec('clearAlerts', options); }, getPermissions: function (options) { _exec('getPermissions', options); }, managePermissions: function (options) { _exec('managePermissions', options); }, resetPermissions: function (options) { _exec('resetPermissions', options); }, deleteLog: function (options) { _exec('deleteLog', options); }, getLog: function (options) { _exec('getLog', options); }, listLogs: function (options) { _exec('listLogs', options); }, getLogItem: function (options) { _exec('getLogItem', options); }, listLogItems: function (options) { _exec('listLogItems', options); }, deleteDestination: function (options) { _exec('deleteDestination', options); }, getDestination: function (options) { _exec('getDestination', options); }, listDestinations: function (options) { _exec('listDestinations', options); }, listDestinationTypes: function (options) { _exec('listDestinationTypes', options); }, manageDestination: function (options) { _exec('manageDestination', options); }, manageDestinationState: function (options) { _exec('manageDestinationState', options); }, validateDestination: function (options) { _exec('validateDestination', options); }, reindexDestination: function (options) { _exec('reindexDestination', options); }, measureDestinationSpeed: function (options) { _exec('measureDestinationSpeed', options); }, genDestinationAuth: function (options) { _exec('genDestinationAuth', options); }, reassignAccount: function (options) { _exec('reassignAccount', options); }, listAssignableAccounts: function (options) { _exec('listAssignableAccounts', options); }, manageAccount: function (options) { _exec('manageAccount', options); }, manageAccountExcludeList: function (options) { _exec('manageAccountExcludeList', options); }, getAccount: function (options) { _exec('getAccount', options); }, getAccountExcludeList: function (options) { _exec('getAccountExcludeList', options); }, listAccounts: function (options) { _exec('listAccounts', options); }, listAccountsByFilters: function (options) { _exec('listAccountsByFilters', options); }, listAccountPackages: function (options) { _exec('listAccountPackages', options); }, addMultiAccountQueueItems: function (options) { _exec('addMultiAccountQueueItems', options); }, resetEncryptionKey: function (options) { _exec('resetEncryptionKey', options); }, addQueueItems: function (options) { _exec('addQueueItems', options); }, listQueueItems: function (options) { _exec('listQueueItems', options); }, listQueueGroups: function (options) { _exec('listQueueGroups', options); }, stopQueueGroup: function (options) { _exec('stopQueueGroup', options); }, stopAllQueueGroup: function (options) { _exec('stopAllQueueGroup', options); }, getQueueGroup: function (options) { _exec('getQueueGroup', options); }, getQueueItem: function (options) { _exec('getQueueItem', options); }, clearQueue: function (options) { _exec('clearQueue', options); }, rerunFailedQueueGroup: function (options) { _exec('rerunFailedQueueGroup', options); }, getBackupItems: function (options) { _exec('getBackupItems', options); }, getBackupItem: function (options) { _exec('getBackupItem', options); }, listBackupForTypeName: function (options) { _exec('listBackupForTypeName', options); }, listBackups: function (options) { _exec('listBackups', options); }, listBackupForType: function (options) { _exec('listBackupForType', options); }, listBackupForAccounts: function (options) { _exec('listBackupForAccounts', options); }, listBackupForDirectories: function (options) { _exec('listBackupForDirectories', options); }, listBackupForDisasterRecovery: function (options) { _exec('listBackupForDisasterRecovery', options); }, getMasterEncryptionKey: function (options) { _exec('getMasterEncryptionKey', options); }, deleteSnapshot: function (options) { _exec('deleteSnapshot', options); }, listShowcase: function (options) { _exec('listShowcase', options); }, approveShowcase: function (options) { _exec('approveShowcase', options); }, manageBackupLock: function (options) { _exec('manageBackupLock', options); }, manageBackupNotes: function (options) { _exec('manageBackupNotes', options); }, manageMultiBackupLock: function (options) { _exec('manageMultiBackupLock', options); }, runExtensionDeployment: function (options) { _exec('runExtensionDeployment', options); }, runCloneJobManually: function (options) { _exec('runCloneJobManually', options); }, duplicateCloneJob: function (options) { _exec('duplicateCloneJob', options); }, manageCloneJob: function (options) { _exec('manageCloneJob', options); }, deleteCloneJob: function (options) { _exec('deleteCloneJob', options); }, getCloneJob: function (options) { _exec('getCloneJob', options); }, listCloneJobs: function (options) { _exec('listCloneJobs', options); }, runBackupJobManually: function (options) { _exec('runBackupJobManually', options); }, duplicateBackupJob: function (options) { _exec('duplicateBackupJob', options); }, manageBackupJob: function (options) { _exec('manageBackupJob', options); }, deleteBackupJob: function (options) { _exec('deleteBackupJob', options); }, getBackupJob: function (options) { _exec('getBackupJob', options); }, listBackupJobs: function (options) { _exec('listBackupJobs', options); } }; }]); }); define('services/alert',[ 'app' ], function (app) { app.factory('alert', ["$rootScope", function($rootScope) { var alert = function(message, state, ttl) { if(ttl === undefined) ttl = 10000; if($rootScope.alerts === undefined) $rootScope.alerts = []; $rootScope.alerts.unshift({message: message, type: state, closeable: true, ttl: ttl }); //window.scrollTo(0, 0); //this._init(message, state); }; alert.prototype = { /* _data: {}, _init: function(message, state) { this._data.message = message; this._data.type = state; if($rootScope.alerts === undefined) $rootScope.alerts = []; $rootScope.alerts.push(this.getData()); }, getData: function () { return this._data; } */ }; return { success: function (message, ttl) { new alert(message, 'success', ttl); }, error: function (message, ttl) { new alert(message, 'danger', ttl); }, warning: function (message, ttl) { new alert(message, 'warning', ttl); }, info: function (message, ttl) { new alert(message, 'info', ttl); } }; }]); }); define('services/confirm',[ 'app' ], function (app) { app.factory('confirm', ["$rootScope", "$uibModal", "lang", "popupPosition", function($rootScope, $uibModal, lang, popupPosition) { return { open: function(options) { if(options.title === undefined) options.title = lang.t("Are you sure?"); if(options.message === undefined) options.message = ''; if(options.cancelLabel === undefined) options.cancelLabel = lang.t('Cancel'); if(options.confirmLabel === undefined) options.confirmLabel = lang.t('OK'); if(options.confirm === undefined || typeof options.confirm !== 'function') options.confirm = function () {}; if(options.cancel === undefined || typeof options.cancel !== 'function') options.cancel = function () {}; if(options.buttons === undefined) options.buttons = []; var model = $uibModal.open({ animation: true, size: "md", ariaLabelledBy: 'modal-title', ariaDescribedBy: 'modal-body', templateUrl: $rootScope.includePath('confirm'), controller: 'confirm', scope: $rootScope, resolve: { title: function() { return options.title; }, message: function() { return options.message; }, buttons: function () { return options.buttons; }, labels: function() { return { cancel: options.cancelLabel, confirm: options.confirmLabel }; } } }); model.opened.then(function() { popupPosition.update(); }); model.result.then(options.confirm, options.cancel); return model; } }; }]); }); define('services/lang',['app'], function (app) { app.factory('lang', ["$i18next", "$location", function ($i18next, $location) { var date_formats = { short: "D MMM YYYY", shorttime: "D MMM YYYY TIME", long: "ddd, MMM D, YYYY", longtime: "ddd, MMM D, YYYY, TIME" }; return { _ns: '', setNS: function(ns, scope) { var self = this; self._ns = ns; if(scope !== undefined) { scope.$on('$destroy', function() { self.resetNS(); }); } }, resetNS: function() { this._ns = ''; }, loadNS: function(ns) { $i18next.loadNamespaces(ns); }, setDefaultNS: function(ns) { this.loadNS(ns); $i18next.setDefaultNamespace(ns); }, initNS: function(defaultNS) { var ns = $location.path(); var parts = ns.split('/'); ns = parts[1]; if(!ns && defaultNS !== undefined) ns = defaultNS; if(ns) this.setDefaultNS(ns); else $rootScope.$broadcast('i18nextNSLoad', this._ns); }, t: function() { var args = []; for(var key in arguments) args.push(arguments[key]); var sprintf = args.slice(1); var text = (this._ns ? this._ns + "|:|" : '') + args[0]; if(!sprintf.length) return $i18next.t(text); return $i18next.t(text, { postProcess: 'sprintf', sprintf: sprintf }); }, d: function (time, format) { var date = moment(time); if(window.PAGE.info.utcOffset) date.utcOffset(window.PAGE.info.utcOffset); if(format === undefined) format = "longtime"; var key = format; format = $i18next.t('date|:|'+key); if(format == key) format = "ddd, MMM D, YYYY, |TIME|"; format = format.replace('|TIME|', window.PAGE.timeformat == 12 ? 'hh:mm A' : 'HH:mm'); return date.format(format); } }; }]); }); define('services/filter',['app'], function (app) { app.factory('filter', [function () { var filter = function(storage_id) { this._init(storage_id); }; filter.prototype = { _storage_key: undefined, _data: {}, _initStorage: function (storage_id) { this._storage_key = "sort_" + storage_id; var sort = localStorage.getItem(this._storage_key); if(sort === undefined) { localStorage.setItem(this._storage_key, JSON.stringify(this._data)); } else { var data = JSON.parse(sort); if(data) this._data = data; } }, _init: function (storage_id) { var defaults = { filter: '' }; this._data = {}; for(var i in defaults) this._data[i] = defaults[i]; if(storage_id !== undefined) this._initStorage(storage_id); }, set: function (key, value) { this._data[key] = value; localStorage.setItem(this._storage_key, JSON.stringify(this._data)); }, get: function (key, defaultValue) { return this._data[key] !== undefined ? this._data[key] : defaultValue; }, setFilter: function (filter) { this.set('filter', filter); }, getFilter: function () { return this.get('filter'); }, setData: function (data) { this._data = data; }, getData: function () { return this._data; } }; return { new: function (storage_id) { return new filter(storage_id); } }; }]); }); define('services/meta',[ 'app' ], function (app) { app.factory('meta', ['storage', "lang", function(storage, lang) { var meta = function(storage_id) { if(storage_id === undefined) throw Error("No storage name provided"); this._storage_id = storage_id; this._storage = storage.create("sort_" + this._storage_id); this._noneStorage[this._storage_id] = {}; for(var key in this._defaults) { if(this._noneStorageKeys.indexOf(key) >= 0 || !this._storage.isSet(key)) { this.set(key, this._defaults[key]); } } }; meta.prototype = { _defaults: { sortReverse: false, sortBy: '', sortDirection: '', sortFields: [], filterValue: '', maxPages: 3, totalItems: 0, currentPage: 1, pageSize: 25, pageSizes: [25, 50, 100, 250, 500], start: 0, limit: 25, itemCountText: undefined }, _noneStorageKeys: ["filterValue"], _noneStorage: {}, _storage_id: undefined, _storage: undefined, _storage_key: undefined, _show_count_text: false, _onChangeFunction: function () {}, onChange: function(func) { this._onChangeFunction = func; }, set: function (key, value) { if(this._noneStorageKeys.indexOf(key) >= 0) { this._noneStorage[this._storage_id][key] = value; } else { this._storage.set(key, value); this._storage.save(); } this._onChangeFunction(); }, get: function (key, defaultValue) { return this._storage.get(key, defaultValue); }, setSortReverse: function (sortReverse) { this.set('sortReverse', sortReverse); }, getSortReverse: function () { return this.get('sortReverse'); }, setSortBy: function (sortBy) { this.set('sortBy', sortBy); }, getSortBy: function () { return this.get('sortBy'); }, setSortDirection: function (sortDirection) { this.set('sortDirection', sortDirection); }, getSortDirection: function () { return this.get('sortDirection'); }, getSortDirectionInt: function() { return this.getSortDirection() === "asc" ? 1 : -1; }, setSortFields: function (sortFields) { this.set('sortFields', sortFields); }, getSortFields: function () { return this.get('sortFields'); }, setFilter: function (filter) { this._noneStorage[this._storage_id].filterValue = filter; }, getFilter: function () { return this._noneStorage[this._storage_id].filterValue; }, setMaxPages: function (maxPages) { this.set('maxPages', maxPages); }, getMaxPages: function () { return this.get('maxPages'); }, setTotalItems: function (totalItems) { this.set('totalItems', parseInt(totalItems)); }, getTotalItems: function () { return this.get('totalItems'); }, setCurrentPage: function (currentPage) { this.set('currentPage', currentPage); }, getCurrentPage: function () { return this.get('currentPage'); }, setPageSize: function (pageSize) { this.set('pageSize', pageSize); }, getPageSize: function () { return this.get('pageSize'); }, setPageSizes: function (pageSizes) { this.set('pageSizes', pageSizes); }, getPageSizes: function () { return this.get('pageSizes'); }, setStart: function (start) { this.set('start', start); }, getStart: function () { return this.get('start'); }, setLimit: function (limit) { this.set('limit', limit); }, getLimit: function () { return this.get('limit'); }, setItemCountText: function (text) { this.set('itemCountText', text); }, getItemCountText: function () { return this.get('itemCountText'); }, showItemCountText: function () { this._show_count_text = true; return this._show_count_text; }, getSkip: function () { return (this.getCurrentPage() - 1) * this.getPageSize(); }, showPagination: function () { return this.get('showPagination', false); }, setData: function (data) { for(var key in data) { if(this._noneStorageKeys.indexOf(key) < 0) continue; this._noneStorage[this._storage_id][key] = data[key]; } this._storage.setData(data); }, getData: function () { var data = this._noneStorage[this._storage_id]; var sdata = this._storage.getData(); for(var key in sdata) { if(this._noneStorageKeys.indexOf(key) >= 0) continue; data[key] = sdata[key]; } return data; }, reset: function () { this.setCurrentPage(1); }, calculate: function (data) { if(data === undefined) data = []; if (this.getTotalItems() > this._min(this.getPageSizes())) { this.set('showPagination', true); var start = (this.getCurrentPage() - 1) * this.getPageSize(); this.setStart(start + 1); //this.setLimit(start + data.length); } else { // hide pager and pagination this.set('showPagination', false); this.setStart((data.length === 0) ? 0 : 1); this.setLimit(data.length); } this.setItemCountText(lang.t("Displaying %s to %s out of %s records", this.getStart(), this.getPageSize() * this.getCurrentPage() > this.getTotalItems() ? this.getTotalItems() : this.getPageSize() * this.getCurrentPage(), this.getTotalItems())); }, _min: function (ary) { var min = null; for(var i; i < ary.length; i++) if(min === null || ary[i] < min) min = ary[i]; return min === null ? 0 : min; } }; return { new: function (storage_id) { return new meta(storage_id); } }; }]); }); define('services/storage',[ 'app' ], function (app) { app.factory('storage', [function() { var STORAGE = function(pool_name) { if(pool_name === undefined) throw Error("You must provide pool name"); this._storage_name = 'JetBackupStorage_' + pool_name; this._data = {}; var storageData = localStorage.getItem(this._storage_name); if(storageData === undefined) this.save(); else this.setData(JSON.parse(storageData)); }; STORAGE.prototype = { _storage_name: undefined, _data: null, set: function (key, value) { this._data[key] = value; }, get: function (key, defaultValue) { return this._data[key] !== undefined ? this._data[key] : defaultValue; }, isSet: function(key) { return this._data[key] !== undefined; }, remove: function(key) { delete this._data[key]; }, save: function() { localStorage.setItem(this._storage_name, JSON.stringify(this._data)); }, setData: function (data) { if(data) this._data = data; }, getData: function () { return this._data; }, destroy: function () { localStorage.removeItem(this._storage_name); this._data={}; } }; return { create: function(pool_name) { return new STORAGE(pool_name); }, delete: function (pool_name) { if(pool_name === undefined) throw Error("You must provide pool name"); localStorage.removeItem('JetBackupStorage_' + pool_name); }, deleteAll: function () { localStorage.clear(); }, exists: function (pool_name) { return !!localStorage.getItem('JetBackupStorage_' + pool_name); } }; }]); }); define('services/permissions',[ 'app' ], function (app) { app.factory('permissions', ["PermPermissionStore", "lang", "consts", function(PermPermissionStore, lang, consts) { var PERMISSIONS = function() {}; PERMISSIONS.prototype = { _permissions: undefined, init: function (permissions) { var self = this; this._permissions = permissions; this.isRoot = !!this._permissions[consts.PERMISSIONS_HAS_ALL_PRIVILEGES]; this.isReseller = !!(this.isRoot || window.PAGE.account.reseller); this.isEnduser = window.PAGE.template === 'enduser'; this.isShowcase = !!(this.isRoot && window.PAGE.showcase.total_unapproved !== undefined && window.PAGE.showcase.total_unapproved); this.isLicenseIssue = !!(window.PAGE.system.licenseIssue !== undefined && window.PAGE.system.licenseIssue); this.isDisableUI = !!(window.PAGE.disableui !== undefined && window.PAGE.disableui); this.isDisasterRecovery = !!(!this.isDisableUI && window.PAGE.system.dr !== undefined && window.PAGE.system.dr); this.isAgreement = !!(!this.isDisableUI && window.PAGE.system.agreement !== undefined && window.PAGE.system.agreement); this.isAgreementPanel = !!(!this.isDisableUI && window.PAGE.system.agreement_panel !== undefined && window.PAGE.system.agreement_panel); this.isFullScreen = !!(this.isShowcase || this.isLicenseIssue || this.isDisasterRecovery || this.isAgreement || this.isAgreementPanel || this.isDisableUI); this.isWPIntegration = !!(this.isRoot && !this.isEnduser && window.PAGE.wp_integrations.length); this.canManageAccounts = this.check(consts.PERMISSIONS_CAN_MANAGE_ACCOUNTS); this.canRestoreBackups = this.check(consts.PERMISSIONS_CAN_RESTORE_BACKUPS); this.canDownloadBackups = this.check(consts.PERMISSIONS_CAN_DOWNLOAD_BACKUPS); this.canManageFullBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_FULL_BACKUPS); this.canManageFileBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_FILE_BACKUPS); this.canManageCronBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_CRON_BACKUPS); this.canManageEmailBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_EMAIL_BACKUPS); this.canManageDatabaseBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_DATABASE_BACKUPS); this.canManageCertificateBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_SSL_BACKUPS); this.canManageDNSZoneBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_DNSZONES_BACKUPS); this.canManageConfigBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_CONFIG_BACKUPS); this.canManageBackupJobs = this.check(consts.PERMISSIONS_CAN_MANAGE_BACKUP_JOBS); this.canManageCloneJobs = this.check(consts.PERMISSIONS_CAN_MANAGE_CLONE_JOBS); this.canManageDestinations = this.check(consts.PERMISSIONS_CAN_MANAGE_DESTINATIONS); this.canManageHooks = this.check(consts.PERMISSIONS_CAN_MANAGE_HOOKS); this.canManagePermissions = this.check(consts.PERMISSIONS_CAN_MANAGE_PERMISSIONS); this.canViewLogs = this.check(consts.PERMISSIONS_CAN_VIEW_LOGS); this.canManageLogs = this.check(consts.PERMISSIONS_CAN_MANAGE_LOGS); this.canViewAlerts = this.check(consts.PERMISSIONS_CAN_VIEW_ALERTS); this.canManageDirectoryBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_DIRECTORY_BACKUPS); this.canManageDisasterRecoveryBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_DISASTER_RECOVERY_BACKUPS); this.canManageFTPBackups = this.check(consts.PERMISSIONS_CAN_MANAGE_FTP_BACKUPS); this.canManageQueue = this.canRestoreBackups || this.canDownloadBackups; this.canAccessSocketAPI = this.check(consts.PERMISSIONS_CAN_ACCESS_SOCKET_API); this.canManageAccountBackups = this.canManageFullBackups || this.canManageFileBackups || this.canManageCronBackups || this.canManageEmailBackups || this.canManageDatabaseBackups || this.canManageCertificateBackups || this.canManageDNSZoneBackups || this.canManageFTPBackups || this.canManageConfigBackups; PermPermissionStore.clearStore(); for(var i in this) { if(!/^can/.test(i) && !/^is/.test(i) && !/^has/.test(i)) continue; PermPermissionStore.definePermission(i, function(name) { if(self[name] === undefined) return false; return self[name]; }); } }, check: function(perm) { return !this.isLicenseIssue && !this.isDisasterRecovery && !this.isShowcase && !this.isAgreement && !this.isAgreementPanel && !this.isDisableUI && !!this._permissions[perm]; }, get: function (prem) { var perms = {}; perms[consts.PERMISSIONS_HAS_ALL_PRIVILEGES] = {name:lang.t("Has All Privileges"),description:'',warning:lang.t("WARNING: Same as granting root access!")}; perms[consts.PERMISSIONS_CAN_MANAGE_ACCOUNTS] = {name:lang.t("Can Manage Accounts"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_RESTORE_BACKUPS] = {name:lang.t("Can Restore Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_DOWNLOAD_BACKUPS] = {name:lang.t("Can Download Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_FULL_BACKUPS] = {name:lang.t("Can Manage Full Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_FILE_BACKUPS] = {name:lang.t("Can Manage File Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_CRON_BACKUPS] = {name:lang.t("Can Manage Cron Job Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_EMAIL_BACKUPS] = {name:lang.t("Can Manage Email Account Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_DATABASE_BACKUPS] = {name:lang.t("Can Manage Database Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_SSL_BACKUPS] = {name:lang.t("Can Manage SSL Certificate Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_DNSZONES_BACKUPS] = {name:lang.t("Can Manage Domain Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_CONFIG_BACKUPS] = {name:lang.t("Can Manage Configuration Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_BACKUP_JOBS] = {name:lang.t("Can Manage Backup Jobs"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_CLONE_JOBS] = {name:lang.t("Can Manage Clone Jobs"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_DESTINATIONS] = {name:lang.t("Can Manage Destinations"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_HOOKS] = {name:lang.t("Can Manage Hooks"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_PERMISSIONS] = {name:lang.t("Can Manage Permissions"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_VIEW_LOGS] = {name:lang.t("Can View Logs"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_LOGS] = {name:lang.t("Can Manage Logs"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_VIEW_ALERTS] = {name:lang.t("Can View Alerts"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_DIRECTORY_BACKUPS] = {name:lang.t("Can Manage Directory Backups"),description:'',warning:lang.t("WARNING: Enabling this permission will give the ability to restore/download files that were backed up in any directory backup job and may contain sensitive information")}; perms[consts.PERMISSIONS_CAN_MANAGE_DISASTER_RECOVERY_BACKUPS] = {name:lang.t("Can Manage Server Backups (BMR)"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_MANAGE_FTP_BACKUPS] = {name:lang.t("Can Manage FTP Account Backups"),description:'',warning:''}; perms[consts.PERMISSIONS_CAN_ACCESS_SOCKET_API] = {name:lang.t("Can Access Socket API"),description:'',warning:''}; return perms[prem] !== undefined ? perms[prem] : null; } }; return new PERMISSIONS(); }]); }); define('services/popup',[ 'app' ], function (app) { app.factory('popup', ["$rootScope", "$uibModal", "lang", "popupPosition", function($rootScope, $uibModal, lang, popupPosition) { var popup = function(options) { this._init(options); }; popup.prototype = { _options: {}, _init: function (options) { this._options = options; }, open: function () { if(this._options.size === undefined) this._options.size = 'md'; if(this._options.resolve === undefined) this._options.resolve = {}; if(this._options.template === undefined) this._options.template = ''; if(this._options.templateViews === undefined) this._options.templateViews = ''; if(this._options.noController === undefined) this._options.noController = false; if(this._options.controller === undefined) this._options.controller = ''; if(this._options.scope === undefined) this._options.scope = $rootScope; var modal = $uibModal.open({ animation: true, size: this._options.size, ariaLabelledBy: 'modal-title', ariaDescribedBy: 'modal-body', templateUrl: $rootScope.includePath(this._options.template, this._options.templateViews), controller: this._options.noController ? null : (this._options.controller ? this._options.controller : this._options.template), scope: this._options.scope, resolve: this._options.resolve }); modal.opened.then(function () { popupPosition.update(); }); return modal; } }; return { open: function (options) { var i = new popup(options); return i.open(); } }; }]); }); define('services/popupPosition',[ 'app' ], function (app) { app.factory('popupPosition', [function() { var popupPosition = function() { this._init(); }; popupPosition.prototype = { _window: window, _offset: 0, _position: 0, _iframe: false, _listener_state: undefined, _listener_funcs: { window: undefined }, _init: function() { this._calculate(); }, _calculate: function () { this._calculateWindow(); this._listener(); }, _calculateWindow: function () { var self = this; self._window = window; self._offset = 0; self._iframe = false; while(true) { var src = self._window.location.href; var newParent = self._window.parent; try { if(newParent === undefined || newParent === self._window || newParent.document === false) break; } catch (e) { break; } self._iframe = true; var iframes = newParent.document.getElementsByTagName('iframe'); self._window = newParent; for (var i = 0; i < iframes.length; i++) { var iframe = iframes[i]; if (iframe.src.substr(0, iframe.src.indexOf('?')) !== src.substr(0, src.indexOf('?'))) continue; var top = iframe.getBoundingClientRect().top; var scrollY = self._window.scrollY; if(self._window.popupPosition !== undefined) { var popupPosition = self._window.popupPosition; if(popupPosition.id !== undefined) { var element = self._window.document.getElementById(popupPosition.id); if(element !== undefined) { top -= element.getBoundingClientRect().top; scrollY = element.scrollTop; } } } self._offset += scrollY + top; break; } } self._window.onresize = function () { self._calculate(); }; }, _listener: function () { if(!this.insideIframe()) return; var self = this; var state = (self._window.popupPosition !== undefined && self._window.popupPosition.id !== undefined) ? self._window.popupPosition.id : 'window'; if( self._listener_state && self._listener_state === state && self._listener_funcs[state] !== undefined ) return; var func = undefined; var listener = undefined; if(self._window.popupPosition !== undefined) { var popupPosition = self._window.popupPosition; if(popupPosition.id !== undefined) { var element = self._window.document.getElementById(popupPosition.id); if(element !== undefined) { func = function () { var offset = popupPosition.offset !== undefined ? popupPosition.offset : 0; self._scroll(element.scrollTop + offset); }; listener = element; } } } else { func = function () { self._scroll(self._window.scrollY); }; listener = self._window; } self._listener_state = state; self._listener_funcs[state] = func; if(listener !== undefined) listener.addEventListener("scroll", func); }, _scroll: function (scrollY) { this._position = scrollY - this._offset; if(this._position < 0) this._position = 0; this.update(); }, update: function () { var self = this; self._calculate(); if(!self.insideIframe()) return; var alert = document.getElementById('alert-floating-container'); if(alert) alert.style.top = self._position + "px"; var modalElements = document.getElementsByClassName('modal'); if(modalElements) for(var i = 0; i < modalElements.length; i++) modalElements[i].style.top = self._position + "px"; }, insideIframe: function () { return !!this._iframe; } }; return new popupPosition(); }]); }); define('services/consts',[ 'app' ], function (app) { app.factory('consts', ["lang", function(lang) { var consts = { DOCS_URL: "https://docs.jetbackup.com/v5.3", CHANGELOG_URL: "https://changelog.jetbackup.com", REQUEST_URL: "https://request.jetapps.com", FORUM_URL: "https://forum.jetapps.com", BLOG_URL: "https://blog.jetapps.com", ACCOUNT_FILTER_TYPE_ACCOUNT: 1<<1, ACCOUNT_FILTER_TYPE_OWNEDBY: 1<<2, ACCOUNT_FILTER_TYPE_SUSPENSION: 1<<3, ACCOUNT_FILTER_TYPE_DISK_USAGE: 1<<4, ACCOUNT_FILTER_TYPE_INODE_USAGE: 1<<5, ACCOUNT_FILTER_TYPE_PACKAGE: 1<<6, ACCOUNT_FILTER_TYPE_RANGE: 1<<7, ACCOUNT_FILTER_TYPE_REGEX: 1<<8, ACCOUNT_FILTER_TYPE_ACCOUNT_TAG: 1<<9, ACCOUNT_FILTER_TYPE_ENCRYPTION: 1<<10, ACCOUNT_FILTER_TYPE_RESELLER: 1<<11, ACCOUNT_FILTER_CONDITION_INCLUDE: 1, ACCOUNT_FILTER_CONDITION_EXCLUDE: 2, SCHEDULE_DELAY_TYPE_MINUTES: 1, SCHEDULE_DELAY_TYPE_HOURS: 2, SCHEDULE_DELAY_TYPE_DAYS: 3, ACCOUNT_BACKUP_OPTION_EMAIL_STRUCTURE_ONLY: 1, ACCOUNT_BACKUP_OPTION_EMAIL_INCLUDE_JUNK: 2, ACCOUNT_BACKUP_OPTION_EXCLUDE_DATABASES: 4, ACCOUNT_PACKAGE_TYPE_USER: 1, ACCOUNT_PACKAGE_TYPE_RESELLER: 2, SCHEDULE_WEEK_DAYS_SUNDAY: 1, SCHEDULE_WEEK_DAYS_MONDAY: 2, SCHEDULE_WEEK_DAYS_TUESDAY: 3, SCHEDULE_WEEK_DAYS_WEDNESDAY: 4, SCHEDULE_WEEK_DAYS_THURSDAY: 5, SCHEDULE_WEEK_DAYS_FRIDAY: 6, SCHEDULE_WEEK_DAYS_SATURDAY: 7, SCHEDULE_TYPE_HOURLY: 1, SCHEDULE_TYPE_DAILY: 2, SCHEDULE_TYPE_WEEKLY: 3, SCHEDULE_TYPE_MONTHLY: 4, SCHEDULE_TYPE_BACKUP_DONE: 5, SCHEDULE_TYPE_CLONE_DONE: 10, SCHEDULE_TYPE_MANUALLY: 8, SCHEDULE_TYPE_SNAPSHOT: 9, SCHEDULE_TYPE_MONTHLY_SUFFIX: ['th', 'st', 'nd', 'rd', 'th', 'th', 'th', 'th', 'th', 'th'], QUEUE_ITEM_TYPE_BACKUP: 1<<0, QUEUE_ITEM_TYPE_RESTORE: 1<<1, QUEUE_ITEM_TYPE_DOWNLOAD: 1<<2, QUEUE_ITEM_TYPE_REINDEX: 1<<3, QUEUE_ITEM_TYPE_CLONE: 1<<4, QUEUE_ITEM_TYPE_SECURITY: 1<<5, QUEUE_ITEM_TYPE_INTEGRITY_CHECK: 1<<6, QUEUE_ITEM_TYPE_SNAPSHOT_DELETE: 1<<7, QUEUE_ITEM_TYPE_EXTENSION_INSTALLATION: 1<<8, QUEUE_ITEM_TYPE_EXTENSION_QUEUE: 1<<9, QUEUE_STATUS_PENDING: 1, QUEUE_STATUS_PROCESSING: 2, // Backup Account Statuses QUEUE_STATUS_BACKUP_ACCOUNT_CONFIG: 30, QUEUE_STATUS_BACKUP_ACCOUNT_DOMAINS: 31, QUEUE_STATUS_BACKUP_ACCOUNT_CERTIFICATES: 32, QUEUE_STATUS_BACKUP_ACCOUNT_FTP: 33, QUEUE_STATUS_BACKUP_ACCOUNT_CRON_JOBS: 34, QUEUE_STATUS_BACKUP_ACCOUNT_DATABASES: 35, QUEUE_STATUS_BACKUP_ACCOUNT_DATABASE_USERS: 36, QUEUE_STATUS_BACKUP_ACCOUNT_HOMEDIR: 37, QUEUE_STATUS_BACKUP_ACCOUNT_EMAILS: 38, QUEUE_STATUS_BACKUP_ACCOUNT_ENCRYPTING: 39, QUEUE_STATUS_BACKUP_ACCOUNT_TRANSFERRING: 40, // Backup Directories Statuses QUEUE_STATUS_BACKUP_DIRECTORY_ENCRYPTING: 50, QUEUE_STATUS_BACKUP_DIRECTORY_TRANSFERRING: 51, // Backup JBConfig Statuses QUEUE_STATUS_BACKUP_JBCONFIG_ENCRYPTION_KEY: 60, QUEUE_STATUS_BACKUP_JBCONFIG_DATABASE: 61, QUEUE_STATUS_BACKUP_JBCONFIG_FILES: 62, QUEUE_STATUS_BACKUP_JBCONFIG_ACCOUNTS_LIST: 63, QUEUE_STATUS_BACKUP_JBCONFIG_VERSION: 64, QUEUE_STATUS_BACKUP_JBCONFIG_ENCRYPTING: 65, QUEUE_STATUS_BACKUP_JBCONFIG_TRANSFERRING: 66, // Restore Account Statuses QUEUE_STATUS_RESTORE_ACCOUNT_CONFIG: 30, QUEUE_STATUS_RESTORE_ACCOUNT_DOMAINS: 31, QUEUE_STATUS_RESTORE_ACCOUNT_CERTIFICATES: 32, QUEUE_STATUS_RESTORE_ACCOUNT_FTP: 33, QUEUE_STATUS_RESTORE_ACCOUNT_CRON_JOBS: 34, QUEUE_STATUS_RESTORE_ACCOUNT_IMPORTING_DATABASES: 35, QUEUE_STATUS_RESTORE_ACCOUNT_DATABASES: 36, QUEUE_STATUS_RESTORE_ACCOUNT_DATABASE_USERS: 37, QUEUE_STATUS_RESTORE_ACCOUNT_HOMEDIR: 38, QUEUE_STATUS_RESTORE_ACCOUNT_EMAILS: 39, QUEUE_STATUS_RESTORE_ACCOUNT_POST_RESTORE: 40, QUEUE_STATUS_RESTORE_ACCOUNT_PRE_RESTORE: 41, // Restore Directories Statuses QUEUE_STATUS_RESTORE_DIRECTORY_FILES: 50, // Restore JBConfig Statuses QUEUE_STATUS_RESTORE_JBCONFIG_DOWNLOADING: 60, QUEUE_STATUS_RESTORE_JBCONFIG_EXTRACT: 61, QUEUE_STATUS_RESTORE_JBCONFIG_DATABASE: 62, QUEUE_STATUS_RESTORE_JBCONFIG_MIGRATE_OWNER: 63, QUEUE_STATUS_RESTORE_JBCONFIG_PLUGINS: 64, QUEUE_STATUS_RESTORE_JBCONFIG_CONFIGS: 65, // Restore Server Backup (BMR) Statuses QUEUE_STATUS_BACKUP_DR_DATABASE: 70, QUEUE_STATUS_BACKUP_DR_ISO: 71, QUEUE_STATUS_BACKUP_DR_ENCRYPTING: 72, QUEUE_STATUS_BACKUP_DR_TRANSFERRING: 73, // Clone Account Statuses QUEUE_STATUS_CLONE_ACCOUNT_PACKAGE: 30, QUEUE_STATUS_CLONE_ACCOUNT_CLONING: 31, // Download Statuses QUEUE_STATUS_DOWNLOAD_DOWNLOADING: 30, QUEUE_STATUS_DOWNLOAD_ARCHIVE: 31, // QUEUE_STATUS_COMPLETED: 100, QUEUE_STATUS_PARTIALLY: 101, QUEUE_STATUS_FAILED: 102, QUEUE_STATUS_ABORTED: 103, QUEUE_STATUS_NEVER_FINISHED: 104, FILE_PERMISSIONS_CATEGORY_HOMEDIR_DATA: 1, FILE_PERMISSIONS_CATEGORY_EMAIL_DATA: 2, FILE_PERMISSIONS_CATEGORY_FILESYSTEM_DATA: 3, ALERT_LEVEL_INFO: 1<<0, ALERT_LEVEL_WARNING: 1<<1, ALERT_LEVEL_CRITICAL: 1<<2, NOTIFICATION_FREQUENCY_REALTIME: 1, NOTIFICATION_FREQUENCY_ONCEADAY: 2, PLUGIN_PERMISSION_ROOT: 1<<0, PLUGIN_PERMISSION_RESELLER: 1<<1, PLUGIN_PERMISSION_USER: 1<<2, PLUGIN_TYPE_DESTINATION: 'destination', PLUGIN_TYPE_NOTIFICATION: 'notification', PLUGIN_TYPE_SECURITY: 'security', PLUGIN_TYPE_ADDON: 'addon', DESTINATION_JOB_TYPE_BACKUP: 1<<0, DESTINATION_JOB_TYPE_CLONE: 1<<1, // Permissions PERMISSIONS_HAS_ALL_PRIVILEGES: 0, PERMISSIONS_CAN_MANAGE_ACCOUNTS: 1, PERMISSIONS_CAN_RESTORE_BACKUPS: 2, PERMISSIONS_CAN_DOWNLOAD_BACKUPS: 3, PERMISSIONS_CAN_MANAGE_FULL_BACKUPS: 4, PERMISSIONS_CAN_MANAGE_FILE_BACKUPS: 5, PERMISSIONS_CAN_MANAGE_CRON_BACKUPS: 6, PERMISSIONS_CAN_MANAGE_EMAIL_BACKUPS: 7, PERMISSIONS_CAN_MANAGE_DATABASE_BACKUPS: 8, PERMISSIONS_CAN_MANAGE_SSL_BACKUPS: 9, PERMISSIONS_CAN_MANAGE_DNSZONES_BACKUPS: 10, PERMISSIONS_CAN_MANAGE_CONFIG_BACKUPS: 11, PERMISSIONS_CAN_MANAGE_BACKUP_JOBS: 12, PERMISSIONS_CAN_MANAGE_CLONE_JOBS: 21, PERMISSIONS_CAN_MANAGE_DESTINATIONS: 13, PERMISSIONS_CAN_MANAGE_HOOKS: 14, PERMISSIONS_CAN_MANAGE_PERMISSIONS: 15, PERMISSIONS_CAN_VIEW_LOGS: 16, PERMISSIONS_CAN_MANAGE_LOGS: 17, PERMISSIONS_CAN_VIEW_ALERTS: 18, PERMISSIONS_CAN_MANAGE_DIRECTORY_BACKUPS: 19, PERMISSIONS_CAN_MANAGE_DISASTER_RECOVERY_BACKUPS: 22, PERMISSIONS_CAN_MANAGE_FTP_BACKUPS: 20, PERMISSIONS_CAN_ACCESS_SOCKET_API: 23, // Accounts CLONE_TYPE_ACCOUNT: 1, CLONE_TYPE_ACCOUNT_CONFIG: 1<<0, CLONE_TYPE_ACCOUNT_HOMEDIR: 1<<1, CLONE_TYPE_ACCOUNT_DATABASES: 1<<2, CLONE_TYPE_ACCOUNT_EMAILS: 1<<3, CLONE_TYPE_ACCOUNT_CRON_JOBS: 1<<4, CLONE_TYPE_ACCOUNT_DOMAINS: 1<<5, CLONE_TYPE_ACCOUNT_CERTIFICATES: 1<<6, CLONE_TYPE_ACCOUNT_DATABASE_USERS: 1<<7, CLONE_TYPE_ACCOUNT_FTP: 1<<8, // Accounts BACKUP_TYPE_ACCOUNT: 1, BACKUP_TYPE_ACCOUNT_CONFIG: 1<<0, BACKUP_TYPE_ACCOUNT_HOMEDIR: 1<<1, BACKUP_TYPE_ACCOUNT_DATABASES: 1<<2, BACKUP_TYPE_ACCOUNT_EMAILS: 1<<3, BACKUP_TYPE_ACCOUNT_CRON_JOBS: 1<<4, BACKUP_TYPE_ACCOUNT_DOMAINS: 1<<5, BACKUP_TYPE_ACCOUNT_CERTIFICATES: 1<<6, BACKUP_TYPE_ACCOUNT_DATABASE_USERS: 1<<7, BACKUP_TYPE_ACCOUNT_FTP: 1<<8, // Directories BACKUP_TYPE_DIRECTORY: 2, BACKUP_TYPE_DIRECTORY_FILES: 1<<0, BACKUP_TYPE_DIRECTORY_DIRS: 1<<1, // JB Config BACKUP_TYPE_JB_CONFIG: 3, BACKUP_TYPE_JB_CONFIG_DATABASE: 1<<0, BACKUP_TYPE_JB_CONFIG_ETC: 1<<1, BACKUP_TYPE_JB_CONFIG_VERSION: 1<<2, BACKUP_TYPE_JB_CONFIG_ACCOUNTS: 1<<3, BACKUP_TYPE_JB_CONFIG_ENCRYPTION: 1<<4, BACKUP_TYPE_JB_CONFIG_WIREDTIGER: 1<<5, // Server Backup (BMR) BACKUP_TYPE_DR: 4, BACKUP_TYPE_DR_DATABASE: 1<<0, BACKUP_TYPE_DR_ISO: 1<<1, BACKUP_TYPE_DR_FILES: 1<<2, BACKUP_STRUCTURE_INCREMENTAL: 1<<0, BACKUP_STRUCTURE_ARCHIVED: 1<<1, BACKUP_STRUCTURE_COMPRESSED: 1<<2, HOOK_POSITION_BACKUP: 1, HOOK_POSITION_RESTORE: 3, HOOK_POSITION_DOWNLOAD: 4, HOOK_POSITION_REINDEX: 5, HOOK_POSITION_SNAPSHOT: 6, HOOK_POSITION_BACKUP_ACCOUNT: 8, HOOK_POSITION_CLONE: 9, HOOK_POSITION_CLONE_ACCOUNT: 10, DATABASE_ENGINE_MYSQL: 1, DATABASE_ENGINE_MONGODB: 2, DATABASE_ENGINE_PGSQL: 3, HOOK_TYPE_POSITION_PRE: 1, HOOK_TYPE_POSITION_POST: 2, TAG_TYPE_ACCOUNT: 1, LOG_TYPE_BACKUP: 1, LOG_TYPE_DOWNLOAD: 2, LOG_TYPE_RESTORE: 3, LOG_TYPE_SYSTEM: 4, LOG_TYPE_REINDEX: 5, LOG_TYPE_BACKUP_ON_DEMAND: 6, LOG_TYPE_CLONE: 7, LOG_TYPE_SECURITY: 8, LOG_TYPE_EXTENSION: 9, LOG_STATUS_COMPLETED: 1, LOG_STATUS_FAILED: 2, LOG_STATUS_ABORTED: 3, LOG_STATUS_PARTIALLY: 4, LOG_STATUS_NEVER_FINISHED: 5, LOG_STATUS_PROCESSING: 6, RECOMMENDED_EXCLUDES_ACCOUNT: { 'basic': [ '*.bkup','*.gz','*.jpa','*.log','*.sql','*.tar','*.tar.gz','*.wpress','*.zip','*/.wysiwygPro_*', '*/backupbuddy_backups/*','*/cache/smarty/*','*/com_akeeba/backup/*','*/core.[0-9]*','*/error_log', '*/var/amasty_fpc/*','*/var/backups/*','*/var/cache/*','*/var/debug/*','*/var/export/*','*/var/import/*', '*/var/log/*','*/var/report/*','*/var/session/*','*/var/tmp/*','*/wp-content/cache/*', '*/wp-content/wphb-cache/*','*/wp-content/uploads/wpcf7_captcha/*','*/wp-content/widget-cache/*', '*/wptsc-cachedir/*','.MirrorSearch','.cpanel/*.sock','.trash','access-logs/*','backup-*.tar.gz', 'logs/*','public_ftp/*','public_html/cache/*','site-*.tar.gz','softaculous_backups/*','tmp/*','lscache/*' ], 'presta': [ '*-large_default.jpg','*-home_default.jpg','*-medium_default.jpg','*-small_default.jpg','*-cart_default.jpg','*-home_default.jpg', '*-thickbox_default.jpg','*-search_default.jpg','public_html/img/**/index.php','**/fileType','**/cache/cachefs/**' ], 'wp': [ '*/wp-content/cache/*','*/wp-content/wphb-cache/*','*/wp-content/uploads/wpcf7_captcha/*','*/wp-content/widget-cache/*', '*/wptsc-cachedir/*','*/backupbuddy_backups/*','*/cache/smarty/*','wp-content/w3tc-cache/*','wp-content/uploads/cache/*', 'wp-content/uploads/wp-rocket/*','wp-content/uploads/wpo-cache/*','wp-content/uploads/wpo-minify/*','wp-content/wflogs/*', 'wp-content/updraft/*','wp-content/uploads/jetbackup/*', '*.sgbp', 'wp-content/uploads/wp-rocket/' ], 'moodle': [ 'moodledata/localcache/*','moodledata/sessions/*','moodledata/temp/*','moodledata/trashdir/*','cache/cachestore_file/*' ], 'magento': [ 'media/catalog/product/cache/*','public_html/var/page_cache/*','public_html/var/view_preprocessed/*', 'public_html/var/session/*','public_html/var/report/*','public_html/generated/*','**/var/cache/mage-tags/*' ], }, PATH_FILTER: /(^[^\/])|(((\/+|^)\.{2})+(\/+|$)|\/{2,})|([`:;\\!$&*()])/, PATH_FILTER_PATTERNS: /(((\/+|^)\.{2})+(\/+|$)|\/{2,})|([`:;\\!$&()])/ }; consts.DOCS_ADMIN_URL = consts.DOCS_URL + "/adminpanel"; consts.DOCS_USER_URL = consts.DOCS_URL + "/userpanel"; consts.ALERT_LEVEL_NAMES = {}; consts.ALERT_LEVEL_NAMES[consts.ALERT_LEVEL_INFO] = lang.t("Information"); consts.ALERT_LEVEL_NAMES[consts.ALERT_LEVEL_WARNING] = lang.t("Warning"); consts.ALERT_LEVEL_NAMES[consts.ALERT_LEVEL_CRITICAL] = lang.t("Critical"); consts.ALERT_LEVEL_TYPES = {}; consts.ALERT_LEVEL_TYPES[consts.ALERT_LEVEL_INFO] = 'information'; consts.ALERT_LEVEL_TYPES[consts.ALERT_LEVEL_WARNING] = 'warning'; consts.ALERT_LEVEL_TYPES[consts.ALERT_LEVEL_CRITICAL] = 'critical'; consts.LOG_TYPE_NAMES = {}; consts.LOG_TYPE_NAMES[consts.LOG_TYPE_BACKUP] = lang.t("Backup"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_CLONE] = lang.t("Clone"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_DOWNLOAD] = lang.t("Download"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_RESTORE] = lang.t("Restore"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_REINDEX] = lang.t("Reindex"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_SECURITY] = lang.t("Security"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_SYSTEM] = lang.t("System"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_BACKUP_ON_DEMAND] = lang.t("Backup on Demand"); consts.LOG_TYPE_NAMES[consts.LOG_TYPE_EXTENSION] = lang.t("Wordpress Installation"); consts.LOG_STATUS_NAMES = {}; consts.LOG_STATUS_NAMES[consts.LOG_STATUS_COMPLETED] = lang.t("Completed"); consts.LOG_STATUS_NAMES[consts.LOG_STATUS_FAILED] = lang.t("Failed"); consts.LOG_STATUS_NAMES[consts.LOG_STATUS_ABORTED] = lang.t("Aborted"); consts.LOG_STATUS_NAMES[consts.LOG_STATUS_PARTIALLY] = lang.t("Partially Completed"); consts.LOG_STATUS_NAMES[consts.LOG_STATUS_NEVER_FINISHED] = lang.t("Never Finished"); consts.LOG_STATUS_NAMES[consts.LOG_STATUS_PROCESSING] = lang.t("Processing"); consts.DATABASE_ENGINE_NAMES = {}; consts.DATABASE_ENGINE_NAMES[consts.DATABASE_ENGINE_MYSQL] = lang.t("MySQL"); consts.DATABASE_ENGINE_NAMES[consts.DATABASE_ENGINE_MONGODB] = lang.t("MongoDB"); consts.DATABASE_ENGINE_NAMES[consts.DATABASE_ENGINE_PGSQL] = lang.t("PostgreSQL"); consts.QUEUE_STATUS_TO_LOG = {}; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_COMPLETED] = consts.LOG_STATUS_COMPLETED; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_FAILED] = consts.LOG_STATUS_FAILED; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_ABORTED] = consts.LOG_STATUS_ABORTED; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_PARTIALLY] = consts.LOG_STATUS_PARTIALLY; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_NEVER_FINISHED] = consts.LOG_STATUS_NEVER_FINISHED; consts.QUEUE_STATUS_TO_LOG[consts.QUEUE_STATUS_PROCESSING] = consts.LOG_STATUS_PROCESSING; consts.DESTINATION_JOB_TYPE_NAMES = {}; consts.DESTINATION_JOB_TYPE_NAMES[consts.DESTINATION_JOB_TYPE_BACKUP] = lang.t("Backup"); consts.DESTINATION_JOB_TYPE_NAMES[consts.DESTINATION_JOB_TYPE_CLONE] = lang.t("Clone"); consts.BACKUP_STRUCTURE_NAMES = {}; consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_INCREMENTAL] = lang.t("Incremental"); consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_ARCHIVED] = lang.t("Archived"); consts.BACKUP_STRUCTURE_NAMES[consts.BACKUP_STRUCTURE_COMPRESSED] = lang.t("Compressed"); consts.ACCOUNT_FILTER_TYPE_NAMES = {}; consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_ACCOUNT] = lang.t("Accounts Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_ACCOUNT_TAG] = lang.t("Account Tags Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_OWNEDBY] = lang.t("Owned By Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_RESELLER] = lang.t("Resellers Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_SUSPENSION] = lang.t("Suspension Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_DISK_USAGE] = lang.t("Disk Space Usage Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_INODE_USAGE] = lang.t("Inodes Usage Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_PACKAGE] = lang.t("Packages Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_RANGE] = lang.t("Characters Range Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_REGEX] = lang.t("Regular Expression Filter"); consts.ACCOUNT_FILTER_TYPE_NAMES[consts.ACCOUNT_FILTER_TYPE_ENCRYPTION] = lang.t("Encryption Filter"); consts.BACKUP_ITEMS_TEXT = {}; consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = lang.t("Panel Config"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR] = lang.t("Home Dir Files"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_DATABASES] = lang.t("\"%s\" Database"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_EMAILS] = lang.t("\"%s\" Email Account"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS] = lang.t("Cron Jobs"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_DOMAINS] = lang.t("\"%s\" Domains"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES] = lang.t("\"%s\" SSL Certificate"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS] = lang.t("\"%s\" Database User"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_FTP] = lang.t("\"%s\" FTP Account"); consts.BACKUP_ITEMS_TEXT[consts.BACKUP_TYPE_ACCOUNT_FULL] = lang.t("Full Account"); consts.BACKUP_DIRECTORY_ITEMS_TEXT = {}; consts.BACKUP_DIRECTORY_ITEMS_TEXT[consts.BACKUP_TYPE_DIRECTORY_FILES] = lang.t("File \"%s\""); consts.BACKUP_DIRECTORY_ITEMS_TEXT[consts.BACKUP_TYPE_DIRECTORY_DIRS] = lang.t("Directory \"%s\""); consts.BACKUP_DR_ITEMS_TEXT = {}; consts.BACKUP_DR_ITEMS_TEXT[consts.BACKUP_TYPE_DR_DATABASE] = lang.t("Database \"%s\""); consts.BACKUP_DR_ITEMS_TEXT[consts.BACKUP_TYPE_DR_ISO] = lang.t("ISO Image \"%s\""); consts.BACKUP_DR_ITEMS_TEXT[consts.BACKUP_TYPE_DR_FILES] = lang.t("Files \"%s\""); consts.BACKUP_TYPE_NAMES = {}; consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_ACCOUNT] = lang.t("Accounts"); consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_DIRECTORY] = lang.t("Directories"); consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_JB_CONFIG] = lang.t("JB Config"); consts.BACKUP_TYPE_NAMES[consts.BACKUP_TYPE_DR] = lang.t("Server Backup (BMR)"); consts.BACKUP_TYPE_ACCOUNT_FULL = consts.BACKUP_TYPE_ACCOUNT_CONFIG | consts.BACKUP_TYPE_ACCOUNT_HOMEDIR | consts.BACKUP_TYPE_ACCOUNT_DATABASES | consts.BACKUP_TYPE_ACCOUNT_EMAILS | consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS | consts.BACKUP_TYPE_ACCOUNT_DOMAINS | consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES | consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS | consts.BACKUP_TYPE_ACCOUNT_FTP; consts.BACKUP_TYPE_ACCOUNT_NAMES = {}; consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = lang.t("Panel Config"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR] = lang.t("Home Dir Files"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASES] = lang.t("Databases"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_EMAILS] = lang.t("Email Accounts"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS] = lang.t("Cron Jobs"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DOMAINS] = lang.t("Domains"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES] = lang.t("SSL Certificates"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS] = lang.t("Database Users"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FTP] = lang.t("FTP Accounts"); consts.BACKUP_TYPE_ACCOUNT_NAMES[consts.BACKUP_TYPE_ACCOUNT_FULL] = lang.t("Full Account"); consts.CLONE_ITEMS_TEXT = {}; consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_CONFIG] = lang.t("Panel Config"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_HOMEDIR] = lang.t("Home Dir Files"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_DATABASES] = lang.t("\"%s\" Database"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_EMAILS] = lang.t("\"%s\" Email Account"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_CRON_JOBS] = lang.t("Cron Jobs"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_DOMAINS] = lang.t("\"%s\" Domains"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_CERTIFICATES] = lang.t("\"%s\" SSL Certificate"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_DATABASE_USERS] = lang.t("\"%s\" Database User"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_FTP] = lang.t("\"%s\" FTP Account"); consts.CLONE_ITEMS_TEXT[consts.CLONE_TYPE_ACCOUNT_FULL] = lang.t("Full Account"); consts.CLONE_TYPE_NAMES = {}; consts.CLONE_TYPE_NAMES[consts.CLONE_TYPE_ACCOUNT] = lang.t("Accounts"); consts.CLONE_TYPE_ACCOUNT_FULL = consts.CLONE_TYPE_ACCOUNT_CONFIG | consts.CLONE_TYPE_ACCOUNT_HOMEDIR | consts.CLONE_TYPE_ACCOUNT_DATABASES | consts.CLONE_TYPE_ACCOUNT_EMAILS | consts.CLONE_TYPE_ACCOUNT_CRON_JOBS | consts.CLONE_TYPE_ACCOUNT_DOMAINS | consts.CLONE_TYPE_ACCOUNT_CERTIFICATES | consts.CLONE_TYPE_ACCOUNT_DATABASE_USERS | consts.CLONE_TYPE_ACCOUNT_FTP; consts.CLONE_TYPE_ACCOUNT_NAMES = {}; consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CONFIG] = lang.t("Panel Config"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_HOMEDIR] = lang.t("Home Dir Files"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASES] = lang.t("Databases"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_EMAILS] = lang.t("Email Accounts"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CRON_JOBS] = lang.t("Cron Jobs"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DOMAINS] = lang.t("Domains"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_CERTIFICATES] = lang.t("SSL Certificates"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_DATABASE_USERS] = lang.t("Database Users"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_FTP] = lang.t("FTP Accounts"); consts.CLONE_TYPE_ACCOUNT_NAMES[consts.CLONE_TYPE_ACCOUNT_FULL] = lang.t("Full Account"); consts.SCHEDULE_TYPES = {}; consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_HOURLY] = lang.t("Hourly"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_DAILY] = lang.t("Daily"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_WEEKLY] = lang.t("Weekly"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_MONTHLY] = lang.t("Monthly"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_BACKUP_DONE] = lang.t("Backup Done"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_MANUALLY] = lang.t("Manually"); consts.SCHEDULE_TYPES[consts.SCHEDULE_TYPE_SNAPSHOT] = lang.t("Backup on Demand"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD = {}; consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CONFIG] = lang.t("Panel Config"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_HOMEDIR] = lang.t("Home Dir"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DATABASES] = lang.t("DB"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_EMAILS] = lang.t("Emails"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CRON_JOBS] = lang.t("Cron Jobs"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DOMAINS] = lang.t("Domains"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_CERTIFICATES] = lang.t("Certificates"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_DATABASE_USERS] = lang.t("DB Users"); consts.BACKUP_TYPE_ACCOUNT_NAMES_WIZARD[consts.BACKUP_TYPE_ACCOUNT_FTP] = lang.t("FTP"); consts.QUEUE_ITEM_TYPE_NAMES = {}; consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP] = lang.t("Backup"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_CLONE] = lang.t("Clone"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE] = lang.t("Restore"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_DOWNLOAD] = lang.t("Download"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_REINDEX] = lang.t("Reindex"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_SECURITY] = lang.t("Security"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_INTEGRITY_CHECK] = lang.t("Backup Cleanup & Integrity Check"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_SNAPSHOT_DELETE] = lang.t("Snapshot Cleanup"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_EXTENSION_INSTALLATION] = lang.t("Wordpress Installation"); consts.QUEUE_ITEM_TYPE_NAMES[consts.QUEUE_ITEM_TYPE_EXTENSION_QUEUE] = lang.t("Wordpress Mass Deployment"); consts.SCHEDULE_DELAY_TYPE_NAMES = {}; consts.SCHEDULE_DELAY_TYPE_NAMES[consts.SCHEDULE_DELAY_TYPE_MINUTES] = lang.t("minutes"); consts.SCHEDULE_DELAY_TYPE_NAMES[consts.SCHEDULE_DELAY_TYPE_HOURS] = lang.t("hours"); consts.SCHEDULE_DELAY_TYPE_NAMES[consts.SCHEDULE_DELAY_TYPE_DAYS] = lang.t("days"); consts.QUEUE_STATUS_NAMES = {}; consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_PENDING] = lang.t("Pending"); consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_PROCESSING] = lang.t("Processing") + "..."; consts.QUEUE_STATUS_SUB_NAMES = {}; // Backup Account Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP] = {}; consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_CONFIG] = lang.t("Backing up Panel Configurations"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_DOMAINS] = lang.t("Backing up Domains and DNS"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_CERTIFICATES] = lang.t("Backing up SSL Certificates"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_FTP] = lang.t("Backing up FTP Accounts"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_CRON_JOBS] = lang.t("Backing up Cron Jobs"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_DATABASES] = lang.t("Backing up Databases"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_DATABASE_USERS] = lang.t("Backing up Database Users"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_HOMEDIR] = lang.t("Backing up Home Directory files"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_EMAILS] = lang.t("Backing up Email Accounts"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_ENCRYPTING] = lang.t("Encrypting backup data"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_ACCOUNT_TRANSFERRING] = lang.t("Transferring backup to all destinations"); // Backup Directories Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DIRECTORY_ENCRYPTING] = lang.t("Encrypting backup data"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DIRECTORY_TRANSFERRING] = lang.t("Transferring backup to all destinations"); // Backup JBConfig Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_ENCRYPTION_KEY] = lang.t("Backing up JetBackup server Encryption Key"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_DATABASE] = lang.t("Backing up JetBackup Database"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_FILES] = lang.t("Backing up JetBackup Files"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_ACCOUNTS_LIST] = lang.t("Backing up JetBackup Accounts list"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_VERSION] = lang.t("Backing up JetBackup Version"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_ENCRYPTING] = lang.t("Encrypting backup data"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_JBCONFIG_TRANSFERRING] = lang.t("Transferring backup to all destinations"); // Backup Server Backup (BMR) Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DR_DATABASE] = lang.t("Backing up JetBackup Database"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DR_ISO] = lang.t("Creating ISO image"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DR_ENCRYPTING] = lang.t("Encrypting backup data"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_BACKUP][consts.QUEUE_STATUS_BACKUP_DR_TRANSFERRING] = lang.t("Transferring backup to all destinations"); // Restore Account Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE] = {}; consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_CONFIG] = lang.t("Restoring Panel Configurations"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_DOMAINS] = lang.t("Restoring Domains and DNS"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_CERTIFICATES] = lang.t("Restoring SSL Certificates"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_FTP] = lang.t("Restoring FTP Accounts"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_CRON_JOBS] = lang.t("Restoring Cron Jobs"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_IMPORTING_DATABASES] = lang.t("Importing databases data"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_DATABASES] = lang.t("Restoring Databases"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_DATABASE_USERS] = lang.t("Restoring Database Users"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_HOMEDIR] = lang.t("Restoring Home Directory files"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_EMAILS] = lang.t("Restoring Email Accounts"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_POST_RESTORE] = lang.t("Performing post restore actions"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_ACCOUNT_PRE_RESTORE] = lang.t("Performing pre restore actions"); // Restore Directories Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_DIRECTORY_FILES] = lang.t("Downloading files"); // Restore JBConfig Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_DOWNLOADING] = lang.t("Downloading backup"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_EXTRACT] = lang.t("Extracting backup from archive"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_DATABASE] = lang.t("Restoring JetBackup database"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_MIGRATE_OWNER] = lang.t("Migrating objects owner"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_PLUGINS] = lang.t("Installing Plugins"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_RESTORE][consts.QUEUE_STATUS_RESTORE_JBCONFIG_CONFIGS] = lang.t("Restoring JetBackup configuration files"); // Clone AccountStatuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_CLONE] = {}; consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_CLONE][consts.QUEUE_STATUS_CLONE_ACCOUNT_PACKAGE] = lang.t("Packaging account databases and information"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_CLONE][consts.QUEUE_STATUS_CLONE_ACCOUNT_CLONING] = lang.t("Cloning to all destinations"); // Download Statuses consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_DOWNLOAD] = {}; consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_DOWNLOAD][consts.QUEUE_STATUS_DOWNLOAD_DOWNLOADING] = lang.t("Downloading backup"); consts.QUEUE_STATUS_SUB_NAMES[consts.QUEUE_ITEM_TYPE_DOWNLOAD][consts.QUEUE_STATUS_DOWNLOAD_ARCHIVE] = lang.t("Compressing backup to archive"); // consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_COMPLETED] = lang.t("Completed"); consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_PARTIALLY] = lang.t("Partially Completed"); consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_FAILED] = lang.t("Failed"); consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_ABORTED] = lang.t("Aborted"); consts.QUEUE_STATUS_NAMES[consts.QUEUE_STATUS_NEVER_FINISHED] = lang.t("Never Finished"); consts.SCHEDULE_WEEK_DAYS_NAMES = {}; consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_SUNDAY] = lang.t("Sunday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_MONDAY] = lang.t("Monday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_TUESDAY] = lang.t("Tuesday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_WEDNESDAY] = lang.t("Wednesday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_THURSDAY] = lang.t("Thursday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_FRIDAY] = lang.t("Friday"); consts.SCHEDULE_WEEK_DAYS_NAMES[consts.SCHEDULE_WEEK_DAYS_SATURDAY] = lang.t("Saturday"); consts.FILE_PERMISSIONS_CATEGORIES = {}; consts.FILE_PERMISSIONS_CATEGORIES[consts.FILE_PERMISSIONS_CATEGORY_HOMEDIR_DATA] = lang.t("Homedir Data"); consts.FILE_PERMISSIONS_CATEGORIES[consts.FILE_PERMISSIONS_CATEGORY_EMAIL_DATA] = lang.t("Email Data"); consts.FILE_PERMISSIONS_CATEGORIES[consts.FILE_PERMISSIONS_CATEGORY_FILESYSTEM_DATA] = lang.t("Filesystem Data"); consts.PLUGIN_PERMISSION_RESELLER = consts.PLUGIN_PERMISSION_ROOT | consts.PLUGIN_PERMISSION_RESELLER; consts.PLUGIN_PERMISSION_USER = consts.PLUGIN_PERMISSION_ROOT | consts.PLUGIN_PERMISSION_RESELLER | consts.PLUGIN_PERMISSION_USER; consts.BACKUP_TYPE_DIRECTORY_FULL = consts.BACKUP_TYPE_DIRECTORY_FILES | consts.BACKUP_TYPE_DIRECTORY_DIRS; consts.BACKUP_TYPE_DIRECTORY_NAMES = {}; consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FILES] = lang.t("Directories (File)"); consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_DIRS] = lang.t("Directories (Directory)"); consts.BACKUP_TYPE_DIRECTORY_NAMES[consts.BACKUP_TYPE_DIRECTORY_FULL] = lang.t("Directories"); consts.BACKUP_TYPE_JB_CONFIG_FULL = consts.BACKUP_TYPE_JB_CONFIG_DATABASE | consts.BACKUP_TYPE_JB_CONFIG_ETC | consts.BACKUP_TYPE_JB_CONFIG_VERSION | consts.BACKUP_TYPE_JB_CONFIG_ACCOUNTS | consts.BACKUP_TYPE_JB_CONFIG_ENCRYPTION | consts.BACKUP_TYPE_JB_CONFIG_WIREDTIGER; consts.BACKUP_TYPE_JB_CONFIG_NAMES = {}; consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_DATABASE] = lang.t("Database"); consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_ETC] = lang.t("ETC Directory"); consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_VERSION] = lang.t("Version File"); consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_ACCOUNTS] = lang.t("Active Accounts"); consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_ENCRYPTION] = lang.t("Encryption Key"); consts.BACKUP_TYPE_JB_CONFIG_NAMES[consts.BACKUP_TYPE_JB_CONFIG_FULL] = lang.t("JB Config"); consts.BACKUP_TYPE_DR_FULL = consts.BACKUP_TYPE_DR_DATABASE | consts.BACKUP_TYPE_DR_ISO | consts.BACKUP_TYPE_DR_FILES; consts.BACKUP_TYPE_DR_NAMES = {}; consts.BACKUP_TYPE_DR_NAMES[consts.BACKUP_TYPE_DR_DATABASE] = lang.t("Database"); consts.BACKUP_TYPE_DR_NAMES[consts.BACKUP_TYPE_DR_ISO] = lang.t("ISO image"); consts.BACKUP_TYPE_DR_NAMES[consts.BACKUP_TYPE_DR_FILES] = lang.t("Files"); consts.BACKUP_TYPE_DR_NAMES[consts.BACKUP_TYPE_DR_FULL] = lang.t("Server Backup (BMR)"); consts.BACKUP_ALLOW_LEGACY_DESTINATION = {}; consts.BACKUP_ALLOW_LEGACY_DESTINATION[consts.BACKUP_TYPE_ACCOUNT] = true; consts.BACKUP_ALLOW_LEGACY_DESTINATION[consts.BACKUP_TYPE_DIRECTORY] = true; consts.BACKUP_ALLOW_LEGACY_DESTINATION[consts.BACKUP_TYPE_JB_CONFIG] = true; consts.BACKUP_ALLOW_LEGACY_DESTINATION[consts.BACKUP_TYPE_DR] = false; consts.BACKUP_ALLOW_LOCAL_DESTINATION = {}; consts.BACKUP_ALLOW_LOCAL_DESTINATION[consts.BACKUP_TYPE_ACCOUNT] = true; consts.BACKUP_ALLOW_LOCAL_DESTINATION[consts.BACKUP_TYPE_DIRECTORY] = true; consts.BACKUP_ALLOW_LOCAL_DESTINATION[consts.BACKUP_TYPE_JB_CONFIG] = true; consts.BACKUP_ALLOW_LOCAL_DESTINATION[consts.BACKUP_TYPE_DR] = false; consts.BACKUP_ALLOW_TIME_BASED_DESTINATION = {}; consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[consts.BACKUP_TYPE_ACCOUNT] = true; consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[consts.BACKUP_TYPE_DIRECTORY] = true; consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[consts.BACKUP_TYPE_JB_CONFIG] = true; consts.BACKUP_ALLOW_TIME_BASED_DESTINATION[consts.BACKUP_TYPE_DR] = false; return consts; }]); }); define('services/util',[ 'app' ], function (app) { app.factory('util', [function() { var deepDiffMapper = function() { return { getChanges: function(original, current, removeParams, skipCallback) { if(original === undefined || current === undefined) return {}; if (!this.isObject(original) || !this.isObject(current)) throw 'Invalid argument. Function given, object expected.'; var changes = {}; for(var i in current) { if(removeParams !== undefined && removeParams.indexOf(i) >= 0) continue; if(i === '_id' || (skipCallback !== undefined && typeof skipCallback === 'function' && skipCallback(i))) changes[i] = current[i]; else if(this.changedValue(original[i], current[i])) changes[i] = current[i]; } return changes; }, isChanged: function(original, current, exclude) { if(original === undefined || current === undefined) return false; if (!this.isObject(original) || !this.isObject(current)) throw 'Invalid argument. Function given, object expected.'; for(var i in current) { if(exclude !== undefined && exclude.indexOf(i) >= 0) continue; if(this.changedValue(original[i], current[i])){ return true; } } return false; }, changedValue: function(original, current) { if (this.isFunction(original) || this.isFunction(current)) throw 'Invalid argument. Function given, object expected.'; if (this.isValue(current)) { if(/^object:[0-9]+$/.test(current)) return false; return original !== current; } var keys = {}; for (var ckey in current) { keys[ckey] = 1; if (this.isFunction(current[ckey])) continue; if(original === undefined || original[ckey] === undefined) return true; if(this.changedValue(original[ckey], current[ckey])) return true; } for (var okey in original) if(!keys[okey]) return true; return false; }, isFunction: function(obj) { return {}.toString.apply(obj) === '[object Function]'; }, isArray: function(obj) { return {}.toString.apply(obj) === '[object Array]'; }, isObject: function(obj) { return {}.toString.apply(obj) === '[object Object]'; }, isDate: function(obj) { return {}.toString.apply(obj) === '[object Date]'; }, isValue: function(obj) { return !this.isObject(obj) && !this.isArray(obj); } } }(); return { sizeToHumanReadable: function(bytes, si, decimals) { return (this.sizeToNumber(bytes, si, decimals) + " " + this.sizeToType(bytes, si)).trim(); }, sizeToNumber: function(bytes, si, decimals) { if(si === undefined) si = false; if(decimals === undefined) decimals = 2; var unit = si ? 1000 : 1024; if (bytes < unit) return bytes; var exp = parseInt(Math.log(bytes)/Math.log(unit)); return (bytes/Math.pow(unit, exp)).toFixed(decimals); }, sizeToType: function(bytes, si) { if(si === undefined) si = false; var unit = si ? 1000 : 1024; if (bytes < unit) return "B"; var exp = parseInt(Math.log(bytes)/Math.log(unit)); var pre = (si ? "kMGTPE" : "KMGTPE"); return pre[exp-1] + "B"; }, copyToClipboard: function (text) { var copyElement = document.createElement("textarea"); copyElement.style.position = 'fixed'; copyElement.style.opacity = '0'; copyElement.textContent = text; var body = document.getElementsByTagName('body')[0]; body.appendChild(copyElement); copyElement.select(); document.execCommand('copy'); body.removeChild(copyElement); }, countObj: function (obj) { var count = 0; for(var key in obj) count++; return count; }, saveParams: function (saveData, details, removeParams, skipCallback) { return deepDiffMapper.getChanges(details, saveData, removeParams, skipCallback); }, duplicateObject: function (obj) { return JSON.parse(JSON.stringify(obj)); }, isChanged: function(saveData, details, exclude) { return deepDiffMapper.isChanged(details, saveData, exclude); }, sleep: function(ms) { const date = Date.now(); var currentDate = null; do { currentDate = Date.now(); } while (currentDate - date < ms); }, versionCompare: function(v1, v2, options) { v1 = v1.replace('-', '.'); v2 = v2.replace('-', '.'); var lexicographical = options && options.lexicographical, zeroExtend = options && options.zeroExtend, v1parts = v1.split('.'), v2parts = v2.split('.'); function isValidPart(x) { return (lexicographical ? /^\d+[A-Za-z]*$/ : /^\d+$/).test(x); } if (!v1parts.every(isValidPart) || !v2parts.every(isValidPart)) { return NaN; } if (zeroExtend) { while (v1parts.length < v2parts.length) v1parts.push("0"); while (v2parts.length < v1parts.length) v2parts.push("0"); } if (!lexicographical) { v1parts = v1parts.map(Number); v2parts = v2parts.map(Number); } for (var i = 0; i < v1parts.length; ++i) { if (v2parts.length == i) { return 1; } if (v1parts[i] == v2parts[i]) { continue; } else if (v1parts[i] > v2parts[i]) { return 1; } else { return -1; } } if (v1parts.length != v2parts.length) { return -1; } return 0; } }; }]); }); define('services/filterManager',['app'], function (app) { app.factory('filterManager', function () { return { buildFilters: function(filtersStructure) { var arrangedFilters = []; // $scope.data.selectedFilters = []; var index = 0; for (var i = 0; i < filtersStructure.length; i++) { if (filtersStructure[i].cond !== undefined && filtersStructure[i].cond === 1) index++; if (arrangedFilters[index] === undefined) arrangedFilters[index] = []; arrangedFilters[index].push(filtersStructure[i]._id); } return arrangedFilters; }, reBuildStructure: function(filtersArr) { var filtersStructure = []; for(var i = 0; i < filtersArr.length; i++) { for(var j = 0; j < filtersArr[i].length; j++) { var data = { _id: filtersArr[i][j] }; if(!(i == 0 && j == 0)) data.cond = j == 0 ? 1 : 2; filtersStructure.push(data); } } return filtersStructure; }, removeFilter: function(filters, index) { filters.splice(index, 1); if(index === 0 && filters[0] !== undefined) delete filters[0].cond; return filters; } } }); }); define('services/pathManager',['app'], function (app) { app.factory('pathManager', [function () { var pathManager = function(list) { this._init(list); }; pathManager.prototype = { _tree: {}, _init: function(list) { this._tree = {}; if(list !== undefined) for(var i = 0; i < list.length; i++) this.addPath(list[i]); }, _getCurrent: function(path) { var parts = path.split('/'); var current = this.getTree(); while (parts.length) { var part = parts.shift(); if(!part) continue; if(current[part] === undefined) return false; current = current[part]; } return current; }, _countObj: function (obj) { var count = 0; for(var key in obj) count++; return count; }, isExists: function(path) { if(!this._countObj(this.getTree())) return false; var current = this._getCurrent(path); if(!current) return false; return !this._countObj(current); }, isParent: function(path) { if(!this._countObj(this.getTree())) return false; var current = this._getCurrent(path); if(!current) return false; return !!this._countObj(current); }, isChildren: function(path) { if(!this._countObj(this.getTree())) return false; var parts = path.split('/'); var current = this.getTree(); while (parts.length) { var part = parts.shift(); if(!part) continue; if(current[part] === undefined) return !this._countObj(current); current = current[part]; } return false; }, addPath: function (path) { var parts = path.split('/'); var current = this.getTree(); while (parts.length) { var part = parts.shift(); if(!part) continue; if(current[part] === undefined) current[part] = {}; current = current[part]; } // remove sub folders for(var key in current) delete current[key]; }, removePath: function (path) { // TODO remove from tree var parts = path.split('/'); var current = this.getTree(); var queue = []; while (parts.length) { var part = parts.shift(); if(!part) continue; if(current[part] === undefined) return false; queue.push({ instance: current, name: part }); current = current[part]; } if(!queue.length) return; var item = queue.pop(); delete item.instance[item.name]; while(queue.length) { item = queue.pop(); if(this._countObj(item.instance[item.name]) > 0) return; delete item.instance[item.name]; } }, getSelected: function () { var paths = []; var tree = this.getTree(); var queue = [{path: '', obj: tree}]; while(queue.length) { var item = queue.shift(); for(var key in item.obj) { var path = item.path + '/' + key; if(this._countObj(item.obj[key])) { queue.push({path: path, obj: item.obj[key]}); } else { paths.push(path); } } } return paths; }, getTree: function () { return this._tree; } }; return { new: function (list) { return new pathManager(list); } }; }]); }); define('directives/pagination',[ 'app' ], function (app, PERMISSIONS) { app.directive('pagination', [function() { return { template: '<div class="row search-page-container">\n' + ' <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">\n' + ' <p ng-show="meta.showItemCountText()">{{ meta.getItemCountText() }}</p>\n' + ' </div>\n' + ' <div class="col-xs-6 col-sm-6 col-md-6 col-lg-6">\n' + ' <div class="pagination-container hidden-xs hidden-sm">\n' + ' <page-size id="table_items_per_page"\n' + ' allowed-sizes="meta.getPageSizes()"\n' + ' total-items="meta.getTotalItems()"\n' + ' ng-model="pageSize"\n' + ' show-all="false"\n' + ' ng-show="!hidePageSize && meta.showPagination()">\n' + ' </page-size>\n' + ' <ul uib-pagination id="table_paginate"\n' + ' total-items="meta.getTotalItems()"\n' + ' ng-model="currentPage"\n' + ' max-size="meta.getMaxPages()"\n' + ' boundary-links="false"\n' + ' direction-links="true"\n' + ' rotate="false"\n' + ' previous-text="<"\n' + ' next-text=">"\n' + ' items-per-page="meta.getPageSize()"\n' + ' ng-show="meta.showPagination()">\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + ' </div>\n' + ' <div class="row hidden-md hidden-lg">\n' + ' <div class="col-xs-12">\n' + ' <p class="text-right" ng-show="meta.showItemCountText()">{{ meta.getItemCountText() }}</p>\n' + ' </div>\n' + ' </div>\n' + ' <div class="row search-page-container visible-xs-block visible-sm-block hidden-md hidden-lg">\n' + ' <div class="col-xs-12 col-sm-12">\n' + ' <div class="pagination-container">\n' + ' <filter-box id="table_filter_mobile"\n' + ' box-options="filterOptions"\n' + ' ng-model="filter"\n' + ' ng-change="fetch()">\n' + ' </filter-box>\n' + ' <page-size id="table_items_per_page_mobile"\n' + ' allowed-sizes="meta.getPageSizes()"\n' + ' total-items="meta.getTotalItems()"\n' + ' ng-model="pageSize"\n' + ' show-all="false"\n' + ' ng-show="!hidePageSize && meta.showPagination()">\n' + ' </page-size>\n' + ' <ul uib-pagination id="table_paginate_mobile"\n' + ' total-items="meta.getTotalItems()"\n' + ' ng-model="currentPage"\n' + ' max-size="0"\n' + ' boundary-links="false"\n' + ' direction-links="true"\n' + ' rotate="false"\n' + ' previous-text="<"\n' + ' next-text=">"\n' + ' items-per-page="meta.getPageSize()"\n' + ' ng-show="meta.showPagination()"\n' + ' class="pagination-small">\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + ' </div>', scope: { "meta": "=", "fetch": "=", "hidePageSize": "=" }, link: function (scope) { scope.currentPage = scope.meta.getCurrentPage(); scope.pageSize = scope.meta.getPageSize(); scope.meta.onChange(function () { scope.currentPage = scope.meta.getCurrentPage(); scope.pageSize = scope.meta.getPageSize(); }); scope.$watch('currentPage', function (newValue, oldValue) { if(newValue === oldValue) return; scope.meta.setCurrentPage(scope.currentPage); if(scope.meta.getTotalItems() > scope.meta.getSkip()) scope.fetch(); }); scope.$watch('pageSize', function (newValue, oldValue) { if(newValue === oldValue) return; scope.meta.setPageSize(scope.pageSize); if(scope.meta.getTotalItems() > scope.meta.getSkip()) scope.fetch(); }); } }; }]); }); define('directives/filterBox',['app'], function (app) { app.directive("filterBox", ["$parse", "lang", function($parse, lang) { return { restrict: "EA", template: '<div ng-hide="!boxOptions[0]" class="input-group" >\n' + ' <span class="input-group-addon">{{filterTitle}}</span>' + ' <select id="{{parentID}}_select"\n' + ' class="form-control"\n' + ' ng-options="filterOpt.value as filterOpt.label for filterOpt in boxOptions"\n' + ' ng-model="filter">\n' + ' </select>\n' + '</div>', require: "ngModel", replace: true, scope: { "parentID": "@id", "filterTitle": "@", "boxOptions": "=boxOptions" }, link: function(scope, element, attrs, ngModel) { if (!ngModel) { return; // do nothing if no ng-model on the directive } ngModel.$render = function() { if(scope.filterTitle === undefined) scope.filterTitle = lang.t("Filter"); scope.filter = ngModel.$viewValue; }; scope.$watch("filter", function(newValue, oldValue) { if (newValue === oldValue) { return; // No update on same value; } ngModel.$setViewValue(scope.filter); }); } }; } ]); }); define('directives/validateField',['app'], function (app) { app.directive("validateField", ["$parse", "lang", function($parse, lang) { return { restrict: "A", require: "ngModel", replace: false, scope: { min: '@', max: '@', regex: '@', ngModel: '=' }, link: function(scope, element, attrs, ngModel) { if (!ngModel) return; // do nothing if no ng-model on the directive var blinkBorder = function(element) { element.css({ borderColor: '#cc0000' }); setTimeout(function () { element.css({ borderColor: 'inherit' }); }, 2000); }; scope.$watch(function () { return ngModel.$modelValue; }, function(newValue) { scope.oldValue = newValue; }); element.on('blur', function () { scope.newValue = ngModel.$viewValue; if(scope.newValue === '') return; switch(attrs.validateField) { case 'int': scope.newValue = parseInt(scope.newValue); if(scope.min !== undefined && scope.newValue < parseInt(scope.min)) scope.newValue = parseInt(scope.min); if(scope.max !== undefined && scope.newValue > parseInt(scope.max)) scope.newValue = parseInt(scope.max); break; case 'float': scope.newValue = parseFloat(scope.newValue); if(scope.min !== undefined && scope.newValue < parseFloat(scope.min)) scope.newValue = parseFloat(scope.min); if(scope.max !== undefined && scope.newValue > parseFloat(scope.max)) scope.newValue = parseFloat(scope.max); break; case 'str': if(!(new RegExp(scope.regex)).test(scope.newValue)) scope.newValue = ''; if(scope.max !== undefined && scope.newValue.length > parseInt(scope.max)) scope.newValue = scope.newValue.substr(0, parseInt(scope.max)); break; case 'path': var regex = new RegExp(/^(\/[\w\s\d.-]+)+\/?$/); if(!regex.test(scope.newValue)) scope.newValue = ''; break; case 'color': var regex = new RegExp(/^#[a-fA-F0-9]{3}(?:[a-fA-F0-9]{3})?$/); if(!regex.test(scope.newValue)) scope.newValue = ''; break; case 'binary': var regex = new RegExp(/^((\/[\w\s\d\-]+)+\/?|[\w\-]+)$/); if(!regex.test(scope.newValue)) scope.newValue = ''; break; case 'email': var regex = new RegExp(/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/); if(!regex.test(scope.newValue)) scope.newValue = ''; break; } if(scope.oldValue == scope.newValue) return; blinkBorder(element); ngModel.$setViewValue(scope.newValue); ngModel.$render(); }); } }; } ]); }); define('directives/inputDropdown',['app'], function (app) { app.directive("inputDropdown", ["$parse", "lang", function($parse, lang) { return { restrict: "E", template: '<div class="input-group">' + ' <span ng-show="prefix" class="input-group-addon">{{prefixLang}}</span>' + ' <select class="form-control"' + ' ng-options="value.key as value.label for value in values"' + ' ng-model="input">' + ' </select>' + ' <span ng-show="input == \'CUSTOM\'" class="input-group-addon">-</span>' + ' <span ng-show="input == \'CUSTOM\'" ng-transclude></span>' + ' <span class="input-group-addon">{{addonLang}}</span>' + '</div>', require: "ngModel", transclude: true, replace: true, scope: { "addon": "@", "prefix": "@", "options": "=", "ngModel": "=" }, link: function(scope, element, attrs, ngModel, transclude) { if (!ngModel) return; // do nothing if no ng-model on the directive scope.addonLang = scope.addon ? scope.addon : ''; scope.prefixLang = scope.prefix ? scope.prefix : ''; scope.values = []; Object.keys(scope.options).sort(function(a, b) { return a - b; }).forEach(function(key) { var value = key; if(value == parseInt(value)) value = parseInt(value); scope.values.push({ key: value, label: scope.options[key] }); }); scope.values.push({ key: 'CUSTOM', label: lang.t("Custom") }); ngModel.$render = function() { scope.input = ngModel.$viewValue; for(var key in scope.options) { if(key == parseInt(key)) key = parseInt(key); if(key === scope.input) return; } scope.input = 'CUSTOM'; }; scope.$watch("input", function(newValue, oldValue) { if (newValue === oldValue || newValue === 'CUSTOM') return; ngModel.$setViewValue(scope.input); }); } }; } ]); }); define('directives/pageSize',[ 'app', ], function (app) { app.directive("pageSize", ["$parse", "pageSizeConfig", "lang", function($parse, pageSizeConfig, lang) { // A value to assign to the page size entry - 'All' var PAGE_SIZE_ALL_VALUE = -1; return { restrict: "EA", template: '<div class="page-size">\n' + ' <div ng-hide="autoHide && options[0].value >= totalItems" class="form-group" >\n' + ' <label for="{{parentID}}_select" class="title">{{pageSizeTitle}}</label>\n' + ' <select id="{{parentID}}_select"\n' + ' class="form-control"\n' + ' ng-options="size.value as size.label for size in options"\n' + ' ng-model="pageSize">\n' + ' </select>\n' + ' </div>\n' + '</div>', require: "ngModel", replace: true, scope: { "parentID": "@id", "totalItems": "=", "allowedSizes": "=", "showAll": "=", "autoHide": "=" }, link: function(scope, element, attrs, ngModel) { if (!ngModel) { return; // do nothing if no ng-model on the directive } function getAllowedPageSizes() { var meta = {}; meta.allowedSizes = scope.allowedSizes || pageSizeConfig.allowedSizes; meta.totalItems = scope.totalItems || pageSizeConfig.totalItems; meta.showAllItems = scope.showAll; if (scope.showAll) { PAGE_SIZE_ALL_VALUE = scope.totalItems || -1; } var sizes = meta.allowedSizes.slice(0); sizes.sort(function(a, b) { return a - b; }); sizes = sizes.map(function(size) { return { label: size, value: size }; }); if (meta.showAllItems) { // Set to 'All' if no other values exist sizes.push({ label: lang.t("All"), value: PAGE_SIZE_ALL_VALUE }); } // Removing filtering because it's breaking some interfaces // When a page doens't have an "All" and has a totalitems // less than the smallest size (10) it breaks. if (sizes.length === 1 && sizes[0].value === meta.totalItems) { scope.pageSize = sizes[0].value; } else if (sizes.filter(function(size) { return size.value === scope.pageSize; }).length === 0) { // ensure pageSize is an option, otherwise set to lowest option scope.pageSize = sizes[0].value; } return sizes; } if (attrs.allowedSizes) { scope.$parent.$watch($parse(attrs.allowedSizes), function() { scope.options = getAllowedPageSizes(); }); } if (attrs.totalItems) { scope.$parent.$watch($parse(attrs.totalItems), function() { scope.options = getAllowedPageSizes(); }); } if (attrs.showAll) { scope.$parent.$watch($parse(attrs.showAll), function() { scope.options = getAllowedPageSizes(); }); } ngModel.$render = function() { scope.pageSizeTitle = lang.t("Page Size"); scope.pageSize = ngModel.$viewValue; }; scope.$watch("pageSize", function(newValue, oldValue) { if (newValue === oldValue) { return; // No update on same value; } if (!newValue) { return; // New value is null or invalid } ngModel.$setViewValue(scope.pageSize); }); scope.$watch("totalItems", function() { scope.options = getAllowedPageSizes(); }); scope.options = getAllowedPageSizes(); } }; } ]); app.constant("pageSizeConfig", { allowedSizes: [10, 20, 50, 100], totalItems: 0, showAllItems: false }); }); define('directives/loadingBox',['app'], function (app) { app.directive('loadingBox', function() { return { restrict: 'E', transclude: true, template: '<div class="alert alert-info"><em class="fas fa-cog fa-spin"></em> <span ng-transclude></span></div>' } }); }); define('directives/tooltip',[ 'app', ], function (app) { app.directive("tooltip", ["$sce", "$compile", "lang", function($sce, $compile, lang) { return { restrict: "A", replace: false, terminal: true, priority: 1000, link: function (scope,element, attrs) { var content = attrs.tooltip; var regex = /^(top|top-left|top-right|bottom|bottom-left|bottom-right|left|left-top|left-bottom|right|right-top|right-bottom)\|(.*)$/; if(regex.test(content)) { var parts = content.match(regex); element.attr('tooltip-placement', parts[1]); content = parts[2]; } regex = /^\{\{(.*)\}\}$/; if(regex.test(content)) { parts = content.match(regex); parts = parts[1].split('.'); content = scope; for(var i = 0; i < parts.length; i++) if(content !== undefined) content = content[parts[i]]; } element.removeAttr("tooltip"); if(!content) { $compile(element)(scope); return; } if(scope.contentHTML === undefined) scope.contentHTML = []; var index = scope.contentHTML.length; scope.contentHTML[index] = $sce.trustAsHtml("<div style='padding: 5px;'>" + lang.t(content) + "</div>"); element.attr('uib-tooltip-html', "contentHTML[" + index + "]"); $compile(element)(scope); } }; } ]); }); define('directives/sortBy',[ 'app', ], function (app) { app.directive("sortBy", ["lang", function(lang) { var ASCENDING = "asc"; var DESCENDING = "desc"; var DEFAULT_ASCENDING_TITLE = lang.t("Ascending"); var DEFAULT_DESCENDING_TITLE = lang.t("Descending"); return { template: '<button class="sort-link" ng-click="sort(sortValue)">\n' + ' <span ng-transclude></span>\n' + ' <span ng-hide="sortMeta.getSortBy() !== sortField">\n' + ' <i class="fas" ng-class="{true: \'fa-sort-up\', false: \'fa-sort-down\'}[sortMeta.getSortDirection() == \'asc\']"\n' + ' ng-attr-title="{{ getTitle() }}"></i>\n' + ' </span>\n' + '</button>', restrict: "EA", transclude: true, replace: true, scope: { sortMeta: "=", sortType: "@", sortField: "@", sortReverse: "@", sortAscendingTitle: "@", sortDescendingTitle: "@", sortReverseDefault: "@", onsort: "&" }, compile: function (element, attributes) { if (!attributes["sortAscendingTitle"]) { attributes["sortAscendingTitle"] = DEFAULT_ASCENDING_TITLE; } if (!attributes["sortDescendingTitle"]) { attributes["sortDescendingTitle"] = DEFAULT_DESCENDING_TITLE; } return function (scope, element, attributes) { /** * Get the title text for the sort direction control. * * @method getTitle */ scope.getTitle = function () { return scope.sortMeta.getSortDirection() === ASCENDING ? attributes["sortAscendingTitle"] : attributes["sortDescendingTitle"]; }; /** * Toggle the sort direction on the selected column */ scope.sort = function () { var meta = scope.sortMeta; if (meta.getSortBy() === scope.sortField) { meta.setSortDirection(meta.getSortDirection() === ASCENDING ? DESCENDING : ASCENDING); } else { meta.setSortBy(scope.sortField); meta.setSortDirection(ASCENDING); } // Make sure onsort exists on the parent scope before executing it var onsort = scope.onsort(); if (angular.isFunction(onsort)) { onsort(meta); } }; } } } }]); }); define('directives/search',[ 'app', ], function (app) { app.directive("search", ["lang", function(lang) { return { restrict: "E", template: '<div class="input-group">\n' + ' <input type="text"\n' + ' id="{{parentID}}_input"\n' + ' class="form-control"\n' + ' placeholder="{{placeholder}}"\n' + ' title="{{title}}"\n' + ' ng-model="filterText"\n' + ' ng-keyup="clear($event)"\n' + ' ng-debounce\n' + ' prevent-default-on-enter\n' + ' auto-focus="{{autofocus}}"\n' + ' aria-label="' + lang.t("Search") + '"/>\n' + ' <span class="input-group-btn">\n' + ' <button id="{{parentID}}_submit_btn"\n' + ' class="btn btn-default"\n' + ' ng-click="filterText=\'\'"\n' + ' type="button"\n' + ' ng-attr-aria-label="{{ !filterText ? ariaLabelSearch : ariaLabelClear }}">\n' + ' <span class="fas"\n' + ' ng-class="{ \'fa-search\' : !filterText, \'fa-times\' :filterText }"\n' + ' aria-hidden="true">\n' + ' </span>\n' + ' </button>\n' + ' </span>\n' + '</div>', require: "ngModel", replace: true, scope: { parentID: "@id", placeholder: "@?placeholder", autofocus: "@?autofocus", title: "@?title" }, compile: function() { return { pre: function(scope, element, attrs) { // eslint-disable-line no-unused-vars if (angular.isUndefined(attrs.placeholder)) { attrs.placeholder = lang.t("Search"); } if (angular.isUndefined(attrs.title)) { attrs.title = lang.t("Search"); } if (angular.isUndefined(attrs.autofocus)) { attrs.autofocus = false; } else { attrs.autofocus = true; } scope.autofocus = attrs.autofocus; scope.placeholder = attrs.placeholder; scope.title = attrs.title; scope.ariaLabelSearch = lang.t("Search"); scope.ariaLabelClear = lang.t("Clear"); }, post: function(scope, element, attrs, ctrls) { // eslint-disable-line no-unused-vars var ngModelCtrl = ctrls; if (!ngModelCtrl) { return; // do nothing if no ng-model on the directive } ngModelCtrl.$render = function() { scope.filterText = ngModelCtrl.$viewValue; }; scope.clear = function(event) { if (event.keyCode === 27) { scope.filterText = ""; } }; var timeout = null; scope.$watch("filterText", function() { if(timeout !== null) clearTimeout(timeout); timeout = setTimeout(function(){ ngModelCtrl.$setViewValue(scope.filterText); }, 300); }); } }; } }; }]); }); define('directives/alertBox',[ 'app', ], function (app) { app.directive("alertBox", ["$timeout", "$compile", "lang", function($timeout, $compile, lang) { var _counter = 0; var ID_DEFAULT_PREFIX = "alert"; var LABELS = [{ name: "errorLabel", defaultText: lang.t("Error:"), }, { name: "warnLabel", defaultText: lang.t("Warning:") }, { name: "infoLabel", defaultText: lang.t("Information:") }, { name: "successLabel", defaultText: lang.t("Success:") }, { name: "moreLabel", defaultText: lang.t("What went wrong?") }]; var initializeModel = function(hasModel, attrs, modelValue) { var data = {}; if (hasModel) { if (angular.isString(modelValue)) { data.message = modelValue; } else if (angular.isObject(modelValue)) { angular.copy(modelValue, data); } else { throw new TypeError("ngModel must be a string or object."); } } if (!angular.isDefined(data.type)) { if (angular.isDefined(attrs.type) && attrs.type) { data.type = attrs.type; } else { data.type = "warning"; } } if (angular.isDefined(data.closable)) { data.closable = ((data.type === "danger") ? false : data.closable); } else if (angular.isDefined(attrs.closable)) { data.closable = ((data.type === "danger") ? false : true); } else { data.closable = false; } if (angular.isDefined(data.autoClose)) { data.autoClose = ((data.type === "danger") ? false : data.autoClose); } else if (angular.isDefined(attrs.autoClose)) { data.autoClose = ((data.type === "danger") ? false : data.autoClose); } else { data.autoClose = false; } if (!angular.isDefined(data.id)) { if (!angular.isDefined(attrs.id)) { data.id = ID_DEFAULT_PREFIX + _counter++; } else { data.id = attrs.id; } } if (hasModel && !angular.isDefined(data.message) && !data.message) { throw new Error("No message provided in the model's message property."); } return data; }; var renderBody = function(scope, element, transclude) { var type = scope.alert.type; var typeBlock = element[0].querySelector(".alert-" + type); var messageSpan = typeBlock.querySelector(".alert-body"); transclude(function(clone) { angular.element(messageSpan).append(clone); }); }; return { restrict: "EA", template: '<div>\n' + ' <div ng-show="alert.type === \'danger\'" class=\'alert alert-danger ng-hide\'>\n' + ' <button id="{{\'btnClose_danger_\' + alert.id}}" type=\'button\' class=\'close\' ng-if=\'alert.closeable\' ng-click=\'runClose()\'>×</button>\n' + ' <button id="{{\'btnMore_danger_\' + alert.id}}" type=\'button\' class=\'btn btn-more btn-link pull-right flip\' ng-if=\'hasToggleHandler\' ng-click=\'runToggleMore()\'>{{moreLabel}}</button>\n' + ' <div class=\'alert-message\'>\n' + ' <span class=\'fas fa-times-circle\'></span>\n' + ' <strong class="alert-title" ng-show="errorLabel">{{errorLabel}}</strong>\n' + ' <span class="alert-body"><span id="{{\'txtMessage_danger_\' + alert.id}}" ng-bind-html="alert.message" ng-if="alert && alert.message"></span></span>\n' + ' <ul ng-if="alert.list && alert.list.length" class="alert-list">\n' + ' <li ng-repeat="value in alert.list">\n' + ' <span id="{{\'txtList_danger_\' + alert.id + \'_\' + $index}}" ng-bind-html="value"></span>\n' + ' </li>\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + '\n' + ' <div ng-show="alert.type === \'info\'" class=\'alert alert-info ng-hide\'>\n' + ' <button id="{{\'btnClose_info_\' + alert.id}}" type=\'button\' class=\'close\' ng-if=\'alert.closeable\' ng-click=\'runClose()\'>×</button>\n' + ' <button id="{{\'btnMore_info_\' + alert.id}}" type=\'button\' class=\'btn btn-more btn-link pull-right flip\' ng-if=\'hasToggleHandler\' ng-click=\'runToggleMore()\'>{{moreLabel}}</button>\n' + ' <div class=\'alert-message\'>\n' + ' <span class=\'fas fa-info-circle\'></span>\n' + ' <strong class="alert-title" ng-show="infoLabel">{{infoLabel}}</strong>\n' + ' <span class="alert-body"><span id="{{\'txtMessage_info_\' + alert.id}}" ng-bind-html="alert.message" ng-if="alert && alert.message"></span></span>\n' + ' <ul ng-if="alert.list && alert.list.length" class="alert-list">\n' + ' <li ng-repeat="value in alert.list">\n' + ' <span id="{{\'txtList_info_\' + alert.id + \'_\' + $index}}" ng-bind-html="value"></span>\n' + ' </li>\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + '\n' + ' <div ng-show="alert.type === \'success\'" class=\'alert alert-success ng-hide\'>\n' + ' <button id="{{\'btnClose_success_\' + alert.id}}" type=\'button\' class=\'close\' ng-if=\'alert.closeable\' ng-click=\'runClose()\'>×</button>\n' + ' <button id="{{\'btnMore_success_\' + alert.id}}" type=\'button\' class=\'btn btn-more btn-link pull-right flip\' ng-if=\'hasToggleHandler\' ng-click=\'runToggleMore()\'>{{moreLabel}}</button>\n' + ' <div class=\'alert-message\'>\n' + ' <span class=\'fas fa-check-circle\'></span>\n' + ' <strong class="alert-title" ng-show="successLabel">{{successLabel}}</strong>\n' + ' <span class="alert-body"><span id="{{\'txtMessage_success_\' + alert.id}}" ng-bind-html="alert.message" ng-if="alert && alert.message"></span></span>\n' + ' <ul ng-if="alert.list && alert.list.length" class="alert-list">\n' + ' <li ng-repeat="value in alert.list">\n' + ' <span id="{{\'txtList_success_\' + alert.id + \'_\' + $index}}" ng-bind-html="value"></span>\n' + ' </li>\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + '\n' + ' <div ng-show="alert.type === \'warning\'" class=\'alert alert-warning ng-hide\'>\n' + ' <button id="{{\'btnClose_warning_\' + alert.id}}" type=\'button\' class=\'close\' ng-if=\'alert.closeable\' ng-click=\'runClose()\'>×</button>\n' + ' <button id="{{\'btnMore_warning_\' + alert.id}}" type=\'button\' class=\'btn btn-more btn-link pull-right flip\' ng-if=\'hasToggleHandler\' ng-click=\'runToggleMore()\'>{{moreLabel}}</button>\n' + ' <div class=\'alert-message\'>\n' + ' <span class=\'fas fa-exclamation-circle\'></span>\n' + ' <strong class="alert-title" ng-show="warnLabel">{{warnLabel}}</strong>\n' + ' <span class="alert-body"><span id="{{\'txtMessage_warning_\' + alert.id}}" ng-bind-html="alert.message" ng-if="alert && alert.message"></span></span>\n' + ' <ul ng-if="alert.list && alert.list.length" class="alert-list">\n' + ' <li ng-repeat="value in alert.list">\n' + ' <span id="{{\'txtList_warning_\' + alert.id + \'_\' + $index}}" ng-bind-html="value"></span>\n' + ' </li>\n' + ' </ul>\n' + ' </div>\n' + ' </div>\n' + '</div>', transclude: true, replace: true, require: "?ngModel", scope: { close: "&onClose", toggleMore: "&onToggleMore", autoClose: "=", errorLabel: "@", warnLabel: "@", infoLabel: "@", successLabel: "@", moreLabel: "@" }, compile: function(element, attrs) { LABELS.forEach(function(label) { if (!angular.isDefined(attrs[label.name])) { attrs[label.name] = label.defaultText; } }); return function(scope, element, attrs, ngModelCtrl, transclude) { if (ngModelCtrl) { ngModelCtrl.$formatters.push(function(modelValue) { return initializeModel(true, attrs, modelValue); }); ngModelCtrl.$render = function() { scope.alert = ngModelCtrl.$viewValue; }; } else { scope.alert = initializeModel(false, attrs); renderBody(scope, element, transclude); } scope.$watch("alert.label", function(newVal) { if ( angular.isDefined(newVal) ) { LABELS.forEach(function(label) { attrs.$set(label.name, newVal); }); } }); scope.runClose = function() { if (scope.timer) { var timer = scope.timer; scope.timer = null; delete scope.timer; $timeout.cancel(timer); } scope.$emit("closeAlertCalled", { id: scope.alert.id }); scope.alert.type = ''; //ngModel.$setViewValue(scope.type); // scope.close(); }; var msecs = scope.autoClose ? parseInt(scope.autoClose, 10) : null; if (msecs && !isNaN(msecs)) { scope.timer = $timeout(function() { scope.runClose(); }, msecs); } scope.hasToggleHandler = angular.isDefined(attrs.onToggleMore); scope.showMore = false; scope.runToggleMore = function() { scope.showMore = !scope.showMore; var e = { id: scope.alert.id, show: scope.showMore }; scope.$emit("toggleMoreAlertCalled", e); scope.toggleMore(e); }; }; } }; } ]); }); define('directives/navigation',[ 'app' ], function (app) { app.directive('navigation', ["$rootScope", "$location", "lang", "permissions", function($rootScope, $location, lang, permissions) { return { template: '<li aria-label="{{ option.label }}" ng-repeat="option in options" ng-if="option.permissions" ng-class="{ \'active\': active == option.class }" > ' + '<a href="{{url}}{{option.href}}" ng-click="changePath(option.href)" tooltip-placement="right" tooltip-enable="collapsed" uib-tooltip="{{ option.label }}" > '+ '<em aria-hidden="true" class="{{ option.icon }}"></em>' + '<span>{{ option.label }}</span>' + '</a>'+ '</li>', scope: { "collapsed": "=", "active": "=" }, link: function (scope) { var account = window.PAGE.account; scope.changePath = function(path) { $location.path(path); }; scope.url = $rootScope.primaryURL; scope.options = [ {label: lang.t("Dashboard"), href: "/", class: 'Dashboard', icon: 'fas fa-home', permissions: true }, {label: lang.t("Accounts"), href: "/accounts", class: 'Accounts', icon: 'fas fa-users', permissions: !permissions.isEnduser && permissions.canManageAccounts }, {label: lang.t("Destinations"), href: "/destinations", class: 'Destinations', icon: 'fas fa-folder', permissions: !permissions.isEnduser && permissions.canManageDestinations }, {label: lang.t("Backup Jobs"), href: "/backupJobs", class: 'BackupJobs', icon: 'fas fa-cubes', permissions: !permissions.isEnduser && permissions.canManageBackupJobs }, {label: lang.t("Clone Jobs"), href: "/cloneJobs", class: 'CloneJobs', icon: 'fas fa-clone', permissions: !permissions.isEnduser && permissions.canManageCloneJobs }, {label: lang.t("Restore & Download"), href: "/restore" + (permissions.isEnduser ? '/full' : '/singleaccount'), class: 'Restore', icon: 'fas fa-sync', permissions: permissions.canManageAccountBackups }, {label: lang.t("Downloads"), href: "/downloads", class: 'Downloads', icon: 'fas fa-cloud-download-alt', permissions: permissions.canDownloadBackups }, {label: lang.t("Alerts"), href: "/alerts", class: 'Alerts', icon: 'fas fa-exclamation-triangle', permissions: permissions.canViewAlerts }, {label: lang.t("Queue"), href: "/queue", class: 'Queue', icon: 'fas fa-clock', permissions: permissions.canManageQueue }, {label: lang.t("Logs"), href: "/logs", class: 'Logs', icon: 'fas fa-file-alt', permissions: !permissions.isEnduser && permissions.canViewLogs }, {label: lang.t("Permissions"), href: "/permissions", class: 'Permissions', icon: 'fas fa-users-cog', permissions: !permissions.isEnduser && permissions.canManagePermissions }, {label: lang.t("Hooks"), href: "/hooks", class: 'Hooks', icon: 'fas fa-flag', permissions: !permissions.isEnduser && permissions.canManageHooks }, {label: lang.t("Security"), href: "/security", class: 'Security', icon: 'fas fa-fingerprint', permissions: !permissions.isEnduser && permissions.isRoot }, {label: lang.t("Plugins"), href: "/plugins", class: 'Plugins', icon: 'fas fa-puzzle-piece', permissions: !permissions.isEnduser && permissions.isRoot }, {label: lang.t("Wordpress Integration"),href: "/extension", class: 'Extension', icon: 'fab fa-wordpress', permissions: permissions.isWPIntegration } ]; scope.pluginsPositions = {}; scope.lastPosition = (scope.options.length-1); var addPlugin = function (plugin) { scope.lastPosition++; scope.options.splice(scope.lastPosition, 0, { label: plugin.name, href: "/plugin/"+plugin.code, class: "Plugin" + plugin.code, icon: plugin.icon ? plugin.icon : 'fas fa-puzzle-piece', permissions: (plugin.visible && !plugin.disabled) }); scope.pluginsPositions[plugin._id] = scope.lastPosition; }; for(var _id in $rootScope.plugins) addPlugin($rootScope.plugins[_id]); $rootScope.$watch('plugins', function () { for(var _id in $rootScope.plugins) { var plugin = $rootScope.plugins[_id]; if(scope.pluginsPositions[_id] === undefined) addPlugin(plugin); else scope.options[scope.pluginsPositions[_id]].permissions = (plugin.visible && !plugin.disabled); } }, true); scope.options.push({label: lang.t("Settings"), href: "/settings", class: 'Settings', icon: 'fas fa-cog', permissions: !permissions.isEnduser && permissions.isRoot }); } }; }]); }); require([ 'app', 'controllers/404', 'controllers/myAccount', 'controllers/agreement', 'controllers/agreementPanel', 'controllers/dashboard', 'controllers/alerts', 'controllers/accounts', 'controllers/accountsOrphans', 'controllers/accountManage', 'controllers/accountReassign', 'controllers/accountExcludeListSelection', 'controllers/modifyDatabasesExcludes', 'controllers/destinations', 'controllers/destinationManage', 'controllers/disasterRecovery', 'controllers/disasterRecovery/selection', 'controllers/disasterRecovery/destination', 'controllers/disasterRecovery/settings', 'controllers/disasterRecovery/backups', 'controllers/disasterRecovery/backups', 'controllers/disasterRecovery/accounts', 'controllers/restoreConditions', 'controllers/restoreConditionManage', 'controllers/backupJobs', 'controllers/backupJobManage', 'controllers/cloneJobs', 'controllers/cloneJobManage', 'controllers/permissions', 'controllers/schedules', 'controllers/scheduleManage', 'controllers/scheduleManagePopup', 'controllers/scheduleSelection', 'controllers/queue', 'controllers/queueItems', 'controllers/queueLogViewer', 'controllers/queuePriorities', 'controllers/queuePriorityManage', 'controllers/security', 'controllers/extension', 'controllers/support', 'controllers/repositories', 'controllers/repositoryManage', 'controllers/filePermissions', 'controllers/filePermissionsManage', 'controllers/hooks', 'controllers/hookManage', 'controllers/tags', 'controllers/tagManage', 'controllers/tagsSelection', 'controllers/destinationsSelection', 'controllers/backupJobsSelection', 'controllers/cloneJobsSelection', 'controllers/backupLockSelection', 'controllers/plugins', 'controllers/packages', 'controllers/showcase', //'controllers/addons', 'controllers/plugin', 'controllers/pluginManage', 'controllers/logs', 'controllers/logViewer', 'controllers/logItems', 'controllers/settings', 'controllers/settings/binary', 'controllers/settings/general', 'controllers/settings/notification', 'controllers/settings/notificationManage', 'controllers/settings/performance', 'controllers/settings/resource', 'controllers/settings/privacy', 'controllers/settings/restore', 'controllers/settings/snapshots', 'controllers/settings/update', 'controllers/fileManager', 'controllers/fileManagerPopup', 'controllers/fileBrowse', 'controllers/downloads', 'controllers/accountSelection', 'controllers/restore', 'controllers/restoreMultiAccount', 'controllers/restoreSingleAccount', 'controllers/restoreDirectories', 'controllers/restoreDisasterRecovery', 'controllers/accountBackups', 'controllers/accountDownloads', 'controllers/accountFilters', 'controllers/accountFilterManage', 'controllers/accountFilterManagePopup', 'controllers/accountFilterGroupManage', 'controllers/accountFilterGroupManagePopup', 'controllers/accountFilterGroups', 'controllers/accountFilterGroupSelection', 'controllers/accountsSelection', 'controllers/accountPackagesSelection', 'controllers/resellersSelection', 'controllers/confirm', 'controllers_enduser/dashboard', 'controllers_enduser/restore', 'controllers_enduser/restore/full', 'controllers_enduser/restore/files', 'controllers_enduser/restore/cron', 'controllers_enduser/restore/dns', 'controllers_enduser/restore/email', 'controllers_enduser/restore/db', 'controllers_enduser/restore/dbuser', 'controllers_enduser/restore/ftp', 'controllers_enduser/restore/ssl', 'controllers_enduser/backups', 'filters/html', 'filters/capitalize', 'filters/executionTime', 'filters/numberFormat', 'services/api', 'services/alert', 'services/confirm', 'services/lang', 'services/filter', 'services/meta', 'services/storage', 'services/permissions', 'services/popup', 'services/popupPosition', 'services/consts', 'services/util', 'services/filterManager', 'services/pathManager', 'directives/pagination', 'directives/filterBox', 'directives/validateField', 'directives/inputDropdown', 'directives/pageSize', 'directives/loadingBox', 'directives/tooltip', 'directives/sortBy', 'directives/search', 'directives/alertBox', 'directives/navigation' ], function (app) { angular.bootstrap(document, ['JetBackupApp']); }); define("main", function(){}); }());
.
Edit
..
Edit
controllers_enduser
Edit
css
Edit
images
Edit
lang
Edit
main.min.js
Edit
plugins
Edit
showcase
Edit
views
Edit
views_enduser
Edit