Files
cloudron-box/src/views/emails.js

391 lines
14 KiB
JavaScript
Raw Normal View History

2020-02-11 21:06:34 +01:00
'use strict';
2020-09-01 16:31:23 +02:00
/* global $, angular, TASK_TYPES */
2020-02-11 21:06:34 +01:00
2020-11-12 16:38:48 +01:00
angular.module('Application').controller('EmailsController', ['$scope', '$location', '$translate', '$timeout', 'Client', function ($scope, $location, $translate, $timeout, Client) {
2020-02-24 12:56:13 +01:00
Client.onReady(function () { if (!Client.getUserInfo().isAtLeastAdmin) $location.path('/'); });
2020-02-11 21:06:34 +01:00
$scope.ready = false;
$scope.config = Client.getConfig();
$scope.user = Client.getUserInfo();
2020-02-11 21:06:34 +01:00
$scope.domains = [];
2020-03-25 20:13:45 -07:00
$scope.pageItemCount = [
2020-11-12 16:38:48 +01:00
{ name: $translate.instant('main.pagination.perPageSelector', { n: 20 }), value: 20 },
{ name: $translate.instant('main.pagination.perPageSelector', { n: 50 }), value: 50 },
{ name: $translate.instant('main.pagination.perPageSelector', { n: 100 }), value: 100 }
2020-03-25 20:13:45 -07:00
];
$scope.activityTypes = [
{ name: 'Bounce', value: 'bounce' },
{ name: 'Deferred', value: 'deferred' },
{ name: 'Delivered', value: 'delivered' },
{ name: 'Denied', value: 'denied' },
{ name: 'Queued', value: 'queued' },
{ name: 'Received', value: 'received' },
];
2020-02-11 22:07:58 -08:00
$scope.activity = {
2020-02-12 15:37:05 +01:00
busy: true,
eventLogs: [],
activeEventLog: null,
2020-02-11 22:07:58 -08:00
currentPage: 1,
2020-03-07 02:21:21 -08:00
perPage: 20,
2020-03-25 20:13:45 -07:00
pageItems: $scope.pageItemCount[0],
selectedTypes: [],
search: '',
2020-02-11 22:07:58 -08:00
2020-02-13 12:01:19 +01:00
refresh: function () {
2020-02-12 15:37:05 +01:00
$scope.activity.busy = true;
2020-03-25 20:13:45 -07:00
var types = $scope.activity.selectedTypes.map(function (a) { return a.value; }).join(',');
Client.getMailEventLogs($scope.activity.search, types, $scope.activity.currentPage, $scope.activity.pageItems.value, function (error, result) {
2020-02-12 15:37:05 +01:00
if (error) return console.error('Failed to fetch mail eventlogs.', error);
$scope.activity.busy = false;
2020-02-12 23:17:24 -08:00
$scope.activity.eventLogs = result;
2020-02-11 22:07:58 -08:00
});
},
showNextPage: function () {
$scope.activity.currentPage++;
2020-02-13 12:01:19 +01:00
$scope.activity.refresh();
2020-02-11 22:07:58 -08:00
},
showPrevPage: function () {
if ($scope.activity.currentPage > 1) $scope.activity.currentPage--;
else $scope.activity.currentPage = 1;
2020-02-13 12:01:19 +01:00
$scope.activity.refresh();
2020-02-12 15:37:05 +01:00
},
showEventLogDetails: function (eventLog) {
if ($scope.activity.activeEventLog === eventLog) $scope.activity.activeEventLog = null;
else $scope.activity.activeEventLog = eventLog;
2020-02-18 19:48:17 -08:00
},
2020-03-25 20:13:45 -07:00
updateFilter: function (fresh) {
if (fresh) $scope.activity.currentPage = 1;
2020-02-18 19:48:17 -08:00
$scope.activity.refresh();
2020-02-11 22:07:58 -08:00
}
};
// this is required because we need to rewrite the MAIL_SERVER_NAME env var
$scope.reconfigureEmailApps = function () {
var installedApps = Client.getInstalledApps();
for (var i = 0; i < installedApps.length; i++) {
if (!installedApps[i].manifest.addons.email) continue;
Client.repairApp(installedApps[i].id, { }, function (error) {
if (error) console.error(error);
});
}
};
2020-08-20 23:06:22 -07:00
$scope.mailLocation = {
2020-08-17 22:44:01 +02:00
busy: false,
error: null,
2020-08-20 23:06:22 -07:00
currentLocation: { domain: null, subdomain: '' },
domain: null,
subdomain: '',
2020-09-01 16:31:23 +02:00
taskId: null,
percent: 0,
message: '',
errorMessage: '',
reconfigure: false,
2020-08-17 22:44:01 +02:00
2020-08-22 19:34:06 -07:00
refresh: function () {
Client.getMailLocation(function (error, location) {
if (error) return console.error('Failed to get max email location', error);
$scope.mailLocation.currentLocation.subdomain = location.subdomain;
$scope.mailLocation.currentLocation.domain = $scope.domains.find(function (d) { return location.domain === d.domain; });
2020-09-01 16:31:23 +02:00
Client.getLatestTaskByType(TASK_TYPES.TASK_CHANGE_MAIL_LOCATION, function (error, task) {
if (error) return console.error(error);
if (!task) return;
$scope.mailLocation.taskId = task.id;
$scope.mailLocation.reconfigure = task.active; // if task is active when this view reloaded, reconfigure email apps when task done
2020-09-01 16:31:23 +02:00
$scope.mailLocation.updateStatus();
});
2020-08-22 19:34:06 -07:00
});
},
2020-08-17 22:44:01 +02:00
show: function () {
2020-08-20 23:06:22 -07:00
$scope.mailLocation.busy = false;
$scope.mailLocation.error = null;
$scope.mailLocation.domain = $scope.mailLocation.currentLocation.domain;
$scope.mailLocation.subdomain = $scope.mailLocation.currentLocation.subdomain;
2020-08-17 22:44:01 +02:00
2020-08-20 23:06:22 -07:00
$scope.mailLocationForm.$setUntouched();
$scope.mailLocationForm.$setPristine();
2020-08-17 22:44:01 +02:00
2020-08-20 23:06:22 -07:00
$('#mailLocationModal').modal('show');
2020-08-17 22:44:01 +02:00
},
2020-09-01 16:31:23 +02:00
updateStatus: function () {
Client.getTask($scope.mailLocation.taskId, function (error, data) {
if (error) return window.setTimeout($scope.mailLocation.updateStatus, 5000);
if (!data.active) {
$scope.mailLocation.taskId = null;
$scope.mailLocation.busy = false;
$scope.mailLocation.message = '';
$scope.mailLocation.percent = 0;
2020-09-01 16:31:23 +02:00
$scope.mailLocation.errorMessage = data.success ? '' : data.error.message;
if ($scope.mailLocation.reconfigure) $scope.reconfigureEmailApps();
2020-09-01 16:31:23 +02:00
return;
}
$scope.mailLocation.busy = true;
$scope.mailLocation.percent = data.percent;
$scope.mailLocation.message = data.message;
window.setTimeout($scope.mailLocation.updateStatus, 1000);
});
},
2020-08-17 22:44:01 +02:00
submit: function () {
2020-08-20 23:06:22 -07:00
$scope.mailLocation.busy = true;
2020-09-01 16:31:23 +02:00
Client.setMailLocation($scope.mailLocation.subdomain, $scope.mailLocation.domain.domain, function (error, result) {
2020-08-20 23:06:22 -07:00
if (error) {
$scope.mailLocation.busy = false;
$scope.mailLocation.error = error;
return;
}
2020-09-01 16:31:23 +02:00
// update UI immediately
$scope.mailLocation.currentLocation = { subdomain: $scope.mailLocation.subdomain, domain: $scope.mailLocation.domain };
$scope.mailLocation.taskId = result.taskId;
$scope.mailLocation.reconfigure = true; // reconfigure email apps when task done
2020-09-01 16:31:23 +02:00
$scope.mailLocation.updateStatus();
$('#mailLocationModal').modal('hide');
2020-08-20 23:06:22 -07:00
});
2020-08-17 22:44:01 +02:00
}
};
$scope.maxEmailSize = {
busy: false,
error: null,
size: 0,
currentSize: 0,
2020-08-22 19:34:06 -07:00
refresh: function () {
Client.getMaxEmailSize(function (error, size) {
if (error) return console.error('Failed to get max email size', error);
$scope.maxEmailSize.currentSize = size;
});
},
2020-08-17 22:44:01 +02:00
show: function() {
$scope.maxEmailSize.busy = false;
$scope.maxEmailSize.error = null;
2020-08-20 22:07:20 -07:00
$scope.maxEmailSize.size = $scope.maxEmailSize.currentSize;
2020-08-17 22:44:01 +02:00
$scope.maxEmailSizeChangeForm.$setUntouched();
$scope.maxEmailSizeChangeForm.$setPristine();
$('#maxEmailSizeChangeModal').modal('show');
},
submit: function () {
2020-08-20 22:07:20 -07:00
$scope.maxEmailSize.busy = true;
Client.setMaxEmailSize($scope.maxEmailSize.size, function (error) {
$scope.maxEmailSize.busy = false;
if (error) return console.error(error);
$scope.maxEmailSize.currentSize = $scope.maxEmailSize.size;
$('#maxEmailSizeChangeModal').modal('hide');
});
2020-08-17 22:44:01 +02:00
}
};
2020-08-22 13:01:25 -07:00
$scope.spamConfig = {
2020-08-17 22:44:01 +02:00
busy: false,
2020-08-22 13:01:25 -07:00
error: {},
acl: { whitelist: [], blacklist: [] },
customConfig: '',
config: '',
blacklist: '', // currently, we don't support whitelist because it requires user to understand a bit more of what he is doing
refresh: function () {
Client.getSpamCustomConfig(function (error, config) {
if (error) return console.error('Failed to get custom spam config', error);
$scope.spamConfig.customConfig = config;
});
Client.getSpamAcl(function (error, acl) {
if (error) return console.error('Failed to get spam acl', error);
$scope.spamConfig.acl = acl;
});
},
2020-08-17 22:44:01 +02:00
show: function() {
2020-08-22 13:01:25 -07:00
$scope.spamConfig.busy = false;
$scope.spamConfig.error = {};
$scope.spamConfig.blacklist = $scope.spamConfig.acl.blacklist.join('\n');
$scope.spamConfig.config = $scope.spamConfig.customConfig;
2020-08-17 22:44:01 +02:00
2020-08-22 13:01:25 -07:00
$scope.spamConfigChangeForm.$setUntouched();
$scope.spamConfigChangeForm.$setPristine();
2020-08-17 22:44:01 +02:00
2020-08-22 13:01:25 -07:00
$('#spamConfigChangeModal').modal('show');
2020-08-17 22:44:01 +02:00
},
submit: function () {
2020-08-22 13:01:25 -07:00
$scope.spamConfig.busy = true;
$scope.spamConfig.error = {};
var blacklist = $scope.spamConfig.blacklist.split('\n').filter(function (l) { return l !== ''; });
Client.setSpamAcl({ blacklist: blacklist, whitelist: [] }, function (error) {
if (error) {
$scope.spamConfig.busy = false;
$scope.spamConfig.error.blacklist = error.message;
$scope.spamConfigChangeForm.blacklist.$setPristine();
return;
}
Client.setSpamCustomConfig($scope.spamConfig.config, function (error) {
if (error) {
$scope.spamConfig.busy = false;
$scope.spamConfig.error.config = error.message;
$scope.spamConfigChangeForm.config.$setPristine();
return;
}
$scope.spamConfig.busy = false;
$scope.spamConfig.refresh();
$('#spamConfigChangeModal').modal('hide');
});
});
2020-08-17 22:44:01 +02:00
}
2020-08-20 23:06:22 -07:00
},
2020-08-17 22:44:01 +02:00
$scope.testEmail = {
busy: false,
error: {},
mailTo: '',
domain: null,
clearForm: function () {
$scope.testEmail.mailTo = '';
},
show: function (domain) {
$scope.testEmail.error = {};
$scope.testEmail.busy = false;
$scope.testEmail.domain = domain;
$scope.testEmail.mailTo = $scope.user.email;
$('#testEmailModal').modal('show');
},
submit: function () {
$scope.testEmail.error = {};
$scope.testEmail.busy = true;
Client.sendTestMail($scope.testEmail.domain.domain, $scope.testEmail.mailTo, function (error) {
$scope.testEmail.busy = false;
if (error) {
$scope.testEmail.error.generic = error.message;
console.error(error);
$('#inputTestMailTo').focus();
return;
}
$('#testEmailModal').modal('hide');
});
}
};
function refreshDomainStatuses() {
$scope.domains.forEach(function (domain) {
Client.getMailStatusForDomain(domain.domain, function (error, result) {
if (error) return console.error('Failed to fetch mail status for domain', domain.domain, error);
domain.status = result;
2020-02-27 10:37:21 -08:00
domain.statusOk = Object.keys(result).every(function (k) {
if (k === 'dns') return Object.keys(result.dns).every(function (k) { return result.dns[k].status; });
if (!('status' in result[k])) return true; // if status is not present, the test was not run
return result[k].status;
});
});
2020-02-20 12:35:51 -08:00
Client.getMailConfigForDomain(domain.domain, function (error, mailConfig) {
if (error) return console.error('Failed to fetch mail config for domain', domain.domain, error);
domain.inbound = mailConfig.enabled;
domain.outbound = mailConfig.relay.provider !== 'noop';
// do this even if no outbound since people forget to remove mailboxes
2020-07-15 15:35:32 -07:00
Client.getMailboxCount(domain.domain, function (error, count) {
2020-02-20 12:35:51 -08:00
if (error) return console.error('Failed to fetch mailboxes for domain', domain.domain, error);
2020-07-15 15:35:32 -07:00
domain.mailboxCount = count;
2020-02-20 12:35:51 -08:00
Client.getMailUsage(domain.domain, function (error, usage) {
if (error) return console.error('Failed to fetch usage for domain', domain.domain, error);
domain.usage = 0;
Object.keys(usage).forEach(function (m) { domain.usage += usage[m].size; });
});
});
});
2020-08-22 19:34:06 -07:00
$scope.maxEmailSize.refresh();
2020-08-22 13:01:25 -07:00
$scope.spamConfig.refresh();
});
}
2020-02-11 21:06:34 +01:00
Client.onReady(function () {
Client.getDomains(function (error, domains) {
if (error) return console.error('Unable to get domain listing.', error);
$scope.domains = domains;
$scope.ready = true;
2020-02-11 22:07:58 -08:00
2020-03-26 18:56:32 -07:00
if ($scope.user.role === 'owner') $scope.activity.refresh();
2020-08-22 19:34:06 -07:00
$scope.mailLocation.refresh();
2020-09-01 16:31:23 +02:00
refreshDomainStatuses();
2020-02-11 21:06:34 +01:00
});
});
// setup all the dialog focus handling
['testEmailModal'].forEach(function (id) {
$('#' + id).on('shown.bs.modal', function () {
$(this).find('[autofocus]:first').focus();
});
});
2020-02-11 21:06:34 +01:00
$('.modal-backdrop').remove();
}]);