Almost all JSON properties to JavaScript camelCase

This commit is contained in:
the-djmaze 2023-01-24 18:58:25 +01:00
parent 7a53cae32f
commit f080a302b1
50 changed files with 501 additions and 562 deletions

View file

@ -114,23 +114,23 @@ folderInformation = (folder, list) => {
Remote.request('FolderInformation', (iError, data) => { Remote.request('FolderInformation', (iError, data) => {
if (!iError && data.Result) { if (!iError && data.Result) {
const result = data.Result, const result = data.Result,
folderFromCache = getFolderFromCacheList(result.Folder); folderFromCache = getFolderFromCacheList(result.folder);
if (folderFromCache) { if (folderFromCache) {
const oldHash = folderFromCache.hash, const oldHash = folderFromCache.hash,
unreadCountChange = (folderFromCache.unreadEmails() !== result.unreadEmails); unreadCountChange = (folderFromCache.unreadEmails() !== result.unreadEmails);
// folderFromCache.revivePropertiesFromJson(result); // folderFromCache.revivePropertiesFromJson(result);
folderFromCache.expires = Date.now(); folderFromCache.expires = Date.now();
folderFromCache.uidNext = result.UidNext; folderFromCache.uidNext = result.uidNext;
folderFromCache.hash = result.Hash; folderFromCache.hash = result.hash;
folderFromCache.totalEmails(result.totalEmails); folderFromCache.totalEmails(result.totalEmails);
folderFromCache.unreadEmails(result.unreadEmails); folderFromCache.unreadEmails(result.unreadEmails);
unreadCountChange && MessageFlagsCache.clearFolder(folderFromCache.fullName); unreadCountChange && MessageFlagsCache.clearFolder(folderFromCache.fullName);
if (result.MessagesFlags.length) { if (result.messagesFlags.length) {
result.MessagesFlags.forEach(message => result.messagesFlags.forEach(message =>
MessageFlagsCache.setFor(folderFromCache.fullName, message.Uid.toString(), message.Flags) MessageFlagsCache.setFor(folderFromCache.fullName, message.uid.toString(), message.flags)
); );
MessagelistUserStore.reloadFlagsAndCachedMessage(); MessagelistUserStore.reloadFlagsAndCachedMessage();
@ -138,7 +138,7 @@ folderInformation = (folder, list) => {
MessagelistUserStore.notifyNewMessages(folderFromCache.fullName, result.newMessages); MessagelistUserStore.notifyNewMessages(folderFromCache.fullName, result.newMessages);
if (!oldHash || unreadCountChange || result.Hash !== oldHash) { if (!oldHash || unreadCountChange || result.hash !== oldHash) {
if (folderFromCache.fullName === FolderUserStore.currentFolderFullName()) { if (folderFromCache.fullName === FolderUserStore.currentFolderFullName()) {
MessagelistUserStore.reload(); MessagelistUserStore.reload();
} else if (getFolderInboxName() === folderFromCache.fullName) { } else if (getFolderInboxName() === folderFromCache.fullName) {
@ -149,9 +149,9 @@ folderInformation = (folder, list) => {
} }
} }
}, { }, {
Folder: folder, folder: folder,
FlagsUids: uids, flagsUids: uids,
UidNext: folderFromCache?.uidNext || 0 // Used to check for new messages uidNext: folderFromCache?.uidNext || 0 // Used to check for new messages
}); });
} else if (SettingsUserStore.useThreads()) { } else if (SettingsUserStore.useThreads()) {
MessagelistUserStore.reloadFlagsAndCachedMessage(); MessagelistUserStore.reloadFlagsAndCachedMessage();
@ -169,7 +169,7 @@ folderInformationMultiply = (boot = false) => {
if (!iError && arrayLength(oData.Result)) { if (!iError && arrayLength(oData.Result)) {
const utc = Date.now(); const utc = Date.now();
oData.Result.forEach(item => { oData.Result.forEach(item => {
const folder = getFolderFromCacheList(item.Folder); const folder = getFolderFromCacheList(item.folder);
if (folder) { if (folder) {
const oldHash = folder.hash, const oldHash = folder.hash,
@ -177,13 +177,13 @@ folderInformationMultiply = (boot = false) => {
// folder.revivePropertiesFromJson(item); // folder.revivePropertiesFromJson(item);
folder.expires = utc; folder.expires = utc;
folder.hash = item.Hash; folder.hash = item.hash;
folder.totalEmails(item.totalEmails); folder.totalEmails(item.totalEmails);
folder.unreadEmails(item.unreadEmails); folder.unreadEmails(item.unreadEmails);
unreadCountChange && MessageFlagsCache.clearFolder(folder.fullName); unreadCountChange && MessageFlagsCache.clearFolder(folder.fullName);
if (!oldHash || item.Hash !== oldHash) { if (!oldHash || item.hash !== oldHash) {
if (folder.fullName === FolderUserStore.currentFolderFullName()) { if (folder.fullName === FolderUserStore.currentFolderFullName()) {
MessagelistUserStore.reload(); MessagelistUserStore.reload();
} }
@ -239,7 +239,7 @@ messagesDeleteHelper = (sFromFolderFullName, aUidForRemove) => {
Remote.abort('MessageList').request('MessageDelete', Remote.abort('MessageList').request('MessageDelete',
moveOrDeleteResponseHelper, moveOrDeleteResponseHelper,
{ {
Folder: sFromFolderFullName, folder: sFromFolderFullName,
Uids: [...aUidForRemove].join(',') Uids: [...aUidForRemove].join(',')
} }
); );
@ -282,7 +282,7 @@ dropFilesInFolder = (sFolderFullName, files) => {
if ('message/rfc822' === file.type) { if ('message/rfc822' === file.type) {
++count; ++count;
let data = new FormData; let data = new FormData;
data.append('Folder', sFolderFullName); data.append('folder', sFolderFullName);
data.append('AppendFile', file); data.append('AppendFile', file);
data.XToken = Settings.app('token'); data.XToken = Settings.app('token');
fetch(serverRequest('Append'), { fetch(serverRequest('Append'), {

View file

@ -98,9 +98,9 @@ export const
hasExternals: false hasExternals: false
}, },
findAttachmentByCid = cid => oAttachments.findByCid(cid), findAttachmentByCid = cId => oAttachments.findByCid(cId),
findLocationByCid = cid => { findLocationByCid = cId => {
const attachment = findAttachmentByCid(cid); const attachment = findAttachmentByCid(cId);
return attachment?.contentLocation ? attachment : 0; return attachment?.contentLocation ? attachment : 0;
}, },

View file

@ -266,10 +266,10 @@ populateMessageBody = (oMessage, popup) => {
if ( if (
json && json &&
MessageModel.validJson(json) && MessageModel.validJson(json) &&
oMessage.folder === json.Folder oMessage.folder === json.folder
) { ) {
const threads = oMessage.threads(), const threads = oMessage.threads(),
isNew = !popup && oMessage.uid != json.Uid && threads.includes(json.Uid), isNew = !popup && oMessage.uid != json.uid && threads.includes(json.uid),
messagesDom = MessageUserStore.bodiesDom(); messagesDom = MessageUserStore.bodiesDom();
if (isNew) { if (isNew) {
oMessage = MessageModel.reviveFromJson(json); oMessage = MessageModel.reviveFromJson(json);
@ -283,11 +283,11 @@ populateMessageBody = (oMessage, popup) => {
MessageUserStore.message(oMessage); MessageUserStore.message(oMessage);
} }
if (oMessage && oMessage.uid == json.Uid) { if (oMessage && oMessage.uid == json.uid) {
popup || MessageUserStore.error(''); popup || MessageUserStore.error('');
/* /*
if (bCached) { if (bCached) {
delete json.Flags; delete json.flags;
} }
*/ */
isNew || oMessage.revivePropertiesFromJson(json); isNew || oMessage.revivePropertiesFromJson(json);

View file

@ -86,7 +86,7 @@ export class AbstractModel {
} }
forEachObjectEntry(json, (key, value) => { forEachObjectEntry(json, (key, value) => {
if ('@' !== key[0]) try { if ('@' !== key[0]) try {
key = key[0].toLowerCase() + key.slice(1); // key = key[0].toLowerCase() + key.slice(1);
switch (typeof this[key]) switch (typeof this[key])
{ {
case 'function': case 'function':

View file

@ -30,9 +30,9 @@ export function MimeToMessage(data, message)
struct.forEach(part => { struct.forEach(part => {
let cd = part.header('content-disposition'), let cd = part.header('content-disposition'),
cid = part.header('content-id'), cId = part.header('content-id'),
type = part.header('content-type'); type = part.header('content-type');
if (cid || cd) { if (cId || cd) {
// if (cd && 'attachment' === cd.value) { // if (cd && 'attachment' === cd.value) {
let attachment = new AttachmentModel; let attachment = new AttachmentModel;
attachment.mimeType = type.value; attachment.mimeType = type.value;
@ -49,8 +49,8 @@ export function MimeToMessage(data, message)
attachment.uid = ''; attachment.uid = '';
attachment.mimeIndex = part.id; attachment.mimeIndex = part.id;
*/ */
attachment.cid = cid ? cid.value : ''; attachment.cId = cId ? cId.value : '';
if (cid && html) { if (cId && html) {
let cid = 'cid:' + attachment.contentId(), let cid = 'cid:' + attachment.contentId(),
found = html.includes(cid); found = html.includes(cid);
attachment.isInline(found); attachment.isInline(found);
@ -64,9 +64,9 @@ export function MimeToMessage(data, message)
} }
} else if ('multipart/signed' === type.value && 'application/pgp-signature' === type.params.protocol) { } else if ('multipart/signed' === type.value && 'application/pgp-signature' === type.params.protocol) {
signed = { signed = {
MicAlg: type.micalg, micAlg: type.micalg,
BodyPart: part.parts[0], bodyPart: part.parts[0],
SigPart: part.parts[1] sigPart: part.parts[1]
}; };
} }
}); });

View file

@ -22,7 +22,7 @@ export class AttachmentModel extends AbstractModel {
this.fileNameExt = ''; this.fileNameExt = '';
this.fileType = FileType.Unknown; this.fileType = FileType.Unknown;
this.isThumbnail = false; this.isThumbnail = false;
this.cid = ''; this.cId = '';
this.contentLocation = ''; this.contentLocation = '';
this.download = ''; this.download = '';
this.folder = ''; this.folder = '';
@ -61,7 +61,7 @@ export class AttachmentModel extends AbstractModel {
} }
contentId() { contentId() {
return this.cid.replace(/^<+|>+$/g, ''); return this.cId.replace(/^<+|>+$/g, '');
} }
/** /**

View file

@ -21,11 +21,11 @@ export class AttachmentCollectionModel extends AbstractCollectionModel
} }
/** /**
* @param {string} cid * @param {string} cId
* @returns {*} * @returns {*}
*/ */
findByCid(cid) { findByCid(cId) {
cid = cid.replace(/^<+|>+$/g, ''); cId = cId.replace(/^<+|>+$/g, '');
return this.find(item => cid === item.contentId()); return this.find(item => cId === item.contentId());
} }
} }

View file

@ -10,16 +10,16 @@ export class ComposeAttachmentModel extends AbstractModel {
* @param {?number=} size = null * @param {?number=} size = null
* @param {boolean=} isInline = false * @param {boolean=} isInline = false
* @param {boolean=} isLinked = false * @param {boolean=} isLinked = false
* @param {string=} CID = '' * @param {string=} cId = ''
* @param {string=} contentLocation = '' * @param {string=} contentLocation = ''
*/ */
constructor(id, fileName, size = null, isInline = false, isLinked = false, CID = '', contentLocation = '') { constructor(id, fileName, size = null, isInline = false, isLinked = false, cId = '', contentLocation = '') {
super(); super();
this.id = id; this.id = id;
this.isInline = !!isInline; this.isInline = !!isInline;
this.isLinked = !!isLinked; this.isLinked = !!isLinked;
this.CID = CID; this.cId = cId;
this.contentLocation = contentLocation; this.contentLocation = contentLocation;
this.fromMessage = false; this.fromMessage = false;

View file

@ -304,7 +304,7 @@ export class ContactModel extends AbstractModel {
// jCard.set('rev', '2022-05-21T10:59:52Z') // jCard.set('rev', '2022-05-21T10:59:52Z')
return { return {
Uid: this.id, uid: this.id,
jCard: JSON.stringify(jCard) jCard: JSON.stringify(jCard)
}; };
} }

View file

@ -124,11 +124,11 @@ export class FolderCollectionModel extends AbstractCollectionModel
); );
const result = super.reviveFromJson(object, oFolder => { const result = super.reviveFromJson(object, oFolder => {
let oCacheFolder = getFolderFromCacheList(oFolder.FullName); let oCacheFolder = getFolderFromCacheList(oFolder.fullName);
if (oCacheFolder) { if (oCacheFolder) {
// oCacheFolder.revivePropertiesFromJson(oFolder); // oCacheFolder.revivePropertiesFromJson(oFolder);
if (oFolder.Hash) { if (oFolder.hash) {
oCacheFolder.hash = oFolder.Hash; oCacheFolder.hash = oFolder.hash;
} }
if (null != oFolder.totalEmails) { if (null != oFolder.totalEmails) {
oCacheFolder.totalEmails(oFolder.totalEmails); oCacheFolder.totalEmails(oFolder.totalEmails);
@ -167,32 +167,32 @@ export class FolderCollectionModel extends AbstractCollectionModel
break; break;
} }
// Flags // Flags
if (oFolder.Flags.includes('\\sentmail')) { if (oFolder.flags.includes('\\sentmail')) {
role = 'sent'; role = 'sent';
} }
if (oFolder.Flags.includes('\\spam')) { if (oFolder.flags.includes('\\spam')) {
role = 'junk'; role = 'junk';
} }
if (oFolder.Flags.includes('\\bin')) { if (oFolder.flags.includes('\\bin')) {
role = 'trash'; role = 'trash';
} }
if (oFolder.Flags.includes('\\important')) { if (oFolder.flags.includes('\\important')) {
role = 'important'; role = 'important';
} }
if (oFolder.Flags.includes('\\starred')) { if (oFolder.flags.includes('\\starred')) {
role = 'flagged'; role = 'flagged';
} }
if (oFolder.Flags.includes('\\all') || oFolder.Flags.includes('\\allmail')) { if (oFolder.flags.includes('\\all') || oFolder.flags.includes('\\allmail')) {
role = 'all'; role = 'all';
} }
} }
*/ */
if (role) { if (role) {
role = role[0].toUpperCase() + role.slice(1); role = role[0].toUpperCase() + role.slice(1);
SystemFolders[role] || (SystemFolders[role] = oFolder.FullName); SystemFolders[role] || (SystemFolders[role] = oFolder.fullName);
} }
oCacheFolder.type(FolderType[getKeyByValue(SystemFolders, oFolder.FullName)] || 0); oCacheFolder.type(FolderType[getKeyByValue(SystemFolders, oFolder.fullName)] || 0);
oCacheFolder.collapsed(!expandedFolders oCacheFolder.collapsed(!expandedFolders
|| !isArray(expandedFolders) || !isArray(expandedFolders)
@ -223,12 +223,12 @@ export class FolderCollectionModel extends AbstractCollectionModel
if (!pfolder) { if (!pfolder) {
pfolder = FolderModel.reviveFromJson({ pfolder = FolderModel.reviveFromJson({
'@Object': 'Object/Folder', '@Object': 'Object/Folder',
Name: name, name: name,
FullName: parentName, fullName: parentName,
Delimiter: delimiter, delimiter: delimiter,
Exists: false, exists: false,
isSubscribed: false, isSubscribed: false,
Flags: ['\\nonexistent'] flags: ['\\nonexistent']
}); });
setFolder(pfolder); setFolder(pfolder);
result.splice(i, 0, pfolder); result.splice(i, 0, pfolder);

View file

@ -43,7 +43,7 @@ const
// MessageFlagsCache.setFor(message.folder, message.uid, flags()); // MessageFlagsCache.setFor(message.folder, message.uid, flags());
} }
}, { }, {
Folder: message.folder, folder: message.folder,
Uids: message.uid, Uids: message.uid,
Keyword: keyword, Keyword: keyword,
SetAction: isSet ? 0 : 1 SetAction: isSet ? 0 : 1
@ -188,12 +188,9 @@ export class MessageModel extends AbstractModel {
* @returns {boolean} * @returns {boolean}
*/ */
revivePropertiesFromJson(json) { revivePropertiesFromJson(json) {
if ('Priority' in json && ![MessagePriority.High, MessagePriority.Low].includes(json.Priority)) {
json.Priority = MessagePriority.Normal;
}
if (super.revivePropertiesFromJson(json)) { if (super.revivePropertiesFromJson(json)) {
// this.foundCIDs = isArray(json.FoundCIDs) ? json.FoundCIDs : []; // this.foundCIDs = isArray(json.FoundCIDs) ? json.FoundCIDs : [];
// this.attachments(AttachmentCollectionModel.reviveFromJson(json.Attachments, this.foundCIDs)); // this.attachments(AttachmentCollectionModel.reviveFromJson(json.attachments, this.foundCIDs));
this.computeSenderEmail(); this.computeSenderEmail();
} }

View file

@ -13,7 +13,7 @@ export class MessageCollectionModel extends AbstractCollectionModel
constructor() { constructor() {
super(); super();
this.Filtered this.Filtered
this.Folder this.folder
this.folderHash this.folderHash
this.folderInfo this.folderInfo
this.totalEmails this.totalEmails

View file

@ -109,9 +109,9 @@ class RemoteUserFetch extends AbstractFetchRemote {
/* /*
folderMove(sPrevFolderFullName, sNewFolderFullName, bSubscribe) { folderMove(sPrevFolderFullName, sNewFolderFullName, bSubscribe) {
return this.post('FolderMove', FolderUserStore.foldersRenaming, { return this.post('FolderMove', FolderUserStore.foldersRenaming, {
Folder: sPrevFolderFullName, folder: sPrevFolderFullName,
NewFolder: sNewFolderFullName, newFolder: sNewFolderFullName,
Subscribe: bSubscribe ? 1 : 0 subscribe: bSubscribe ? 1 : 0
}); });
} }
*/ */

View file

@ -62,9 +62,9 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
const nameToEdit = folder?.nameForEdit().trim(); const nameToEdit = folder?.nameForEdit().trim();
if (nameToEdit && folder.name() !== nameToEdit) { if (nameToEdit && folder.name() !== nameToEdit) {
Remote.abort('Folders').post('FolderRename', FolderUserStore.foldersRenaming, { Remote.abort('Folders').post('FolderRename', FolderUserStore.foldersRenaming, {
Folder: folder.fullName, folder: folder.fullName,
NewFolderName: nameToEdit, newFolderName: nameToEdit,
Subscribe: folder.isSubscribed() ? 1 : 0 subscribe: folder.isSubscribed() ? 1 : 0
}) })
.then(data => { .then(data => {
folder.name(nameToEdit/*data.name*/); folder.name(nameToEdit/*data.name*/);
@ -76,7 +76,7 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
// TODO: rename all subfolders with folder.delimiter to prevent reload? // TODO: rename all subfolders with folder.delimiter to prevent reload?
} else { } else {
removeFolderFromCacheList(folder.fullName); removeFolderFromCacheList(folder.fullName);
folder.fullName = data.Result.FullName; folder.fullName = data.Result.fullName;
setFolder(folder); setFolder(folder);
const parent = getFolderFromCacheList(folder.parentName); const parent = getFolderFromCacheList(folder.parentName);
sortFolders(parent ? parent.subFolders : FolderUserStore.folderList); sortFolders(parent ? parent.subFolders : FolderUserStore.folderList);
@ -126,7 +126,7 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
if (folderToRemove) { if (folderToRemove) {
Remote.abort('Folders').post('FolderDelete', FolderUserStore.foldersDeleting, { Remote.abort('Folders').post('FolderDelete', FolderUserStore.foldersDeleting, {
Folder: folderToRemove.fullName folder: folderToRemove.fullName
}).then( }).then(
() => { () => {
// folderToRemove.flags.push('\\nonexistent'); // folderToRemove.flags.push('\\nonexistent');
@ -159,7 +159,7 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
let type = event.target.value; let type = event.target.value;
// TODO: append '.default' ? // TODO: append '.default' ?
Remote.request('FolderSetMetadata', null, { Remote.request('FolderSetMetadata', null, {
Folder: folder.fullName, folder: folder.fullName,
Key: FolderMetadataKeys.KolabFolderType, Key: FolderMetadataKeys.KolabFolderType,
Value: type Value: type
}); });
@ -169,8 +169,8 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
toggleFolderSubscription(folder) { toggleFolderSubscription(folder) {
let subscribe = !folder.isSubscribed(); let subscribe = !folder.isSubscribed();
Remote.request('FolderSubscribe', null, { Remote.request('FolderSubscribe', null, {
Folder: folder.fullName, folder: folder.fullName,
Subscribe: subscribe ? 1 : 0 subscribe: subscribe ? 1 : 0
}); });
folder.isSubscribed(subscribe); folder.isSubscribed(subscribe);
} }
@ -178,8 +178,8 @@ export class UserSettingsFolders /*extends AbstractViewSettings*/ {
toggleFolderCheckable(folder) { toggleFolderCheckable(folder) {
let checkable = !folder.checkable(); let checkable = !folder.checkable();
Remote.request('FolderCheckable', null, { Remote.request('FolderCheckable', null, {
Folder: folder.fullName, folder: folder.fullName,
Checkable: checkable ? 1 : 0 checkable: checkable ? 1 : 0
}); });
folder.checkable(checkable); folder.checkable(checkable);
} }

View file

@ -92,8 +92,8 @@ export class UserSettingsThemes /*extends AbstractViewSettings*/ {
}) })
.on('onComplete', (id, result, data) => { .on('onComplete', (id, result, data) => {
themeBackground.loading(false); themeBackground.loading(false);
themeBackground.name(data?.Result?.Name || ''); themeBackground.name(data?.Result?.name || '');
themeBackground.hash(data?.Result?.Hash || ''); themeBackground.hash(data?.Result?.hash || '');
if (!themeBackground.name() || !themeBackground.hash()) { if (!themeBackground.name() || !themeBackground.hash()) {
let errorMsg = ''; let errorMsg = '';
if (data.ErrorCode) { if (data.ErrorCode) {

View file

@ -63,7 +63,7 @@ export const GnuPGUserStore = new class {
} }
} }
}, { }, {
KeyId: key.id, keyId: key.id,
isPrivate: isPrivate isPrivate: isPrivate
} }
); );
@ -77,7 +77,7 @@ export const GnuPGUserStore = new class {
showScreenPopup(OpenPgpKeyPopupView, [key]); showScreenPopup(OpenPgpKeyPopupView, [key]);
} }
}, { }, {
KeyId: key.id, keyId: key.id,
isPrivate: isPrivate, isPrivate: isPrivate,
Passphrase: pass Passphrase: pass
} }
@ -166,7 +166,7 @@ export const GnuPGUserStore = new class {
const const
pgpInfo = message.pgpEncrypted(); pgpInfo = message.pgpEncrypted();
if (pgpInfo) { if (pgpInfo) {
let ids = [message.to[0].email].concat(pgpInfo.KeyIds), let ids = [message.to[0].email].concat(pgpInfo.keyIds),
i = ids.length, key; i = ids.length, key;
while (i--) { while (i--) {
key = findGnuPGKey(this.privateKeys, ids[i]); key = findGnuPGKey(this.privateKeys, ids[i]);
@ -177,10 +177,10 @@ export const GnuPGUserStore = new class {
if (key) { if (key) {
// Also check message.from[0].email // Also check message.from[0].email
let params = { let params = {
Folder: message.folder, folder: message.folder,
Uid: message.uid, uid: message.uid,
PartId: pgpInfo.PartId, partId: pgpInfo.PartId,
KeyId: key.id, keyId: key.id,
Passphrase: await askPassphrase(key, 'BUTTON_DECRYPT'), Passphrase: await askPassphrase(key, 'BUTTON_DECRYPT'),
Data: '' // message.plain() optional Data: '' // message.plain() optional
} }
@ -195,13 +195,13 @@ export const GnuPGUserStore = new class {
} }
async verify(message) { async verify(message) {
let data = message.pgpSigned(); // { BodyPartId: "1", SigPartId: "2", MicAlg: "pgp-sha256" } let data = message.pgpSigned(); // { bodyPartId: "1", sigPartId: "2", micAlg: "pgp-sha256" }
if (data) { if (data) {
data = { ...data }; // clone data = { ...data }; // clone
// const sender = message.from[0].email; // const sender = message.from[0].email;
// let mode = await this.hasPublicKeyForEmails([sender]); // let mode = await this.hasPublicKeyForEmails([sender]);
data.Folder = message.folder; data.folder = message.folder;
data.Uid = message.uid; data.uid = message.uid;
if (data.BodyPart) { if (data.BodyPart) {
data.BodyPart = data.BodyPart.raw; data.BodyPart = data.BodyPart.raw;
data.SigPart = data.SigPart.body; data.SigPart = data.SigPart.body;

View file

@ -47,7 +47,7 @@ addObservablesTo(MessagelistUserStore, {
page: 1, page: 1,
pageBeforeThread: 1, pageBeforeThread: 1,
error: '', error: '',
// Folder: '', // folder: '',
endHash: '', endHash: '',
endThreadUid: 0, endThreadUid: 0,
@ -69,17 +69,17 @@ addComputablesTo(MessagelistUserStore, {
return value; return value;
}, },
isArchiveFolder: () => FolderUserStore.archiveFolder() === MessagelistUserStore().Folder, isArchiveFolder: () => FolderUserStore.archiveFolder() === MessagelistUserStore().folder,
isDraftFolder: () => FolderUserStore.draftsFolder() === MessagelistUserStore().Folder, isDraftFolder: () => FolderUserStore.draftsFolder() === MessagelistUserStore().folder,
isSentFolder: () => FolderUserStore.sentFolder() === MessagelistUserStore().Folder, isSentFolder: () => FolderUserStore.sentFolder() === MessagelistUserStore().folder,
isSpamFolder: () => FolderUserStore.spamFolder() === MessagelistUserStore().Folder, isSpamFolder: () => FolderUserStore.spamFolder() === MessagelistUserStore().folder,
isTrashFolder: () => FolderUserStore.trashFolder() === MessagelistUserStore().Folder, isTrashFolder: () => FolderUserStore.trashFolder() === MessagelistUserStore().folder,
archiveAllowed: () => ![UNUSED_OPTION_VALUE, MessagelistUserStore().Folder].includes(FolderUserStore.archiveFolder()) archiveAllowed: () => ![UNUSED_OPTION_VALUE, MessagelistUserStore().folder].includes(FolderUserStore.archiveFolder())
&& !MessagelistUserStore.isDraftFolder(), && !MessagelistUserStore.isDraftFolder(),
canMarkAsSpam: () => !(UNUSED_OPTION_VALUE === FolderUserStore.spamFolder() canMarkAsSpam: () => !(UNUSED_OPTION_VALUE === FolderUserStore.spamFolder()
@ -147,14 +147,14 @@ MessagelistUserStore.notifyNewMessages = (folder, newMessages) => {
i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', { i18n('MESSAGE_LIST/NEW_MESSAGE_NOTIFICATION', {
COUNT: len COUNT: len
}), }),
{ Url: mailBox(newMessages[0].Folder) } { Url: mailBox(newMessages[0].folder) }
); );
} else { } else {
newMessages.forEach(item => { newMessages.forEach(item => {
NotificationUserStore.display( NotificationUserStore.display(
EmailCollectionModel.reviveFromJson(item.From).toString(), EmailCollectionModel.reviveFromJson(item.from).toString(),
item.subject, item.subject,
{ Folder: item.Folder, Uid: item.Uid } { folder: item.folder, uid: item.uid }
); );
}); });
} }
@ -208,12 +208,12 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach
let unreadCountChange = false; let unreadCountChange = false;
const const
folder = getFolderFromCacheList(collection.Folder), folder = getFolderFromCacheList(collection.folder),
folderInfo = collection.folderInfo; folderInfo = collection.folderInfo;
if (folder && !bCached) { if (folder && !bCached) {
// folder.revivePropertiesFromJson(result); // folder.revivePropertiesFromJson(result);
folder.expires = Date.now(); folder.expires = Date.now();
folder.uidNext = folderInfo.UidNext; folder.uidNext = folderInfo.uidNext;
folder.hash = collection.folderHash; folder.hash = collection.folderHash;
if (null != folderInfo.totalEmails) { if (null != folderInfo.totalEmails) {
@ -228,8 +228,8 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach
folder.unreadEmails(folderInfo.unreadEmails); folder.unreadEmails(folderInfo.unreadEmails);
} }
folder.flags(folderInfo.Flags); folder.flags(folderInfo.flags);
let flags = folderInfo.PermanentFlags; let flags = folderInfo.permanentFlags;
if (flags.includes('\\*')) { if (flags.includes('\\*')) {
let i = 6; let i = 6;
while (--i) { while (--i) {
@ -253,14 +253,14 @@ MessagelistUserStore.reload = (bDropPagePosition = false, bDropCurrentFolderCach
MessagelistUserStore.threadUid(collection.threadUid); MessagelistUserStore.threadUid(collection.threadUid);
MessagelistUserStore.endHash( MessagelistUserStore.endHash(
collection.Folder + collection.folder +
'|' + collection.search + '|' + collection.search +
'|' + MessagelistUserStore.threadUid() + '|' + MessagelistUserStore.threadUid() +
'|' + MessagelistUserStore.page() '|' + MessagelistUserStore.page()
); );
MessagelistUserStore.endThreadUid(collection.threadUid); MessagelistUserStore.endThreadUid(collection.threadUid);
const message = MessageUserStore.message(); const message = MessageUserStore.message();
if (message && collection.Folder !== message.folder) { if (message && collection.folder !== message.folder) {
MessageUserStore.message(null); MessageUserStore.message(null);
} }
@ -330,7 +330,7 @@ MessagelistUserStore.setAction = (sFolderFullName, iSetAction, messages) => {
folder.unreadEmails(folder.unreadEmails() - alreadyUnread + length); folder.unreadEmails(folder.unreadEmails() - alreadyUnread + length);
} }
Remote.request('MessageSetSeen', null, { Remote.request('MessageSetSeen', null, {
Folder: sFolderFullName, folder: sFolderFullName,
Uids: rootUids.join(','), Uids: rootUids.join(','),
SetAction: iSetAction == MessageSetAction.SetSeen ? 1 : 0 SetAction: iSetAction == MessageSetAction.SetSeen ? 1 : 0
}); });
@ -339,7 +339,7 @@ MessagelistUserStore.setAction = (sFolderFullName, iSetAction, messages) => {
case MessageSetAction.SetFlag: case MessageSetAction.SetFlag:
case MessageSetAction.UnsetFlag: case MessageSetAction.UnsetFlag:
Remote.request('MessageSetFlagged', null, { Remote.request('MessageSetFlagged', null, {
Folder: sFolderFullName, folder: sFolderFullName,
Uids: rootUids.join(','), Uids: rootUids.join(','),
SetAction: iSetAction == MessageSetAction.SetFlag ? 1 : 0 SetAction: iSetAction == MessageSetAction.SetFlag ? 1 : 0
}); });

View file

@ -11,7 +11,7 @@ const HTML5Notification = window.Notification,
NotificationsGranted = () => 'granted' === HTML5NotificationStatus(), NotificationsGranted = () => 'granted' === HTML5NotificationStatus(),
dispatchMessage = data => { dispatchMessage = data => {
focus(); focus();
if (data.Folder && data.Uid) { if (data.folder && data.uid) {
fireEvent('mailbox.message.show', data); fireEvent('mailbox.message.show', data);
} else if (data.Url) { } else if (data.Url) {
hasher.setHash(data.Url); hasher.setHash(data.Url);
@ -60,8 +60,8 @@ export const NotificationUserStore = new class {
icon: imageSrc || Links.staticLink('css/images/icon-message-notification.png'), icon: imageSrc || Links.staticLink('css/images/icon-message-notification.png'),
data: messageData data: messageData
}; };
if (messageData?.Uid) { if (messageData?.uid) {
options.tag = messageData.Uid; options.tag = messageData.uid;
} }
if (WorkerNotifications) { if (WorkerNotifications) {
// Service-Worker-Allowed HTTP header to allow the scope. // Service-Worker-Allowed HTTP header to allow the scope.

View file

@ -214,14 +214,14 @@ export const OpenPGPUserStore = new class {
* https://docs.openpgpjs.org/#sign-and-verify-cleartext-messages * https://docs.openpgpjs.org/#sign-and-verify-cleartext-messages
*/ */
async verify(message) { async verify(message) {
const data = message.pgpSigned(), // { BodyPartId: "1", SigPartId: "2", MicAlg: "pgp-sha256" } const data = message.pgpSigned(), // { bodyPartId: "1", sigPartId: "2", micAlg: "pgp-sha256" }
publicKey = this.publicKeys().find(key => key.emails.includes(message.from[0].email)); publicKey = this.publicKeys().find(key => key.emails.includes(message.from[0].email));
if (data && publicKey) { if (data && publicKey) {
data.Folder = message.folder; data.folder = message.folder;
data.Uid = message.uid; data.uid = message.uid;
data.GnuPG = 0; data.GnuPG = 0;
let response; let response;
if (data.SigPartId) { if (data.sigPartId) {
response = await Remote.post('MessagePgpVerify', null, data); response = await Remote.post('MessagePgpVerify', null, data);
} else if (data.BodyPart) { } else if (data.BodyPart) {
response = { Result: { text: data.BodyPart.raw, signature: data.SigPart.body } }; response = { Result: { text: data.BodyPart.raw, signature: data.SigPart.body } };

View file

@ -198,7 +198,7 @@ export const
gnupg = GnuPGUserStore.hasPublicKeyForEmails([sender]), gnupg = GnuPGUserStore.hasPublicKeyForEmails([sender]),
openpgp = OpenPGPUserStore.hasPublicKeyForEmails([sender]); openpgp = OpenPGPUserStore.hasPublicKeyForEmails([sender]);
// Detached signature use GnuPG first, else we must download whole message // Detached signature use GnuPG first, else we must download whole message
if (gnupg && signed.SigPartId) { if (gnupg && signed.sigPartId) {
return GnuPGUserStore.verify(message); return GnuPGUserStore.verify(message);
} }
if (openpgp) { if (openpgp) {

View file

@ -514,7 +514,7 @@ export class ComposePopupView extends AbstractViewPopup {
this.saving(false); this.saving(false);
if (!iError) { if (!iError) {
if (oData.Result.NewFolder && oData.Result.NewUid) { if (oData.Result.folder && oData.Result.uid) {
result = true; result = true;
if (this.bFromDraft) { if (this.bFromDraft) {
@ -524,8 +524,8 @@ export class ComposePopupView extends AbstractViewPopup {
} }
} }
this.draftsFolder(oData.Result.NewFolder); this.draftsFolder(oData.Result.folder);
this.draftUid(oData.Result.NewUid); this.draftUid(oData.Result.uid);
this.savedTime(new Date); this.savedTime(new Date);
@ -968,7 +968,7 @@ export class ComposePopupView extends AbstractViewPopup {
this.setFocusInPopup(); this.setFocusInPopup();
} }
// item.CID item.isInline item.isLinked // item.cId item.isInline item.isLinked
const downloads = this.attachments.filter(item => item && !item.tempName()).map(item => item.id); const downloads = this.attachments.filter(item => item && !item.tempName()).map(item => item.id);
if (arrayLength(downloads)) { if (arrayLength(downloads)) {
Remote.request('MessageUploadAttachments', Remote.request('MessageUploadAttachments',
@ -984,14 +984,14 @@ export class ComposePopupView extends AbstractViewPopup {
if (iError || !result?.[index]) { if (iError || !result?.[index]) {
attachment.error(getUploadErrorDescByCode(UploadErrorCode.NoFileUploaded)); attachment.error(getUploadErrorDescByCode(UploadErrorCode.NoFileUploaded));
} else { } else {
attachment.tempName(result[index].TempName); attachment.tempName(result[index].tempName);
attachment.type(result[index].MimeType); attachment.type(result[index].mimeType);
} }
} }
}); });
}, },
{ {
Attachments: downloads attachments: downloads
}, },
999000 999000
); );
@ -1058,10 +1058,10 @@ export class ComposePopupView extends AbstractViewPopup {
this.dragAndDropOver(false); this.dragAndDropOver(false);
const const
size = pInt(oData.Size, null), size = pInt(oData.size, null),
attachment = new ComposeAttachmentModel( attachment = new ComposeAttachmentModel(
sId, sId,
oData.FileName ? oData.FileName.toString() : '', oData.fileName ? oData.fileName.toString() : '',
size size
); );
@ -1113,11 +1113,11 @@ export class ComposePopupView extends AbstractViewPopup {
.waiting(false) .waiting(false)
.uploading(false) .uploading(false)
.complete(true); .complete(true);
attachment.fileName(attachmentJson.Name); attachment.fileName(attachmentJson.name);
attachment.size(attachmentJson.Size ? pInt(attachmentJson.Size) : 0); attachment.size(attachmentJson.size ? pInt(attachmentJson.size) : 0);
attachment.tempName(attachmentJson.TempName ? attachmentJson.TempName : ''); attachment.tempName(attachmentJson.tempName ? attachmentJson.tempName : '');
attachment.isInline = false; attachment.isInline = false;
attachment.type(attachmentJson.MimeType); attachment.type(attachmentJson.mimeType);
} }
} }
}); });
@ -1227,7 +1227,7 @@ export class ComposePopupView extends AbstractViewPopup {
item.estimatedSize, item.estimatedSize,
item.isInline(), item.isInline(),
item.isLinked(), item.isLinked(),
item.cid, item.cId,
item.contentLocation item.contentLocation
); );
attachment.fromMessage = true; attachment.fromMessage = true;
@ -1395,7 +1395,7 @@ export class ComposePopupView extends AbstractViewPopup {
attachments[item.tempName()] = { attachments[item.tempName()] = {
name: item.fileName(), name: item.fileName(),
inline: item.isInline, inline: item.isInline,
cid: item.CID, cId: item.cId,
location: item.contentLocation, location: item.contentLocation,
type: item.mimeType() type: item.mimeType()
}; };
@ -1405,32 +1405,32 @@ export class ComposePopupView extends AbstractViewPopup {
const const
identity = this.currentIdentity(), identity = this.currentIdentity(),
params = { params = {
IdentityID: identity.id(), identityID: identity.id(),
MessageFolder: this.draftsFolder(), messageFolder: this.draftsFolder(),
MessageUid: this.draftUid(), messageUid: this.draftUid(),
SaveFolder: sSaveFolder, saveFolder: sSaveFolder,
From: this.from(), from: this.from(),
To: this.to(), to: this.to(),
Cc: this.cc(), cc: this.cc(),
Bcc: this.bcc(), bcc: this.bcc(),
ReplyTo: this.replyTo(), replyTo: this.replyTo(),
subject: this.subject(), subject: this.subject(),
DraftInfo: this.aDraftInfo, draftInfo: this.aDraftInfo,
InReplyTo: this.sInReplyTo, inReplyTo: this.sInReplyTo,
References: this.sReferences, references: this.sReferences,
MarkAsImportant: this.markAsImportant() ? 1 : 0, markAsImportant: this.markAsImportant() ? 1 : 0,
Attachments: attachments, attachments: attachments,
// Only used at send, not at save: // Only used at send, not at save:
Dsn: this.requestDsn() ? 1 : 0, dsn: this.requestDsn() ? 1 : 0,
ReadReceiptRequest: this.requestReadReceipt() ? 1 : 0 readReceiptRequest: this.requestReadReceipt() ? 1 : 0
}, },
recipients = draft ? [identity.email()] : this.allRecipients(), recipients = draft ? [identity.email()] : this.allRecipients(),
sign = !draft && this.pgpSign() && this.canPgpSign(), sign = !draft && this.pgpSign() && this.canPgpSign(),
encrypt = this.pgpEncrypt() && this.canPgpEncrypt(), encrypt = this.pgpEncrypt() && this.canPgpEncrypt(),
TextIsHtml = this.oEditor.isHtml(); isHtml = this.oEditor.isHtml();
let Text = this.oEditor.getData(); let Text = this.oEditor.getData();
if (TextIsHtml) { if (isHtml) {
let l; let l;
do { do {
l = Text.length; l = Text.length;
@ -1440,27 +1440,27 @@ export class ComposePopupView extends AbstractViewPopup {
// Remove hubspot data-hs- attributes // Remove hubspot data-hs- attributes
.replace(/(<[^>]+)\s+data-hs-[a-z-]+=("[^"]+"|'[^']+')/gi, '$1'); .replace(/(<[^>]+)\s+data-hs-[a-z-]+=("[^"]+"|'[^']+')/gi, '$1');
} while (l != Text.length) } while (l != Text.length)
params.Html = Text; params.html = Text;
params.Text = htmlToPlain(Text); params.plain = htmlToPlain(Text);
} else { } else {
params.Text = Text; params.plain = Text;
} }
if (this.mailvelope && 'mailvelope' === this.viewArea()) { if (this.mailvelope && 'mailvelope' === this.viewArea()) {
params.Encrypted = draft params.encrypted = draft
? await this.mailvelope.createDraft() ? await this.mailvelope.createDraft()
: await this.mailvelope.encrypt(recipients); : await this.mailvelope.encrypt(recipients);
} else if (sign || encrypt) { } else if (sign || encrypt) {
let data = new MimePart; let data = new MimePart;
data.headers['Content-Type'] = 'text/'+(TextIsHtml?'html':'plain')+'; charset="utf-8"'; data.headers['Content-Type'] = 'text/'+(isHtml?'html':'plain')+'; charset="utf-8"';
data.headers['Content-Transfer-Encoding'] = 'base64'; data.headers['Content-Transfer-Encoding'] = 'base64';
data.body = base64_encode(Text); data.body = base64_encode(Text);
if (TextIsHtml) { if (isHtml) {
const alternative = new MimePart, plain = new MimePart; const alternative = new MimePart, plain = new MimePart;
alternative.headers['Content-Type'] = 'multipart/alternative'; alternative.headers['Content-Type'] = 'multipart/alternative';
plain.headers['Content-Type'] = 'text/plain; charset="utf-8"'; plain.headers['Content-Type'] = 'text/plain; charset="utf-8"';
plain.headers['Content-Transfer-Encoding'] = 'base64'; plain.headers['Content-Transfer-Encoding'] = 'base64';
plain.body = base64_encode(params.Text); plain.body = base64_encode(params.plain);
// First add plain // First add plain
alternative.children.push(plain); alternative.children.push(plain);
// Now add HTML // Now add HTML
@ -1470,7 +1470,7 @@ export class ComposePopupView extends AbstractViewPopup {
if (!draft && sign?.[1]) { if (!draft && sign?.[1]) {
if ('openpgp' == sign[0]) { if ('openpgp' == sign[0]) {
// Doesn't sign attachments // Doesn't sign attachments
params.Html = params.Text = ''; params.html = params.plain = '';
let signed = new MimePart; let signed = new MimePart;
signed.headers['Content-Type'] = signed.headers['Content-Type'] =
'multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"'; 'multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"';
@ -1481,14 +1481,14 @@ export class ComposePopupView extends AbstractViewPopup {
signature.headers['Content-Transfer-Encoding'] = '7Bit'; signature.headers['Content-Transfer-Encoding'] = '7Bit';
signature.body = await OpenPGPUserStore.sign(data.toString(), sign[1], 1); signature.body = await OpenPGPUserStore.sign(data.toString(), sign[1], 1);
signed.children.push(signature); signed.children.push(signature);
params.Signed = signed.toString(); params.signed = signed.toString();
params.Boundary = signed.boundary; params.Boundary = signed.boundary;
data = signed; data = signed;
} else if ('gnupg' == sign[0]) { } else if ('gnupg' == sign[0]) {
// TODO: sign in PHP fails // TODO: sign in PHP fails
// params.SignData = data.toString(); // params.signData = data.toString();
params.SignFingerprint = sign[1].fingerprint; params.signFingerprint = sign[1].fingerprint;
params.SignPassphrase = await GnuPGUserStore.sign(sign[1]); params.signPassphrase = await GnuPGUserStore.sign(sign[1]);
} else { } else {
throw 'Signing with ' + sign[0] + ' not yet implemented'; throw 'Signing with ' + sign[0] + ' not yet implemented';
} }
@ -1496,11 +1496,11 @@ export class ComposePopupView extends AbstractViewPopup {
if (encrypt) { if (encrypt) {
if ('openpgp' == encrypt) { if ('openpgp' == encrypt) {
// Doesn't encrypt attachments // Doesn't encrypt attachments
params.Encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients); params.encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients);
params.Signed = ''; params.signed = '';
} else if ('gnupg' == encrypt) { } else if ('gnupg' == encrypt) {
// Does encrypt attachments // Does encrypt attachments
params.EncryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients)); params.encryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients));
} else { } else {
throw 'Encryption with ' + encrypt + ' not yet implemented'; throw 'Encryption with ' + encrypt + ' not yet implemented';
} }

View file

@ -43,7 +43,7 @@ export class FolderClearPopupView extends AbstractViewPopup {
this.clearing(false); this.clearing(false);
iError ? alert(getNotification(iError)) : this.close(); iError ? alert(getNotification(iError)) : this.close();
}, { }, {
Folder: folder.fullName folder: folder.fullName
}); });
} }
} }

View file

@ -46,11 +46,11 @@ export class FolderCreatePopupView extends AbstractViewPopup {
submitForm(form) { submitForm(form) {
if (form.reportValidity()) { if (form.reportValidity()) {
const data = new FormData(form); const data = new FormData(form);
data.set('Subscribe', this.folderSubscribe() ? 1 : 0); data.set('subscribe', this.folderSubscribe() ? 1 : 0);
let parentFolderName = this.selectedParentValue(); let parentFolderName = this.selectedParentValue();
if (!parentFolderName && 1 < FolderUserStore.namespace.length) { if (!parentFolderName && 1 < FolderUserStore.namespace.length) {
data.set('Parent', FolderUserStore.namespace.slice(0, FolderUserStore.namespace.length - 1)); data.set('parent', FolderUserStore.namespace.slice(0, FolderUserStore.namespace.length - 1));
} }
Remote.abort('Folders').post('FolderCreate', FolderUserStore.foldersCreating, data) Remote.abort('Folders').post('FolderCreate', FolderUserStore.foldersCreating, data)

View file

@ -297,7 +297,7 @@ export class MailMessageList extends AbstractViewRight {
); );
addEventListener('mailbox.message.show', e => { addEventListener('mailbox.message.show', e => {
const sFolder = e.detail.Folder, iUid = e.detail.Uid; const sFolder = e.detail.folder, iUid = e.detail.uid;
const message = MessagelistUserStore.find( const message = MessagelistUserStore.find(
item => sFolder === item?.folder && iUid == item?.uid item => sFolder === item?.folder && iUid == item?.uid
@ -370,12 +370,12 @@ export class MailMessageList extends AbstractViewRight {
if (hashes.length) { if (hashes.length) {
Remote.post('AttachmentsActions', null, { Remote.post('AttachmentsActions', null, {
Do: 'Zip', Do: 'Zip',
Folder: MessagelistUserStore().Folder, folder: MessagelistUserStore().folder,
// Uids: uids, // Uids: uids,
Hashes: hashes Hashes: hashes
}) })
.then(result => { .then(result => {
let hash = result?.Result?.FileHash; let hash = result?.Result?.fileHash;
if (hash) { if (hash) {
download(attachmentDownload(hash), hash+'.zip'); download(attachmentDownload(hash), hash+'.zip');
} else { } else {
@ -403,7 +403,7 @@ export class MailMessageList extends AbstractViewRight {
Hashes: hashes Hashes: hashes
}) })
.then(result => { .then(result => {
let hash = result?.Result?.FileHash; let hash = result?.Result?.fileHash;
if (hash) { if (hash) {
download(attachmentDownload(hash), hash+'.zip'); download(attachmentDownload(hash), hash+'.zip');
} else { } else {
@ -504,7 +504,7 @@ export class MailMessageList extends AbstractViewRight {
MessageFlagsCache.clearFolder(sFolderFullName); MessageFlagsCache.clearFolder(sFolderFullName);
Remote.request('MessageSetSeenToAll', null, { Remote.request('MessageSetSeenToAll', null, {
Folder: sFolderFullName, folder: sFolderFullName,
SetAction: 1, SetAction: 1,
ThreadUids: uids.join(',') ThreadUids: uids.join(',')
}); });

View file

@ -492,7 +492,7 @@ export class MailMessageView extends AbstractViewRight {
Hashes: hashes Hashes: hashes
}) })
.then(result => { .then(result => {
let hash = result?.Result?.FileHash; let hash = result?.Result?.fileHash;
if (hash) { if (hash) {
download(attachmentDownload(hash), hash+'.zip'); download(attachmentDownload(hash), hash+'.zip');
} else { } else {
@ -534,11 +534,11 @@ export class MailMessageView extends AbstractViewRight {
MessagelistUserStore.reloadFlagsAndCachedMessage(); MessagelistUserStore.reloadFlagsAndCachedMessage();
} }
}, { }, {
MessageFolder: oMessage.folder, messageFolder: oMessage.folder,
MessageUid: oMessage.uid, messageUid: oMessage.uid,
ReadReceipt: oMessage.readReceipt(), readReceipt: oMessage.readReceipt(),
subject: i18n('READ_RECEIPT/SUBJECT', { SUBJECT: oMessage.subject() }), subject: i18n('READ_RECEIPT/SUBJECT', { SUBJECT: oMessage.subject() }),
Text: i18n('READ_RECEIPT/BODY', { 'READ-RECEIPT': AccountUserStore.email() }) plain: i18n('READ_RECEIPT/BODY', { 'READ-RECEIPT': AccountUserStore.email() })
}); });
} }
} }

View file

@ -10,9 +10,9 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
NAME = 'Avatars', NAME = 'Avatars',
AUTHOR = 'SnappyMail', AUTHOR = 'SnappyMail',
URL = 'https://snappymail.eu/', URL = 'https://snappymail.eu/',
VERSION = '1.7', VERSION = '1.8',
RELEASE = '2023-01-05', RELEASE = '2023-01-23',
REQUIRED = '2.23.0', REQUIRED = '2.25.0',
CATEGORY = 'Contacts', CATEGORY = 'Contacts',
LICENSE = 'MIT', LICENSE = 'MIT',
DESCRIPTION = 'Show graphic of sender in message and messages list (supports BIMI, Gravatar and identicon, Contacts is still TODO)'; DESCRIPTION = 'Show graphic of sender in message and messages list (supports BIMI, Gravatar and identicon, Contacts is still TODO)';
@ -54,23 +54,23 @@ class AvatarsPlugin extends \RainLoop\Plugins\AbstractPlugin
private function JsonAvatar($message) : ?string private function JsonAvatar($message) : ?string
{ {
$mFrom = empty($message['From'][0]) ? null : $message['From'][0]; $mFrom = empty($message['from'][0]) ? null : $message['from'][0];
if ($mFrom instanceof \MailSo\Mime\Email) { if ($mFrom instanceof \MailSo\Mime\Email) {
$mFrom = $mFrom->jsonSerialize(); $mFrom = $mFrom->jsonSerialize();
} }
if (\is_array($mFrom)) { if (\is_array($mFrom)) {
if ('pass' == $mFrom['DkimStatus'] && $this->Config()->Get('plugin', 'service', true)) { if ('pass' == $mFrom['dkimStatus'] && $this->Config()->Get('plugin', 'service', true)) {
// 'data:image/png;base64,[a-zA-Z0-9+/=]' // 'data:image/png;base64,[a-zA-Z0-9+/=]'
return static::getServiceIcon($mFrom['Email']); return static::getServiceIcon($mFrom['email']);
} }
if (!$this->Config()->Get('plugin', 'delay', true) if (!$this->Config()->Get('plugin', 'delay', true)
&& ($this->Config()->Get('plugin', 'gravatar', false) && ($this->Config()->Get('plugin', 'gravatar', false)
|| ($this->Config()->Get('plugin', 'bimi', false) && 'pass' == $mFrom['DkimStatus']) || ($this->Config()->Get('plugin', 'bimi', false) && 'pass' == $mFrom['dkimStatus'])
|| !$this->Config()->Get('plugin', 'service', true) || !$this->Config()->Get('plugin', 'service', true)
) )
) try { ) try {
// Base64Url // Base64Url
return \SnappyMail\Crypt::EncryptUrlSafe($mFrom['Email']); return \SnappyMail\Crypt::EncryptUrlSafe($mFrom['email']);
} catch (\Throwable $e) { } catch (\Throwable $e) {
\SnappyMail\Log::error('Crypt', $e->getMessage()); \SnappyMail\Log::error('Crypt', $e->getMessage());
} }

View file

@ -5,7 +5,7 @@ class DemoAccountPlugin extends \RainLoop\Plugins\AbstractPlugin
const const
NAME = 'Demo Account Extension', NAME = 'Demo Account Extension',
CATEGORY = 'Login', CATEGORY = 'Login',
REQUIRED = '2.23', REQUIRED = '2.25',
DESCRIPTION = 'Extension to enable a demo account'; DESCRIPTION = 'Extension to enable a demo account';
/** /**
@ -59,9 +59,9 @@ class DemoAccountPlugin extends \RainLoop\Plugins\AbstractPlugin
} }
else if ('DoFolderCreate' === $sMethodName || 'DoFolderRename' === $sMethodName) { else if ('DoFolderCreate' === $sMethodName || 'DoFolderRename' === $sMethodName) {
// Block spam https://github.com/the-djmaze/snappymail/issues/371 // Block spam https://github.com/the-djmaze/snappymail/issues/371
$latin = transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $aActionParams['Folder']); $latin = transliterator_transliterate('Any-Latin; Latin-ASCII; Lower()', $aActionParams['folder']);
if (false !== \strpos($latin, 'nigger')) { if (false !== \strpos($latin, 'nigger')) {
\error_log("blocked {$sMethodName} {$aActionParams['Folder']}"); \error_log("blocked {$sMethodName} {$aActionParams['folder']}");
exit; exit;
} }
} }

View file

@ -9,9 +9,9 @@ class MailboxDetectPlugin extends \RainLoop\Plugins\AbstractPlugin
NAME = 'MailboxDetect', NAME = 'MailboxDetect',
AUTHOR = 'SnappyMail', AUTHOR = 'SnappyMail',
URL = 'https://snappymail.eu/', URL = 'https://snappymail.eu/',
VERSION = '2.1', VERSION = '2.2',
RELEASE = '2022-12-15', RELEASE = '2023-01-23',
REQUIRED = '2.23.1', REQUIRED = '2.25.0',
CATEGORY = 'General', CATEGORY = 'General',
LICENSE = 'MIT', LICENSE = 'MIT',
DESCRIPTION = 'Autodetect system folders and/or create them when needed'; DESCRIPTION = 'Autodetect system folders and/or create them when needed';
@ -66,21 +66,21 @@ class MailboxDetectPlugin extends \RainLoop\Plugins\AbstractPlugin
$aMap = $this->systemFoldersNames($oAccount); $aMap = $this->systemFoldersNames($oAccount);
$sDelimiter = ''; $sDelimiter = '';
foreach ($aResponse['Result']['@Collection'] as $i => $folder) { foreach ($aResponse['Result']['@Collection'] as $i => $folder) {
$sDelimiter || ($sDelimiter = $folder['Delimiter']); $sDelimiter || ($sDelimiter = $folder['delimiter']);
if ($folder['role']) { if ($folder['role']) {
$roles[$folder['role']] = true; $roles[$folder['role']] = true;
} else if (\in_array('\\sentmail', $folder['Flags'])) { } else if (\in_array('\\sentmail', $folder['flags'])) {
$found['sent'][] = $i; $found['sent'][] = $i;
} else if (\in_array('\\spam', $folder['Flags'])) { } else if (\in_array('\\spam', $folder['flags'])) {
$found['junk'][] = $i; $found['junk'][] = $i;
} else if (\in_array('\\bin', $folder['Flags'])) { } else if (\in_array('\\bin', $folder['flags'])) {
$found['trash'][] = $i; $found['trash'][] = $i;
} else if (\in_array('\\starred', $folder['Flags'])) { } else if (\in_array('\\starred', $folder['flags'])) {
$found['flagged'][] = $i; $found['flagged'][] = $i;
} else { } else {
// Kolab // Kolab
$kolab = $folder['Metadata'][MetadataKeys::KOLAB_CTYPE] $kolab = $folder['metadata'][MetadataKeys::KOLAB_CTYPE]
?? $folder['Metadata'][MetadataKeys::KOLAB_CTYPE_SHARED] ?? $folder['metadata'][MetadataKeys::KOLAB_CTYPE_SHARED]
?? ''; ?? '';
if ('mail.inbox' === $kolab) { if ('mail.inbox' === $kolab) {
$found['inbox'][] = $i; $found['inbox'][] = $i;
@ -94,9 +94,9 @@ class MailboxDetectPlugin extends \RainLoop\Plugins\AbstractPlugin
$found['trash'][] = $i; $found['trash'][] = $i;
} else { } else {
$iFolderType = 0; $iFolderType = 0;
if (isset($aMap[$folder['FullName']])) { if (isset($aMap[$folder['fullName']])) {
$iFolderType = $aMap[$folder['FullName']]; $iFolderType = $aMap[$folder['fullName']];
} else if (isset($aMap[$folder['name']]) || isset($aMap["INBOX{$folder['Delimiter']}{$folder['name']}"])) { } else if (isset($aMap[$folder['name']]) || isset($aMap["INBOX{$folder['delimiter']}{$folder['name']}"])) {
$iFolderType = $aMap[$folder['name']]; $iFolderType = $aMap[$folder['name']];
} }
if ($iFolderType && isset($types[$iFolderType])) { if ($iFolderType && isset($types[$iFolderType])) {

View file

@ -4,11 +4,11 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
{ {
const const
NAME = 'Nextcloud', NAME = 'Nextcloud',
VERSION = '2.15', VERSION = '2.16',
RELEASE = '2023-01-17', RELEASE = '2023-01-23',
CATEGORY = 'Integrations', CATEGORY = 'Integrations',
DESCRIPTION = 'Integrate with Nextcloud v20+', DESCRIPTION = 'Integrate with Nextcloud v20+',
REQUIRED = '2.24.6'; REQUIRED = '2.25.0';
public function Init() : void public function Init() : void
{ {
@ -89,7 +89,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
'filename' => '', 'filename' => '',
'success' => false 'success' => false
]; ];
if ($sSaveFolder && !empty($aValues['Folder']) && !empty($aValues['Uid'])) { if ($sSaveFolder && !empty($aValues['folder']) && !empty($aValues['uid'])) {
$oActions = \RainLoop\Api::Actions(); $oActions = \RainLoop\Api::Actions();
$oMailClient = $oActions->MailClient(); $oMailClient = $oActions->MailClient();
if (!$oMailClient->IsLoggined()) { if (!$oMailClient->IsLoggined()) {
@ -113,9 +113,9 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
$aResult['success'] = $oFiles->file_put_contents($sFilename, $rResource); $aResult['success'] = $oFiles->file_put_contents($sFilename, $rResource);
} }
}, },
(string) $aValues['Folder'], (string) $aValues['folder'],
(int) $aValues['Uid'], (int) $aValues['uid'],
isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : '' isset($aValues['mimeIndex']) ? (string) $aValues['mimeIndex'] : ''
); );
} }
@ -132,8 +132,8 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
$oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder); $oFiles->is_dir($sSaveFolder) || $oFiles->mkdir($sSaveFolder);
$data->result = true; $data->result = true;
foreach ($data->items as $aItem) { foreach ($data->items as $aItem) {
$sSavedFileName = isset($aItem['FileName']) ? $aItem['FileName'] : 'file.dat'; $sSavedFileName = isset($aItem['fileName']) ? $aItem['fileName'] : 'file.dat';
$sSavedFileHash = !empty($aItem['FileHash']) ? $aItem['FileHash'] : ''; $sSavedFileHash = !empty($aItem['fileHash']) ? $aItem['fileHash'] : '';
if (!empty($sSavedFileHash)) { if (!empty($sSavedFileHash)) {
$fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb'); $fFile = $data->filesProvider->GetFile($data->account, $sSavedFileHash, 'rb');
if (\is_resource($fFile)) { if (\is_resource($fFile)) {
@ -150,7 +150,7 @@ class NextcloudPlugin extends \RainLoop\Plugins\AbstractPlugin
} }
foreach ($data->items as $aItem) { foreach ($data->items as $aItem) {
$sFileHash = (string) (isset($aItem['FileHash']) ? $aItem['FileHash'] : ''); $sFileHash = (string) (isset($aItem['fileHash']) ? $aItem['fileHash'] : '');
if (!empty($sFileHash)) { if (!empty($sFileHash)) {
$data->filesProvider->Clear($data->account, $sFileHash); $data->filesProvider->Clear($data->account, $sFileHash);
} }

View file

@ -67,7 +67,7 @@ class BodyStructure implements \JsonSerializable
$sIdx = '-' . $this->PartID(); $sIdx = '-' . $this->PartID();
$sMimeType = \strtolower(\trim($this->ContentType())); $sMimeType = $this->sContentType;
if ('message/rfc822' === $sMimeType) { if ('message/rfc822' === $sMimeType) {
return "message{$sIdx}.eml"; return "message{$sIdx}.eml";
} }
@ -85,7 +85,7 @@ class BodyStructure implements \JsonSerializable
return \str_replace('/', $sIdx.'.', $sMimeType); return \str_replace('/', $sIdx.'.', $sMimeType);
} }
return ($this->IsInline() ? 'inline' : 'part' ) . $sIdx; return ($this->isInline() ? 'inline' : 'part' ) . $sIdx;
} }
public function ContentType() : string public function ContentType() : string
@ -93,16 +93,6 @@ class BodyStructure implements \JsonSerializable
return $this->sContentType; return $this->sContentType;
} }
public function ContentTypeParameters() : array
{
return $this->aContentTypeParams;
}
public function Size() : int
{
return $this->iSize;
}
public function EstimatedSize() : int public function EstimatedSize() : int
{ {
$fCoefficient = 1; $fCoefficient = 1;
@ -124,26 +114,21 @@ class BodyStructure implements \JsonSerializable
return $this->sCharset; return $this->sCharset;
} }
public function ContentID() : string
{
return $this->sContentID;
}
public function ContentLocation() : string
{
return $this->sLocation;
}
public function SubParts() : array public function SubParts() : array
{ {
return $this->aSubParts; return $this->aSubParts;
} }
public function IsInline() : bool public function isInline() : bool
{ {
return 'inline' === $this->sDisposition || \strlen($this->sContentID); return 'inline' === $this->sDisposition || \strlen($this->sContentID);
} }
public function isText() : bool
{
return 'text/html' === $this->sContentType || 'text/plain' === $this->sContentType;
}
public function IsPgpEncrypted() : bool public function IsPgpEncrypted() : bool
{ {
// https://datatracker.ietf.org/doc/html/rfc3156#section-4 // https://datatracker.ietf.org/doc/html/rfc3156#section-4
@ -179,8 +164,7 @@ class BodyStructure implements \JsonSerializable
&& ( && (
'attachment' === $this->sDisposition || ( 'attachment' === $this->sDisposition || (
!\str_starts_with($this->sContentType, 'multipart/') !\str_starts_with($this->sContentType, 'multipart/')
&& 'text/html' !== $this->sContentType && !$this->isText()
&& 'text/plain' !== $this->sContentType
) )
); );
} }
@ -197,8 +181,7 @@ class BodyStructure implements \JsonSerializable
$aParts = []; $aParts = [];
$gParts = $this->SearchByCallback(function ($oItem) { $gParts = $this->SearchByCallback(function ($oItem) {
return ('text/html' === $oItem->sContentType || 'text/plain' === $oItem->sContentType) return $oItem->isText() && !$oItem->IsAttachment();
&& !$oItem->IsAttachment();
}); });
foreach ($gParts as $oPart) { foreach ($gParts as $oPart) {
$aParts[] = $oPart; $aParts[] = $oPart;
@ -211,7 +194,7 @@ class BodyStructure implements \JsonSerializable
if (!$aParts) { if (!$aParts) {
$gEncryptedParts = $this->SearchByContentType('multipart/encrypted'); $gEncryptedParts = $this->SearchByContentType('multipart/encrypted');
foreach ($gEncryptedParts as $oPart) { foreach ($gEncryptedParts as $oPart) {
if ($oPart->IsPgpEncrypted() && $oPart->SubParts()[1]->IsInline()) { if ($oPart->IsPgpEncrypted() && $oPart->SubParts()[1]->isInline()) {
return array($oPart->SubParts()[1]); return array($oPart->SubParts()[1]);
} }
} }
@ -223,9 +206,7 @@ class BodyStructure implements \JsonSerializable
public function SearchCharset() : string public function SearchCharset() : string
{ {
$gParts = $this->SearchByCallback(function ($oPart) { $gParts = $this->SearchByCallback(function ($oPart) {
return $oPart->Charset() return $oPart->Charset() && $oPart->isText() && !$oPart->IsAttachment();
&& ('text/html' === $oPart->sContentType || 'text/plain' === $oPart->sContentType)
&& !$oPart->IsAttachment();
}); });
if (!$gParts->valid()) { if (!$gParts->valid()) {
@ -494,7 +475,7 @@ class BodyStructure implements \JsonSerializable
} }
$oStructure = new self; $oStructure = new self;
$oStructure->sContentType = \strtolower($sContentTypeMain.'/'.$sContentTypeSub); $oStructure->sContentType = \strtolower(\trim($sContentTypeMain.'/'.$sContentTypeSub));
$oStructure->aContentTypeParams = $aContentTypeParams; $oStructure->aContentTypeParams = $aContentTypeParams;
$oStructure->sCharset = $sCharset; $oStructure->sCharset = $sCharset;
$oStructure->sContentID = $sContentID; $oStructure->sContentID = $sContentID;
@ -545,14 +526,14 @@ class BodyStructure implements \JsonSerializable
public function jsonSerialize() public function jsonSerialize()
{ {
return array( return array(
'MimeIndex' => $this->PartID(), 'mimeIndex' => $this->sPartID,
'MimeType' => $this->ContentType(), 'mimeType' => $this->sContentType,
'MimeTypeParams' => $this->ContentTypeParameters(), 'mimeTypeParams' => $this->aContentTypeParams,
'FileName' => \MailSo\Base\Utils::SecureFileName($this->FileName(true)), 'fileName' => \MailSo\Base\Utils::SecureFileName($this->FileName(true)),
'EstimatedSize' => $this->EstimatedSize(), 'estimatedSize' => $this->EstimatedSize(),
'Cid' => $this->ContentID(), 'cId' => $this->sContentID,
'ContentLocation' => $this->ContentLocation(), 'contentLocation' => $this->sLocation,
'IsInline' => $this->IsInline() 'isInline' => $this->isInline()
); );
} }
} }

View file

@ -171,8 +171,8 @@ class Folder implements \JsonSerializable
$aExtended = array( $aExtended = array(
'totalEmails' => (int) $this->MESSAGES, 'totalEmails' => (int) $this->MESSAGES,
'unreadEmails' => (int) $this->UNSEEN, 'unreadEmails' => (int) $this->UNSEEN,
'UidNext' => (int) $this->UIDNEXT, 'uidNext' => (int) $this->UIDNEXT,
// 'Hash' => $this->Hash($this->ImapClient()->Hash()) // 'hash' => $this->Hash($this->ImapClient()->Hash())
); );
} }
*/ */
@ -185,16 +185,16 @@ class Folder implements \JsonSerializable
return array( return array(
'@Object' => 'Object/Folder', '@Object' => 'Object/Folder',
'name' => $this->Name(), 'name' => $this->Name(),
'FullName' => $this->FolderName, 'fullName' => $this->FolderName,
'Delimiter' => (string) $this->sDelimiter, 'delimiter' => (string) $this->sDelimiter,
'isSubscribed' => $this->IsSubscribed(), 'isSubscribed' => $this->IsSubscribed(),
'Exists' => $this->Exists(), 'exists' => $this->Exists(),
'Selectable' => $this->Selectable(), 'selectable' => $this->Selectable(),
'Flags' => $this->aFlagsLowerCase, 'flags' => $this->aFlagsLowerCase,
// 'Extended' => $aExtended, // 'extended' => $aExtended,
// 'PermanentFlags' => $this->PermanentFlags, // 'permanentFlags' => $this->PermanentFlags,
'Metadata' => $this->aMetadata, 'metadata' => $this->aMetadata,
'UidNext' => $this->UIDNEXT, 'uidNext' => $this->UIDNEXT,
// https://datatracker.ietf.org/doc/html/rfc8621#section-2 // https://datatracker.ietf.org/doc/html/rfc8621#section-2
'totalEmails' => $this->MESSAGES, 'totalEmails' => $this->MESSAGES,
'unreadEmails' => $this->UNSEEN, 'unreadEmails' => $this->UNSEEN,

View file

@ -49,24 +49,24 @@ class FolderInformation implements \JsonSerializable
{ {
$result = array( $result = array(
'id' => $this->MAILBOXID, 'id' => $this->MAILBOXID,
'Name' => $this->FolderName, 'name' => $this->FolderName,
'Flags' => $this->Flags, 'flags' => $this->Flags,
'PermanentFlags' => $this->PermanentFlags, 'permanentFlags' => $this->PermanentFlags,
'UidNext' => $this->UIDNEXT, 'uidNext' => $this->UIDNEXT,
'UidValidity' => $this->UIDVALIDITY 'uidValidity' => $this->UIDVALIDITY
); );
if (isset($this->MESSAGES)) { if (isset($this->MESSAGES)) {
$result['totalEmails'] = $this->MESSAGES; $result['totalEmails'] = $this->MESSAGES;
$result['unreadEmails'] = $this->UNSEEN; $result['unreadEmails'] = $this->UNSEEN;
} }
if (isset($this->HIGHESTMODSEQ)) { if (isset($this->HIGHESTMODSEQ)) {
$result['HighestModSeq'] = $this->HIGHESTMODSEQ; $result['highestModSeq'] = $this->HIGHESTMODSEQ;
} }
if (isset($this->APPENDLIMIT)) { if (isset($this->APPENDLIMIT)) {
$result['Appendlimit'] = $this->APPENDLIMIT; $result['appendLimit'] = $this->APPENDLIMIT;
} }
if (isset($this->SIZE)) { if (isset($this->SIZE)) {
$result['Size'] = $this->SIZE; $result['size'] = $this->SIZE;
} }
return $result; return $result;
} }

View file

@ -61,8 +61,8 @@ class Attachment implements \JsonSerializable
{ {
return \array_merge([ return \array_merge([
'@Object' => 'Object/Attachment', '@Object' => 'Object/Attachment',
'Folder' => $this->sFolder, 'folder' => $this->sFolder,
'Uid' => $this->iUid 'uid' => $this->iUid
], $this->oBodyStructure->jsonSerialize()); ], $this->oBodyStructure->jsonSerialize());
} }
} }

View file

@ -327,10 +327,10 @@ class MailClient
} }
$aNewMessages[] = array( $aNewMessages[] = array(
'Folder' => $sFolderName, 'folder' => $sFolderName,
'Uid' => $iUid, 'uid' => $iUid,
'subject' => $oHeaders->ValueByName(MimeHeader::SUBJECT, !$sContentTypeCharset), 'subject' => $oHeaders->ValueByName(MimeHeader::SUBJECT, !$sContentTypeCharset),
'From' => $oHeaders->GetAsEmailCollection(MimeHeader::FROM_, !$sContentTypeCharset) 'from' => $oHeaders->GetAsEmailCollection(MimeHeader::FROM_, !$sContentTypeCharset)
); );
} }
} }
@ -359,8 +359,8 @@ class MailClient
$iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID); $iUid = (int) $oFetchResponse->GetFetchValue(FetchType::UID);
$aLowerFlags = \array_map('mb_strtolower', \array_map('\\MailSo\\Base\\Utils::Utf7ModifiedToUtf8', $oFetchResponse->GetFetchValue(FetchType::FLAGS))); $aLowerFlags = \array_map('mb_strtolower', \array_map('\\MailSo\\Base\\Utils::Utf7ModifiedToUtf8', $oFetchResponse->GetFetchValue(FetchType::FLAGS)));
$aFlags[] = array( $aFlags[] = array(
'Uid' => $iUid, 'uid' => $iUid,
'Flags' => $aLowerFlags 'flags' => $aLowerFlags
); );
} }
} else { } else {
@ -368,18 +368,18 @@ class MailClient
} }
return array( return array(
'Folder' => $sFolderName, 'folder' => $sFolderName,
'totalEmails' => $oInfo->MESSAGES, 'totalEmails' => $oInfo->MESSAGES,
'unreadEmails' => $oInfo->UNSEEN, 'unreadEmails' => $oInfo->UNSEEN,
'UidNext' => $oInfo->UIDNEXT, 'uidNext' => $oInfo->UIDNEXT,
'UidValidity' => $oInfo->UIDVALIDITY, 'uidValidity' => $oInfo->UIDVALIDITY,
'HighestModSeq' => $oInfo->HIGHESTMODSEQ, 'highestModSeq' => $oInfo->HIGHESTMODSEQ,
'AppendLimit' => $oInfo->APPENDLIMIT ?: $this->oImapClient->AppendLimit(), 'appendLimit' => $oInfo->APPENDLIMIT ?: $this->oImapClient->AppendLimit(),
'MailboxId' => $oInfo->MAILBOXID ?: '', 'mailboxId' => $oInfo->MAILBOXID ?: '',
// 'Flags' => $oInfo->Flags, // 'flags' => $oInfo->Flags,
// 'PermanentFlags' => $oInfo->PermanentFlags, // 'permanentFlags' => $oInfo->PermanentFlags,
'Hash' => $oInfo->getHash($this->oImapClient->Hash()), 'hash' => $oInfo->getHash($this->oImapClient->Hash()),
'MessagesFlags' => $aFlags, 'messagesFlags' => $aFlags,
'newMessages' => $this->getFolderNextMessageInformation( 'newMessages' => $this->getFolderNextMessageInformation(
$sFolderName, $sFolderName,
$iPrevUidNext, $iPrevUidNext,

View file

@ -353,7 +353,7 @@ class Message implements \JsonSerializable
foreach ($gEncryptedParts as $oPart) { foreach ($gEncryptedParts as $oPart) {
if ($oPart->IsPgpEncrypted()) { if ($oPart->IsPgpEncrypted()) {
$oMessage->pgpEncrypted = [ $oMessage->pgpEncrypted = [
'PartId' => $oPart->SubParts()[1]->PartID() 'partId' => $oPart->SubParts()[1]->PartID()
]; ];
} }
} }
@ -367,22 +367,22 @@ class Message implements \JsonSerializable
$oMessage->pgpSigned = [ $oMessage->pgpSigned = [
// /?/Raw/&q[]=/0/Download/&q[]=/... // /?/Raw/&q[]=/0/Download/&q[]=/...
// /?/Raw/&q[]=/0/View/&q[]=/... // /?/Raw/&q[]=/0/View/&q[]=/...
'BodyPartId' => $oPart->SubParts()[0]->PartID(), 'bodyPartId' => $oPart->SubParts()[0]->PartID(),
'SigPartId' => $oPgpSignaturePart->PartID(), 'sigPartId' => $oPgpSignaturePart->PartID(),
'MicAlg' => $oHeaders ? (string) $oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, 'micalg') : '' 'micAlg' => $oHeaders ? (string) $oHeaders->ParameterValue(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE, 'micalg') : ''
]; ];
/* /*
// An empty section specification refers to the entire message, including the header. // An empty section specification refers to the entire message, including the header.
// But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME]. // But Dovecot does not return it with BODY.PEEK[1], so we also use BODY.PEEK[1.MIME].
$sPgpText = \trim( $sPgpText = \trim(
\trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['BodyPartId'].'.MIME]')) \trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['bodyPartId'].'.MIME]'))
. "\r\n\r\n" . "\r\n\r\n"
. \trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['BodyPartId'].']')) . \trim($oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['bodyPartId'].']'))
); );
if ($sPgpText) { if ($sPgpText) {
$oMessage->pgpSigned['Body'] = $sPgpText; $oMessage->pgpSigned['Body'] = $sPgpText;
} }
$sPgpSignatureText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['SigPartId'].']'); $sPgpSignatureText = $oFetchResponse->GetFetchValue(FetchType::BODY.'['.$oMessage->pgpSigned['sigPartId'].']');
if ($sPgpSignatureText && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE')) { if ($sPgpSignatureText && 0 < \strpos($sPgpSignatureText, 'BEGIN PGP SIGNATURE')) {
$oMessage->pgpSigned['Signature'] = $oPart->SubParts()[0]->PartID(); $oMessage->pgpSigned['Signature'] = $oPart->SubParts()[0]->PartID();
} }
@ -416,7 +416,7 @@ class Message implements \JsonSerializable
// Cleartext Signature // Cleartext Signature
if (!$oMessage->pgpSigned && \str_contains($sText, '-----BEGIN PGP SIGNED MESSAGE-----')) { if (!$oMessage->pgpSigned && \str_contains($sText, '-----BEGIN PGP SIGNED MESSAGE-----')) {
$oMessage->pgpSigned = [ $oMessage->pgpSigned = [
'BodyPartId' => $oPart->PartID() 'bodyPartId' => $oPart->PartID()
]; ];
} }
@ -427,8 +427,8 @@ class Message implements \JsonSerializable
$keyIds = $GPG->getEncryptedMessageKeys($sText); $keyIds = $GPG->getEncryptedMessageKeys($sText);
} }
$oMessage->pgpEncrypted = [ $oMessage->pgpEncrypted = [
'PartId' => $oPart->PartID(), 'partId' => $oPart->PartID(),
'KeyIds' => $keyIds 'keyIds' => $keyIds
]; ];
} }
@ -487,42 +487,42 @@ class Message implements \JsonSerializable
return array( return array(
'@Object' => 'Object/Message', '@Object' => 'Object/Message',
'Folder' => $this->sFolder, 'folder' => $this->sFolder,
'Uid' => $this->Uid, 'uid' => $this->Uid,
'subject' => \trim(Utils::Utf8Clear($this->sSubject)), 'subject' => \trim(Utils::Utf8Clear($this->sSubject)),
'encrypted' => 'multipart/encrypted' == $this->sContentType || $this->pgpEncrypted, 'encrypted' => 'multipart/encrypted' == $this->sContentType || $this->pgpEncrypted,
'MessageId' => $this->sMessageId, 'messageId' => $this->sMessageId,
'SpamScore' => $this->bIsSpam ? 100 : $this->SpamScore, 'spamScore' => $this->bIsSpam ? 100 : $this->SpamScore,
'SpamResult' => $this->sSpamResult, 'spamResult' => $this->sSpamResult,
'IsSpam' => $this->bIsSpam, 'isSpam' => $this->bIsSpam,
'HasVirus' => $this->bHasVirus, 'hasVirus' => $this->bHasVirus,
// 'VirusScanned' => $this->sVirusScanned, // 'virusScanned' => $this->sVirusScanned,
'DateTimeStampInUTC' => $this->iInternalTimeStampInUTC, 'dateTimeStampInUTC' => $this->iInternalTimeStampInUTC,
// \MailSo\Mime\EmailCollection // \MailSo\Mime\EmailCollection
'From' => $this->oFrom, 'from' => $this->oFrom,
'ReplyTo' => $this->oReplyTo, 'replyTo' => $this->oReplyTo,
'To' => $this->oTo, 'to' => $this->oTo,
'Cc' => $this->oCc, 'cc' => $this->oCc,
'Bcc' => $this->oBcc, 'bcc' => $this->oBcc,
'Sender' => $this->oSender, 'sender' => $this->oSender,
'DeliveredTo' => $this->oDeliveredTo, 'deliveredTo' => $this->oDeliveredTo,
'Priority' => $this->iPriority, 'priority' => $this->iPriority,
'Threads' => $this->aThreads, 'threads' => $this->aThreads,
'UnsubsribeLinks' => $this->UnsubsribeLinks, 'unsubsribeLinks' => $this->UnsubsribeLinks,
'ReadReceipt' => '', 'readReceipt' => '',
'Autocrypt' => $this->sAutocrypt, 'autocrypt' => $this->sAutocrypt,
'Attachments' => $this->Attachments, 'attachments' => $this->Attachments,
'spf' => $this->SPF, 'spf' => $this->SPF,
'dkim' => $this->DKIM, 'dkim' => $this->DKIM,
'dmarc' => $this->DMARC, 'dmarc' => $this->DMARC,
'Flags' => $aFlags, 'flags' => $aFlags,
'InReplyTo' => $this->InReplyTo, 'inReplyTo' => $this->InReplyTo,
// https://datatracker.ietf.org/doc/html/rfc8621#section-4.1.1 // https://datatracker.ietf.org/doc/html/rfc8621#section-4.1.1
'id' => $this->sEmailId, 'id' => $this->sEmailId,

View file

@ -62,12 +62,12 @@ class MessageCollection extends \MailSo\Base\Collection
return array_merge(parent::jsonSerialize(), array( return array_merge(parent::jsonSerialize(), array(
'totalEmails' => $this->totalEmails, 'totalEmails' => $this->totalEmails,
'totalThreads' => $this->totalThreads, 'totalThreads' => $this->totalThreads,
'Folder' => $this->FolderName, 'folder' => $this->FolderName,
'folderHash' => $this->FolderHash, 'folderHash' => $this->FolderHash,
'folderInfo' => $this->FolderInfo, 'folderInfo' => $this->FolderInfo,
'threadUid' => $this->ThreadUid, 'threadUid' => $this->ThreadUid,
'newMessages' => $this->NewMessages, 'newMessages' => $this->NewMessages,
// 'Filtered' => $this->Filtered, // 'filtered' => $this->Filtered,
'offset' => $this->Offset, 'offset' => $this->Offset,
'limit' => $this->Limit, 'limit' => $this->Limit,
'search' => $this->Search, 'search' => $this->Search,

View file

@ -24,9 +24,9 @@ class Attachment
private string $sFileName; private string $sFileName;
private int $iFileSize; // private int $iFileSize;
private string $sCID; private string $sContentID;
private bool $bIsInline; private bool $bIsInline;
@ -42,15 +42,15 @@ class Attachment
* @param resource $rResource * @param resource $rResource
*/ */
function __construct($rResource, string $sFileName, int $iFileSize, bool $bIsInline, function __construct($rResource, string $sFileName, int $iFileSize, bool $bIsInline,
bool $bIsLinked, string $sCID, array $aCustomContentTypeParams = [], bool $bIsLinked, string $sContentID, array $aCustomContentTypeParams = [],
string $sContentLocation = '', string $sContentType = '') string $sContentLocation = '', string $sContentType = '')
{ {
$this->rResource = $rResource; $this->rResource = $rResource;
$this->sFileName = $sFileName; $this->sFileName = $sFileName;
$this->iFileSize = $iFileSize; // $this->iFileSize = $iFileSize;
$this->bIsInline = $bIsInline; $this->bIsInline = $bIsInline;
$this->bIsLinked = $bIsLinked; $this->bIsLinked = $bIsLinked;
$this->sCID = $sCID; $this->sContentID = $sContentID;
$this->aCustomContentTypeParams = $aCustomContentTypeParams; $this->aCustomContentTypeParams = $aCustomContentTypeParams;
$this->sContentLocation = $sContentLocation; $this->sContentLocation = $sContentLocation;
$this->sContentType = $sContentType $this->sContentType = $sContentType
@ -77,34 +77,19 @@ class Attachment
return $this->aCustomContentTypeParams; return $this->aCustomContentTypeParams;
} }
public function CID() : string
{
return $this->sCID;
}
public function ContentLocation() : string
{
return $this->sContentLocation;
}
public function FileName() : string public function FileName() : string
{ {
return $this->sFileName; return $this->sFileName;
} }
public function FileSize() : int public function isInline() : bool
{
return $this->iFileSize;
}
public function IsInline() : bool
{ {
return $this->bIsInline; return $this->bIsInline;
} }
public function IsLinked() : bool public function isLinked() : bool
{ {
return $this->bIsLinked && \strlen($this->sCID); return $this->bIsLinked && \strlen($this->sContentID);
} }
public function ToPart() : Part public function ToPart() : Part
@ -112,8 +97,8 @@ class Attachment
$oAttachmentPart = new Part; $oAttachmentPart = new Part;
$sFileName = \trim($this->sFileName); $sFileName = \trim($this->sFileName);
$sCID = $this->CID(); $sContentID = $this->sContentID;
$sContentLocation = $this->ContentLocation(); $sContentLocation = $this->sContentLocation;
$oContentTypeParameters = null; $oContentTypeParameters = null;
$oContentDispositionParameters = null; $oContentDispositionParameters = null;
@ -137,14 +122,14 @@ class Attachment
$oAttachmentPart->Headers->append( $oAttachmentPart->Headers->append(
new Header(Enumerations\Header::CONTENT_DISPOSITION, new Header(Enumerations\Header::CONTENT_DISPOSITION,
($this->IsInline() ? 'inline' : 'attachment'). ($this->isInline() ? 'inline' : 'attachment').
($oContentDispositionParameters ? '; '.$oContentDispositionParameters : '') ($oContentDispositionParameters ? '; '.$oContentDispositionParameters : '')
) )
); );
if (\strlen($sCID)) { if (\strlen($sContentID)) {
$oAttachmentPart->Headers->append( $oAttachmentPart->Headers->append(
new Header(Enumerations\Header::CONTENT_ID, $sCID) new Header(Enumerations\Header::CONTENT_ID, $sContentID)
); );
} }

View file

@ -210,9 +210,9 @@ class Email implements \JsonSerializable
{ {
return array( return array(
'@Object' => 'Object/Email', '@Object' => 'Object/Email',
'Name' => \MailSo\Base\Utils::Utf8Clear($this->GetDisplayName()), 'name' => \MailSo\Base\Utils::Utf8Clear($this->GetDisplayName()),
'Email' => \MailSo\Base\Utils::Utf8Clear($this->GetEmail(true)), 'email' => \MailSo\Base\Utils::Utf8Clear($this->GetEmail(true)),
'DkimStatus' => $this->sDkimStatus 'dkimStatus' => $this->sDkimStatus
); );
} }
} }

View file

@ -365,7 +365,7 @@ class Message extends Part
if (1 == \count($this->SubParts)) { if (1 == \count($this->SubParts)) {
$oRootPart = $this->SubParts[0]; $oRootPart = $this->SubParts[0];
foreach ($this->oAttachmentCollection as $oAttachment) { foreach ($this->oAttachmentCollection as $oAttachment) {
if ($oAttachment->IsLinked()) { if ($oAttachment->isLinked()) {
$oRelatedPart = new Part; $oRelatedPart = new Part;
$oRelatedPart->Headers->append( $oRelatedPart->Headers->append(
new Header(Enumerations\Header::CONTENT_TYPE, 'multipart/related') new Header(Enumerations\Header::CONTENT_TYPE, 'multipart/related')
@ -383,7 +383,7 @@ class Message extends Part
$oMixedPart = null; $oMixedPart = null;
foreach ($this->oAttachmentCollection as $oAttachment) { foreach ($this->oAttachmentCollection as $oAttachment) {
if ($oRelatedPart && $oAttachment->IsLinked()) { if ($oRelatedPart && $oAttachment->isLinked()) {
$oRelatedPart->SubParts->append($oAttachment->ToPart()); $oRelatedPart->SubParts->append($oAttachment->ToPart());
} else { } else {
if (!$oMixedPart) { if (!$oMixedPart) {

View file

@ -51,21 +51,6 @@ class Part
{ {
return \trim(\strtolower($this->Headers->ValueByName(Enumerations\Header::CONTENT_TYPE))); return \trim(\strtolower($this->Headers->ValueByName(Enumerations\Header::CONTENT_TYPE)));
} }
/*
public function ContentTypeParameters() : ParameterCollection
{
return $this->Headers->ParametersByName(\MailSo\Mime\Enumerations\Header::CONTENT_TYPE);
}
*/
public function ContentID() : string
{
return \trim($this->Headers->ValueByName(Enumerations\Header::CONTENT_ID));
}
public function ContentLocation() : string
{
return \trim($this->Headers->ValueByName(Enumerations\Header::CONTENT_LOCATION));
}
public function IsFlowedFormat() : bool public function IsFlowedFormat() : bool
{ {

View file

@ -1012,10 +1012,10 @@ class Actions
$iError = Enumerations\UploadError::ON_SAVING; $iError = Enumerations\UploadError::ON_SAVING;
} else { } else {
$aResponse['Attachment'] = array( $aResponse['Attachment'] = array(
'Name' => $aFile['name'], 'name' => $aFile['name'],
'TempName' => $sSavedName, 'tempName' => $sSavedName,
'MimeType' => $aFile['type'], 'mimeType' => $aFile['type'],
'Size' => (int) $aFile['size'] 'size' => (int) $aFile['size']
); );
} }
} }

View file

@ -13,7 +13,7 @@ trait Attachments
public function DoAttachmentsActions() : array public function DoAttachmentsActions() : array
{ {
$sAction = $this->GetActionParam('Do', ''); $sAction = $this->GetActionParam('Do', '');
$sFolder = $this->GetActionParam('Folder', ''); $sFolder = $this->GetActionParam('folder', '');
$aHashes = $this->GetActionParam('Hashes', null); $aHashes = $this->GetActionParam('Hashes', null);
$oFilesProvider = $this->FilesProvider(); $oFilesProvider = $this->FilesProvider();
if (empty($sAction) || !$this->GetCapa(Capa::ATTACHMENTS_ACTIONS) || !$oFilesProvider || !$oFilesProvider->IsActive()) { if (empty($sAction) || !$this->GetCapa(Capa::ATTACHMENTS_ACTIONS) || !$oFilesProvider || !$oFilesProvider->IsActive()) {
@ -29,13 +29,13 @@ trait Attachments
if (\is_array($aHashes) && \count($aHashes)) { if (\is_array($aHashes) && \count($aHashes)) {
foreach ($aHashes as $sZipHash) { foreach ($aHashes as $sZipHash) {
$aResult = $this->getMimeFileByHash($oAccount, $sZipHash); $aResult = $this->getMimeFileByHash($oAccount, $sZipHash);
if (empty($aResult['FileHash'])) { if (empty($aResult['fileHash'])) {
$bError = true; $bError = true;
break; break;
} }
$aData[] = $aResult; $aData[] = $aResult;
if (!empty($aResult['MimeIndex'])) { if (!empty($aResult['mimeIndex'])) {
$mUIDs[$aResult['Uid']] = $aResult['Uid']; $mUIDs[$aResult['uid']] = $aResult['uid'];
} }
} }
} }
@ -59,8 +59,8 @@ trait Attachments
$oZip->open($sZipFileName, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE); $oZip->open($sZipFileName, \ZIPARCHIVE::CREATE | \ZIPARCHIVE::OVERWRITE);
$oZip->setArchiveComment('SnappyMail/'.APP_VERSION); $oZip->setArchiveComment('SnappyMail/'.APP_VERSION);
foreach ($aData as $aItem) { foreach ($aData as $aItem) {
$sFullFileNameHash = $oFilesProvider->GetFileName($oAccount, $aItem['FileHash']); $sFullFileNameHash = $oFilesProvider->GetFileName($oAccount, $aItem['fileHash']);
$sFileName = ($mUIDs ? "{$aItem['Uid']}/" : ($sFolder ? "{$aItem['Uid']}-" : '')) . $aItem['FileName']; $sFileName = ($mUIDs ? "{$aItem['uid']}/" : ($sFolder ? "{$aItem['uid']}-" : '')) . $aItem['fileName'];
if (!$oZip->addFile($sFullFileNameHash, $sFileName)) { if (!$oZip->addFile($sFullFileNameHash, $sFileName)) {
$bError = true; $bError = true;
} }
@ -77,9 +77,9 @@ trait Attachments
$oZip = new \SnappyMail\Stream\ZIP($sZipFileName); $oZip = new \SnappyMail\Stream\ZIP($sZipFileName);
// $oZip->setArchiveComment('SnappyMail/'.APP_VERSION); // $oZip->setArchiveComment('SnappyMail/'.APP_VERSION);
foreach ($aData as $aItem) { foreach ($aData as $aItem) {
if ($aItem['FileHash']) { if ($aItem['fileHash']) {
$sFullFileNameHash = $oFilesProvider->GetFileName($oAccount, $aItem['FileHash']); $sFullFileNameHash = $oFilesProvider->GetFileName($oAccount, $aItem['fileHash']);
if (!$oZip->addFile($sFullFileNameHash, $aItem['FileName'])) { if (!$oZip->addFile($sFullFileNameHash, $aItem['fileName'])) {
$bError = true; $bError = true;
} }
} }
@ -92,8 +92,8 @@ trait Attachments
$oZip->compressFiles(\Phar::GZ); $oZip->compressFiles(\Phar::GZ);
foreach ($aData as $aItem) { foreach ($aData as $aItem) {
$oZip->addFile( $oZip->addFile(
$oFilesProvider->GetFileName($oAccount, $aItem['FileHash']), $oFilesProvider->GetFileName($oAccount, $aItem['fileHash']),
($mUIDs ? "{$aItem['Uid']}/" : ($sFolder ? "{$aItem['Uid']}-" : '')) . $aItem['FileName'] ($mUIDs ? "{$aItem['uid']}/" : ($sFolder ? "{$aItem['uid']}-" : '')) . $aItem['fileName']
); );
} }
$oZip->compressFiles(\Phar::GZ); $oZip->compressFiles(\Phar::GZ);
@ -102,15 +102,15 @@ trait Attachments
} }
foreach ($aData as $aItem) { foreach ($aData as $aItem) {
$oFilesProvider->Clear($oAccount, $aItem['FileHash']); $oFilesProvider->Clear($oAccount, $aItem['fileHash']);
} }
if (!$bError) { if (!$bError) {
$mResult = array( $mResult = array(
'FileHash' => $this->encodeRawKey($oAccount, array( 'fileHash' => $this->encodeRawKey($oAccount, array(
'FileName' => ($sFolder ? 'messages' : 'attachments') . \date('-YmdHis') . '.zip', 'fileName' => ($sFolder ? 'messages' : 'attachments') . \date('-YmdHis') . '.zip',
'MimeType' => 'application/zip', 'mimeType' => 'application/zip',
'FileHash' => $sZipHash 'fileHash' => $sZipHash
)) ))
); );
} }
@ -136,12 +136,12 @@ trait Attachments
{ {
$aValues = $this->decodeRawKey($oAccount, $sHash); $aValues = $this->decodeRawKey($oAccount, $sHash);
$sFolder = isset($aValues['Folder']) ? (string) $aValues['Folder'] : ''; $sFolder = isset($aValues['folder']) ? (string) $aValues['folder'] : '';
$iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; $iUid = isset($aValues['uid']) ? (int) $aValues['uid'] : 0;
$sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; $sMimeIndex = isset($aValues['mimeIndex']) ? (string) $aValues['mimeIndex'] : '';
$sContentTypeIn = isset($aValues['MimeType']) ? (string) $aValues['MimeType'] : ''; $sContentTypeIn = isset($aValues['mimeType']) ? (string) $aValues['mimeType'] : '';
$sFileNameIn = isset($aValues['FileName']) ? (string) $aValues['FileName'] : 'file.dat'; $sFileNameIn = isset($aValues['fileName']) ? (string) $aValues['fileName'] : 'file.dat';
$oFileProvider = $this->FilesProvider(); $oFileProvider = $this->FilesProvider();
@ -170,8 +170,8 @@ trait Attachments
}, $sFolder, $iUid, $sMimeIndex); }, $sFolder, $iUid, $sMimeIndex);
$aValues['FileName'] = $sFileNameIn; $aValues['fileName'] = $sFileNameIn;
$aValues['FileHash'] = $mResult ? $sResultHash : ''; $aValues['fileHash'] = $mResult ? $sResultHash : '';
return $aValues; return $aValues;
} }

View file

@ -95,14 +95,14 @@ trait Contacts
$bResult = false; $bResult = false;
if ($this->HasActionParam('Uid') && $this->HasActionParam('jCard')) { if ($this->HasActionParam('uid') && $this->HasActionParam('jCard')) {
$oAddressBookProvider = $this->AddressBookProvider($oAccount); $oAddressBookProvider = $this->AddressBookProvider($oAccount);
if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) { if ($oAddressBookProvider && $oAddressBookProvider->IsActive()) {
$vCard = \Sabre\VObject\Reader::readJson($this->GetActionParam('jCard')); $vCard = \Sabre\VObject\Reader::readJson($this->GetActionParam('jCard'));
if ($vCard && $vCard instanceof \Sabre\VObject\Component\VCard) { if ($vCard && $vCard instanceof \Sabre\VObject\Component\VCard) {
$vCard->REV = \gmdate('Ymd\\THis\\Z'); $vCard->REV = \gmdate('Ymd\\THis\\Z');
$vCard->PRODID = 'SnappyMail-'.APP_VERSION; $vCard->PRODID = 'SnappyMail-'.APP_VERSION;
$sUid = \trim($this->GetActionParam('Uid')); $sUid = \trim($this->GetActionParam('uid'));
$oContact = $sUid ? $oAddressBookProvider->GetContactByID($sUid) : null; $oContact = $sUid ? $oAddressBookProvider->GetContactByID($sUid) : null;
if (!$oContact) { if (!$oContact) {
$oContact = new \RainLoop\Providers\AddressBook\Classes\Contact(); $oContact = new \RainLoop\Providers\AddressBook\Classes\Contact();

View file

@ -18,7 +18,7 @@ trait Folders
{ {
$oAccount = $this->initMailClientConnection(); $oAccount = $this->initMailClientConnection();
$sFolderFullName = $this->GetActionParam('Folder', ''); $sFolderFullName = $this->GetActionParam('folder', '');
if ($oAccount if ($oAccount
&& !empty($sFolderFullName) && !empty($sFolderFullName)
@ -89,9 +89,9 @@ trait Folders
try try
{ {
$oFolder = $this->MailClient()->FolderCreate( $oFolder = $this->MailClient()->FolderCreate(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
$this->GetActionParam('Parent', ''), $this->GetActionParam('parent', ''),
!!$this->GetActionParam('Subscribe', 1) !!$this->GetActionParam('subscribe', 1)
); );
// FolderInformation(string $sFolderName, int $iPrevUidNext = 0, array $aUids = array()) // FolderInformation(string $sFolderName, int $iPrevUidNext = 0, array $aUids = array())
@ -106,7 +106,7 @@ trait Folders
public function DoFolderSetMetadata() : array public function DoFolderSetMetadata() : array
{ {
$this->initMailClientConnection(); $this->initMailClientConnection();
$sFolderFullName = $this->GetActionParam('Folder'); $sFolderFullName = $this->GetActionParam('folder');
$sMetadataKey = $this->GetActionParam('Key'); $sMetadataKey = $this->GetActionParam('Key');
if ($sFolderFullName && $sMetadataKey) { if ($sFolderFullName && $sMetadataKey) {
$this->MailClient()->FolderSetMetadata($sFolderFullName, [ $this->MailClient()->FolderSetMetadata($sFolderFullName, [
@ -120,8 +120,8 @@ trait Folders
{ {
$this->initMailClientConnection(); $this->initMailClientConnection();
$sFolderFullName = $this->GetActionParam('Folder', ''); $sFolderFullName = $this->GetActionParam('folder', '');
$bSubscribe = '1' === (string) $this->GetActionParam('Subscribe', '0'); $bSubscribe = '1' === (string) $this->GetActionParam('subscribe', '0');
try try
{ {
@ -142,7 +142,7 @@ trait Folders
{ {
$oAccount = $this->getAccountFromToken(); $oAccount = $this->getAccountFromToken();
$sFolderFullName = $this->GetActionParam('Folder', ''); $sFolderFullName = $this->GetActionParam('folder', '');
$oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount); $oSettingsLocal = $this->SettingsProvider(true)->Load($oAccount);
@ -152,7 +152,7 @@ trait Folders
$aCheckableFolder = array(); $aCheckableFolder = array();
} }
if (!empty($this->GetActionParam('Checkable', '0'))) { if (!empty($this->GetActionParam('checkable', '0'))) {
$aCheckableFolder[] = $sFolderFullName; $aCheckableFolder[] = $sFolderFullName;
} else { } else {
$aCheckableFolderNew = array(); $aCheckableFolderNew = array();
@ -181,9 +181,9 @@ trait Folders
try try
{ {
$this->MailClient()->FolderMove( $this->MailClient()->FolderMove(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
$this->GetActionParam('NewFolder', ''), $this->GetActionParam('newFolder', ''),
!!$this->GetActionParam('Subscribe', 1) !!$this->GetActionParam('subscribe', 1)
); );
} }
catch (\Throwable $oException) catch (\Throwable $oException)
@ -201,13 +201,13 @@ trait Folders
{ {
$this->initMailClientConnection(); $this->initMailClientConnection();
$sName = $this->GetActionParam('NewFolderName', ''); $sName = $this->GetActionParam('newFolderName', '');
try try
{ {
$sFullName = $this->MailClient()->FolderRename( $sFullName = $this->MailClient()->FolderRename(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
$sName, $sName,
!!$this->GetActionParam('Subscribe', 1) !!$this->GetActionParam('subscribe', 1)
); );
} }
catch (\Throwable $oException) catch (\Throwable $oException)
@ -217,8 +217,8 @@ trait Folders
// FolderInformation(string $sFolderName, int $iPrevUidNext = 0, array $aUids = array()) // FolderInformation(string $sFolderName, int $iPrevUidNext = 0, array $aUids = array())
return $this->DefaultResponse(array( return $this->DefaultResponse(array(
'Name' => $sName, 'name' => $sName,
'FullName' => $sFullName, 'fullName' => $sFullName,
)); ));
} }
@ -231,7 +231,7 @@ trait Folders
try try
{ {
$this->MailClient()->FolderDelete($this->GetActionParam('Folder', '')); $this->MailClient()->FolderDelete($this->GetActionParam('folder', ''));
} }
catch (\MailSo\Mail\Exceptions\NonEmptyFolder $oException) catch (\MailSo\Mail\Exceptions\NonEmptyFolder $oException)
{ {
@ -254,7 +254,7 @@ trait Folders
try try
{ {
$this->MailClient()->FolderClear($this->GetActionParam('Folder', '')); $this->MailClient()->FolderClear($this->GetActionParam('folder', ''));
} }
catch (\Throwable $oException) catch (\Throwable $oException)
{ {
@ -274,9 +274,9 @@ trait Folders
try try
{ {
return $this->DefaultResponse($this->MailClient()->FolderInformation( return $this->DefaultResponse($this->MailClient()->FolderInformation(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
(int) $this->GetActionParam('UidNext', 0), (int) $this->GetActionParam('uidNext', 0),
new \MailSo\Imap\SequenceSet($this->GetActionParam('FlagsUids', [])) new \MailSo\Imap\SequenceSet($this->GetActionParam('flagsUids', []))
)); ));
} }
catch (\Throwable $oException) catch (\Throwable $oException)
@ -302,10 +302,10 @@ trait Folders
try try
{ {
$aInboxInformation = $this->MailClient()->FolderInformation($sFolder); $aInboxInformation = $this->MailClient()->FolderInformation($sFolder);
if (isset($aInboxInformation['Folder'])) { if (isset($aInboxInformation['folder'])) {
$aResult[] = [ $aResult[] = [
'Folder' => $aInboxInformation['Folder'], 'folder' => $aInboxInformation['folder'],
'Hash' => $aInboxInformation['Hash'], 'hash' => $aInboxInformation['hash'],
'totalEmails' => $aInboxInformation['totalEmails'], 'totalEmails' => $aInboxInformation['totalEmails'],
'unreadEmails' => $aInboxInformation['unreadEmails'], 'unreadEmails' => $aInboxInformation['unreadEmails'],
]; ];

View file

@ -100,7 +100,7 @@ trait Messages
{ {
$oAccount = $this->initMailClientConnection(); $oAccount = $this->initMailClientConnection();
$sDraftFolder = $this->GetActionParam('SaveFolder', ''); $sDraftFolder = $this->GetActionParam('saveFolder', '');
if (!\strlen($sDraftFolder)) { if (!\strlen($sDraftFolder)) {
throw new ClientException(Notifications::UnknownError); throw new ClientException(Notifications::UnknownError);
} }
@ -132,16 +132,16 @@ trait Messages
$mResult = true; $mResult = true;
$sMessageFolder = $this->GetActionParam('MessageFolder', ''); $sMessageFolder = $this->GetActionParam('messageFolder', '');
$iMessageUid = (int) $this->GetActionParam('MessageUid', 0); $iMessageUid = (int) $this->GetActionParam('messageUid', 0);
if (\strlen($sMessageFolder) && 0 < $iMessageUid) { if (\strlen($sMessageFolder) && 0 < $iMessageUid) {
$this->MailClient()->MessageDelete($sMessageFolder, new SequenceSet($iMessageUid)); $this->MailClient()->MessageDelete($sMessageFolder, new SequenceSet($iMessageUid));
} }
if (null !== $iNewUid && 0 < $iNewUid) { if (null !== $iNewUid && 0 < $iNewUid) {
$mResult = array( $mResult = array(
'NewFolder' => $sDraftFolder, 'folder' => $sDraftFolder,
'NewUid' => $iNewUid 'uid' => $iNewUid
); );
} }
} }
@ -156,8 +156,8 @@ trait Messages
$oConfig = $this->Config(); $oConfig = $this->Config();
$sSentFolder = $this->GetActionParam('SaveFolder', ''); $sSentFolder = $this->GetActionParam('saveFolder', '');
$aDraftInfo = $this->GetActionParam('DraftInfo', null); $aDraftInfo = $this->GetActionParam('draftInfo', null);
$oMessage = $this->buildMessage($oAccount, false); $oMessage = $this->buildMessage($oAccount, false);
@ -173,7 +173,7 @@ trait Messages
$oMessage->ToStream(true), array($rMessageStream), 8192, true, true, true); $oMessage->ToStream(true), array($rMessageStream), 8192, true, true, true);
if (false !== $iMessageStreamSize) { if (false !== $iMessageStreamSize) {
$bDsn = !empty($this->GetActionParam('Dsn', 0)); $bDsn = !empty($this->GetActionParam('dsn', 0));
$this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, $bDsn, true); $this->smtpSendMessage($oAccount, $oMessage, $rMessageStream, $iMessageStreamSize, $bDsn, true);
if (\is_array($aDraftInfo) && 3 === \count($aDraftInfo)) { if (\is_array($aDraftInfo) && 3 === \count($aDraftInfo)) {
@ -244,8 +244,8 @@ trait Messages
$this->deleteMessageAttachments($oAccount); $this->deleteMessageAttachments($oAccount);
$sDraftFolder = $this->GetActionParam('MessageFolder', ''); $sDraftFolder = $this->GetActionParam('messageFolder', '');
$iDraftUid = (int) $this->GetActionParam('MessageUid', 0); $iDraftUid = (int) $this->GetActionParam('messageUid', 0);
if (\strlen($sDraftFolder) && 0 < $iDraftUid) { if (\strlen($sDraftFolder) && 0 < $iDraftUid) {
try try
{ {
@ -329,8 +329,8 @@ trait Messages
$mResult = true; $mResult = true;
$sFolderFullName = $this->GetActionParam('MessageFolder', ''); $sFolderFullName = $this->GetActionParam('messageFolder', '');
$iUid = (int) $this->GetActionParam('MessageUid', 0); $iUid = (int) $this->GetActionParam('messageUid', 0);
$this->Cacher($oAccount)->Set(\RainLoop\KeyPathHelper::ReadReceiptCache($oAccount->Email(), $sFolderFullName, $iUid), '1'); $this->Cacher($oAccount)->Set(\RainLoop\KeyPathHelper::ReadReceiptCache($oAccount->Email(), $sFolderFullName, $iUid), '1');
@ -374,7 +374,7 @@ trait Messages
try try
{ {
$this->MailClient()->MessageSetFlag( $this->MailClient()->MessageSetFlag(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
empty($sThreadUids) ? new SequenceSet('1:*', false) : new SequenceSet(\explode(',', $sThreadUids)), empty($sThreadUids) ? new SequenceSet('1:*', false) : new SequenceSet(\explode(',', $sThreadUids)),
MessageFlag::SEEN, MessageFlag::SEEN,
!empty($this->GetActionParam('SetAction', '0')) !empty($this->GetActionParam('SetAction', '0'))
@ -415,8 +415,8 @@ trait Messages
$this->verifyCacheByKey($sRawKey); $this->verifyCacheByKey($sRawKey);
} else { } else {
$sFolder = $this->GetActionParam('Folder', ''); $sFolder = $this->GetActionParam('folder', '');
$iUid = (int) $this->GetActionParam('Uid', 0); $iUid = (int) $this->GetActionParam('uid', 0);
} }
$oAccount = $this->initMailClientConnection(); $oAccount = $this->initMailClientConnection();
@ -446,7 +446,7 @@ trait Messages
{ {
$this->initMailClientConnection(); $this->initMailClientConnection();
$sFolder = $this->GetActionParam('Folder', ''); $sFolder = $this->GetActionParam('folder', '');
$aUids = \explode(',', (string) $this->GetActionParam('Uids', '')); $aUids = \explode(',', (string) $this->GetActionParam('Uids', ''));
try try
@ -566,7 +566,7 @@ trait Messages
try try
{ {
$aAttachments = $this->GetActionParam('Attachments', array()); $aAttachments = $this->GetActionParam('attachments', array());
if (!\is_array($aAttachments)) { if (!\is_array($aAttachments)) {
$aAttachments = []; $aAttachments = [];
} }
@ -575,9 +575,9 @@ trait Messages
foreach ($aAttachments as $mIndex => $sAttachment) { foreach ($aAttachments as $mIndex => $sAttachment) {
$aAttachments[$mIndex] = false; $aAttachments[$mIndex] = false;
if ($aValues = $this->decodeRawKey($oAccount, $sAttachment)) { if ($aValues = $this->decodeRawKey($oAccount, $sAttachment)) {
$sFolder = isset($aValues['Folder']) ? (string) $aValues['Folder'] : ''; $sFolder = isset($aValues['folder']) ? (string) $aValues['folder'] : '';
$iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; $iUid = isset($aValues['uid']) ? (int) $aValues['uid'] : 0;
$sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; $sMimeIndex = isset($aValues['mimeIndex']) ? (string) $aValues['mimeIndex'] : '';
$sTempName = \sha1($sAttachment); $sTempName = \sha1($sAttachment);
if (!$oFilesProvider->FileExists($oAccount, $sTempName)) { if (!$oFilesProvider->FileExists($oAccount, $sTempName)) {
@ -595,10 +595,10 @@ trait Messages
if ($self->FilesProvider()->PutFile($oAccount, $sTempName, $rResource)) { if ($self->FilesProvider()->PutFile($oAccount, $sTempName, $rResource)) {
$aAttachments[$mIndex] = [ $aAttachments[$mIndex] = [
// 'Name' => $sFileName, // 'name' => $sFileName,
'TempName' => $sTempName, 'tempName' => $sTempName,
'MimeType' => $sContentType 'mimeType' => $sContentType
// 'Size' => 0 // 'size' => 0
]; ];
} }
} }
@ -609,10 +609,10 @@ trait Messages
?: \SnappyMail\File\MimeType::fromFilename($sTempName) ?: \SnappyMail\File\MimeType::fromFilename($sTempName)
?: 'application/octet-stream'; // 'text/plain' ?: 'application/octet-stream'; // 'text/plain'
$aAttachments[$mIndex] = [ $aAttachments[$mIndex] = [
// 'Name' => $sFileName, // 'name' => $sFileName,
'TempName' => $sTempName, 'tempName' => $sTempName,
'MimeType' => $sContentType 'mimeType' => $sContentType
// 'Size' => $oFilesProvider->FileSize($oAccount, $sTempName) // 'size' => $oFilesProvider->FileSize($oAccount, $sTempName)
]; ];
} }
} }
@ -632,19 +632,19 @@ trait Messages
*/ */
public function DoMessagePgpVerify() : array public function DoMessagePgpVerify() : array
{ {
$sFolderName = $this->GetActionParam('Folder', ''); $sFolderName = $this->GetActionParam('folder', '');
$iUid = (int) $this->GetActionParam('Uid', 0); $iUid = (int) $this->GetActionParam('uid', 0);
$sBodyPart = $this->GetActionParam('BodyPart', ''); $sBodyPart = $this->GetActionParam('bodyPart', '');
$sSigPart = $this->GetActionParam('SigPart', ''); $sSigPart = $this->GetActionParam('sigPart', '');
if ($sBodyPart) { if ($sBodyPart) {
$result = [ $result = [
'text' => \preg_replace('/\\r?\\n/su', "\r\n", $sBodyPart), 'text' => \preg_replace('/\\r?\\n/su', "\r\n", $sBodyPart),
'signature' => $this->GetActionParam('SigPart', '') 'signature' => $this->GetActionParam('sigPart', '')
]; ];
} else { } else {
$sBodyPartId = $this->GetActionParam('BodyPartId', ''); $sBodyPartId = $this->GetActionParam('bodyPartId', '');
$sSigPartId = $this->GetActionParam('SigPartId', ''); $sSigPartId = $this->GetActionParam('sigPartId', '');
// $sMicAlg = $this->GetActionParam('MicAlg', ''); // $sMicAlg = $this->GetActionParam('micAlg', '');
$oAccount = $this->initMailClientConnection(); $oAccount = $this->initMailClientConnection();
@ -872,7 +872,7 @@ trait Messages
try try
{ {
$this->MailClient()->MessageSetFlag( $this->MailClient()->MessageSetFlag(
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
new SequenceSet(\explode(',', (string) $this->GetActionParam('Uids', ''))), new SequenceSet(\explode(',', (string) $this->GetActionParam('Uids', ''))),
$sMessageFlag, $sMessageFlag,
!empty($this->GetActionParam('SetAction', '0')), !empty($this->GetActionParam('SetAction', '0')),
@ -889,7 +889,7 @@ trait Messages
private function deleteMessageAttachments(Account $oAccount) : void private function deleteMessageAttachments(Account $oAccount) : void
{ {
$aAttachments = $this->GetActionParam('Attachments', null); $aAttachments = $this->GetActionParam('attachments', null);
if (\is_array($aAttachments)) { if (\is_array($aAttachments)) {
foreach (\array_keys($aAttachments) as $sTempName) { foreach (\array_keys($aAttachments) as $sTempName) {
@ -902,9 +902,9 @@ trait Messages
private function buildReadReceiptMessage(Account $oAccount) : \MailSo\Mime\Message private function buildReadReceiptMessage(Account $oAccount) : \MailSo\Mime\Message
{ {
$sReadReceipt = $this->GetActionParam('ReadReceipt', ''); $sReadReceipt = $this->GetActionParam('readReceipt', '');
$sSubject = $this->GetActionParam('subject', ''); $sSubject = $this->GetActionParam('subject', '');
$sText = $this->GetActionParam('Text', ''); $sText = $this->GetActionParam('plain', '');
$oIdentity = $this->GetIdentityByID($oAccount, '', true); $oIdentity = $this->GetIdentityByID($oAccount, '', true);
@ -966,10 +966,10 @@ trait Messages
$oMessage->SetXMailer('SnappyMail/'.APP_VERSION); $oMessage->SetXMailer('SnappyMail/'.APP_VERSION);
} }
$sFrom = $this->GetActionParam('From', ''); $sFrom = $this->GetActionParam('from', '');
$oMessage->SetFrom(\MailSo\Mime\Email::Parse($sFrom)); $oMessage->SetFrom(\MailSo\Mime\Email::Parse($sFrom));
/* /*
$oFromIdentity = $this->GetIdentityByID($oAccount, $this->GetActionParam('IdentityID', '')); $oFromIdentity = $this->GetIdentityByID($oAccount, $this->GetActionParam('identityID', ''));
if ($oFromIdentity) if ($oFromIdentity)
{ {
$oMessage->SetFrom(new \MailSo\Mime\Email( $oMessage->SetFrom(new \MailSo\Mime\Email(
@ -986,49 +986,49 @@ trait Messages
$oFrom = $oMessage->GetFrom(); $oFrom = $oMessage->GetFrom();
$oMessage->RegenerateMessageId($oFrom ? $oFrom->GetDomain() : ''); $oMessage->RegenerateMessageId($oFrom ? $oFrom->GetDomain() : '');
$oReplyTo = new \MailSo\Mime\EmailCollection($this->GetActionParam('ReplyTo', '')); $oReplyTo = new \MailSo\Mime\EmailCollection($this->GetActionParam('replyTo', ''));
if ($oReplyTo->count()) { if ($oReplyTo->count()) {
$oMessage->SetReplyTo($oReplyTo); $oMessage->SetReplyTo($oReplyTo);
} }
if (!empty($this->GetActionParam('ReadReceiptRequest', 0))) { if (!empty($this->GetActionParam('readReceiptRequest', 0))) {
// Read Receipts Reference Main Account Email, Not Identities #147 // Read Receipts Reference Main Account Email, Not Identities #147
// $oMessage->SetReadReceipt(($oFromIdentity ?: $oAccount)->Email()); // $oMessage->SetReadReceipt(($oFromIdentity ?: $oAccount)->Email());
$oMessage->SetReadReceipt($oFrom->GetEmail()); $oMessage->SetReadReceipt($oFrom->GetEmail());
} }
if (!empty($this->GetActionParam('MarkAsImportant', 0))) { if (!empty($this->GetActionParam('markAsImportant', 0))) {
$oMessage->SetPriority(\MailSo\Mime\Enumerations\MessagePriority::HIGH); $oMessage->SetPriority(\MailSo\Mime\Enumerations\MessagePriority::HIGH);
} }
$oMessage->SetSubject($this->GetActionParam('subject', '')); $oMessage->SetSubject($this->GetActionParam('subject', ''));
$oToEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('To', '')); $oToEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('to', ''));
if ($oToEmails->count()) { if ($oToEmails->count()) {
$oMessage->SetTo($oToEmails); $oMessage->SetTo($oToEmails);
} }
$oCcEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('Cc', '')); $oCcEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('cc', ''));
if ($oCcEmails->count()) { if ($oCcEmails->count()) {
$oMessage->SetCc($oCcEmails); $oMessage->SetCc($oCcEmails);
} }
$oBccEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('Bcc', '')); $oBccEmails = new \MailSo\Mime\EmailCollection($this->GetActionParam('bcc', ''));
if ($oBccEmails->count()) { if ($oBccEmails->count()) {
$oMessage->SetBcc($oBccEmails); $oMessage->SetBcc($oBccEmails);
} }
$aDraftInfo = $this->GetActionParam('DraftInfo', null); $aDraftInfo = $this->GetActionParam('draftInfo', null);
if ($bWithDraftInfo && \is_array($aDraftInfo) && !empty($aDraftInfo[0]) && !empty($aDraftInfo[1]) && !empty($aDraftInfo[2])) { if ($bWithDraftInfo && \is_array($aDraftInfo) && !empty($aDraftInfo[0]) && !empty($aDraftInfo[1]) && !empty($aDraftInfo[2])) {
$oMessage->SetDraftInfo($aDraftInfo[0], $aDraftInfo[1], $aDraftInfo[2]); $oMessage->SetDraftInfo($aDraftInfo[0], $aDraftInfo[1], $aDraftInfo[2]);
} }
$sInReplyTo = $this->GetActionParam('InReplyTo', ''); $sInReplyTo = $this->GetActionParam('inReplyTo', '');
if (\strlen($sInReplyTo)) { if (\strlen($sInReplyTo)) {
$oMessage->SetInReplyTo($sInReplyTo); $oMessage->SetInReplyTo($sInReplyTo);
} }
$sReferences = $this->GetActionParam('References', ''); $sReferences = $this->GetActionParam('references', '');
if (\strlen($sReferences)) { if (\strlen($sReferences)) {
$oMessage->SetReferences($sReferences); $oMessage->SetReferences($sReferences);
} }
@ -1038,7 +1038,7 @@ trait Messages
$aFoundContentLocationUrls = array(); $aFoundContentLocationUrls = array();
$oPart; $oPart;
if ($sSigned = $this->GetActionParam('Signed', '')) { if ($sSigned = $this->GetActionParam('signed', '')) {
$aSigned = \explode("\r\n\r\n", $sSigned, 2); $aSigned = \explode("\r\n\r\n", $sSigned, 2);
// $sBoundary = \preg_replace('/^.+boundary="([^"]+)".+$/Dsi', '$1', $aSigned[0]); // $sBoundary = \preg_replace('/^.+boundary="([^"]+)".+$/Dsi', '$1', $aSigned[0]);
$sBoundary = $this->GetActionParam('Boundary', ''); $sBoundary = $this->GetActionParam('Boundary', '');
@ -1055,7 +1055,7 @@ trait Messages
unset($oAlternativePart); unset($oAlternativePart);
unset($sSigned); unset($sSigned);
} else if ($sEncrypted = $this->GetActionParam('Encrypted', '')) { } else if ($sEncrypted = $this->GetActionParam('encrypted', '')) {
$oPart = new MimePart; $oPart = new MimePart;
$oPart->Headers->AddByName( $oPart->Headers->AddByName(
MimeEnumHeader::CONTENT_TYPE, MimeEnumHeader::CONTENT_TYPE,
@ -1081,7 +1081,7 @@ trait Messages
unset($sEncrypted); unset($sEncrypted);
} else { } else {
if ($sHtml = $this->GetActionParam('Html', '')) { if ($sHtml = $this->GetActionParam('html', '')) {
$oPart = new MimePart; $oPart = new MimePart;
$oPart->Headers->AddByName(MimeEnumHeader::CONTENT_TYPE, 'multipart/alternative'); $oPart->Headers->AddByName(MimeEnumHeader::CONTENT_TYPE, 'multipart/alternative');
$oMessage->SubParts->append($oPart); $oMessage->SubParts->append($oPart);
@ -1090,7 +1090,7 @@ trait Messages
$this->Plugins()->RunHook('filter.message-html', array($oAccount, $oMessage, &$sHtml)); $this->Plugins()->RunHook('filter.message-html', array($oAccount, $oMessage, &$sHtml));
// First add plain // First add plain
$sPlain = $this->GetActionParam('Text', '') ?: \MailSo\Base\HtmlUtils::ConvertHtmlToPlain($sHtml); $sPlain = $this->GetActionParam('plain', '') ?: \MailSo\Base\HtmlUtils::ConvertHtmlToPlain($sHtml);
$this->Plugins()->RunHook('filter.message-plain', array($oAccount, $oMessage, &$sPlain)); $this->Plugins()->RunHook('filter.message-plain', array($oAccount, $oMessage, &$sPlain));
$oAlternativePart = new MimePart; $oAlternativePart = new MimePart;
$oAlternativePart->Headers->AddByName(MimeEnumHeader::CONTENT_TYPE, 'text/plain; charset=utf-8'); $oAlternativePart->Headers->AddByName(MimeEnumHeader::CONTENT_TYPE, 'text/plain; charset=utf-8');
@ -1116,7 +1116,7 @@ trait Messages
unset($sHtml); unset($sHtml);
} else { } else {
$sPlain = $this->GetActionParam('Text', ''); $sPlain = $this->GetActionParam('plain', '');
if ($sSignature = $this->GetActionParam('Signature', null)) { if ($sSignature = $this->GetActionParam('Signature', null)) {
$oPart = new MimePart; $oPart = new MimePart;
$oPart->Headers->AddByName( $oPart->Headers->AddByName(
@ -1154,7 +1154,7 @@ trait Messages
} }
unset($oPart); unset($oPart);
$aAttachments = $this->GetActionParam('Attachments', null); $aAttachments = $this->GetActionParam('attachments', null);
if (\is_array($aAttachments)) { if (\is_array($aAttachments)) {
foreach ($aAttachments as $sTempName => $aData) { foreach ($aAttachments as $sTempName => $aData) {
$sFileName = (string) $aData['name']; $sFileName = (string) $aData['name'];
@ -1200,8 +1200,8 @@ trait Messages
} }
} }
$sFingerprint = $this->GetActionParam('SignFingerprint', ''); $sFingerprint = $this->GetActionParam('signFingerprint', '');
$sPassphrase = $this->GetActionParam('SignPassphrase', ''); $sPassphrase = $this->GetActionParam('signPassphrase', '');
if ($sFingerprint) { if ($sFingerprint) {
$GPG = $this->GnuPG(); $GPG = $this->GnuPG();
$oBody = $oMessage->GetRootPart(); $oBody = $oMessage->GetRootPart();
@ -1242,7 +1242,7 @@ trait Messages
$oPart->SubParts->append($oSignaturePart); $oPart->SubParts->append($oSignaturePart);
} }
$aFingerprints = \json_decode($this->GetActionParam('EncryptFingerprints', ''), true); $aFingerprints = \json_decode($this->GetActionParam('encryptFingerprints', ''), true);
if ($aFingerprints) { if ($aFingerprints) {
$GPG = $this->GnuPG(); $GPG = $this->GnuPG();
$oBody = $oMessage->GetRootPart(); $oBody = $oMessage->GetRootPart();

View file

@ -78,7 +78,7 @@ trait Pgp
} }
$GPG->addDecryptKey( $GPG->addDecryptKey(
$this->GetActionParam('KeyId', ''), $this->GetActionParam('keyId', ''),
$this->GetActionParam('Passphrase', '') $this->GetActionParam('Passphrase', '')
); );
@ -102,9 +102,9 @@ trait Pgp
// $oPart = \MailSo\Mime\Part::FromStream($rStreamHandle); // $oPart = \MailSo\Mime\Part::FromStream($rStreamHandle);
} }
}, },
$this->GetActionParam('Folder', ''), $this->GetActionParam('folder', ''),
(int) $this->GetActionParam('Uid', ''), (int) $this->GetActionParam('uid', ''),
$this->GetActionParam('PartId', '') $this->GetActionParam('partId', '')
); );
} }
@ -126,7 +126,7 @@ trait Pgp
{ {
$GPG = $this->GnuPG(); $GPG = $this->GnuPG();
return $this->DefaultResponse($GPG ? $GPG->export( return $this->DefaultResponse($GPG ? $GPG->export(
$this->GetActionParam('KeyId', ''), $this->GetActionParam('keyId', ''),
$this->GetActionParam('Passphrase', '') $this->GetActionParam('Passphrase', '')
) : false); ) : false);
} }
@ -149,7 +149,7 @@ trait Pgp
public function DoGnupgDeleteKey() : array public function DoGnupgDeleteKey() : array
{ {
$GPG = $this->GnuPG(); $GPG = $this->GnuPG();
$sKeyId = $this->GetActionParam('KeyId', ''); $sKeyId = $this->GetActionParam('keyId', '');
$bPrivate = !!$this->GetActionParam('isPrivate', 0); $bPrivate = !!$this->GetActionParam('isPrivate', 0);
return $this->DefaultResponse($GPG ? $GPG->deleteKey($sKeyId, $bPrivate) : false); return $this->DefaultResponse($GPG ? $GPG->deleteKey($sKeyId, $bPrivate) : false);
} }
@ -157,7 +157,7 @@ trait Pgp
public function DoGnupgImportKey() : array public function DoGnupgImportKey() : array
{ {
$sKey = $this->GetActionParam('Key', ''); $sKey = $this->GetActionParam('Key', '');
$sKeyId = $this->GetActionParam('KeyId', ''); $sKeyId = $this->GetActionParam('keyId', '');
$sEmail = $this->GetActionParam('Email', ''); $sEmail = $this->GetActionParam('Email', '');
if (!$sKey) { if (!$sKey) {
@ -266,7 +266,7 @@ trait Pgp
public function DoStorePGPKey() : array public function DoStorePGPKey() : array
{ {
$key = $this->GetActionParam('Key', ''); $key = $this->GetActionParam('Key', '');
$keyId = $this->GetActionParam('KeyId', ''); $keyId = $this->GetActionParam('keyId', '');
return $this->DefaultResponse(($key && $keyId && $this->StorePGPKey($key, $keyId))); return $this->DefaultResponse(($key && $keyId && $this->StorePGPKey($key, $keyId)));
} }

View file

@ -16,9 +16,9 @@ trait Raw
(string) $this->GetActionParam('RawKey', '') (string) $this->GetActionParam('RawKey', '')
); );
$sFolder = isset($aValues['Folder']) ? (string) $aValues['Folder'] : ''; $sFolder = isset($aValues['folder']) ? (string) $aValues['folder'] : '';
$iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; $iUid = isset($aValues['uid']) ? (int) $aValues['uid'] : 0;
$sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; $sMimeIndex = isset($aValues['mimeIndex']) ? (string) $aValues['mimeIndex'] : '';
\header('Content-Type: text/plain'); \header('Content-Type: text/plain');
@ -51,24 +51,19 @@ trait Raw
$oAccount = $this->getAccountFromToken(); $oAccount = $this->getAccountFromToken();
$sData = $this->StorageProvider()->Get($oAccount, $mData = $this->StorageProvider()->Get($oAccount,
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
'background' 'background'
); );
if (!empty($sData)) if (!empty($mData)) {
{ $mData = \json_decode($mData, true);
$aData = \json_decode($sData, true); if (!empty($mData['ContentType']) && !empty($mData['Raw'])) {
unset($sData);
if (!empty($aData['ContentType']) && !empty($aData['Raw']) &&
\in_array($aData['ContentType'], array('image/png', 'image/jpg', 'image/jpeg')))
{
$this->cacheByKey($sRawKey); $this->cacheByKey($sRawKey);
\header('Content-Type: '.$aData['ContentType']); \header('Content-Type: '.$mData['ContentType']);
echo \base64_decode($aData['Raw']); echo \base64_decode($mData['Raw']);
unset($aData); unset($mData);
return true; return true;
} }
@ -133,13 +128,13 @@ trait Raw
$bIsRangeRequest = true; $bIsRangeRequest = true;
} }
$sFolder = isset($aValues['Folder']) ? (string) $aValues['Folder'] : ''; $sFolder = isset($aValues['folder']) ? (string) $aValues['folder'] : '';
$iUid = isset($aValues['Uid']) ? (int) $aValues['Uid'] : 0; $iUid = isset($aValues['uid']) ? (int) $aValues['uid'] : 0;
$sMimeIndex = isset($aValues['MimeIndex']) ? (string) $aValues['MimeIndex'] : ''; $sMimeIndex = isset($aValues['mimeIndex']) ? (string) $aValues['mimeIndex'] : '';
$sContentTypeIn = isset($aValues['MimeType']) ? (string) $aValues['MimeType'] : ''; $sContentTypeIn = isset($aValues['mimeType']) ? (string) $aValues['mimeType'] : '';
$sFileNameIn = isset($aValues['FileName']) ? (string) $aValues['FileName'] : ''; $sFileNameIn = isset($aValues['fileName']) ? (string) $aValues['fileName'] : '';
$sFileHashIn = isset($aValues['FileHash']) ? (string) $aValues['FileHash'] : ''; $sFileHashIn = isset($aValues['fileHash']) ? (string) $aValues['fileHash'] : '';
if (!empty($sFileHashIn)) { if (!empty($sFileHashIn)) {
$this->verifyCacheByKey($sRawKey); $this->verifyCacheByKey($sRawKey);

View file

@ -116,59 +116,59 @@ trait Response
$oAccount = $this->getAccountFromToken(); $oAccount = $this->getAccountFromToken();
if (!$mResult['DateTimeStampInUTC'] || $this->Config()->Get('labs', 'date_from_headers', true)) { if (!$mResult['dateTimeStampInUTC'] || $this->Config()->Get('labs', 'date_from_headers', true)) {
$iDateTimeStampInUTC = $mResponse->HeaderTimeStampInUTC; $iDateTimeStampInUTC = $mResponse->HeaderTimeStampInUTC;
if ($iDateTimeStampInUTC) { if ($iDateTimeStampInUTC) {
$mResult['DateTimeStampInUTC'] = $iDateTimeStampInUTC; $mResult['dateTimeStampInUTC'] = $iDateTimeStampInUTC;
} }
} }
// \MailSo\Mime\EmailCollection // \MailSo\Mime\EmailCollection
foreach (['ReplyTo','From','To','Cc','Bcc','Sender','DeliveredTo'] as $prop) { foreach (['replyTo','from','to','cc','bcc','sender','deliveredTo'] as $prop) {
$mResult[$prop] = $this->responseObject($mResult[$prop], $prop); $mResult[$prop] = $this->responseObject($mResult[$prop], $prop);
} }
$sSubject = $mResult['subject']; $sSubject = $mResult['subject'];
$mResult['Hash'] = \md5($mResult['Folder'].$mResult['Uid']); $mResult['hash'] = \md5($mResult['folder'].$mResult['uid']);
$mResult['RequestHash'] = $this->encodeRawKey($oAccount, array( $mResult['requestHash'] = $this->encodeRawKey($oAccount, array(
'Folder' => $mResult['Folder'], 'folder' => $mResult['folder'],
'Uid' => $mResult['Uid'], 'uid' => $mResult['uid'],
'MimeType' => 'message/rfc822', 'mimeType' => 'message/rfc822',
'FileName' => (\strlen($sSubject) ? \MailSo\Base\Utils::SecureFileName($sSubject) : 'message-'.$mResult['Uid']) . '.eml' 'fileName' => (\strlen($sSubject) ? \MailSo\Base\Utils::SecureFileName($sSubject) : 'message-'.$mResult['uid']) . '.eml'
)); ));
$mResult['Attachments'] = $this->responseObject($mResponse->Attachments, 'Attachments'); $mResult['attachments'] = $this->responseObject($mResponse->Attachments, 'attachments');
if (!$sParent) { if (!$sParent) {
$mResult['DraftInfo'] = $mResponse->DraftInfo; $mResult['draftInfo'] = $mResponse->DraftInfo;
$mResult['UnsubsribeLinks'] = $mResponse->UnsubsribeLinks; $mResult['unsubsribeLinks'] = $mResponse->UnsubsribeLinks;
$mResult['References'] = $mResponse->References; $mResult['references'] = $mResponse->References;
$mResult['Html'] = $mResponse->Html(); $mResult['html'] = $mResponse->Html();
$mResult['Plain'] = $mResponse->Plain(); $mResult['plain'] = $mResponse->Plain();
// $this->GetCapa(Capa::OPEN_PGP) || $this->GetCapa(Capa::GNUPG) // $this->GetCapa(Capa::OPEN_PGP) || $this->GetCapa(Capa::GNUPG)
$mResult['PgpSigned'] = $mResponse->pgpSigned; $mResult['pgpSigned'] = $mResponse->pgpSigned;
$mResult['PgpEncrypted'] = $mResponse->pgpEncrypted; $mResult['pgpEncrypted'] = $mResponse->pgpEncrypted;
$mResult['ReadReceipt'] = $mResponse->ReadReceipt; $mResult['readReceipt'] = $mResponse->ReadReceipt;
if (\strlen($mResult['ReadReceipt']) && !\in_array('$forwarded', $mResult['Flags'])) { if (\strlen($mResult['readReceipt']) && !\in_array('$forwarded', $mResult['flags'])) {
// \in_array('$mdnsent', $mResult['Flags']) // \in_array('$mdnsent', $mResult['flags'])
if (\strlen($mResult['ReadReceipt'])) { if (\strlen($mResult['readReceipt'])) {
try try
{ {
$oReadReceipt = \MailSo\Mime\Email::Parse($mResult['ReadReceipt']); $oReadReceipt = \MailSo\Mime\Email::Parse($mResult['readReceipt']);
if (!$oReadReceipt) { if (!$oReadReceipt) {
$mResult['ReadReceipt'] = ''; $mResult['readReceipt'] = '';
} }
} }
catch (\Throwable $oException) { unset($oException); } catch (\Throwable $oException) { unset($oException); }
} }
if (\strlen($mResult['ReadReceipt']) && '1' === $this->Cacher($oAccount)->Get( if (\strlen($mResult['readReceipt']) && '1' === $this->Cacher($oAccount)->Get(
\RainLoop\KeyPathHelper::ReadReceiptCache($oAccount->Email(), $mResult['Folder'], $mResult['Uid']), '0')) \RainLoop\KeyPathHelper::ReadReceiptCache($oAccount->Email(), $mResult['folder'], $mResult['uid']), '0'))
{ {
$mResult['ReadReceipt'] = ''; $mResult['readReceipt'] = '';
} }
} }
} }
@ -177,13 +177,13 @@ trait Response
if ($mResponse instanceof \MailSo\Mail\Attachment) { if ($mResponse instanceof \MailSo\Mail\Attachment) {
$mResult = $mResponse->jsonSerialize(); $mResult = $mResponse->jsonSerialize();
$mResult['IsThumbnail'] = $this->GetCapa(Capa::ATTACHMENT_THUMBNAILS) && $this->isFileHasThumbnail($mResult['FileName']); $mResult['isThumbnail'] = $this->GetCapa(Capa::ATTACHMENT_THUMBNAILS) && $this->isFileHasThumbnail($mResult['fileName']);
$mResult['Download'] = $this->encodeRawKey($this->getAccountFromToken(), array( $mResult['download'] = $this->encodeRawKey($this->getAccountFromToken(), array(
'Folder' => $mResult['Folder'], 'folder' => $mResult['folder'],
'Uid' => $mResult['Uid'], 'uid' => $mResult['uid'],
'MimeIndex' => $mResult['MimeIndex'], 'mimeIndex' => $mResult['mimeIndex'],
'MimeType' => $mResult['MimeType'], 'mimeType' => $mResult['mimeType'],
'FileName' => $mResult['FileName'] 'fileName' => $mResult['fileName']
)); ));
return $mResult; return $mResult;
} }
@ -193,7 +193,7 @@ trait Response
$sHash = $mResponse->Hash($this->MailClient()->ImapClient()->Hash()); $sHash = $mResponse->Hash($this->MailClient()->ImapClient()->Hash());
if ($sHash) { if ($sHash) {
$aResult['Hash'] = $sHash; $aResult['hash'] = $sHash;
} }
if (null === $this->aCheckableFolder) { if (null === $this->aCheckableFolder) {
@ -204,7 +204,7 @@ trait Response
); );
$this->aCheckableFolder = \is_array($aCheckable) ? $aCheckable : array(); $this->aCheckableFolder = \is_array($aCheckable) ? $aCheckable : array();
} }
$aResult['Checkable'] = \in_array($mResponse->FullName(), $this->aCheckableFolder); $aResult['checkable'] = \in_array($mResponse->FullName(), $this->aCheckableFolder);
return $aResult; return $aResult;
} }

View file

@ -159,8 +159,8 @@ trait Themes
if ($this->StorageProvider()->Put($oAccount, if ($this->StorageProvider()->Put($oAccount,
\RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG, \RainLoop\Providers\Storage\Enumerations\StorageType::CONFIG,
'background', 'background',
// Used by RawUserBackground()
\RainLoop\Utils::jsonEncode(array( \RainLoop\Utils::jsonEncode(array(
'Name' => $aFile['name'],
'ContentType' => $sMimeType, 'ContentType' => $sMimeType,
'Raw' => \base64_encode($sData) 'Raw' => \base64_encode($sData)
)) ))
@ -201,8 +201,8 @@ trait Themes
} }
return $this->DefaultResponse(!empty($sName) && !empty($sHash) ? array( return $this->DefaultResponse(!empty($sName) && !empty($sHash) ? array(
'Name' => $sName, 'name' => $sName,
'Hash' => $sHash 'hash' => $sHash
) : false); ) : false);
} }
} }

20
vendors/jua/jua.js vendored
View file

@ -44,11 +44,9 @@
{ {
return oFile.size return oFile.size
? { ? {
FileName: (oFile.name || '').replace(/^.*\/([^/]*)$/, '$1'), fileName: (oFile.name || '').replace(/^.*\/([^/]*)$/, '$1'),
Size: oFile.size, size: oFile.size,
Type: oFile.type, file: oFile
Folder: '',
File : oFile
} }
: null; // Folder : null; // Folder
}, },
@ -233,7 +231,7 @@
*/ */
uploadTask(sUid, oFileInfo) uploadTask(sUid, oFileInfo)
{ {
if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo['File']) if (false === this.oUids[sUid] || !oFileInfo || !oFileInfo.file)
{ {
return false; return false;
} }
@ -285,7 +283,7 @@
fStartFunction && fStartFunction(sUid); fStartFunction && fStartFunction(sUid);
oFormData.append(this.options.name, oFileInfo['File']); oFormData.append(this.options.name, oFileInfo.file);
oXhr.send(oFormData); oXhr.send(oFormData);
@ -329,11 +327,9 @@
getDataFromFiles(oInput.files, fFileCallback, limit); getDataFromFiles(oInput.files, fFileCallback, limit);
} else { } else {
fFileCallback({ fFileCallback({
FileName: oInput.value.split(/\\\//).pop(), fileName: oInput.value.split(/\\\//).pop(),
Size: null, size: null,
Type: null, file : null
Folder: '',
File : null
}); });
} }
}); });