diff options
Diffstat (limited to 'mailnews/base/prefs/content/accountcreation/createInBackend.js')
-rw-r--r-- | mailnews/base/prefs/content/accountcreation/createInBackend.js | 337 |
1 files changed, 337 insertions, 0 deletions
diff --git a/mailnews/base/prefs/content/accountcreation/createInBackend.js b/mailnews/base/prefs/content/accountcreation/createInBackend.js new file mode 100644 index 000000000..cd984fd3c --- /dev/null +++ b/mailnews/base/prefs/content/accountcreation/createInBackend.js @@ -0,0 +1,337 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * Takes an |AccountConfig| JS object and creates that account in the + * Thunderbird backend (which also writes it to prefs). + * + * @param config {AccountConfig} The account to create + * + * @return - the account created. + */ + +Components.utils.import("resource:///modules/mailServices.js"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +function createAccountInBackend(config) +{ + // incoming server + let inServer = MailServices.accounts.createIncomingServer( + config.incoming.username, + config.incoming.hostname, + sanitize.enum(config.incoming.type, ["pop3", "imap", "nntp"])); + inServer.port = config.incoming.port; + inServer.authMethod = config.incoming.auth; + inServer.password = config.incoming.password; + if (config.rememberPassword && config.incoming.password.length) + rememberPassword(inServer, config.incoming.password); + +#ifdef MOZ_MAILNEWS_OAUTH2 + if (inServer.authMethod == Ci.nsMsgAuthMethod.OAuth2) { + inServer.setCharValue("oauth2.scope", config.oauthSettings.scope); + inServer.setCharValue("oauth2.issuer", config.oauthSettings.issuer); + } +#endif + + // SSL + if (config.incoming.socketType == 1) // plain + inServer.socketType = Ci.nsMsgSocketType.plain; + else if (config.incoming.socketType == 2) // SSL / TLS + inServer.socketType = Ci.nsMsgSocketType.SSL; + else if (config.incoming.socketType == 3) // STARTTLS + inServer.socketType = Ci.nsMsgSocketType.alwaysSTARTTLS; + //inServer.prettyName = config.displayName; + inServer.prettyName = config.identity.emailAddress; + + inServer.doBiff = true; + inServer.biffMinutes = config.incoming.checkInterval; + const loginAtStartupPrefTemplate = + "mail.server.%serverkey%.login_at_startup"; + var loginAtStartupPref = + loginAtStartupPrefTemplate.replace("%serverkey%", inServer.key); + Services.prefs.setBoolPref(loginAtStartupPref, + config.incoming.loginAtStartup); + if (config.incoming.type == "pop3") + { + const leaveOnServerPrefTemplate = + "mail.server.%serverkey%.leave_on_server"; + const daysToLeaveOnServerPrefTemplate = + "mail.server.%serverkey%.num_days_to_leave_on_server"; + const deleteFromServerPrefTemplate = + "mail.server.%serverkey%.delete_mail_left_on_server"; + const deleteByAgeFromServerPrefTemplate = + "mail.server.%serverkey%.delete_by_age_from_server"; + const downloadOnBiffPrefTemplate = + "mail.server.%serverkey%.download_on_biff"; + var leaveOnServerPref = + leaveOnServerPrefTemplate.replace("%serverkey%", inServer.key); + var ageFromServerPref = + deleteByAgeFromServerPrefTemplate.replace("%serverkey%", inServer.key); + var daysToLeaveOnServerPref = + daysToLeaveOnServerPrefTemplate.replace("%serverkey%", inServer.key); + var deleteFromServerPref = + deleteFromServerPrefTemplate.replace("%serverkey%", inServer.key); + let downloadOnBiffPref = + downloadOnBiffPrefTemplate.replace("%serverkey%", inServer.key); + Services.prefs.setBoolPref(leaveOnServerPref, + config.incoming.leaveMessagesOnServer); + Services.prefs.setIntPref(daysToLeaveOnServerPref, + config.incoming.daysToLeaveMessagesOnServer); + Services.prefs.setBoolPref(deleteFromServerPref, + config.incoming.deleteOnServerWhenLocalDelete); + Services.prefs.setBoolPref(ageFromServerPref, + config.incoming.deleteByAgeFromServer); + Services.prefs.setBoolPref(downloadOnBiffPref, + config.incoming.downloadOnBiff); + } + inServer.valid = true; + + let username = config.outgoing.auth > 1 ? config.outgoing.username : null; + let outServer = MailServices.smtp.findServer(username, config.outgoing.hostname); + assert(config.outgoing.addThisServer || + config.outgoing.useGlobalPreferredServer || + config.outgoing.existingServerKey, + "No SMTP server: inconsistent flags"); + + if (config.outgoing.addThisServer && !outServer) + { + outServer = MailServices.smtp.createServer(); + outServer.hostname = config.outgoing.hostname; + outServer.port = config.outgoing.port; + outServer.authMethod = config.outgoing.auth; + if (config.outgoing.auth > 1) + { + outServer.username = username; + outServer.password = config.incoming.password; + if (config.rememberPassword && config.incoming.password.length) + rememberPassword(outServer, config.incoming.password); + } + +#ifdef MOZ_MAILNEWS_OAUTH2 + if (outServer.authMethod == Ci.nsMsgAuthMethod.OAuth2) { + let pref = "mail.smtpserver." + outServer.key + "."; + Services.prefs.setCharPref(pref + "oauth2.scope", + config.oauthSettings.scope); + Services.prefs.setCharPref(pref + "oauth2.issuer", + config.oauthSettings.issuer); + } +#endif + + if (config.outgoing.socketType == 1) // no SSL + outServer.socketType = Ci.nsMsgSocketType.plain; + else if (config.outgoing.socketType == 2) // SSL / TLS + outServer.socketType = Ci.nsMsgSocketType.SSL; + else if (config.outgoing.socketType == 3) // STARTTLS + outServer.socketType = Ci.nsMsgSocketType.alwaysSTARTTLS; + + // API problem: <http://mxr.mozilla.org/seamonkey/source/mailnews/compose/public/nsISmtpServer.idl#93> + outServer.description = config.displayName; + if (config.password) + outServer.password = config.outgoing.password; + + // If this is the first SMTP server, set it as default + if (!MailServices.smtp.defaultServer || + !MailServices.smtp.defaultServer.hostname) + MailServices.smtp.defaultServer = outServer; + } + + // identity + // TODO accounts without identity? + let identity = MailServices.accounts.createIdentity(); + identity.fullName = config.identity.realname; + identity.email = config.identity.emailAddress; + + // for new accounts, default to replies being positioned above the quote + // if a default account is defined already, take its settings instead + if (config.incoming.type == "imap" || config.incoming.type == "pop3") + { + identity.replyOnTop = 1; + // identity.sigBottom = false; // don't set this until Bug 218346 is fixed + + if (MailServices.accounts.accounts.length && + MailServices.accounts.defaultAccount) + { + let defAccount = MailServices.accounts.defaultAccount; + let defIdentity = defAccount.defaultIdentity; + if (defAccount.incomingServer.canBeDefaultServer && + defIdentity && defIdentity.valid) + { + identity.replyOnTop = defIdentity.replyOnTop; + identity.sigBottom = defIdentity.sigBottom; + } + } + } + + // due to accepted conventions, news accounts should default to plain text + if (config.incoming.type == "nntp") + identity.composeHtml = false; + + identity.valid = true; + + if (config.outgoing.existingServerKey) + identity.smtpServerKey = config.outgoing.existingServerKey; + else if (!config.outgoing.useGlobalPreferredServer) + identity.smtpServerKey = outServer.key; + + // account and hook up + // Note: Setting incomingServer will cause the AccountManager to refresh + // itself, which could be a problem if we came from it and we haven't set + // the identity (see bug 521955), so make sure everything else on the + // account is set up before you set the incomingServer. + let account = MailServices.accounts.createAccount(); + account.addIdentity(identity); + account.incomingServer = inServer; + if (inServer.canBeDefaultServer && (!MailServices.accounts.defaultAccount || + !MailServices.accounts.defaultAccount + .incomingServer.canBeDefaultServer)) + MailServices.accounts.defaultAccount = account; + + verifyLocalFoldersAccount(MailServices.accounts); + setFolders(identity, inServer); + + // save + MailServices.accounts.saveAccountInfo(); + try { + Services.prefs.savePrefFile(null); + } catch (ex) { + ddump("Could not write out prefs: " + ex); + } + return account; +} + +function setFolders(identity, server) +{ + // TODO: support for local folders for global inbox (or use smart search + // folder instead) + + var baseURI = server.serverURI + "/"; + + // Names will be localized in UI, not in folder names on server/disk + // TODO allow to override these names in the XML config file, + // in case e.g. Google or AOL use different names? + // Workaround: Let user fix it :) + var fccName = "Sent"; + var draftName = "Drafts"; + var templatesName = "Templates"; + + identity.draftFolder = baseURI + draftName; + identity.stationeryFolder = baseURI + templatesName; + identity.fccFolder = baseURI + fccName; + + identity.fccFolderPickerMode = 0; + identity.draftsFolderPickerMode = 0; + identity.tmplFolderPickerMode = 0; +} + +function rememberPassword(server, password) +{ + if (server instanceof Components.interfaces.nsIMsgIncomingServer) + var passwordURI = server.localStoreType + "://" + server.hostName; + else if (server instanceof Components.interfaces.nsISmtpServer) + var passwordURI = "smtp://" + server.hostname; + else + throw new NotReached("Server type not supported"); + + let login = Cc["@mozilla.org/login-manager/loginInfo;1"] + .createInstance(Ci.nsILoginInfo); + login.init(passwordURI, null, passwordURI, server.username, password, "", ""); + try { + Services.logins.addLogin(login); + } catch (e) { + if (e.message.includes("This login already exists")) { + // TODO modify + } else { + throw e; + } + } +} + +/** + * Check whether the user's setup already has an incoming server + * which matches (hostname, port, username) the primary one + * in the config. + * (We also check the email address as username.) + * + * @param config {AccountConfig} filled in (no placeholders) + * @return {nsIMsgIncomingServer} If it already exists, the server + * object is returned. + * If it's a new server, |null| is returned. + */ +function checkIncomingServerAlreadyExists(config) +{ + assert(config instanceof AccountConfig); + let incoming = config.incoming; + let existing = MailServices.accounts.findRealServer(incoming.username, + incoming.hostname, + sanitize.enum(incoming.type, ["pop3", "imap", "nntp"]), + incoming.port); + + // if username does not have an '@', also check the e-mail + // address form of the name. + if (!existing && !incoming.username.includes("@")) + existing = MailServices.accounts.findRealServer(config.identity.emailAddress, + incoming.hostname, + sanitize.enum(incoming.type, ["pop3", "imap", "nntp"]), + incoming.port); + return existing; +}; + +/** + * Check whether the user's setup already has an outgoing server + * which matches (hostname, port, username) the primary one + * in the config. + * + * @param config {AccountConfig} filled in (no placeholders) + * @return {nsISmtpServer} If it already exists, the server + * object is returned. + * If it's a new server, |null| is returned. + */ +function checkOutgoingServerAlreadyExists(config) +{ + assert(config instanceof AccountConfig); + let smtpServers = MailServices.smtp.servers; + while (smtpServers.hasMoreElements()) + { + let existingServer = smtpServers.getNext() + .QueryInterface(Ci.nsISmtpServer); + // TODO check username with full email address, too, like for incoming + if (existingServer.hostname == config.outgoing.hostname && + existingServer.port == config.outgoing.port && + existingServer.username == config.outgoing.username) + return existingServer; + } + return null; +}; + +/** + * Check if there already is a "Local Folders". If not, create it. + * Copied from AccountWizard.js with minor updates. + */ +function verifyLocalFoldersAccount(am) +{ + let localMailServer; + try { + localMailServer = am.localFoldersServer; + } + catch (ex) { + localMailServer = null; + } + + try { + if (!localMailServer) + { + // creates a copy of the identity you pass in + am.createLocalMailAccount(); + try { + localMailServer = am.localFoldersServer; + } + catch (ex) { + ddump("Error! we should have found the local mail server " + + "after we created it."); + } + } + } + catch (ex) { ddump("Error in verifyLocalFoldersAccount " + ex); } +} |