'use strict'; /* global angular */ /* global $ */ angular.module('Application').controller('MainController', ['$scope', '$route', '$timeout', '$location', '$interval', 'Notification', 'Client', function ($scope, $route, $timeout, $location, $interval, Notification, Client) { $scope.initialized = false; // used to animate the UI $scope.user = Client.getUserInfo(); $scope.installedApps = Client.getInstalledApps(); $scope.config = {}; $scope.client = Client; $scope.subscription = {}; $scope.notificationCount = 0; $scope.hideNavBarActions = $location.path() === '/logs'; $scope.backgroundImageUrl = ''; $scope.reboot = { busy: false, show: function () { $scope.reboot.busy = false; $('#rebootModal').modal('show'); }, submit: function () { $scope.reboot.busy = true; Client.reboot(function (error) { if (error) return Client.error(error); $('#rebootModal').modal('hide'); // trigger refetch to show offline banner $timeout(function () { Client.getStatus(function () {}); }, 5000); }); } }; $scope.isActive = function (url) { if (!$route.current) return false; return $route.current.$$route.originalPath.indexOf(url) === 0; }; $scope.logout = function (event) { event.stopPropagation(); $scope.initialized = false; Client.logout(); }; $scope.openSubscriptionSetup = function () { Client.openSubscriptionSetup($scope.subscription); }; // NOTE: this function is exported and called from the appstore.js $scope.updateSubscriptionStatus = function () { Client.getSubscription(function (error, subscription) { if (error && error.statusCode === 412) return; // not yet registered if (error && error.statusCode === 402) return; // invalid appstore token if (error) return console.error(error); $scope.subscription = subscription; }); }; function refreshNotifications() { if (!Client.getUserInfo().isAtLeastAdmin) return; Client.getNotifications({ acknowledged: false }, 1, 100, function (error, results) { // counter maxes out at 100 if (error) console.error(error); else $scope.notificationCount = results.length; }); } // update state of acknowledged notification $scope.notificationAcknowledged = function () { refreshNotifications(); }; function redirectOnMandatory2FA() { if (Client.getConfig().mandatory2FA && !Client.getUserInfo().twoFactorAuthenticationEnabled) { $location.path('/profile').search({ setup2fa: true }); } } // Make it redirect if the browser URL is changed directly - https://forum.cloudron.io/topic/7510/bug-in-2fa-force $scope.$on('$routeChangeStart', function (/* event */) { if ($scope.initialized) redirectOnMandatory2FA(); }); var gPlatformStatusNotification = null; function trackPlatformStatus() { Client.getPlatformStatus(function (error, result) { if (error) return console.error('Failed to get platform status.', error); // see box/src/platform.js if (result.message === 'Ready') { if (gPlatformStatusNotification) { gPlatformStatusNotification.kill(); gPlatformStatusNotification = null; } return; } if (!gPlatformStatusNotification) { var options = { title: 'Platform status', message: result.message, delay: 'notimeout', replaceMessage: true, closeOnClick: false }; Notification.primary(options).then(function (result) { gPlatformStatusNotification = result; $timeout(trackPlatformStatus, 5000); }); } else { gPlatformStatusNotification.message = result.message; $timeout(trackPlatformStatus, 5000); } }); } function init() { Client.getStatus(function (error, status) { if (error) return Client.initError(error, init); // WARNING if anything about the routing is changed here test these use-cases: // // 1. Caas // 3. selfhosted restore // 4. local development with gulp develop if (!status.activated) { console.log('Not activated yet, redirecting', status); if (status.restore.active || status.restore.errorMessage) { // show the error message in restore page window.location.href = '/restore.html' + window.location.search; } else { window.location.href = (status.adminFqdn ? '/setup.html' : '/setupdns.html') + window.location.search; } return; } // support local development with localhost check if (window.location.hostname !== status.adminFqdn && window.location.hostname !== 'localhost' && !window.location.hostname.startsWith('192.')) { // user is accessing by IP or by the old admin location (pre-migration) window.location.href = '/setupdns.html' + window.location.search; return; } // check version and force reload if needed if (!localStorage.version) { localStorage.version = status.version; } else if (localStorage.version !== status.version) { localStorage.version = status.version; window.location.reload(true); } console.log('Running dashboard version ', localStorage.version); // get user profile as the first thing. this populates the "scope" and affects subsequent API calls Client.refreshUserInfo(function (error) { if (error) return Client.initError(error, init); Client.refreshConfig(function (error) { if (error) return Client.initError(error, init); Client.refreshAvailableLanguages(function (error) { if (error) return Client.initError(error, init); Client.refreshInstalledApps(function (error) { if (error) return Client.initError(error, init); // now mark the Client to be ready Client.setReady(); $scope.config = Client.getConfig(); if (Client.getUserInfo().hasBackgroundImage) { document.getElementById('mainContentContainer').style.backgroundImage = 'url("' + Client.getBackgroundImageUrl() + '")'; document.getElementById('mainContentContainer').classList.add('has-background'); } $scope.initialized = true; redirectOnMandatory2FA(); $interval(refreshNotifications, 60 * 1000); refreshNotifications(); Client.getSubscription(function (error, subscription) { if (error && error.statusCode === 412) return; // not yet registered if (error && error.statusCode === 402) return; // invalid appstore token if (error) return console.error(error); $scope.subscription = subscription; // only track platform status if we are registered trackPlatformStatus(); }); }); }); }); }); }); } Client.onConfig(function (config) { if (config.cloudronName) { document.title = config.cloudronName; } }); init(); // setup all the dialog focus handling ['updateModal'].forEach(function (id) { $('#' + id).on('shown.bs.modal', function () { $(this).find('[autofocus]:first').focus(); }); }); }]);