Viewing File: /usr/local/cpanel/base/frontend/jupiter/email_accounts/services/emailAccountsService.js
/*
# email_accounts/services/emailAccountsService.js Copyright 2022 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
*/
/* global define: false, PAGE: false */
define(
[
"angular",
"lodash",
"cjt/util/locale",
"cjt/util/parse",
"cjt/util/query",
"cjt/io/uapi-request",
"cjt/io/batch-request",
"cjt/io/uapi",
"cjt/io/api",
"cjt/services/APIService",
"cjt/services/alertService",
],
function(angular, _, LOCALE, PARSE, QUERY, APIREQUEST, BATCH) {
"use strict";
var HTML_INFINITY = "∞";
var DEFAULT_ACCOUNT_LOGIN = "Main Account";
var app = angular.module("cpanel.emailAccounts.service", [
"cjt2.services.api",
"cjt2.services.alert",
]);
app.value("PAGE", PAGE);
/**
* Service wrapper for email accounts
*
* @module domains
*
* @param {Object} $q angular $q object
* @param {Object} APIService cjt2 api service
* @param {Object} $timeout
* @param {Object} PAGE window.PAGE object
*/
app.factory("emailAccountsService", [
"$q",
"APIService",
"alertService",
"$timeout",
"PAGE",
function($q, APIService, alertService, $timeout, PAGE) {
// This class provides conveniences that allow an
// alert with an automatically-created ID to be removed
// or replaced easily. It mandates that each alert be
// NON-replace.
function AlertObject(args) {
this._init(args);
}
_.assign(
AlertObject.prototype,
{
_init: function(args) {
if (args.replace) {
throw "bad replace";
}
var localArgs = _.assign( {}, args );
localArgs.replace = false;
alertService.add(localArgs);
var alerts = alertService.getAlerts( args.group );
var theAlert = alerts.slice(-1)[0];
var alertID = theAlert.id;
this.id = alertID;
this.group = args.group;
},
remove: function remove() {
alertService.removeById( this.id, this.group );
},
}
);
// --------------------------------------------------
// Set the default success transform on the prototype
var servicePrototype = new APIService({
transformAPISuccess: function(response) {
return response.data;
},
});
var EmailAccountsService = function() {};
EmailAccountsService.prototype = servicePrototype;
var emailStats;
/**
* Helps with the classes on the quota progress bar
*
* @method quotaProgressType
* @param {number} displayPercentage
* @returns {string} class for the quota progress bar
*/
function quotaProgressType(displayPercentage) {
if (displayPercentage >= 80) {
return "danger";
} else if (displayPercentage >= 60) {
return "warning";
} else if (displayPercentage < 60) {
return "success";
} else {
return "success";
}
}
/**
* Restructures Email account
*
* @method decorateEmailObj
* @param {Object} obj Email account object returned from API
* @returns {Object} returns modified email account
*/
function decorateEmailObj(obj) {
obj.diskused = parseInt(obj.diskused, 10);
obj.humandiskused = LOCALE.format_bytes( obj._diskused );
obj.id = obj.email;
if (obj._diskquota === 0 || obj.diskquota === 0 || obj.diskquota === "unlimited") {
obj.diskquota = 0;
obj.humandiskquota = HTML_INFINITY;
obj.diskusedpercent = 0;
obj.quotaType = "unlimited";
obj.quota = "";
obj.displayProgressbar = false;
} else {
obj.diskquota = parseInt(obj._diskquota, 10) / 1024 / 1024;
obj.humandiskquota = LOCALE.format_bytes(obj._diskquota);
obj.diskusedpercent = ((obj._diskused / obj._diskquota) * 100).toFixed(2);
obj.quotaProgressType = quotaProgressType(obj.diskusedpercent);
obj.quotaType = "userdefined";
obj.quota = obj.diskquota;
obj.quotaUnit = "MB";
obj.displayProgressbar = true;
}
obj.humandiskusedpercent = LOCALE.numf(obj.diskusedpercent) + "%";
obj.suspended_login = PARSE.parsePerlBoolean(obj.suspended_login);
obj.suspended_incoming = PARSE.parsePerlBoolean(obj.suspended_incoming);
obj.suspended_outgoing = PARSE.parsePerlBoolean(obj.suspended_outgoing);
obj.hold_outgoing = PARSE.parsePerlBoolean(obj.hold_outgoing);
obj.has_suspended = PARSE.parsePerlBoolean(obj.has_suspended);
obj.isDefault = obj.login === DEFAULT_ACCOUNT_LOGIN;
var webmailQuery = QUERY.make_query_string( {
user: obj.email,
return_request_uri: location.pathname,
} );
obj.webmailLink = "../mail/webmailform.html?" + webmailQuery;
return obj;
}
function _isNonClobberableUser(user) {
// See https://go.cpanel.net/UserManager-list_users for what “special” means.
if (user.special) {
return true;
}
return _.values(user.services).some( function(s) {
return PARSE.parsePerlBoolean(s.enabled);
} );
}
angular.extend(EmailAccountsService.prototype, {
/**
* Gets local storage values
* @method getStoredValue
* @param {string} key
* @return {string} returns the stored value
*/
getStoredValue: function(key) {
var storageValue = localStorage.getItem(key);
if ( storageValue && (0 === storageValue.indexOf(PAGE.securityToken + ":")) ) {
storageValue = storageValue.substr( 1 + PAGE.securityToken.length );
} else {
storageValue = "";
}
return storageValue;
},
/**
* dataWrapper
* @method _dataWrapper
* @return {Promise} Returns a promise
*/
_dataWrapper: function(apiCall) {
return this.deferred(apiCall).promise;
},
/**
* Gets upgrade url
* @method getUpgradeUrl
* @return {string} Returns upgarde url
*/
getUpgradeUrl: function() {
return PAGE.upgradeUrl;
},
/**
* Gets email resource usage
* @method getEmailStats
* @return {Promise} Returns a promise
*/
getEmailStats: function() {
if (emailStats) {
return $q.resolve(emailStats);
}
var apiCall = new APIREQUEST.Class();
apiCall.initialize("ResourceUsage", "get_usages");
apiCall.addFilter("id", "contains", "email_accounts");
return this.deferred(apiCall).promise
.then(function(response) {
emailStats = {};
var stats;
if (response && response.length) {
stats = response[0];
emailStats.maximum = parseInt(stats.maximum, 10);
emailStats.used = parseInt(stats.usage, 10);
if (!isNaN(emailStats.maximum) && emailStats.maximum) {
emailStats.available = emailStats.maximum - emailStats.used;
} else {
emailStats.available = -1;
}
} else {
return $q.reject();
}
return emailStats;
});
},
/**
* Gets domains
* @method getMailDomains
* @return {Promise} Returns a promise
*/
getMailDomains: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "list_mail_domains");
return this.deferred(apiCall).promise
.then(function(response) {
var domains = _.map(response, _.property("domain"));
return domains;
});
},
// Promise resolves truthy if the User Manager user
// is either nonexistent or has no services.
_isClobberableUserPromise: function _isClobberableUserPromise(emailAddressStr) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("UserManager", "list_users");
apiCall.addFilter("full_username", "eq", emailAddressStr);
return this._dataWrapper(apiCall).then( function(users) {
return !users.some(_isNonClobberableUser) && users[0];
} );
},
/**
* Creates email account
*
* XXX: getEmailStats() must be called first.
*
* @method createEmail
* @param {Object} accountDetails Email account details
* @return {Promise} Returns a promise
*/
createEmail: function(accountDetails) {
if (!emailStats) {
throw "Call getEmailStats() first.";
}
var apiCall = new APIREQUEST.Class();
var apiArgs, apiOverrides;
if (!accountDetails.setPassword) {
apiArgs = {
"username": accountDetails.userName,
"domain": accountDetails.domain,
"alternate_email": accountDetails.recoveryEmail,
"send_invite": 1,
"services.email.enabled": 1,
"services.email.quota": accountDetails.quota,
"services.email.send_welcome_email": accountDetails.sendWelcomeEmail ? 1 : 0,
};
// need to email reset link
apiCall.initialize("UserManager", "create_user", apiArgs);
// If this API call fails we want to examine the
// full response to see if there’s a typed error.
apiOverrides = {
transformAPIFailure: Object,
};
} else {
apiArgs = {
email: accountDetails.userName,
domain: accountDetails.domain,
password: accountDetails.password,
quota: accountDetails.quota,
send_welcome_email: accountDetails.sendWelcomeEmail ? 1 : 0,
};
apiCall.initialize("Email", "add_pop", apiArgs);
}
var self = this;
var realFailureXformer = this.presetDefaultHandlers.transformAPIFailure;
var emailAddressStr = accountDetails.userName + "@" + accountDetails.domain;
var ALERTGROUP = "emailAccounts";
var alertObj = new AlertObject( {
group: ALERTGROUP,
type: "info",
message: LOCALE.maketext("Creating email account …"),
} );
var apiPromise = this.deferred(apiCall, apiOverrides).promise;
return apiPromise
.then(function(response) {
emailStats.used = emailStats.used + 1;
if (emailStats.available !== -1) {
emailStats.available = emailStats.available - 1;
}
// Plus Addressing to be sent to the Inbox
if (accountDetails.autoCreateSubaddressFolders !== true) {
var subAddressingAPI = new APIREQUEST.Class();
subAddressingAPI.initialize("Email", "disable_mailbox_autocreate", {
email: emailAddressStr,
});
return self.deferred(subAddressingAPI).promise.then(function() {
return response;
});
}
return response;
}).catch( function(createResp) {
// If the call failed, check for
// “AlreadyExists”, which means a User
// Manager entry already exists for that
// email address.
if (createResp.data && createResp.data.type === "AlreadyExists") {
var isLeftover = !_isNonClobberableUser(createResp.data && createResp.data.detail.entry);
if (isLeftover) {
var clobberableAcct = createResp.data.detail;
var phrases = [
LOCALE.maketext("“[_1]” already exists in the [asis,User Manager].", _.escape(emailAddressStr) ),
LOCALE.maketext("This account appears to be left over from a previous subaccount.", _.escape(emailAddressStr)),
LOCALE.maketext("Deleting …"),
];
new AlertObject( {
group: ALERTGROUP,
type: "info",
message: phrases.join(" "),
} );
var deleteArgs = {
username: accountDetails.userName,
domain: accountDetails.domain,
};
// We confirmed that User Manager’s
// conflicting user is a “leftover”,
// so let’s delete that user.
var apiCall = new APIREQUEST.Class();
apiCall.initialize("UserManager", "delete_user", deleteArgs);
return self._dataWrapper(apiCall).then( function() {
var msgHtml;
if (clobberableAcct.alternate_email) {
msgHtml = LOCALE.maketext("The system deleted [asis,User Manager]’s old leftover “[_1]” account (alternate email address: [_2]).", _.escape(emailAddressStr), _.escape(clobberableAcct.alternate_email));
} else {
msgHtml = LOCALE.maketext("The system deleted [asis,User Manager]’s old leftover “[_1]” account.", _.escape(emailAddressStr));
}
alertService.add( {
group: ALERTGROUP,
type: "info",
message: msgHtml,
replace: false,
} );
// Now that we’ve deleted the
// empty User Manager account,
// retry the original creation.
return self.createEmail(accountDetails);
} );
}
}
return $q.reject(typeof createResp === "string" ? createResp : realFailureXformer(createResp));
}).finally( function() {
alertObj.remove();
});
},
/**
* Gets default account usage
* @method getDefaultAccountUsage
* @return {Promise} Returns a promise
*/
getDefaultAccountUsage: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "get_main_account_disk_usage");
return this._dataWrapper(apiCall);
},
/**
* Gets whether or not the shared address book is enabled
* @method isSharedAddressBookEnabled
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the shared AB is enabled
*/
isSharedAddressBookEnabled: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("DAV", "has_shared_global_addressbook");
return this._dataWrapper(apiCall);
},
/**
* Enables the shared address book
* @method enableSharedAddressBook
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the shared AB is enabled
*/
enableSharedAddressBook: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("DAV", "enable_shared_global_addressbook");
return this._dataWrapper(apiCall);
},
/**
* Disables the shared address book
* @method disableSharedAddressBook
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the shared AB is enabled
*/
disableSharedAddressBook: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("DAV", "disable_shared_global_addressbook");
return this._dataWrapper(apiCall);
},
/**
* Gets whether or not UTF-8 Mailboxes names are enabled.
* @method isUTF8MailboxNamesEnabled
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the call was successful.
*/
isUTF8MailboxNamesEnabled: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Mailboxes", "has_utf8_mailbox_names");
return this._dataWrapper(apiCall);
},
/**
* Enables UTF-8 mailbox support
* @method enableUTF8MailboxNames
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the call was successful.
*/
enableUTF8MailboxNames: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Mailboxes", "set_utf8_mailbox_names");
apiCall.addArgument("enabled", 1);
return this._dataWrapper(apiCall);
},
/**
* Disables UTF-8 mailbox support
* @method disableUTF8MailboxNames
* @return {Promise} Returns a promise that resolves to a boolean indicating whether or not the call was successful.
*/
disableUTF8MailboxNames: function() {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Mailboxes", "set_utf8_mailbox_names");
apiCall.addArgument("enabled", 0);
return this._dataWrapper(apiCall);
},
/**
* Gets email account details
* @method getEmailAccountDetails
* @param {string} email email account
* @return {Promise} Returns a promise
*/
getEmailAccountDetails: function(email) {
if (email) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "list_pops_with_disk");
apiCall.addFilter("email", "eq", email);
apiCall.addArgument("no_human_readable_keys", 1);
apiCall.addArgument("get_restrictions", 1);
var autoCreateApiCall = new APIREQUEST.Class();
autoCreateApiCall.initialize("Email", "get_mailbox_autocreate", {
"email": email,
});
var batchApiCall = new BATCH.Class([apiCall, autoCreateApiCall]);
var self = this;
return self.deferred(batchApiCall).promise
.then(function(responses) {
responses = responses.map(function(response) {
return response.data;
});
// Extract auto create setting
var detailsResponse = responses[0];
detailsResponse[0].autoCreateSubaddressFolders = responses[1];
return detailsResponse;
})
.then(function(response) {
if (_.isArray(response) && response.length === 0) {
return $q.reject(LOCALE.maketext("You do not have an email account named “[_1]”.", _.escape(email)));
}
return decorateEmailObj(response[0]);
}, function(error) {
return error;
});
}
},
/**
* Determine if Plus Address Folder Generation is Enabled
* @method isPlusAddressFolderCreationEnabled
* @param {string} email email account
* @return {Promise} Returns a promise
*/
isPlusAddressFolderCreationEnabled: function(email) {
if (email) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "get_mailbox_autocreate", {
"email": email,
});
return this.deferred(apiCall).promise.then(function(response) {
return response;
});
}
},
/**
* Disable Plus Address Folder Generation
* @method disablePlusAddressFolderCreation
* @param {string} email email account
* @return {Promise} Returns a promise
*/
disablePlusAddressFolderCreation: function(email) {
return this._createAPICall(
"disable_mailbox_autocreate",
{
email: email,
fullEmail: email,
},
{
success: LOCALE.translatable("You disabled automatic folder creation for “[_1]”."),
error: LOCALE.translatable("The system could not disable automatic folder creation for “[_1]”."),
}
);
},
/**
* Enable Plus Address Folder Generation
* @method enablePlusAddressFolderCreation
* @param {string} email email account
* @return {Promise} Returns a promise
*/
enablePlusAddressFolderCreation: function(email) {
return this._createAPICall(
"enable_mailbox_autocreate",
{
email: email,
fullEmail: email,
},
{
success: LOCALE.translatable("You enabled automatic folder creation for “[_1]”."),
error: LOCALE.translatable("The system could not enable automatic folder creation for “[_1]”."),
}
);
},
/**
* Delete email account
* @method deleteEmail
* @param {string} email email account
* @return {Promise} Returns a promise
*/
deleteEmail: function(email) {
if (email) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "delete_pop", { email: email });
return this.deferred(apiCall).promise
.then(function(response) {
emailStats.used = emailStats.used - 1;
if (emailStats.available !== -1) {
emailStats.available = emailStats.available + 1;
}
return response;
});
}
},
/**
* Delete multiple emails
* @method deleteEmails
* @param {string[]} emails email accounts
* @return {Promise} Returns a promise
*/
deleteEmails: function(emails) {
if (emails && emails.length > 0) {
var batchCalls = [];
for (var i = 0, len = emails.length; i < len; i++) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "delete_pop", { email: emails[i].email });
batchCalls.push(apiCall);
}
var batch = new BATCH.Class(batchCalls);
return this.deferred(batch).promise
.then(function(response) {
emailStats.used = emailStats.used - emails.length;
if (emailStats.available !== -1) {
emailStats.available = emailStats.available + emails.length;
}
return response;
});
}
},
_createAPICall: function(method, attributes, messages) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", method, attributes);
return this._dataWrapper(apiCall).then(
function() {
return messages.success ? { method: method, type: "success", message: LOCALE.makevar(messages.success, _.escape(attributes.fullEmail)), autoClose: 10000 } : { method: method, type: "success" };
},
function(error) {
return messages.error ? { method: method, type: "danger", message: LOCALE.makevar(messages.error, _.escape(attributes.fullEmail), error) } : { method: method, type: "danger" };
}
);
},
/**
* Gets the number of currently held messages in the mail queue for the specified email account
* @method getHeldMessageCount
* @param {Object} emailAccount The email account to get the held message count for
* @return {Promise} Returns a promise that resolves to an integer count of the number of held messages
*/
getHeldMessageCount: function(email) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "get_held_message_count", {
email: email,
});
return this._dataWrapper(apiCall);
},
/**
* Deletes any held messages in the mail queue for the specified email account
* @method deleteHeldMessages
* @param {Object} emailAccount The email account to delete the held messages for
* @return {Promise} Returns a promise that resolves to an integer count of the number of deleted messages
*/
deleteHeldMessages: function(email, releaseAfterDelete) {
var apiCall = new APIREQUEST.Class();
apiCall.initialize("Email", "delete_held_messages", {
email: email,
release_after_delete: (releaseAfterDelete) ? 1 : 0,
});
return this._dataWrapper(apiCall);
},
_handleSuspensions: function(newSettings, currentSuspendedState, suspendOptions) {
var calls = [];
if (suspendOptions.incoming !== currentSuspendedState.incoming) {
if (!suspendOptions.incoming) {
calls.push(this._createAPICall(
"unsuspend_incoming",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You unsuspended incoming mail for “[_1]”."),
error: LOCALE.translatable("We can’t unsuspend incoming mail for “[_1]”:“[_2]”"),
}
));
} else {
calls.push(this._createAPICall(
"suspend_incoming",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You suspended incoming mail for “[_1]”."),
error: LOCALE.translatable("We can’t suspend incoming mail for “[_1]”:“[_2]”"),
}
));
}
}
if (suspendOptions.login !== currentSuspendedState.login) {
if (!suspendOptions.login) {
calls.push(this._createAPICall(
"unsuspend_login",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You unsuspended logins for “[_1]”."),
error: LOCALE.translatable("We can’t unsuspend logins for “[_1]”:“[_2]”"),
}
));
} else {
calls.push(this._createAPICall(
"suspend_login",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You suspended logins for “[_1]”."),
error: LOCALE.translatable("We can’t suspend logins for “[_1]”:“[_2]”"),
}
));
}
}
if (suspendOptions.outgoing !== currentSuspendedState.outgoing) {
if (suspendOptions.outgoing === "hold") {
calls.push(this._createAPICall(
"hold_outgoing",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("We’re holding outgoing mail for “[_1]”."),
error: LOCALE.translatable("We can’t hold mail for “[_1]”:“[_2]”"),
}
));
} else if (suspendOptions.outgoing === "suspend") {
calls.push(this._createAPICall(
"suspend_outgoing",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You suspended outgoing mail for “[_1]”."),
error: LOCALE.translatable("We can’t suspend outgoing mail for “[_1]”:“[_2]”"),
}
));
}
if (currentSuspendedState.outgoing === "suspend") {
calls.push(this._createAPICall(
"unsuspend_outgoing",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You unsuspended outgoing mail for “[_1]”."),
error: LOCALE.translatable("We can’t unsuspend outgoing mail for “[_1]”:“[_2]”"),
}
));
}
if (currentSuspendedState.outgoing === "hold") {
calls.push(this._createAPICall(
"release_outgoing",
{
email: newSettings.email,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You unsuspended outgoing mail for “[_1]”."),
error: LOCALE.translatable("We can’t unsuspend outgoing mail for “[_1]”:“[_2]”"),
}
));
}
}
return calls;
},
/**
* Updates email account details
* @method updateEmail
* @param {Object} oldSettings old email account values
* @param {Object} newSettings new email account values
* @param {Object} currentSuspendedState current suspended state
* @param {Object} suspendOptions suspend options
* @return {Promise} Returns a promise
*/
updateEmail: function(oldSettings, newSettings, currentSuspendedState, suspendOptions) {
var calls = [];
if (oldSettings && newSettings) {
if (oldSettings.autoCreateSubaddressFolders !== newSettings.autoCreateSubaddressFolders) {
if (newSettings.autoCreateSubaddressFolders) {
calls.push(this.enablePlusAddressFolderCreation(newSettings.email));
} else {
calls.push(this.disablePlusAddressFolderCreation(newSettings.email));
}
}
if (typeof newSettings.password !== "undefined" && newSettings.password) {
calls.push(this._createAPICall(
"passwd_pop",
{
email: newSettings.email,
password: newSettings.password,
domain: newSettings.domain,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You updated the password for “[_1]”."),
error: LOCALE.translatable("We can’t update the password for “[_1]”:“[_2]”"),
}
));
}
if (Number(oldSettings.diskquota).toFixed(2) !== newSettings.quota.toFixed(2)) {
calls.push(this._createAPICall(
"edit_pop_quota",
{
email: newSettings.user,
domain: newSettings.domain,
quota: newSettings.quota,
fullEmail: newSettings.email,
},
{
success: LOCALE.translatable("You updated the storage space for “[_1]”."),
error: LOCALE.translatable("We can’t update the storage space for “[_1]”:“[_2]”"),
}
));
}
if (suspendOptions && currentSuspendedState) {
// Handle deletion of queued email before processing the account suspensions
if (suspendOptions.deleteHeldMessages) {
var releaseAfterDelete = currentSuspendedState.outgoing === "hold" && suspendOptions.outgoing === "allow";
var self = this;
return this.deleteHeldMessages(newSettings.email, releaseAfterDelete).then(
function(deletedCount) {
if (releaseAfterDelete) {
suspendOptions.outgoing = "hold";
}
var additionalCalls = self._handleSuspensions(newSettings, currentSuspendedState, suspendOptions);
var allCalls = calls.concat(additionalCalls);
if ( allCalls.length > 0 ) {
return $q.all(allCalls);
} else {
return $timeout( function() {
return $q.resolve(
[{
type: "success",
method: "delete_held_messages",
message: LOCALE.maketext("[quant,_1,message has,messages have] been queued for deletion from the outgoing mail queue.", deletedCount),
}]
);
}, 0);
}
},
function(error) {
return $timeout( function() {
return $q.resolve(
[{ type: "danger", message: error }]
);
}, 0);
}
);
} else {
var additionalCalls = this._handleSuspensions(newSettings, currentSuspendedState, suspendOptions);
calls = calls.concat(additionalCalls);
}
}
if ( calls.length > 0 ) {
return $q.all(calls);
} else {
return $timeout( function() {
return $q.resolve(
[{ type: "success", message: LOCALE.maketext("Email account “[_1]” is up to date.", newSettings.email), autoClose: 10000 }]
);
}, 0);
}
}
},
/**
* Gets the list of email accounts
* @method getEmailAccounts
* @param {Object} apiParams An object providing the UAPI filter, paginate, and sort properties
* @return {Promise} Returns a promise that resolves to the list of email accounts
*/
getEmailAccounts: function(apiParams) {
if ( this.currentGetRequest && this.currentGetRequest.jqXHR ) {
this.currentGetRequest.jqXHR.abort();
}
var apiCall = new APIREQUEST.Class();
// We always format the data on the frontend so avoid doing it on the backend for non-displayed data
if (!apiParams) {
apiParams = {};
}
apiParams.no_human_readable_keys = 1;
apiParams.get_restrictions = 1;
apiParams.include_main = 1;
apiCall.initialize("Email", "list_pops_with_disk", apiParams);
var deferred = $q.defer();
var service = this;
// We want to be able to access the underlying jQuery XHR object here so that we can
// .abort() any in flight calls to list_pops_with_disk when a new one is submitted.
this.currentGetRequest = new APIService.AngularAPICall(apiCall, {
done: function(response) {
service.currentGetRequest = undefined;
if ( response.parsedResponse.error ) {
deferred.reject(response.parsedResponse.error);
} else {
var result = response.parsedResponse;
var rdata = result.data;
var rdatalen = rdata.length;
for (var rd = 0; rd < rdatalen; rd++) {
decorateEmailObj(rdata[rd]);
}
deferred.resolve(result);
}
},
fail: function() {
service.currentGetRequest = undefined;
},
});
return deferred.promise;
},
});
return new EmailAccountsService();
},
]);
}
);
Back to Directory
File Manager