Publish Vulpes Preview 15 sources for desktop, Android and Tundra

Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
This commit is contained in:
OverSu 2026-09-30 23:13:03 +02:00
commit b38dea0597
25901 changed files with 9982925 additions and 369 deletions

View file

@ -0,0 +1,273 @@
/**
* Configurator for fake
**/
define(
[
'logic',
'../accountcommon',
'../a64',
'../accountmixins',
'../imap/account',
'../pop3/account',
'../smtp/account',
'../allback',
'exports'
],
function(
logic,
$accountcommon,
$a64,
$acctmixins,
$imapacct,
$pop3acct,
$smtpacct,
allback,
exports
) {
var PIECE_ACCOUNT_TYPE_TO_CLASS = {
'imap': $imapacct.ImapAccount,
'pop3': $pop3acct.Pop3Account,
'smtp': $smtpacct.SmtpAccount,
};
/**
* Composite account type to expose account piece types with individual
* implementations (ex: imap, smtp) together as a single account. This is
* intended to be a very thin layer that shields consuming code from the
* fact that IMAP and SMTP are not actually bundled tightly together.
*/
function CompositeAccount(universe, accountDef, folderInfo, dbConn,
receiveProtoConn) {
this.universe = universe;
this.id = accountDef.id;
this.accountDef = accountDef;
logic.defineScope(this, 'Account', { accountId: this.id });
// Currently we don't persist the disabled state of an account because it's
// easier for the UI to be edge-triggered right now and ensure that the
// triggering occurs once each session.
this._enabled = true;
this.problems = [];
// For oauth2, hold on to a "last renew attempt" timestamp. However, since it
// uses performance.now() that can be reset depending on clock time and
// environment (shared worker always resets to 0 for instance), always reset
// the value here to 0. It is just a transient timestamp that is useful
// during the lifetime of the app.
if (accountDef.credentials && accountDef.credentials.oauth2) {
accountDef.credentials.oauth2._transientLastRenew = 0;
}
this.identities = accountDef.identities;
if (!PIECE_ACCOUNT_TYPE_TO_CLASS.hasOwnProperty(accountDef.receiveType)) {
logic(this, 'badAccountType', { type: accountDef.receiveType });
}
if (!PIECE_ACCOUNT_TYPE_TO_CLASS.hasOwnProperty(accountDef.sendType)) {
logic(this, 'badAccountType', { type: accountDef.sendType });
}
this._receivePiece =
new PIECE_ACCOUNT_TYPE_TO_CLASS[accountDef.receiveType](
universe, this,
accountDef.id, accountDef.credentials, accountDef.receiveConnInfo,
folderInfo, dbConn, receiveProtoConn);
this._sendPiece =
new PIECE_ACCOUNT_TYPE_TO_CLASS[accountDef.sendType](
universe, this,
accountDef.id, accountDef.credentials,
accountDef.sendConnInfo, dbConn);
// expose public lists that are always manipulated in place.
this.folders = this._receivePiece.folders;
this.meta = this._receivePiece.meta;
this.mutations = this._receivePiece.mutations;
// Mix in any fields common to all accounts.
$acctmixins.accountConstructorMixin.call(
this, this._receivePiece, this._sendPiece);
}
exports.Account = exports.CompositeAccount = CompositeAccount;
CompositeAccount.prototype = {
toString: function() {
return '[CompositeAccount: ' + this.id + ']';
},
get supportsServerFolders() {
return this._receivePiece.supportsServerFolders;
},
toBridgeWire: function() {
return {
id: this.accountDef.id,
name: this.accountDef.name,
type: this.accountDef.type,
defaultPriority: this.accountDef.defaultPriority,
enabled: this.enabled,
problems: this.problems,
syncRange: this.accountDef.syncRange,
syncInterval: this.accountDef.syncInterval,
notifyOnNew: this.accountDef.notifyOnNew,
playSoundOnSend: this.accountDef.playSoundOnSend,
identities: this.identities,
credentials: {
username: this.accountDef.credentials.username,
outgoingUsername: this.accountDef.credentials.outgoingUsername,
// no need to send the password to the UI.
// send all the oauth2 stuff we've got, though.
oauth2: this.accountDef.credentials.oauth2
},
servers: [
{
type: this.accountDef.receiveType,
connInfo: this.accountDef.receiveConnInfo,
activeConns: this._receivePiece.numActiveConns || 0,
},
{
type: this.accountDef.sendType,
connInfo: this.accountDef.sendConnInfo,
activeConns: this._sendPiece.numActiveConns || 0,
}
],
};
},
toBridgeFolder: function() {
return {
id: this.accountDef.id,
name: this.accountDef.name,
path: this.accountDef.name,
type: 'account',
};
},
get enabled() {
return this._enabled;
},
set enabled(val) {
this._enabled = this._receivePiece.enabled = val;
},
saveAccountState: function(reuseTrans, callback, reason) {
return this._receivePiece.saveAccountState(reuseTrans, callback, reason);
},
get _saveAccountIsImminent() {
return this.__saveAccountIsImminent;
},
set _saveAccountIsImminent(val) {
this.___saveAccountIsImminent =
this._receivePiece._saveAccountIsImminent = val;
},
runAfterSaves: function(callback) {
return this._receivePiece.runAfterSaves(callback);
},
allOperationsCompleted: function() {
if (this._receivePiece.allOperationsCompleted) {
this._receivePiece.allOperationsCompleted();
}
},
/**
* Check that the account is healthy in that we can login at all.
* We'll check both the incoming server and the SMTP server; for
* simplicity, the errors are returned as follows:
*
* callback(incomingErr, outgoingErr);
*
* If you don't want to check both pieces, you should just call
* checkAccount on the receivePiece or sendPiece as appropriate.
*/
checkAccount: function(callback) {
var latch = allback.latch();
this._receivePiece.checkAccount(latch.defer('incoming'));
this._sendPiece.checkAccount(latch.defer('outgoing'));
latch.then(function(results) {
callback(results.incoming[0], results.outgoing[0]);
});
},
/**
* Shutdown the account; see `MailUniverse.shutdown` for semantics.
*/
shutdown: function(callback) {
this._sendPiece.shutdown();
this._receivePiece.shutdown(callback);
},
accountDeleted: function() {
this._sendPiece.accountDeleted();
this._receivePiece.accountDeleted();
},
deleteFolder: function(folderId, callback) {
return this._receivePiece.deleteFolder(folderId, callback);
},
sliceFolderMessages: function(folderId, bridgeProxy) {
return this._receivePiece.sliceFolderMessages(folderId, bridgeProxy);
},
searchFolderMessages: function(folderId, bridgeHandle, phrase, whatToSearch) {
return this._receivePiece.searchFolderMessages(
folderId, bridgeHandle, phrase, whatToSearch);
},
syncFolderList: function(callback) {
return this._receivePiece.syncFolderList(callback);
},
sendMessage: function(composer, callback) {
return this._sendPiece.sendMessage(
composer,
function(err, errDetails) {
if (!err) {
// The saving is done asynchronously as a best-effort.
this._receivePiece.saveSentMessage(composer);
}
callback(err, errDetails, null);
}.bind(this));
},
getFolderStorageForFolderId: function(folderId) {
return this._receivePiece.getFolderStorageForFolderId(folderId);
},
getFolderMetaForFolderId: function(folderId) {
return this._receivePiece.getFolderMetaForFolderId(folderId);
},
runOp: function(op, mode, callback) {
return this._receivePiece.runOp(op, mode, callback);
},
/**
* Kick off jobs to create required folders, both locally and on the
* server. See imap/account.js and activesync/account.js for documentation.
*
* @param {function} callback
* Called when all jobs have run.
*/
ensureEssentialOnlineFolders: function(callback) {
return this._receivePiece.ensureEssentialOnlineFolders(callback);
},
getFirstFolderWithType: $acctmixins.getFirstFolderWithType,
upgradeFolderStoragesIfNeeded: function() {
for (var key in this._receivePiece._folderStorages) {
var storage = this._receivePiece._folderStorages[key];
storage.upgradeIfNeeded();
}
}
};
}); // end define