sogo/UI/WebServerResources/js/Preferences/PreferencesController.js
Francis Lachapelle 5b3d84ee24 refactor(preferences): conditionally activate the Sieve script
All the user defaults are now editable through the Preferences module,
even if an external Sieve script is enabled. However, the user can
disable the external Sieve script and force the activation of the
"sogo" Sieve script.
2019-11-15 14:37:35 -05:00

543 lines
18 KiB
JavaScript

/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* JavaScript for SOGoPreferences */
(function() {
'use strict';
/**
* @ngInject
*/
PreferencesController.$inject = ['$q', '$window', '$state', '$mdMedia', '$mdSidenav', '$mdDialog', '$mdToast', 'sgSettings', 'sgFocus', 'Dialog', 'User', 'Account', 'Preferences', 'Authentication'];
function PreferencesController($q, $window, $state, $mdMedia, $mdSidenav, $mdDialog, $mdToast, sgSettings, focus, Dialog, User, Account, Preferences, Authentication) {
var vm = this, mailboxes = [], today = new Date().beginOfDay();
this.$onInit = function() {
this.preferences = Preferences;
this.passwords = { newPassword: null, newPasswordConfirmation: null };
this.timeZonesList = $window.timeZonesList;
this.timeZonesSearchText = '';
this.sieveVariablesCapability = ($window.sieveCapabilities.indexOf('variables') >= 0);
this.mailLabelKeyRE = new RegExp(/^(?!^_\$)[^(){} %*\"\\\\]*?$/);
// Set alternate avatar in User service
if (Preferences.defaults.SOGoAlternateAvatar)
User.$alternateAvatar = Preferences.defaults.SOGoAlternateAvatar;
this.updateVacationDates();
};
this.go = function(module, form) {
if (form.$valid) {
// Close sidenav on small devices
if (!$mdMedia('gt-md'))
$mdSidenav('left').close();
$state.go('preferences.' + module);
}
};
this.onLanguageChange = function(form) {
if (form.$valid)
Dialog.confirm(l('Warning'),
l('Save preferences and reload page now?'),
{ok: l('Yes'), cancel: l('No')})
.then(function() {
vm.save(form, { quick: true }).then(function() {
$window.location.reload(true);
});
});
};
this.resetCalendarCategories = function(form) {
this.preferences.defaults.SOGoCalendarCategories = _.keys($window.defaultCalendarCategories);
this.preferences.defaults.SOGoCalendarCategoriesColorsValues = _.values($window.defaultCalendarCategories);
form.$setDirty();
};
this.addCalendarCategory = function(form) {
var i = _.indexOf(this.preferences.defaults.SOGoCalendarCategories, l('New category'));
if (i < 0) {
this.preferences.defaults.SOGoCalendarCategories.push(l('New category'));
this.preferences.defaults.SOGoCalendarCategoriesColorsValues.push("#aaa");
form.$setDirty();
i = this.preferences.defaults.SOGoCalendarCategories.length - 1;
}
focus('calendarCategory_' + i);
};
this.resetCalendarCategoryValidity = function(index, form) {
form['calendarCategory_' + index].$setValidity('duplicate', true);
};
this.removeCalendarCategory = function(index, form) {
this.preferences.defaults.SOGoCalendarCategories.splice(index, 1);
this.preferences.defaults.SOGoCalendarCategoriesColorsValues.splice(index, 1);
form.$setDirty();
};
this.addContactCategory = function(form) {
var i = _.indexOf(this.preferences.defaults.SOGoContactsCategories, "");
if (i < 0) {
this.preferences.defaults.SOGoContactsCategories.push("");
i = this.preferences.defaults.SOGoContactsCategories.length - 1;
}
focus('contactCategory_' + i);
form.$setDirty();
};
this.removeContactCategory = function(index, form) {
this.preferences.defaults.SOGoContactsCategories.splice(index, 1);
form.$setDirty();
};
this.addMailAccount = function(ev, form) {
var account;
this.preferences.defaults.AuxiliaryMailAccounts.push({});
account = _.last(this.preferences.defaults.AuxiliaryMailAccounts);
angular.extend(account,
{
isNew: true,
name: "",
identities: [
{
fullName: "",
email: ""
}
],
receipts: {
receiptAction: "ignore",
receiptNonRecipientAction: "ignore",
receiptOutsideDomainAction: "ignore",
receiptAnyAction: "ignore"
}
});
$mdDialog.show({
controller: 'AccountDialogController',
controllerAs: '$AccountDialogController',
templateUrl: 'editAccount?account=new',
targetEvent: ev,
locals: {
defaults: this.preferences.defaults,
account: account,
accountId: (this.preferences.defaults.AuxiliaryMailAccounts.length-1),
mailCustomFromEnabled: $window.mailCustomFromEnabled
}
}).then(function() {
form.$setDirty();
}).catch(function() {
vm.preferences.defaults.AuxiliaryMailAccounts.pop();
});
};
this.editMailAccount = function(event, index, form) {
var account = this.preferences.defaults.AuxiliaryMailAccounts[index];
$mdDialog.show({
controller: 'AccountDialogController',
controllerAs: '$AccountDialogController',
templateUrl: 'editAccount?account=' + index,
targetEvent: event,
locals: {
defaults: this.preferences.defaults,
account: account,
accountId: index,
mailCustomFromEnabled: $window.mailCustomFromEnabled
}
}).then(function() {
vm.preferences.defaults.AuxiliaryMailAccounts[index] = account;
form.$setDirty();
}, function() {
// Cancel
});
};
this.removeMailAccount = function(index, form) {
this.preferences.defaults.AuxiliaryMailAccounts.splice(index, 1);
form.$setDirty();
};
this.resetMailLabelValidity = function(index, form) {
form['mailIMAPLabel_' + index].$setValidity('duplicate', true);
};
this.addMailLabel = function(form) {
// See $omit() in the Preferences services for real key generation
var key = '_$$' + guid();
this.preferences.defaults.SOGoMailLabelsColorsKeys.push("label");
this.preferences.defaults.SOGoMailLabelsColorsValues.push(["New label", "#aaa"]);
focus('mailLabel_' + (_.size(this.preferences.defaults.SOGoMailLabelsColorsKeys) - 1));
form.$setDirty();
};
this.removeMailLabel = function(index, form) {
this.preferences.defaults.SOGoMailLabelsColorsKeys.splice(index, 1);
this.preferences.defaults.SOGoMailLabelsColorsValues.splice(index, 1);
form.$setDirty();
};
function _loadAllMailboxes() {
var account;
if (mailboxes.length) {
return;
}
if (sgSettings.activeUser('path').mail) {
// Fetch a flatten version of the mailboxes list of the main account (0)
// This list will be forwarded to the Sieve filter controller
account = new Account({ id: 0 });
account.$getMailboxes().then(function() {
var allMailboxes = account.$flattenMailboxes({all: true}),
index = -1,
length = allMailboxes.length;
while (++index < length) {
mailboxes.push(allMailboxes[index]);
}
});
}
}
this.addMailFilter = function(ev, form) {
var filter = { match: 'all', active: 1 };
_loadAllMailboxes();
$mdDialog.show({
templateUrl: 'editFilter?filter=new',
controller: 'FiltersDialogController',
controllerAs: 'filterEditor',
targetEvent: ev,
locals: {
filter: filter,
mailboxes: mailboxes,
labels: this.preferences.defaults.SOGoMailLabelsColors
}
}).then(function() {
if (!vm.preferences.defaults.SOGoSieveFilters)
vm.preferences.defaults.SOGoSieveFilters = [];
vm.preferences.defaults.SOGoSieveFilters.push(filter);
form.$setDirty();
});
};
this.editMailFilter = function(ev, index, form) {
var filter = angular.copy(this.preferences.defaults.SOGoSieveFilters[index]);
_loadAllMailboxes();
$mdDialog.show({
templateUrl: 'editFilter?filter=' + index,
controller: 'FiltersDialogController',
controllerAs: 'filterEditor',
targetEvent: null,
locals: {
filter: filter,
mailboxes: mailboxes,
labels: this.preferences.defaults.SOGoMailLabelsColors
}
}).then(function() {
vm.preferences.defaults.SOGoSieveFilters[index] = filter;
form.$setDirty();
},
_.noop); // Cancel
};
this.removeMailFilter = function(index, form) {
this.preferences.defaults.SOGoSieveFilters.splice(index, 1);
form.$setDirty();
};
this.onFiltersOrderChanged = function(form) {
// Return a callback that will affect the form
if (!this._onFiltersOrderChanged) {
this._onFiltersOrderChanged = function(type) {
form.$setDirty();
};
}
return this._onFiltersOrderChanged;
};
this.addDefaultEmailAddresses = function(form) {
var v = [];
if (angular.isDefined(this.preferences.defaults.Vacation.autoReplyEmailAddresses)) {
v = this.preferences.defaults.Vacation.autoReplyEmailAddresses.split(',');
}
this.preferences.defaults.Vacation.autoReplyEmailAddresses = (_.union($window.defaultEmailAddresses.split(','), v)).join(',');
form.$setDirty();
};
this.userFilter = function(search, excludedUsers) {
if (search.length < sgSettings.minimumSearchLength())
return [];
return User.$filter(search, excludedUsers).then(function(users) {
// Set users avatars
_.forEach(users, function(user) {
if (!user.$$image) {
if (user.image)
user.$$image = user.image;
else
user.$$image = vm.preferences.avatar(user.c_email, 40, {no_404: true});
}
});
return users;
});
};
this.manageSieveScript = function(form) {
this.preferences.defaults.hasActiveExternalSieveScripts = false;
form.$setDirty();
};
this.confirmChanges = function($event, form) {
var target;
if (form.$dirty && form.$valid) {
// Stop default action
$event.preventDefault();
$event.stopPropagation();
// Find target link
target = $event.target;
while (target.tagName != 'A')
target = target.parentNode;
Dialog.confirm(l('Unsaved Changes'),
l('Do you want to save your changes made to the configuration?'),
{ ok: l('Save'), cancel: l('Don\'t Save') })
.then(function() {
// Save & follow link
vm.save(form, { quick: true }).then(function() {
$window.location = target.href;
});
}, function() {
// Don't save & follow link
$window.location = target.href;
});
}
};
this.save = function(form, options) {
var i, sendForm, addresses, defaultAddresses, domains, domain;
sendForm = true;
domains = [];
// We do some sanity checks
if ($window.forwardConstraints > 0 &&
angular.isDefined(this.preferences.defaults.Forward) &&
this.preferences.defaults.Forward.enabled &&
angular.isDefined(this.preferences.defaults.Forward.forwardAddress)) {
addresses = this.preferences.defaults.Forward.forwardAddress.split(",");
// We first extract the list of 'known domains' to SOGo
defaultAddresses = $window.defaultEmailAddresses.split(/, */);
_.forEach(defaultAddresses, function(adr) {
var domain = adr.split("@")[1];
if (domain) {
domains.push(domain.toLowerCase());
}
});
// We check if we're allowed or not to forward based on the domain defaults
for (i = 0; i < addresses.length && sendForm; i++) {
domain = addresses[i].split("@")[1].toLowerCase();
if (domains.indexOf(domain) < 0 && $window.forwardConstraints == 1) {
Dialog.alert(l('Error'), l("You are not allowed to forward your messages to an external email address."));
sendForm = false;
}
else if (domains.indexOf(domain) >= 0 && $window.forwardConstraints == 2) {
Dialog.alert(l('Error'), l("You are not allowed to forward your messages to an internal email address."));
sendForm = false;
}
else if ($window.forwardConstraints == 2 &&
$window.forwardConstraintsDomains.length > 0 &&
$window.forwardConstraintsDomains.indexOf(domain) < 0) {
Dialog.alert(l('Error'), l("You are not allowed to forward your messages to this domain:") + " " + domain);
sendForm = false;
}
}
}
// IMAP labels must be unique
if (this.preferences.defaults.SOGoMailLabelsColorsKeys.length !=
this.preferences.defaults.SOGoMailLabelsColorsValues.length ||
this.preferences.defaults.SOGoMailLabelsColorsKeys.length !=
_.uniq(this.preferences.defaults.SOGoMailLabelsColorsKeys).length) {
Dialog.alert(l('Error'), l("IMAP labels must have unique names."));
_.forEach(this.preferences.defaults.SOGoMailLabelsColorsKeys, function (value, i, keys) {
if (form['mailIMAPLabel_' + i].$dirty &&
(keys.indexOf(value) != i ||
keys.indexOf(value, i+1) > -1)) {
form['mailIMAPLabel_' + i].$setValidity('duplicate', false);
sendForm = false;
}
});
}
// Calendar categories must be unique
if (this.preferences.defaults.SOGoCalendarCategories.length !=
_.uniq(this.preferences.defaults.SOGoCalendarCategories).length) {
Dialog.alert(l('Error'), l("Calendar categories must have unique names."));
_.forEach(this.preferences.defaults.SOGoCalendarCategories, function (value, i, keys) {
if (form['calendarCategory_' + i].$dirty &&
(keys.indexOf(value) != i ||
keys.indexOf(value, i+1) > -1)) {
form['calendarCategory_' + i].$setValidity('duplicate', false);
sendForm = false;
}
});
}
// Contact categories must be unique
if (this.preferences.defaults.SOGoContactsCategories.length !=
_.uniq(this.preferences.defaults.SOGoContactsCategories).length) {
Dialog.alert(l('Error'), l("Contact categories must have unique names."));
_.forEach(this.preferences.defaults.SOGoContactsCategories, function (value, i, keys) {
if (form['contactCategory_' + i].$dirty &&
(keys.indexOf(value) != i ||
keys.indexOf(value, i+1) > -1)) {
form['contactCategory_' + i].$setValidity('duplicate', false);
sendForm = false;
}
});
}
if (sendForm)
return this.preferences.$save().then(function(data) {
if (!options || !options.quick) {
$mdToast.show(
$mdToast.simple()
.content(l('Preferences saved'))
.position('bottom right')
.hideDelay(2000));
form.$setPristine();
}
});
return $q.reject();
};
this.canChangePassword = function() {
if (this.passwords.newPassword && this.passwords.newPassword.length > 0 &&
this.passwords.newPasswordConfirmation && this.passwords.newPasswordConfirmation.length &&
this.passwords.newPassword == this.passwords.newPasswordConfirmation)
return true;
return false;
};
this.changePassword = function() {
Authentication.changePassword(this.passwords.newPassword).then(function() {
var alert = $mdDialog.alert({
title: l('Password'),
content: l('The password was changed successfully.'),
ok: l('OK')
});
$mdDialog.show( alert )
.finally(function() {
alert = undefined;
});
}, function(msg) {
var alert = $mdDialog.alert({
title: l('Password'),
content: msg,
ok: l('OK')
});
$mdDialog.show( alert )
.finally(function() {
alert = undefined;
});
});
};
this.timeZonesListFilter = function(filter) {
return _.filter(this.timeZonesList, function(value) {
return value.toUpperCase().indexOf(filter.toUpperCase()) >= 0;
});
};
this.updateVacationDates = function() {
var d = this.preferences.defaults;
if (d &&
d.Vacation &&
d.Vacation.enabled) {
this.toggleVacationStartDate();
this.toggleVacationEndDate();
}
};
this.toggleVacationStartDate = function() {
var v;
v = this.preferences.defaults.Vacation;
if (v.startDateEnabled) {
// Enabling the start date
if (!v.startDate) {
v.startDate = new Date();
}
if (v.endDateEnabled && v.endDate && v.startDate.getTime() > v.endDate.getTime()) {
v.startDate = new Date(v.endDate.getTime());
v.startDate.addDays(-1);
}
}
};
this.toggleVacationEndDate = function() {
var v;
v = this.preferences.defaults.Vacation;
if (v.endDateEnabled) {
// Enabling the end date
if (!v.endDate) {
v.endDate = new Date();
}
if (v.startDateEnabled && v.startDate && v.endDate.getTime() < v.startDate.getTime()) {
v.endDate = new Date(v.startDate.getTime());
v.endDate.addDays(1);
}
}
};
this.validateVacationStartDate = function(date) {
var d = vm.preferences.defaults, r = true;
if (d &&
d.Vacation &&
d.Vacation.enabled) {
if (d.Vacation.startDateEnabled) {
r = (!d.Vacation.endDateEnabled ||
!d.Vacation.endDate ||
date.getTime() <= d.Vacation.endDate.getTime());
}
}
return r;
};
this.validateVacationEndDate = function(date) {
var d = vm.preferences.defaults, r = true;
if (d &&
d.Vacation &&
d.Vacation.enabled) {
if (d.Vacation.endDateEnabled) {
r = (!d.Vacation.startDateEnabled ||
!d.Vacation.startDate ||
date.getTime() >= d.Vacation.startDate.getTime());
}
}
return r;
};
}
angular
.module('SOGo.PreferencesUI')
.controller('PreferencesController', PreferencesController);
})();