/* -*- 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/. */ /** * This file creates the class AccountConfig, which is a JS object that holds * a configuration for a certain account. It is *not* created in the backend * yet (use aw-createAccount.js for that), and it may be incomplete. * * Several AccountConfig objects may co-exist, e.g. for autoconfig. * One AccountConfig object is used to prefill and read the widgets * in the Wizard UI. * When we autoconfigure, we autoconfig writes the values into a * new object and returns that, and the caller can copy these * values into the object used by the UI. * * See also * * for values stored. */ function AccountConfig() { this.incoming = this.createNewIncoming(); this.incomingAlternatives = []; this.outgoing = this.createNewOutgoing(); this.outgoingAlternatives = []; this.identity = { // displayed real name of user realname : "%REALNAME%", // email address of user, as shown in From of outgoing mails emailAddress : "%EMAILADDRESS%", }; this.inputFields = []; this.domains = []; }; AccountConfig.prototype = { // @see createNewIncoming() incoming : null, // @see createNewOutgoing() outgoing : null, /** * Other servers which can be used instead of |incoming|, * in order of decreasing preference. * (|incoming| itself should not be included here.) * { Array of incoming/createNewIncoming() } */ incomingAlternatives : null, outgoingAlternatives : null, // OAuth2 configuration, if needed. oauthSettings : null, // just an internal string to refer to this. Do not show to user. id : null, // who created the config. // { one of kSource* } source : 0, displayName : null, // { Array of { varname (value without %), displayName, exampleValue } } inputFields : null, // email address domains for which this config is applicable // { Array of Strings } domains : null, /** * Factory function for incoming and incomingAlternatives */ createNewIncoming : function() { return { // { String-enum: "pop3", "imap", "nntp" } type : null, hostname : null, // { Integer } port : null, // May be a placeholder (starts and ends with %). { String } username : null, password : null, // { enum: 1 = plain, 2 = SSL/TLS, 3 = STARTTLS always, 0 = not inited } // ('TLS when available' is insecure and not supported here) socketType : 0, /** * true when the cert is invalid (and thus SSL useless), because it's * 1) not from an accepted CA (including self-signed certs) * 2) for a different hostname or * 3) expired. * May go back to false when user explicitly accepted the cert. */ badCert : false, /** * How to log in to the server: plaintext or encrypted pw, GSSAPI etc. * Defined by Ci.nsMsgAuthMethod * Same as server pref "authMethod". */ auth : 0, /** * Other auth methods that we think the server supports. * They are ordered by descreasing preference. * (|auth| itself is not included in |authAlternatives|) * {Array of Ci.nsMsgAuthMethod} (same as .auth) */ authAlternatives : null, // in minutes { Integer } checkInterval : 10, loginAtStartup : true, // POP3 only: // Not yet implemented. { Boolean } useGlobalInbox : false, leaveMessagesOnServer : true, daysToLeaveMessagesOnServer : 14, deleteByAgeFromServer : true, // When user hits delete, delete from local store and from server deleteOnServerWhenLocalDelete : true, downloadOnBiff : true, }; }, /** * Factory function for outgoing and outgoingAlternatives */ createNewOutgoing : function() { return { type : "smtp", hostname : null, port : null, // see incoming username : null, // see incoming. may be null, if auth is 0. password : null, // see incoming. may be null, if auth is 0. socketType : 0, // see incoming badCert : false, // see incoming auth : 0, // see incoming authAlternatives : null, // see incoming addThisServer : true, // if we already have an SMTP server, add this // if we already have an SMTP server, use it. useGlobalPreferredServer : false, // we should reuse an already configured SMTP server. // nsISmtpServer.key existingServerKey : null, // user display value for existingServerKey existingServerLabel : null, }; }, /** * Returns a deep copy of this object, * i.e. modifying the copy will not affect the original object. */ copy : function() { // Workaround: deepCopy() fails to preserve base obj (instanceof) var result = new AccountConfig(); for (var prop in this) result[prop] = deepCopy(this[prop]); return result; }, isComplete : function() { return (!!this.incoming.hostname && !!this.incoming.port && !!this.incoming.socketType && !!this.incoming.auth && !!this.incoming.username && (!!this.outgoing.existingServerKey || (!!this.outgoing.hostname && !!this.outgoing.port && !!this.outgoing.socketType && !!this.outgoing.auth && !!this.outgoing.username))); }, }; // enum consts // .source AccountConfig.kSourceUser = 1; // user manually entered the config AccountConfig.kSourceXML = 2; // config from XML from ISP or Mozilla DB AccountConfig.kSourceGuess = 3; // guessConfig() /** * Some fields on the account config accept placeholders (when coming from XML). * * These are the predefined ones * * %EMAILADDRESS% (full email address of the user, usually entered by user) * * %EMAILLOCALPART% (email address, part before @) * * %EMAILDOMAIN% (email address, part after @) * * %REALNAME% * as well as those defined in account.inputFields.*.varname, with % added * before and after. * * These must replaced with real values, supplied by the user or app, * before the account is created. This is done here. You call this function once * you have all the data - gathered the standard vars mentioned above as well as * all listed in account.inputFields, and pass them in here. This function will * insert them in the fields, returning a fully filled-out account ready to be * created. * * @param account {AccountConfig} * The account data to be modified. It may or may not contain placeholders. * After this function, it should not contain placeholders anymore. * This object will be modified in-place. * * @param emailfull {String} * Full email address of this account, e.g. "joe@example.com". * Empty of incomplete email addresses will/may be rejected. * * @param realname {String} * Real name of user, as will appear in From of outgoing messages * * @param password {String} * The password for the incoming server and (if necessary) the outgoing server */ function replaceVariables(account, realname, emailfull, password) { sanitize.nonemptystring(emailfull); let emailsplit = emailfull.split("@"); assert(emailsplit.length == 2, "email address not in expected format: must contain exactly one @"); let emaillocal = sanitize.nonemptystring(emailsplit[0]); let emaildomain = sanitize.hostname(emailsplit[1]); sanitize.label(realname); sanitize.nonemptystring(realname); let otherVariables = {}; otherVariables.EMAILADDRESS = emailfull; otherVariables.EMAILLOCALPART = emaillocal; otherVariables.EMAILDOMAIN = emaildomain; otherVariables.REALNAME = realname; if (password) { account.incoming.password = password; account.outgoing.password = password; // set member only if auth required? } account.incoming.username = _replaceVariable(account.incoming.username, otherVariables); account.outgoing.username = _replaceVariable(account.outgoing.username, otherVariables); account.incoming.hostname = _replaceVariable(account.incoming.hostname, otherVariables); if (account.outgoing.hostname) // will be null if user picked existing server. account.outgoing.hostname = _replaceVariable(account.outgoing.hostname, otherVariables); account.identity.realname = _replaceVariable(account.identity.realname, otherVariables); account.identity.emailAddress = _replaceVariable(account.identity.emailAddress, otherVariables); account.displayName = _replaceVariable(account.displayName, otherVariables); } function _replaceVariable(variable, values) { let str = variable; if (typeof(str) != "string") return str; for (let varname in values) str = str.replace("%" + varname + "%", values[varname]); return str; }