2018-01-22 13:01:38 -08:00
|
|
|
'use strict';
|
|
|
|
|
|
2019-01-22 10:54:03 +01:00
|
|
|
/* global angular:false */
|
|
|
|
|
/* global $:false */
|
|
|
|
|
|
2018-06-11 10:30:02 -07:00
|
|
|
angular.module('Application').controller('EmailController', ['$scope', '$location', '$timeout', '$rootScope', 'Client', function ($scope, $location, $timeout, $rootScope, Client) {
|
2018-08-03 10:09:04 -07:00
|
|
|
Client.onReady(function () { if (!Client.getUserInfo().admin) $location.path('/'); });
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.ready = false;
|
|
|
|
|
$scope.refreshBusy = true;
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.client = Client;
|
|
|
|
|
$scope.user = Client.getUserInfo();
|
|
|
|
|
$scope.config = Client.getConfig();
|
2018-12-06 10:28:42 -08:00
|
|
|
$scope.apps = Client.getInstalledApps();
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.domains = [];
|
2018-01-23 15:11:33 +01:00
|
|
|
$scope.users = [];
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.selectedDomain = null;
|
|
|
|
|
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.expectedDnsRecords = {
|
|
|
|
|
mx: { },
|
|
|
|
|
dkim: { },
|
|
|
|
|
spf: { },
|
|
|
|
|
dmarc: { },
|
|
|
|
|
ptr: { }
|
|
|
|
|
};
|
|
|
|
|
$scope.expectedDnsRecordsTypes = [
|
|
|
|
|
{ name: 'MX', value: 'mx' },
|
|
|
|
|
{ name: 'DKIM', value: 'dkim' },
|
|
|
|
|
{ name: 'SPF', value: 'spf' },
|
|
|
|
|
{ name: 'DMARC', value: 'dmarc' },
|
|
|
|
|
{ name: 'PTR', value: 'ptr' }
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$scope.showView = function (view) {
|
|
|
|
|
// wait for dialog to be fully closed to avoid modal behavior breakage when moving to a different view already
|
|
|
|
|
$('.modal').on('hidden.bs.modal', function () {
|
|
|
|
|
$('.modal').off('hidden.bs.modal');
|
|
|
|
|
$location.path(view);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('.modal').modal('hide');
|
|
|
|
|
};
|
|
|
|
|
|
2019-04-22 16:40:50 -07:00
|
|
|
$scope.usesTokenAuth = function (provider) {
|
|
|
|
|
return provider === 'postmark-smtp' || provider === 'sendgrid-smtp';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$scope.usesExternalServer = function (provider) {
|
|
|
|
|
return provider !== 'cloudron-smtp' && provider !== 'noop';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$scope.usesPasswordAuth = function (provider) {
|
|
|
|
|
return provider !== 'postmark-smtp' && provider !== 'sendgrid-smtp';
|
2018-01-22 13:01:38 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$scope.catchall = {
|
2018-04-12 13:02:32 +02:00
|
|
|
mailboxes: [],
|
2018-01-22 13:01:38 -08:00
|
|
|
busy: false,
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.catchall.busy = true;
|
|
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
var addresses = $scope.catchall.mailboxes.map(function (m) { return m.name; });
|
|
|
|
|
|
|
|
|
|
Client.setCatchallAddresses($scope.selectedDomain.domain, addresses, function (error) {
|
2018-01-22 13:01:38 -08:00
|
|
|
if (error) console.error('Unable to add catchall address.', error);
|
|
|
|
|
|
2019-01-31 12:24:27 -08:00
|
|
|
$timeout(function () { $scope.catchall.busy = false; }, 2000); // otherwise, it's too fast
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
2018-04-12 13:02:32 +02:00
|
|
|
},
|
|
|
|
|
|
|
|
|
|
refresh: function () {
|
|
|
|
|
$scope.catchall.mailboxes = $scope.selectedDomain.mailConfig.catchAll.map(function (name) {
|
|
|
|
|
return $scope.mailboxes.mailboxes.find(function (m) { return m.name === name; });
|
|
|
|
|
}).filter(function (m) { return !!m; });
|
2018-01-22 13:01:38 -08:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-04-01 21:58:12 +02:00
|
|
|
$scope.mailinglists = {
|
|
|
|
|
busy: false,
|
2018-04-06 16:43:43 +02:00
|
|
|
mailinglists: [],
|
2018-04-01 21:58:12 +02:00
|
|
|
|
2018-04-06 16:43:43 +02:00
|
|
|
add: {
|
|
|
|
|
busy: false,
|
2018-04-09 16:12:18 +02:00
|
|
|
error: null,
|
2018-04-06 16:43:43 +02:00
|
|
|
name: '',
|
|
|
|
|
members: [],
|
|
|
|
|
|
2018-04-09 16:12:18 +02:00
|
|
|
reset: function () {
|
|
|
|
|
$scope.mailinglists.add.busy = false;
|
|
|
|
|
$scope.mailinglists.add.error = null;
|
|
|
|
|
$scope.mailinglists.add.name = '';
|
|
|
|
|
$scope.mailinglists.add.members = [];
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
show: function () {
|
|
|
|
|
$scope.mailinglists.add.reset();
|
|
|
|
|
$('#mailinglistAddModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-06 16:43:43 +02:00
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailinglists.add.busy = true;
|
2018-04-01 21:58:12 +02:00
|
|
|
|
2018-04-12 11:57:15 +02:00
|
|
|
var members = $scope.mailinglists.add.members.map(function (m) { return m.name; });
|
|
|
|
|
|
|
|
|
|
Client.addMailingList($scope.selectedDomain.domain, $scope.mailinglists.add.name, members, function (error) {
|
2018-04-06 16:43:43 +02:00
|
|
|
if (error) {
|
2018-04-09 16:12:18 +02:00
|
|
|
$scope.mailinglists.add.busy = false;
|
|
|
|
|
$scope.mailinglists.add.error = error;
|
2018-04-06 16:43:43 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-09 16:12:18 +02:00
|
|
|
$scope.mailinglists.add.reset();
|
2018-04-06 16:43:43 +02:00
|
|
|
$scope.mailinglists.refresh();
|
2018-04-09 16:12:18 +02:00
|
|
|
|
|
|
|
|
$('#mailinglistAddModal').modal('hide');
|
2018-04-01 21:58:12 +02:00
|
|
|
});
|
2018-04-06 16:43:43 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-09 15:01:12 +02:00
|
|
|
edit: {
|
|
|
|
|
busy: false,
|
|
|
|
|
error: null,
|
2018-04-12 12:02:20 +02:00
|
|
|
name: '',
|
|
|
|
|
members: [],
|
2018-04-09 15:01:12 +02:00
|
|
|
|
|
|
|
|
show: function (list) {
|
2018-04-12 12:02:20 +02:00
|
|
|
$scope.mailinglists.edit.name = list.name;
|
2018-06-12 13:37:31 -07:00
|
|
|
var members = list.members.map(function (name) {
|
|
|
|
|
return $scope.mailboxes.mailboxes.find(function (m) { return m.name === name; });
|
|
|
|
|
});
|
2018-04-12 12:12:11 +02:00
|
|
|
|
|
|
|
|
// A mailinglist may contain mailbox names, which do not exist, so remove them here
|
|
|
|
|
$scope.mailinglists.edit.members = members.filter(function (m) { return !!m; });
|
2018-04-09 15:01:12 +02:00
|
|
|
|
|
|
|
|
$('#mailinglistEditModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailinglists.edit.busy = true;
|
|
|
|
|
|
2018-04-12 12:02:20 +02:00
|
|
|
var members = $scope.mailinglists.edit.members.map(function (m) { return m.name; });
|
|
|
|
|
|
|
|
|
|
Client.updateMailingList($scope.selectedDomain.domain, $scope.mailinglists.edit.name, members, function (error) {
|
2018-04-09 15:01:12 +02:00
|
|
|
$scope.mailinglists.edit.busy = false;
|
|
|
|
|
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
2018-04-12 12:12:22 +02:00
|
|
|
$scope.mailinglists.refresh();
|
|
|
|
|
|
2018-04-09 15:01:12 +02:00
|
|
|
$('#mailinglistEditModal').modal('hide');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-06 16:43:43 +02:00
|
|
|
remove: {
|
|
|
|
|
busy: false,
|
|
|
|
|
list: null,
|
|
|
|
|
|
|
|
|
|
show: function (list) {
|
|
|
|
|
$scope.mailinglists.remove.list = list;
|
|
|
|
|
|
|
|
|
|
$('#mailinglistRemoveModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailinglists.remove.busy = true;
|
|
|
|
|
|
|
|
|
|
Client.removeMailingList($scope.selectedDomain.domain, $scope.mailinglists.remove.list.name, function (error) {
|
|
|
|
|
$scope.mailinglists.remove.busy = false;
|
|
|
|
|
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.mailinglists.remove.list = null;
|
|
|
|
|
$scope.mailinglists.refresh();
|
|
|
|
|
|
|
|
|
|
$('#mailinglistRemoveModal').modal('hide');
|
2018-04-01 21:58:12 +02:00
|
|
|
});
|
2018-04-06 16:43:43 +02:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
refresh: function (callback) {
|
|
|
|
|
callback = typeof callback === 'function' ? callback : function (error) { if (error) return console.error(error); };
|
|
|
|
|
|
2018-04-12 11:57:15 +02:00
|
|
|
Client.listMailingLists($scope.selectedDomain.domain, function (error, result) {
|
2018-04-12 13:02:32 +02:00
|
|
|
if (error) return callback(error);
|
2018-04-06 16:43:43 +02:00
|
|
|
|
2018-04-12 12:15:23 +02:00
|
|
|
$scope.mailinglists.mailinglists = result;
|
2018-04-12 13:02:32 +02:00
|
|
|
|
|
|
|
|
callback();
|
2018-04-01 21:58:12 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-05-23 23:34:09 -07:00
|
|
|
$scope.toggleMailFromValidation = function () {
|
|
|
|
|
Client.setMailFromValidation($scope.selectedDomain.domain, !$scope.selectedDomain.mailConfig.mailFromValidation, function (error) {
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
$scope.refreshDomain();
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
$scope.incomingEmail = {
|
|
|
|
|
busy: false,
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
toggleEmailEnabled: function () {
|
|
|
|
|
if ($scope.selectedDomain.mailConfig.enabled) {
|
|
|
|
|
$('#disableEmailModal').modal('show');
|
|
|
|
|
} else {
|
|
|
|
|
$('#enableEmailModal').modal('show');
|
|
|
|
|
}
|
|
|
|
|
},
|
2018-05-29 17:17:53 +02:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
enable: function () {
|
|
|
|
|
$('#enableEmailModal').modal('hide');
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
$scope.incomingEmail.busy = true;
|
2018-07-25 10:51:58 -07:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
Client.enableMailForDomain($scope.selectedDomain.domain, true , function (error) {
|
2018-07-25 10:51:58 -07:00
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
2018-08-12 13:13:52 -07:00
|
|
|
$scope.reconfigureEmailApps();
|
|
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
Client.setDnsRecords($scope.selectedDomain.domain, function (error) {
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.refreshDomain();
|
|
|
|
|
|
|
|
|
|
$scope.incomingEmail.busy = false;
|
|
|
|
|
});
|
2018-07-25 10:51:58 -07:00
|
|
|
});
|
2018-07-30 11:26:26 -07:00
|
|
|
},
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
disable: function () {
|
|
|
|
|
$('#disableEmailModal').modal('hide');
|
2018-05-06 23:36:40 -07:00
|
|
|
|
2018-07-30 11:26:26 -07:00
|
|
|
$scope.incomingEmail.busy = true;
|
|
|
|
|
|
|
|
|
|
Client.enableMailForDomain($scope.selectedDomain.domain, false , function (error) {
|
|
|
|
|
if (error) return console.error(error);
|
2018-08-12 13:13:52 -07:00
|
|
|
|
|
|
|
|
$scope.reconfigureEmailApps();
|
2018-07-30 11:26:26 -07:00
|
|
|
$scope.refreshDomain();
|
|
|
|
|
$scope.incomingEmail.busy = false;
|
|
|
|
|
});
|
|
|
|
|
}
|
2018-01-22 13:01:38 -08:00
|
|
|
};
|
|
|
|
|
|
2018-03-30 18:06:40 +02:00
|
|
|
$scope.mailboxes = {
|
2018-04-05 21:00:33 +02:00
|
|
|
mailboxes: [],
|
2018-04-06 16:51:57 +02:00
|
|
|
|
2018-04-05 21:00:33 +02:00
|
|
|
add: {
|
2018-04-09 15:56:20 +02:00
|
|
|
error: null,
|
2018-04-05 21:00:33 +02:00
|
|
|
busy: false,
|
|
|
|
|
name: '',
|
|
|
|
|
owner: null,
|
|
|
|
|
|
2018-04-09 15:56:20 +02:00
|
|
|
reset: function () {
|
|
|
|
|
$scope.mailboxes.add.busy = false;
|
|
|
|
|
$scope.mailboxes.add.error = null;
|
|
|
|
|
$scope.mailboxes.add.name = '';
|
|
|
|
|
$scope.mailboxes.add.owner = null;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
show: function () {
|
|
|
|
|
$scope.mailboxes.add.reset();
|
|
|
|
|
$('#mailboxAddModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-05 21:00:33 +02:00
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailboxes.add.busy = true;
|
|
|
|
|
|
|
|
|
|
Client.addMailbox($scope.selectedDomain.domain, $scope.mailboxes.add.name, $scope.mailboxes.add.owner.id, function (error) {
|
2018-04-06 16:51:57 +02:00
|
|
|
if (error) {
|
2018-04-09 15:56:20 +02:00
|
|
|
$scope.mailboxes.add.busy = false;
|
2018-04-09 16:21:32 +02:00
|
|
|
$scope.mailboxes.add.error = error;
|
2018-04-06 16:51:57 +02:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-09 15:56:20 +02:00
|
|
|
$scope.mailboxes.add.reset();
|
2018-04-12 13:02:32 +02:00
|
|
|
$scope.mailboxes.refresh(function (error) {
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.catchall.refresh();
|
2018-04-09 15:56:20 +02:00
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
$('#mailboxAddModal').modal('hide');
|
|
|
|
|
});
|
2018-04-05 21:00:33 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-09 12:42:14 +02:00
|
|
|
edit: {
|
|
|
|
|
busy: false,
|
|
|
|
|
error: null,
|
2018-04-12 12:26:51 +02:00
|
|
|
name: '',
|
|
|
|
|
owner: null,
|
|
|
|
|
aliases: '',
|
2018-04-09 12:42:14 +02:00
|
|
|
|
|
|
|
|
show: function (mailbox) {
|
2018-04-12 12:26:51 +02:00
|
|
|
$scope.mailboxes.edit.name = mailbox.name;
|
2019-01-10 13:31:49 -08:00
|
|
|
$scope.mailboxes.edit.owner = mailbox.owner; // this can be null if mailbox had no owner
|
2018-04-12 12:26:51 +02:00
|
|
|
$scope.mailboxes.edit.aliases = mailbox.aliases;
|
2018-04-09 12:42:14 +02:00
|
|
|
|
|
|
|
|
$('#mailboxEditModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
2018-04-09 15:01:12 +02:00
|
|
|
$scope.mailboxes.edit.busy = true;
|
2018-04-09 12:42:14 +02:00
|
|
|
|
2019-01-10 13:31:49 -08:00
|
|
|
// $scope.mailboxes.edit.owner is expected to be validated by the UI
|
2018-04-12 12:26:51 +02:00
|
|
|
Client.updateMailbox($scope.selectedDomain.domain, $scope.mailboxes.edit.name, $scope.mailboxes.edit.owner.id, function (error) {
|
2018-04-09 12:42:14 +02:00
|
|
|
if (error) {
|
|
|
|
|
$scope.mailboxes.edit.error = error;
|
|
|
|
|
$scope.mailboxes.edit.busy = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-04-12 12:26:51 +02:00
|
|
|
var aliases = $scope.mailboxes.edit.aliases.split(',').map(function (a) { return a.trim(); }).filter(function (a) { return !!a; });
|
2018-04-09 12:42:14 +02:00
|
|
|
|
2018-04-12 12:26:51 +02:00
|
|
|
Client.setAliases($scope.selectedDomain.domain, $scope.mailboxes.edit.name, aliases, function (error) {
|
2018-04-09 12:42:14 +02:00
|
|
|
if (error) {
|
|
|
|
|
$scope.mailboxes.edit.error = error;
|
|
|
|
|
$scope.mailboxes.edit.busy = false;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$scope.mailboxes.edit.busy = false;
|
|
|
|
|
$scope.mailboxes.edit.error = null;
|
2018-04-12 12:26:51 +02:00
|
|
|
$scope.mailboxes.edit.name = '';
|
|
|
|
|
$scope.mailboxes.edit.owner = null;
|
|
|
|
|
$scope.mailboxes.edit.aliases = '';
|
2018-04-09 12:42:14 +02:00
|
|
|
$scope.mailboxes.refresh();
|
|
|
|
|
|
|
|
|
|
$('#mailboxEditModal').modal('hide');
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-05 21:22:07 +02:00
|
|
|
remove: {
|
|
|
|
|
busy: false,
|
|
|
|
|
mailbox: null,
|
|
|
|
|
|
|
|
|
|
show: function (mailbox) {
|
|
|
|
|
$scope.mailboxes.remove.mailbox = mailbox;
|
|
|
|
|
|
|
|
|
|
$('#mailboxRemoveModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailboxes.remove.busy = true;
|
|
|
|
|
|
|
|
|
|
Client.removeMailbox($scope.selectedDomain.domain, $scope.mailboxes.remove.mailbox.name, function (error) {
|
|
|
|
|
$scope.mailboxes.remove.busy = false;
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.mailboxes.remove.mailbox = null;
|
2018-04-12 13:02:32 +02:00
|
|
|
$scope.mailboxes.refresh(function (error) {
|
|
|
|
|
if (error) return console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.catchall.refresh();
|
2018-04-05 21:22:07 +02:00
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
$('#mailboxRemoveModal').modal('hide');
|
|
|
|
|
});
|
2018-04-05 21:22:07 +02:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
refresh: function (callback) {
|
|
|
|
|
callback = typeof callback === 'function' ? callback : function (error) { if (error) return console.error(error); };
|
|
|
|
|
|
2018-04-05 21:00:33 +02:00
|
|
|
Client.getMailboxes($scope.selectedDomain.domain, function (error, mailboxes) {
|
2018-04-12 13:02:32 +02:00
|
|
|
if (error) return callback(error);
|
2018-04-05 21:00:33 +02:00
|
|
|
|
|
|
|
|
Client.listAliases($scope.selectedDomain.domain, function (error, aliases) {
|
2018-04-12 13:02:32 +02:00
|
|
|
if (error) return callback(error);
|
2018-04-05 21:00:33 +02:00
|
|
|
|
|
|
|
|
$scope.mailboxes.mailboxes = mailboxes.map(function (m) {
|
2018-04-05 21:15:02 +02:00
|
|
|
m.aliases = aliases.filter(function (a) { return a.aliasTarget === m.name; }).map(function (a) { return a.name; }).join(',');
|
2019-01-10 13:31:49 -08:00
|
|
|
m.owner = $scope.users.find(function (u) { return u.id === m.ownerId; }); // owner may not exist
|
|
|
|
|
m.ownerDisplayName = m.owner ? m.owner.display : ''; // this meta property is set when we get the user list
|
2018-12-06 10:28:42 -08:00
|
|
|
|
2018-04-05 21:00:33 +02:00
|
|
|
return m;
|
|
|
|
|
});
|
2018-04-12 13:02:32 +02:00
|
|
|
|
|
|
|
|
callback();
|
2018-04-05 21:00:33 +02:00
|
|
|
});
|
|
|
|
|
});
|
2018-03-30 18:06:40 +02:00
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.mailRelayPresets = [
|
|
|
|
|
{ provider: 'cloudron-smtp', name: 'Built-in SMTP server' },
|
|
|
|
|
{ provider: 'external-smtp', name: 'External SMTP server', host: '', port: 587 },
|
|
|
|
|
{ provider: 'ses-smtp', name: 'Amazon SES', host: 'email-smtp.us-east-1.amazonaws.com', port: 587 },
|
|
|
|
|
{ provider: 'google-smtp', name: 'Google', host: 'smtp.gmail.com', port: 587 },
|
|
|
|
|
{ provider: 'mailgun-smtp', name: 'Mailgun', host: 'smtp.mailgun.org', port: 587 },
|
2018-07-23 16:42:11 -07:00
|
|
|
{ provider: 'mailjet-smtp', name: 'Mailjet', host: '', port: 587 },
|
2018-01-22 13:01:38 -08:00
|
|
|
{ provider: 'postmark-smtp', name: 'Postmark', host: 'smtp.postmarkapp.com', port: 587 },
|
|
|
|
|
{ provider: 'sendgrid-smtp', name: 'SendGrid', host: 'smtp.sendgrid.net', port: 587, username: 'apikey' },
|
2019-03-15 11:16:43 -07:00
|
|
|
{ provider: 'noop', name: 'Disable' },
|
2018-01-22 13:01:38 -08:00
|
|
|
];
|
|
|
|
|
|
|
|
|
|
$scope.mailRelay = {
|
|
|
|
|
error: null,
|
|
|
|
|
success: false,
|
|
|
|
|
busy: false,
|
|
|
|
|
preset: $scope.mailRelayPresets[0],
|
|
|
|
|
|
|
|
|
|
presetChanged: function () {
|
|
|
|
|
$scope.mailRelay.error = null;
|
|
|
|
|
|
|
|
|
|
$scope.mailRelay.relay.provider = $scope.mailRelay.preset.provider;
|
|
|
|
|
$scope.mailRelay.relay.host = $scope.mailRelay.preset.host;
|
|
|
|
|
$scope.mailRelay.relay.port = $scope.mailRelay.preset.port;
|
|
|
|
|
$scope.mailRelay.relay.username = '';
|
|
|
|
|
$scope.mailRelay.relay.password = '';
|
|
|
|
|
$scope.mailRelay.relay.serverApiToken = '';
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// form data to be set on load
|
|
|
|
|
relay: {
|
|
|
|
|
provider: 'cloudron-smtp',
|
|
|
|
|
host: '',
|
|
|
|
|
port: 25,
|
|
|
|
|
username: '',
|
|
|
|
|
password: '',
|
|
|
|
|
serverApiToken: ''
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.mailRelay.error = null;
|
|
|
|
|
$scope.mailRelay.busy = true;
|
|
|
|
|
$scope.mailRelay.success = false;
|
|
|
|
|
|
|
|
|
|
var data = {
|
|
|
|
|
provider: $scope.mailRelay.relay.provider,
|
|
|
|
|
host: $scope.mailRelay.relay.host,
|
|
|
|
|
port: $scope.mailRelay.relay.port
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// fill in provider specific username/password usage
|
|
|
|
|
if (data.provider === 'postmark-smtp') {
|
|
|
|
|
data.username = $scope.mailRelay.relay.serverApiToken;
|
|
|
|
|
data.password = $scope.mailRelay.relay.serverApiToken;
|
|
|
|
|
} else if (data.provider === 'sendgrid-smtp') {
|
|
|
|
|
data.username = 'apikey';
|
|
|
|
|
data.password = $scope.mailRelay.relay.serverApiToken;
|
|
|
|
|
} else {
|
|
|
|
|
data.username = $scope.mailRelay.relay.username;
|
|
|
|
|
data.password = $scope.mailRelay.relay.password;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
Client.setMailRelay($scope.selectedDomain.domain, data, function (error) {
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.mailRelay.busy = false;
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
$scope.mailRelay.error = error.message;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.selectedDomain.relay = data;
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.mailRelay.success = true;
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.refreshDomain();
|
|
|
|
|
|
|
|
|
|
// clear success indicator after 3sec
|
|
|
|
|
$timeout(function () { $scope.mailRelay.success = false; }, 3000);
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
$scope.testEmail = {
|
|
|
|
|
busy: false,
|
|
|
|
|
error: {},
|
|
|
|
|
|
|
|
|
|
mailTo: '',
|
|
|
|
|
|
2018-01-23 16:10:09 -08:00
|
|
|
domain: null,
|
|
|
|
|
|
2018-01-22 13:01:38 -08:00
|
|
|
clearForm: function () {
|
|
|
|
|
$scope.testEmail.mailTo = '';
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
show: function () {
|
|
|
|
|
$scope.testEmail.error = {};
|
|
|
|
|
$scope.testEmail.busy = false;
|
|
|
|
|
|
2018-01-23 16:10:09 -08:00
|
|
|
$scope.testEmail.domain = $scope.selectedDomain;
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.testEmail.mailTo = $scope.user.email;
|
|
|
|
|
|
|
|
|
|
$('#testEmailModal').modal('show');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
submit: function () {
|
|
|
|
|
$scope.testEmail.error = {};
|
|
|
|
|
$scope.testEmail.busy = true;
|
|
|
|
|
|
2018-02-03 18:09:41 -08:00
|
|
|
Client.sendTestMail($scope.selectedDomain.domain, $scope.testEmail.mailTo, function (error) {
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.testEmail.busy = false;
|
|
|
|
|
|
|
|
|
|
if (error) {
|
|
|
|
|
$scope.testEmail.error.generic = error.message;
|
|
|
|
|
console.error(error);
|
|
|
|
|
$('#inputTestMailTo').focus();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$('#testEmailModal').modal('hide');
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-05-06 23:47:38 -07:00
|
|
|
function resetDnsRecords() {
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.expectedDnsRecordsTypes.forEach(function (record) {
|
|
|
|
|
var type = record.value;
|
2018-05-06 23:47:38 -07:00
|
|
|
$scope.expectedDnsRecords[type] = {};
|
|
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
$('#collapse_dns_' + type).collapse('hide');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#collapse_outbound_smtp').collapse('hide');
|
|
|
|
|
$('#collapse_rbl').collapse('hide');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function showExpectedDnsRecords() {
|
|
|
|
|
// open the record details if they are not correct
|
|
|
|
|
$scope.expectedDnsRecordsTypes.forEach(function (record) {
|
|
|
|
|
var type = record.value;
|
|
|
|
|
$scope.expectedDnsRecords[type] = $scope.selectedDomain.mailStatus.dns[type] || {};
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
if (!$scope.expectedDnsRecords[type].status) {
|
|
|
|
|
$('#collapse_dns_' + type).collapse('show');
|
|
|
|
|
}
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
2018-01-23 12:30:35 +01:00
|
|
|
|
|
|
|
|
if (!$scope.selectedDomain.mailStatus.relay.status) {
|
|
|
|
|
$('#collapse_outbound_smtp').collapse('show');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$scope.selectedDomain.mailStatus.rbl.status) {
|
|
|
|
|
$('#collapse_rbl').collapse('show');
|
|
|
|
|
}
|
2018-01-22 13:01:38 -08:00
|
|
|
}
|
|
|
|
|
|
2018-04-09 18:00:08 +02:00
|
|
|
$scope.selectDomain = function () {
|
|
|
|
|
$location.path('/email/' + $scope.selectedDomain.domain, false);
|
|
|
|
|
};
|
|
|
|
|
|
2018-08-12 13:13:52 -07:00
|
|
|
// this is required because we need to rewrite the MAIL_DOMAINS 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.configureApp(installedApps[i].id, { }, function (error) {
|
|
|
|
|
if (error) console.error(error);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.refreshDomain = function () {
|
|
|
|
|
$scope.refreshBusy = true;
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-05-06 23:47:38 -07:00
|
|
|
resetDnsRecords();
|
2018-01-23 12:30:35 +01:00
|
|
|
|
|
|
|
|
Client.getMailConfigForDomain($scope.selectedDomain.domain, function (error, mailConfig) {
|
|
|
|
|
if (error) {
|
|
|
|
|
$scope.refreshBusy = false;
|
|
|
|
|
return console.error(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// pre-fill the form
|
|
|
|
|
$scope.mailRelay.relay.provider = mailConfig.relay.provider;
|
|
|
|
|
$scope.mailRelay.relay.host = mailConfig.relay.host;
|
|
|
|
|
$scope.mailRelay.relay.port = mailConfig.relay.port;
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.mailRelay.relay.username = '';
|
|
|
|
|
$scope.mailRelay.relay.password = '';
|
|
|
|
|
$scope.mailRelay.relay.serverApiToken = '';
|
|
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
if (mailConfig.relay.provider === 'postmark-smtp') {
|
|
|
|
|
$scope.mailRelay.relay.serverApiToken = mailConfig.relay.username;
|
|
|
|
|
} else if (mailConfig.relay.provider === 'sendgrid-smtp') {
|
|
|
|
|
$scope.mailRelay.relay.serverApiToken = mailConfig.relay.password;
|
2018-01-22 13:01:38 -08:00
|
|
|
} else {
|
2018-01-23 12:30:35 +01:00
|
|
|
$scope.mailRelay.relay.username = mailConfig.relay.username;
|
|
|
|
|
$scope.mailRelay.relay.password = mailConfig.relay.password;
|
2018-01-22 13:01:38 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < $scope.mailRelayPresets.length; i++) {
|
2018-01-23 12:30:35 +01:00
|
|
|
if ($scope.mailRelayPresets[i].provider === mailConfig.relay.provider) {
|
2018-01-22 13:01:38 -08:00
|
|
|
$scope.mailRelay.preset = $scope.mailRelayPresets[i];
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-01-23 12:41:52 +01:00
|
|
|
// amend to selected domain to be available for the UI
|
|
|
|
|
$scope.selectedDomain.mailConfig = mailConfig;
|
|
|
|
|
$scope.selectedDomain.mailStatus = {};
|
|
|
|
|
|
2018-04-12 13:02:32 +02:00
|
|
|
$scope.mailboxes.refresh(function (error) {
|
|
|
|
|
if (error) console.error(error);
|
|
|
|
|
|
|
|
|
|
$scope.mailinglists.refresh();
|
|
|
|
|
$scope.catchall.refresh();
|
|
|
|
|
});
|
2018-04-01 21:58:12 +02:00
|
|
|
|
2018-01-23 12:41:52 +01:00
|
|
|
// we will fetch the status without blocking the ui
|
2018-01-23 12:30:35 +01:00
|
|
|
Client.getMailStatusForDomain($scope.selectedDomain.domain, function (error, mailStatus) {
|
2018-01-23 12:41:52 +01:00
|
|
|
$scope.refreshBusy = false;
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:41:52 +01:00
|
|
|
if (error) return console.error(error);
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:41:52 +01:00
|
|
|
$scope.selectedDomain.mailStatus = mailStatus;
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:30:35 +01:00
|
|
|
showExpectedDnsRecords();
|
|
|
|
|
});
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
2018-01-23 12:30:35 +01:00
|
|
|
};
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 12:38:19 +01:00
|
|
|
$scope.refreshStatus = function () {
|
|
|
|
|
$scope.refreshBusy = true;
|
|
|
|
|
|
|
|
|
|
Client.getMailStatusForDomain($scope.selectedDomain.domain, function (error, mailStatus) {
|
|
|
|
|
if (error) {
|
|
|
|
|
$scope.refreshBusy = false;
|
|
|
|
|
return console.error(error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// overwrite the selected domain status to be available for the UI
|
|
|
|
|
$scope.selectedDomain.mailStatus = mailStatus;
|
|
|
|
|
|
|
|
|
|
showExpectedDnsRecords();
|
|
|
|
|
|
|
|
|
|
$scope.refreshBusy = false;
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2018-01-23 15:11:33 +01:00
|
|
|
Client.onReady(function () {
|
2018-04-09 18:00:08 +02:00
|
|
|
var domain = $location.path().slice('/email/'.length);
|
|
|
|
|
|
2018-01-23 15:11:33 +01:00
|
|
|
Client.getUsers(function (error, users) {
|
|
|
|
|
if (error) return console.error('Unable to get user listing.', error);
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-04-05 21:00:33 +02:00
|
|
|
// ensure we have a display value available
|
|
|
|
|
$scope.users = users.map(function (u) {
|
|
|
|
|
u.display = u.username || u.email;
|
|
|
|
|
return u;
|
|
|
|
|
});
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-12-06 10:28:42 -08:00
|
|
|
$scope.users = users;
|
|
|
|
|
|
2018-01-23 15:11:33 +01:00
|
|
|
Client.getDomains(function (error, domains) {
|
|
|
|
|
if (error) return console.error('Unable to get domain listing.', error);
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 15:11:33 +01:00
|
|
|
$scope.domains = domains;
|
2018-04-09 18:00:08 +02:00
|
|
|
$scope.selectedDomain = domains.find(function (d) { return d.domain === domain; });
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-04-09 18:00:08 +02:00
|
|
|
if (!$scope.selectedDomain) {
|
|
|
|
|
$location.path('/email/' + domains[0].domain, false);
|
|
|
|
|
} else {
|
|
|
|
|
$scope.refreshDomain();
|
|
|
|
|
}
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-01-23 15:11:33 +01:00
|
|
|
$scope.ready = true;
|
|
|
|
|
});
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
2018-04-09 18:00:08 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function hashChangeListener() {
|
2018-04-11 12:16:44 +02:00
|
|
|
// prevent the change listener to handle the change if it does not belong to this view. The eventhandler will be subsequently removed
|
|
|
|
|
if (!$scope.ready || !$location.path().startsWith('/email/')) return;
|
2018-04-09 18:00:08 +02:00
|
|
|
|
|
|
|
|
// event listener is called from DOM not angular, need to use $apply
|
|
|
|
|
$scope.$apply(function () {
|
|
|
|
|
var domain = $location.path().slice('/email/'.length);
|
|
|
|
|
$scope.selectedDomain = $scope.domains.find(function (d) { return d.domain === domain; });
|
|
|
|
|
|
|
|
|
|
if (!$scope.selectedDomain) {
|
|
|
|
|
$location.path('/email/' + $scope.domains[0].domain, false);
|
|
|
|
|
} else {
|
|
|
|
|
$scope.refreshDomain();
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
window.addEventListener('hashchange', hashChangeListener);
|
2018-01-22 13:01:38 -08:00
|
|
|
|
2018-04-09 18:00:08 +02:00
|
|
|
$scope.$on('$destroy', function handler() {
|
|
|
|
|
window.removeEventListener('hashchange', hashChangeListener);
|
2018-01-22 13:01:38 -08:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// setup all the dialog focus handling
|
2018-04-09 16:12:18 +02:00
|
|
|
['testEmailModal', 'mailboxAddModal', 'mailboxEditModal', 'mailinglistEditModal', 'mailinglistAddModal'].forEach(function (id) {
|
2018-01-22 13:01:38 -08:00
|
|
|
$('#' + id).on('shown.bs.modal', function () {
|
|
|
|
|
$(this).find("[autofocus]:first").focus();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('.modal-backdrop').remove();
|
|
|
|
|
}]);
|