snappymail/dev/Remote/User/Fetch.js

819 lines
18 KiB
JavaScript
Raw Normal View History

import { isArray, isNonEmptyArray, pString, pInt } from 'Common/Utils';
2016-06-30 08:02:45 +08:00
import {
getFolderHash,
getFolderInboxName,
getFolderUidNext,
getFolderFromCacheList,
MessageFlagsCache
} from 'Common/Cache';
2016-06-30 08:02:45 +08:00
2021-03-10 18:44:48 +08:00
import { SettingsGet } from 'Common/Globals';
2021-01-27 19:02:37 +08:00
import { SUB_QUERY_PREFIX } from 'Common/Links';
2016-06-30 08:02:45 +08:00
import { AppUserStore } from 'Stores/User/App';
import { SettingsUserStore } from 'Stores/User/Settings';
import { FolderUserStore } from 'Stores/User/Folder';
2016-06-30 08:02:45 +08:00
import { AbstractFetchRemote } from 'Remote/AbstractFetch';
import { FolderCollectionModel } from 'Model/FolderCollection';
//const toUTF8 = window.TextEncoder
// ? text => String.fromCharCode(...new TextEncoder().encode(text))
// : text => unescape(encodeURIComponent(text)),
const urlsafeArray = array => btoa(unescape(encodeURIComponent(array.join('\x00').replace(/\r\n/g, '\n'))))
.replace('+', '-')
.replace('/', '_')
.replace('=', '');
class RemoteUserFetch extends AbstractFetchRemote {
/**
* @param {?Function} fCallback
*/
folders(fCallback) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'Folders',
{
2021-03-10 18:44:48 +08:00
SentFolder: SettingsGet('SentFolder'),
DraftFolder: SettingsGet('DraftFolder'),
SpamFolder: SettingsGet('SpamFolder'),
TrashFolder: SettingsGet('TrashFolder'),
ArchiveFolder: SettingsGet('ArchiveFolder')
2019-07-05 03:19:24 +08:00
},
null,
'',
['Folders']
);
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
* @param {string} sEmail
* @param {string} sLogin
* @param {string} sPassword
* @param {boolean} bSignMe
* @param {string=} sLanguage
* @param {string=} sAdditionalCode
* @param {boolean=} bAdditionalCodeSignMe
*/
login(fCallback, sEmail, sLogin, sPassword, bSignMe, sLanguage, sAdditionalCode, bAdditionalCodeSignMe) {
this.defaultRequest(fCallback, 'Login', {
Email: sEmail,
Login: sLogin,
Password: sPassword,
Language: sLanguage || '',
AdditionalCode: sAdditionalCode || '',
AdditionalCodeSignMe: bAdditionalCodeSignMe ? 1 : 0,
SignMe: bSignMe ? 1 : 0
});
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
getTwoFactor(fCallback) {
this.defaultRequest(fCallback, 'GetTwoFactorInfo');
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
createTwoFactor(fCallback) {
this.defaultRequest(fCallback, 'CreateTwoFactorSecret');
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
clearTwoFactor(fCallback) {
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
showTwoFactorSecret(fCallback) {
this.defaultRequest(fCallback, 'ShowTwoFactorSecret');
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
* @param {string} sCode
*/
testTwoFactor(fCallback, sCode) {
this.defaultRequest(fCallback, 'TestTwoFactorInfo', {
Code: sCode
});
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
* @param {boolean} bEnable
*/
enableTwoFactor(fCallback, bEnable) {
this.defaultRequest(fCallback, 'EnableTwoFactor', {
Enable: bEnable ? 1 : 0
});
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
clearTwoFactorInfo(fCallback) {
this.defaultRequest(fCallback, 'ClearTwoFactorInfo');
}
/**
* @param {?Function} fCallback
*/
contactsSync(fCallback) {
2020-09-30 20:07:03 +08:00
this.defaultRequest(fCallback, 'ContactsSync', null, 200000);
}
/**
* @param {?Function} fCallback
* @param {boolean} bEnable
* @param {string} sUrl
* @param {string} sUser
* @param {string} sPassword
*/
saveContactsSyncData(fCallback, bEnable, sUrl, sUser, sPassword) {
this.defaultRequest(fCallback, 'SaveContactsSyncData', {
Enable: bEnable ? 1 : 0,
Url: sUrl,
User: sUser,
Password: sPassword
});
}
/**
* @param {?Function} fCallback
* @param {string} sEmail
* @param {string} sPassword
* @param {boolean=} bNew
*/
accountSetup(fCallback, sEmail, sPassword, bNew = true) {
this.defaultRequest(fCallback, 'AccountSetup', {
Email: sEmail,
Password: sPassword,
New: bNew ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sEmailToDelete
*/
accountDelete(fCallback, sEmailToDelete) {
this.defaultRequest(fCallback, 'AccountDelete', {
EmailToDelete: sEmailToDelete
});
}
/**
* @param {?Function} fCallback
* @param {Array} aAccounts
* @param {Array} aIdentities
*/
accountsAndIdentitiesSortOrder(fCallback, aAccounts, aIdentities) {
this.defaultRequest(fCallback, 'AccountsAndIdentitiesSortOrder', {
Accounts: aAccounts,
Identities: aIdentities
});
}
/**
* @param {?Function} fCallback
* @param {string} sId
* @param {string} sEmail
* @param {string} sName
* @param {string} sReplyTo
* @param {string} sBcc
* @param {string} sSignature
* @param {boolean} bSignatureInsertBefore
*/
identityUpdate(fCallback, sId, sEmail, sName, sReplyTo, sBcc, sSignature, bSignatureInsertBefore) {
this.defaultRequest(fCallback, 'IdentityUpdate', {
Id: sId,
Email: sEmail,
Name: sName,
ReplyTo: sReplyTo,
Bcc: sBcc,
Signature: sSignature,
SignatureInsertBefore: bSignatureInsertBefore ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sIdToDelete
*/
identityDelete(fCallback, sIdToDelete) {
this.defaultRequest(fCallback, 'IdentityDelete', {
IdToDelete: sIdToDelete
});
}
/**
* @param {?Function} fCallback
*/
accountsAndIdentities(fCallback) {
this.defaultRequest(fCallback, 'AccountsAndIdentities');
}
2021-01-19 23:01:30 +08:00
/**
* @param {?Function} fCallback
* @param {SieveScriptModel} script
*/
filtersScriptSave(fCallback, script) {
this.defaultRequest(fCallback, 'FiltersScriptSave', script.toJson());
}
/**
* @param {?Function} fCallback
* @param {string} name
*/
filtersScriptActivate(fCallback, name) {
this.defaultRequest(fCallback, 'FiltersScriptActivate', {name:name});
}
/**
* @param {?Function} fCallback
* @param {string} name
*/
filtersScriptDelete(fCallback, name) {
this.defaultRequest(fCallback, 'FiltersScriptDelete', {name:name});
}
/**
* @param {?Function} fCallback
*/
filtersGet(fCallback) {
this.defaultRequest(fCallback, 'Filters', {});
}
/**
* @param {?Function} fCallback
*/
templates(fCallback) {
this.defaultRequest(fCallback, 'Templates', {});
}
/**
* @param {Function} fCallback
* @param {string} sID
*/
templateGetById(fCallback, sID) {
this.defaultRequest(fCallback, 'TemplateGetByID', {
ID: sID
});
}
/**
* @param {Function} fCallback
* @param {string} sID
*/
templateDelete(fCallback, sID) {
this.defaultRequest(fCallback, 'TemplateDelete', {
IdToDelete: sID
});
}
/**
* @param {Function} fCallback
* @param {string} sID
* @param {string} sName
* @param {string} sBody
*/
templateSetup(fCallback, sID, sName, sBody) {
this.defaultRequest(fCallback, 'TemplateSetup', {
ID: sID,
Name: sName,
Body: sBody
});
}
/**
* @param {Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {number=} iOffset = 0
* @param {number=} iLimit = 20
* @param {string=} sSearch = ''
* @param {string=} sThreadUid = ''
* @param {boolean=} bSilent = false
*/
messageList(fCallback, sFolderFullNameRaw, iOffset = 0, iLimit = 20, sSearch = '', sThreadUid = '', bSilent = false) {
sFolderFullNameRaw = pString(sFolderFullNameRaw);
2019-07-05 03:19:24 +08:00
const folderHash = getFolderHash(sFolderFullNameRaw),
useThreads = AppUserStore.threadsAllowed() && SettingsUserStore.useThreads(),
inboxUidNext = getFolderInboxName() === sFolderFullNameRaw ? getFolderUidNext(sFolderFullNameRaw) : '';
let params = {}, sGetAdd = '';
if (folderHash && (!sSearch || !sSearch.includes('is:'))) {
sGetAdd = 'MessageList/' +
2021-01-27 19:02:37 +08:00
SUB_QUERY_PREFIX +
'/' +
urlsafeArray([
sFolderFullNameRaw,
iOffset,
iLimit,
sSearch,
SettingsGet('ProjectHash'),
folderHash,
inboxUidNext,
useThreads ? 1 : 0,
useThreads ? sThreadUid : ''
]);
} else {
params = {
2019-07-05 03:19:24 +08:00
Folder: sFolderFullNameRaw,
Offset: iOffset,
Limit: iLimit,
Search: sSearch,
UidNext: inboxUidNext,
UseThreads: useThreads ? 1 : 0,
2019-07-05 03:19:24 +08:00
ThreadUid: useThreads ? sThreadUid : ''
};
}
2021-02-25 17:12:48 +08:00
this.defaultRequest(
fCallback,
'MessageList',
params,
sSearch ? 300000 : 30000,
sGetAdd,
2019-07-05 03:19:24 +08:00
bSilent ? [] : ['MessageList']
);
}
/**
* @param {?Function} fCallback
* @param {Array} aDownloads
*/
messageUploadAttachments(fCallback, aDownloads) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'MessageUploadAttachments',
{
Attachments: aDownloads
2019-07-05 03:19:24 +08:00
},
999000
);
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {number} iUid
* @returns {boolean}
*/
message(fCallback, sFolderFullNameRaw, iUid) {
sFolderFullNameRaw = pString(sFolderFullNameRaw);
iUid = pInt(iUid);
2019-07-05 03:19:24 +08:00
if (getFolderFromCacheList(sFolderFullNameRaw) && 0 < iUid) {
this.defaultRequest(
fCallback,
'Message',
{},
null,
'Message/' +
2021-01-27 19:02:37 +08:00
SUB_QUERY_PREFIX +
2019-07-05 03:19:24 +08:00
'/' +
urlsafeArray([
sFolderFullNameRaw,
iUid,
SettingsGet('ProjectHash'),
AppUserStore.threadsAllowed() && SettingsUserStore.useThreads() ? 1 : 0
]),
2019-07-05 03:19:24 +08:00
['Message']
);
return true;
}
return false;
}
/**
* @param {?Function} fCallback
* @param {Array} aExternals
*/
composeUploadExternals(fCallback, aExternals) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'ComposeUploadExternals',
{
Externals: aExternals
2019-07-05 03:19:24 +08:00
},
999000
);
}
/**
* @param {?Function} fCallback
* @param {string} sUrl
* @param {string} sAccessToken
*/
composeUploadDrive(fCallback, sUrl, sAccessToken) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'ComposeUploadDrive',
{
AccessToken: sAccessToken,
Url: sUrl
2019-07-05 03:19:24 +08:00
},
999000
);
}
/**
* @param {?Function} fCallback
* @param {string} folder
* @param {Array=} list = []
*/
folderInformation(fCallback, folder, list = []) {
let request = true;
const uids = [];
if (isNonEmptyArray(list)) {
request = false;
list.forEach(messageListItem => {
if (!MessageFlagsCache.getFor(messageListItem.folder, messageListItem.uid)) {
uids.push(messageListItem.uid);
}
if (messageListItem.threads.length) {
messageListItem.threads.forEach(uid => {
if (!MessageFlagsCache.getFor(messageListItem.folder, uid)) {
uids.push(uid);
}
});
}
});
if (uids.length) {
request = true;
}
}
2019-07-05 03:19:24 +08:00
if (request) {
this.defaultRequest(fCallback, 'FolderInformation', {
Folder: folder,
FlagsUids: isArray(uids) ? uids.join(',') : '',
UidNext: getFolderInboxName() === folder ? getFolderUidNext(folder) : ''
});
} else if (SettingsUserStore.useThreads()) {
2020-09-15 15:29:25 +08:00
rl.app.reloadFlagsCurrentMessageListAndMessageFromCache();
}
}
/**
* @param {?Function} fCallback
* @param {Array} aFolders
*/
folderInformationMultiply(fCallback, aFolders) {
this.defaultRequest(fCallback, 'FolderInformationMultiply', {
Folders: aFolders
});
}
/**
* @param {?Function} fCallback
*/
logout(fCallback) {
this.defaultRequest(fCallback, 'Logout');
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {Array} aUids
* @param {boolean} bSetFlagged
*/
messageSetFlagged(fCallback, sFolderFullNameRaw, aUids, bSetFlagged) {
this.defaultRequest(fCallback, 'MessageSetFlagged', {
Folder: sFolderFullNameRaw,
Uids: aUids.join(','),
SetAction: bSetFlagged ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {Array} aUids
* @param {boolean} bSetSeen
*/
messageSetSeen(fCallback, sFolderFullNameRaw, aUids, bSetSeen) {
this.defaultRequest(fCallback, 'MessageSetSeen', {
Folder: sFolderFullNameRaw,
Uids: aUids.join(','),
SetAction: bSetSeen ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {boolean} bSetSeen
2016-12-15 05:56:17 +08:00
* @param {Array} aThreadUids = null
*/
2016-12-15 05:56:17 +08:00
messageSetSeenToAll(fCallback, sFolderFullNameRaw, bSetSeen, aThreadUids = null) {
this.defaultRequest(fCallback, 'MessageSetSeenToAll', {
Folder: sFolderFullNameRaw,
SetAction: bSetSeen ? 1 : 0,
ThreadUids: aThreadUids ? aThreadUids.join(',') : ''
});
}
/**
* @param {?Function} fCallback
* @param {Object} oData
*/
saveMessage(fCallback, oData) {
2020-09-30 20:07:03 +08:00
this.defaultRequest(fCallback, 'SaveMessage', oData, 200000);
}
/**
* @param {?Function} fCallback
* @param {string} sMessageFolder
* @param {string} sMessageUid
* @param {string} sReadReceipt
* @param {string} sSubject
* @param {string} sText
*/
sendReadReceiptMessage(fCallback, sMessageFolder, sMessageUid, sReadReceipt, sSubject, sText) {
this.defaultRequest(fCallback, 'SendReadReceiptMessage', {
MessageFolder: sMessageFolder,
MessageUid: sMessageUid,
ReadReceipt: sReadReceipt,
Subject: sSubject,
Text: sText
});
}
/**
* @param {?Function} fCallback
* @param {Object} oData
*/
sendMessage(fCallback, oData) {
2020-09-30 20:07:03 +08:00
this.defaultRequest(fCallback, 'SendMessage', oData, 300000);
}
/**
* @param {?Function} fCallback
* @param {Object} oData
*/
saveSystemFolders(fCallback, oData) {
this.defaultRequest(fCallback, 'SystemFoldersUpdate', oData);
}
/**
* @param {?Function} fCallback
* @param {Object} oData
*/
saveSettings(fCallback, oData) {
this.defaultRequest(fCallback, 'SettingsUpdate', oData);
}
/**
* @param {string} key
2021-03-18 23:12:24 +08:00
* @param {?scalar} value
* @param {?Function} fCallback
*/
2021-03-18 23:12:24 +08:00
saveSetting(key, value, fCallback) {
this.saveSettings(fCallback, {
[key]: value
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
*/
folderClear(fCallback, sFolderFullNameRaw) {
this.defaultRequest(fCallback, 'FolderClear', {
Folder: sFolderFullNameRaw
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {boolean} bSubscribe
*/
folderSetSubscribe(fCallback, sFolderFullNameRaw, bSubscribe) {
this.defaultRequest(fCallback, 'FolderSubscribe', {
Folder: sFolderFullNameRaw,
Subscribe: bSubscribe ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolderFullNameRaw
* @param {boolean} bCheckable
*/
folderSetCheckable(fCallback, sFolderFullNameRaw, bCheckable) {
this.defaultRequest(fCallback, 'FolderCheckable', {
Folder: sFolderFullNameRaw,
Checkable: bCheckable ? 1 : 0
});
}
/**
* @param {?Function} fCallback
* @param {string} sFolder
* @param {string} sToFolder
* @param {Array} aUids
* @param {string=} sLearning
* @param {boolean=} bMarkAsRead
*/
messagesMove(fCallback, sFolder, sToFolder, aUids, sLearning, bMarkAsRead) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'MessageMove',
{
FromFolder: sFolder,
ToFolder: sToFolder,
Uids: aUids.join(','),
MarkAsRead: bMarkAsRead ? 1 : 0,
Learning: sLearning || ''
2019-07-05 03:19:24 +08:00
},
null,
'',
['MessageList']
);
}
/**
* @param {?Function} fCallback
* @param {string} sFolder
* @param {string} sToFolder
* @param {Array} aUids
*/
messagesCopy(fCallback, sFolder, sToFolder, aUids) {
this.defaultRequest(fCallback, 'MessageCopy', {
FromFolder: sFolder,
ToFolder: sToFolder,
Uids: aUids.join(',')
});
2016-06-30 08:02:45 +08:00
}
2014-08-21 23:08:34 +08:00
/**
* @param {?Function} fCallback
* @param {string} sFolder
* @param {Array} aUids
*/
messagesDelete(fCallback, sFolder, aUids) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'MessageDelete',
{
Folder: sFolder,
Uids: aUids.join(',')
2019-07-05 03:19:24 +08:00
},
null,
'',
['MessageList']
);
}
/**
* @param {?Function} fCallback
*/
appDelayStart(fCallback) {
this.defaultRequest(fCallback, 'AppDelayStart');
}
/**
* @param {?Function} fCallback
*/
quota(fCallback) {
this.defaultRequest(fCallback, 'Quota');
}
/**
* @param {?Function} fCallback
* @param {number} iOffset
* @param {number} iLimit
* @param {string} sSearch
*/
contacts(fCallback, iOffset, iLimit, sSearch) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'Contacts',
{
Offset: iOffset,
Limit: iLimit,
Search: sSearch
2019-07-05 03:19:24 +08:00
},
null,
'',
['Contacts']
);
}
/**
* @param {?Function} fCallback
* @param {string} sRequestUid
* @param {string} sUid
* @param {Array} aProperties
*/
contactSave(fCallback, sRequestUid, sUid, aProperties) {
this.defaultRequest(fCallback, 'ContactSave', {
RequestUid: sRequestUid,
Uid: sUid,
Properties: aProperties
});
2016-06-30 08:02:45 +08:00
}
/**
* @param {?Function} fCallback
* @param {Array} aUids
*/
contactsDelete(fCallback, aUids) {
this.defaultRequest(fCallback, 'ContactsDelete', {
Uids: aUids.join(',')
});
2016-06-30 08:02:45 +08:00
}
/**
* @param {?Function} fCallback
* @param {string} sQuery
* @param {number} iPage
*/
suggestions(fCallback, sQuery, iPage) {
2019-07-05 03:19:24 +08:00
this.defaultRequest(
fCallback,
'Suggestions',
{
Query: sQuery,
Page: iPage
2019-07-05 03:19:24 +08:00
},
null,
'',
['Suggestions']
);
}
2016-06-30 08:02:45 +08:00
/**
* @param {?Function} fCallback
*/
clearUserBackground(fCallback) {
this.defaultRequest(fCallback, 'ClearUserBackground');
}
foldersReload(fCallback) {
this.abort('Folders')
.postRequest('Folders', FolderUserStore.foldersLoading)
.then(data => {
data = FolderCollectionModel.reviveFromJson(data.Result);
data && data.storeIt();
fCallback && fCallback(true);
})
.catch(() => fCallback && setTimeout(() => fCallback(false), 1));
}
foldersReloadWithTimeout() {
this.setTrigger(FolderUserStore.foldersLoading, true);
clearTimeout(this.foldersTimeout);
this.foldersTimeout = setTimeout(() => this.foldersReload(), 500);
}
folderDelete(sFolderFullNameRaw) {
return this.postRequest('FolderDelete', FolderUserStore.foldersDeleting, {
2020-10-23 21:15:54 +08:00
Folder: sFolderFullNameRaw
});
}
folderCreate(sNewFolderName, sParentName) {
return this.postRequest('FolderCreate', FolderUserStore.foldersCreating, {
2020-10-23 21:15:54 +08:00
Folder: sNewFolderName,
Parent: sParentName
});
}
folderRename(sPrevFolderFullNameRaw, sNewFolderName) {
return this.postRequest('FolderRename', FolderUserStore.foldersRenaming, {
2020-10-23 21:15:54 +08:00
Folder: sPrevFolderFullNameRaw,
NewFolderName: sNewFolderName
});
}
attachmentsActions(sAction, aHashes, fTrigger) {
return this.postRequest('AttachmentsActions', fTrigger, {
2020-10-23 21:15:54 +08:00
Do: sAction,
Hashes: aHashes
});
}
}
2016-06-30 08:02:45 +08:00
export default new RemoteUserFetch();