mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-08-30 12:39:20 +03:00
Merge branch 'master' into patch-1
This commit is contained in:
commit
92ed4fcc81
82 changed files with 607 additions and 343 deletions
|
|
@ -10,18 +10,20 @@ export class MimeHeaderAutocryptModel/* extends AbstractModel*/
|
|||
|
||||
if (value) {
|
||||
value.split(';').forEach(entry => {
|
||||
entry = entry.split('=');
|
||||
entry = entry.match(/^([^=]+)=(.*)$/);
|
||||
const trim = str => (str || '').trim().replace(/^["']|["']+$/g, '');
|
||||
this[trim(entry[0]).replace('-', '_')] = trim(entry[1]);
|
||||
this[trim(entry[1]).replace('-', '_')] = trim(entry[2]);
|
||||
});
|
||||
this.keydata = this.keydata.replace(/\s+/g, '\n');
|
||||
}
|
||||
}
|
||||
|
||||
toString() {
|
||||
let result = `addr=${this.addr}; `;
|
||||
if ('mutual' === this.prefer_encrypt) {
|
||||
return `addr=${this.addr}; prefer-encrypt=mutual; keydata=${this.keydata}`;
|
||||
result += 'prefer-encrypt=mutual; ';
|
||||
}
|
||||
return `addr=${this.addr}; keydata=${this.keydata}`;
|
||||
return result + 'keydata=' + this.keydata.replace(/\n/g, '\n ');
|
||||
}
|
||||
|
||||
pem() {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export class AdvancedSearchPopupView extends AbstractViewPopup {
|
|||
text: '',
|
||||
keyword: '',
|
||||
repliedValue: -1,
|
||||
selectedDateValue: -1,
|
||||
selectedDateValue: 0,
|
||||
selectedTreeValue: '',
|
||||
|
||||
hasAttachment: false,
|
||||
|
|
@ -58,7 +58,7 @@ export class AdvancedSearchPopupView extends AbstractViewPopup {
|
|||
// We should think about migrating all SEARCH/DATE_ to either SEARCH/SINCE_DATE or SEARCH/BEFORE_DATE
|
||||
// and adjust the prefix accordingly
|
||||
// let prefix_since = 'SEARCH/SINCE_DATE_';
|
||||
let prefix = 'SEARCH/DATE_';
|
||||
let prefix = 'SEARCH/SINCE_';
|
||||
let prefix_before = 'SEARCH/BEFORE_DATE_';
|
||||
return [
|
||||
{ id: -365, name: i18n(prefix_before + 'YEAR') },
|
||||
|
|
@ -67,7 +67,7 @@ export class AdvancedSearchPopupView extends AbstractViewPopup {
|
|||
{ id: -30, name: i18n(prefix_before + 'MONTH') },
|
||||
{ id: -7, name: i18n(prefix_before + '7_DAYS') },
|
||||
{ id: -3, name: i18n(prefix_before + '3_DAYS') },
|
||||
{ id: -1, name: i18n(prefix + 'ALL') },
|
||||
{ id: 0, name: i18n('SEARCH/DATE_ALL') },
|
||||
{ id: 3, name: i18n(prefix + '3_DAYS') },
|
||||
{ id: 7, name: i18n(prefix + '7_DAYS') },
|
||||
{ id: 30, name: i18n(prefix + 'MONTH') },
|
||||
|
|
@ -110,7 +110,7 @@ export class AdvancedSearchPopupView extends AbstractViewPopup {
|
|||
append('text', self.text().trim());
|
||||
append('keyword', self.keyword());
|
||||
append('in', self.selectedTreeValue());
|
||||
if (-1 < self.selectedDateValue()) {
|
||||
if (0 < self.selectedDateValue()) {
|
||||
let d = new Date();
|
||||
d.setDate(d.getDate() - self.selectedDateValue());
|
||||
append('since', d.toISOString().split('T')[0]);
|
||||
|
|
@ -151,8 +151,7 @@ export class AdvancedSearchPopupView extends AbstractViewPopup {
|
|||
self.text(pString(params.get('text')));
|
||||
self.keyword(pString(params.get('keyword')));
|
||||
self.selectedTreeValue(pString(params.get('in')));
|
||||
// self.selectedDateValue(params.get('since'));
|
||||
self.selectedDateValue(-1);
|
||||
self.selectedDateValue(0);
|
||||
self.hasAttachment(params.has('attachment'));
|
||||
self.starred(params.has('flagged'));
|
||||
self.unseen(params.has('unseen'));
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
this.sendError(true);
|
||||
this.sendErrorDesc(
|
||||
getNotification(iError, data?.ErrorMessage, Notifications.CantSendMessage)
|
||||
+ "\n" + data?.ErrorMessageAdditional
|
||||
+ "\n" + (data?.ErrorMessageAdditional || data?.ErrorMessage)
|
||||
);
|
||||
};
|
||||
try {
|
||||
|
|
@ -535,9 +535,13 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
this.savedErrorDesc(msg);
|
||||
} else {
|
||||
params.signPassphrase && Passphrases.delete(identity);
|
||||
this.sendError(true);
|
||||
sendFailed(iError, data);
|
||||
// Remove remembered passphrase as it could be wrong
|
||||
let key = ('S/MIME' === params.sign) ? identity : null;
|
||||
params.signFingerprint
|
||||
&& this.signOptions.forEach(option => ('GnuPG' === option[0]) && (key = option[1]));
|
||||
key && Passphrases.delete(key);
|
||||
}
|
||||
} else {
|
||||
if (arrayLength(this.aDraftInfo) > 0) {
|
||||
|
|
@ -886,7 +890,7 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
}
|
||||
|
||||
if (options.mode && oLastMessage) {
|
||||
let encrypted,
|
||||
let usePlain,
|
||||
sCc = '',
|
||||
sDate = timestampToString(oLastMessage.dateTimestamp(), 'FULL'),
|
||||
sSubject = oLastMessage.subject(),
|
||||
|
|
@ -994,18 +998,14 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
break;
|
||||
|
||||
default:
|
||||
encrypted = PgpUserStore.isEncrypted(sText);
|
||||
if (encrypted) {
|
||||
usePlain = PgpUserStore.isEncrypted(sText) || isPlainEditor() || !oLastMessage.isHtml();
|
||||
if (usePlain) {
|
||||
sText = oLastMessage.plain();
|
||||
}
|
||||
}
|
||||
|
||||
this.editor(editor => {
|
||||
encrypted || editor.setHtml(sText);
|
||||
if (encrypted || isPlainEditor()) {
|
||||
editor.modePlain();
|
||||
}
|
||||
encrypted && editor.setPlain(sText);
|
||||
usePlain ? (editor.modePlain() | editor.setPlain(sText)) : editor.setHtml(sText);
|
||||
this.setSignature(identity, options.mode);
|
||||
this.setFocusInPopup();
|
||||
});
|
||||
|
|
@ -1506,6 +1506,8 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
do {
|
||||
l = Text.length;
|
||||
Text = Text
|
||||
// Remove line duplication
|
||||
.replace(/<br><\/div>/gi, '</div>')
|
||||
// Remove Microsoft Office styling
|
||||
.replace(/(<[^>]+[;"'])\s*mso-[a-z-]+\s*:[^;"']+/gi, '$1')
|
||||
// Remove hubspot data-hs- attributes
|
||||
|
|
@ -1546,12 +1548,11 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
alternative.children.push(data);
|
||||
data = alternative;
|
||||
}
|
||||
let sign = true;
|
||||
let isSigned = false;
|
||||
for (let i = 0; i < signOptions.length; ++i) {
|
||||
if ('OpenPGP' == signOptions[i][0]) {
|
||||
try {
|
||||
// Doesn't sign attachments
|
||||
params.html = params.plain = '';
|
||||
let signed = new MimePart;
|
||||
signed.headers['Content-Type'] =
|
||||
'multipart/signed; micalg="pgp-sha256"; protocol="application/pgp-signature"';
|
||||
|
|
@ -1562,6 +1563,8 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
signature.headers['Content-Transfer-Encoding'] = '7Bit';
|
||||
signature.body = await OpenPGPUserStore.sign(data.toString(), signOptions[i][1], 1);
|
||||
signed.children.push(signature);
|
||||
isSigned = true;
|
||||
params.html = params.plain = '';
|
||||
params.signed = signed.toString();
|
||||
params.boundary = signed.boundary;
|
||||
data = signed;
|
||||
|
|
@ -1569,13 +1572,11 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
Object.entries(PgpUserStore.getPublicKeyOfEmails([getEmail(this.from())]) || {})
|
||||
.forEach(([k,v]) => params.publicKey = v);
|
||||
*/
|
||||
break;
|
||||
} catch (e) {
|
||||
sign = false;
|
||||
console.error(e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ('GnuPG' == signOptions[i][0]) {
|
||||
} else if ('GnuPG' == signOptions[i][0]) {
|
||||
// TODO: sign in PHP fails
|
||||
let pass = await GnuPGUserStore.sign(signOptions[i][1]);
|
||||
if (null != pass) {
|
||||
|
|
@ -1583,12 +1584,10 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
params.signFingerprint = signOptions[i][1].fingerprint;
|
||||
params.signPassphrase = pass;
|
||||
// params.attachPublicKey = false;
|
||||
} else {
|
||||
sign = false;
|
||||
isSigned = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if ('S/MIME' == signOptions[i][0]) {
|
||||
} else if ('S/MIME' == signOptions[i][0]) {
|
||||
// TODO: sign in PHP fails
|
||||
params.sign = 'S/MIME';
|
||||
// params.signCertificate = identity.smimeCertificate();
|
||||
|
|
@ -1601,14 +1600,13 @@ export class ComposePopupView extends AbstractViewPopup {
|
|||
);
|
||||
if (null != pass) {
|
||||
params.signPassphrase = pass.password;
|
||||
// pass.remember && Passphrases.handle(identity, pass.password);
|
||||
} else {
|
||||
sign = false;
|
||||
pass.remember && Passphrases.handle(identity, pass.password);
|
||||
isSigned = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (signOptions.length && !sign) {
|
||||
if (signOptions.length && !isSigned) {
|
||||
throw 'Signing failed';
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ const
|
|||
imapMessage_all_headers: false,
|
||||
imapMessage_list_limit: 10000,
|
||||
imapSearch_filter: '',
|
||||
imapSpam_headers: '',
|
||||
imapVirus_headers: '',
|
||||
|
||||
sieveEnabled: false,
|
||||
sieveHost: '',
|
||||
|
|
@ -80,15 +82,17 @@ const
|
|||
},
|
||||
disabled_capabilities: oDomain.imapDisabled_capabilities(),
|
||||
folder_list_limit: pInt(oDomain.imapFolder_list_limit()),
|
||||
message_list_limit: pInt(oDomain.imapMessage_list_limit())
|
||||
message_list_limit: pInt(oDomain.imapMessage_list_limit()),
|
||||
/*
|
||||
expunge_all_on_delete: ,
|
||||
fast_simple_search: ,
|
||||
fetch_new_messages: ,
|
||||
force_select: ,
|
||||
message_all_headers: ,
|
||||
search_filter:
|
||||
*/
|
||||
search_filter: oDomain.imapSearch_filter(),
|
||||
spam_headers: oDomain.imapSpam_headers(),
|
||||
virus_headers: oDomain.imapVirus_headers()
|
||||
},
|
||||
SMTP: {
|
||||
host: oDomain.smtpHost,
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ const
|
|||
SignMeOn = 1,
|
||||
SignMeUnused = 2;
|
||||
|
||||
|
||||
export class LoginUserView extends AbstractViewLogin {
|
||||
constructor() {
|
||||
super();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue