mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Almost all JSON properties to JavaScript camelCase
This commit is contained in:
parent
7a53cae32f
commit
f080a302b1
|
@ -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'), {
|
||||||
|
|
|
@ -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;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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':
|
||||||
|
|
|
@ -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]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -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, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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 } };
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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';
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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(',')
|
||||||
});
|
});
|
||||||
|
|
|
@ -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() })
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
@ -541,18 +522,18 @@ class BodyStructure implements \JsonSerializable
|
||||||
return $aDict;
|
return $aDict;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
#[\ReturnTypeWillChange]
|
||||||
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()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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']
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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'],
|
||||||
];
|
];
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
20
vendors/jua/jua.js
vendored
|
@ -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
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue