From 6f33bc23d3a1bc276ee31faf7de75571bfa50019 Mon Sep 17 00:00:00 2001 From: the-djmaze <> Date: Fri, 23 Feb 2024 03:14:36 +0100 Subject: [PATCH] Added Import S/MIME certificate popup And much better handling of the sign and encrypt options --- dev/Settings/User/Security.js | 5 + dev/Stores/User/GnuPG.js | 3 +- dev/Stores/User/Mailvelope.js | 124 +++++++++++ dev/Stores/User/Pgp.js | 152 +------------ dev/View/Popup/Compose.js | 206 +++++++++++------- dev/View/Popup/SMimeImport.js | 50 +++++ .../app/libraries/RainLoop/Actions/SMime.php | 9 + .../v/0.0.0/app/localization/ar-SA/user.json | 1 + .../v/0.0.0/app/localization/bg-BG/user.json | 1 + .../v/0.0.0/app/localization/cs-CZ/user.json | 1 + .../v/0.0.0/app/localization/da-DK/user.json | 1 + .../v/0.0.0/app/localization/de-DE/user.json | 1 + .../v/0.0.0/app/localization/el-GR/user.json | 1 + .../v/0.0.0/app/localization/en-GB/user.json | 1 + .../v/0.0.0/app/localization/en/user.json | 1 + .../v/0.0.0/app/localization/es-ES/user.json | 1 + .../v/0.0.0/app/localization/et-EE/user.json | 1 + .../v/0.0.0/app/localization/eu/user.json | 1 + .../v/0.0.0/app/localization/fa-IR/user.json | 1 + .../v/0.0.0/app/localization/fi-FI/user.json | 1 + .../v/0.0.0/app/localization/fr-FR/user.json | 1 + .../v/0.0.0/app/localization/hu-HU/user.json | 1 + .../v/0.0.0/app/localization/id-ID/user.json | 1 + .../v/0.0.0/app/localization/is-IS/user.json | 1 + .../v/0.0.0/app/localization/it-IT/user.json | 1 + .../v/0.0.0/app/localization/ja-JP/user.json | 1 + .../v/0.0.0/app/localization/ko-KR/user.json | 1 + .../v/0.0.0/app/localization/lt-LT/user.json | 1 + .../v/0.0.0/app/localization/lv-LV/user.json | 1 + .../v/0.0.0/app/localization/nb-NO/user.json | 1 + .../v/0.0.0/app/localization/nl-NL/user.json | 1 + .../v/0.0.0/app/localization/pl-PL/user.json | 1 + .../v/0.0.0/app/localization/pt-BR/user.json | 1 + .../v/0.0.0/app/localization/pt-PT/user.json | 1 + .../v/0.0.0/app/localization/pt/user.json | 1 + .../v/0.0.0/app/localization/ro-RO/user.json | 1 + .../v/0.0.0/app/localization/ru-RU/user.json | 1 + .../v/0.0.0/app/localization/sk-SK/user.json | 1 + .../v/0.0.0/app/localization/sl-SI/user.json | 1 + .../v/0.0.0/app/localization/sv-SE/user.json | 1 + .../v/0.0.0/app/localization/tr-TR/user.json | 1 + .../v/0.0.0/app/localization/uk-UA/user.json | 1 + .../v/0.0.0/app/localization/vi-VN/user.json | 1 + .../v/0.0.0/app/localization/zh-CN/user.json | 1 + .../v/0.0.0/app/localization/zh-TW/user.json | 1 + .../Views/User/PopupsSMimeImport.html | 13 ++ .../Views/User/SettingsSecurity.html | 2 + 47 files changed, 375 insertions(+), 227 deletions(-) create mode 100644 dev/Stores/User/Mailvelope.js create mode 100644 dev/View/Popup/SMimeImport.js create mode 100644 snappymail/v/0.0.0/app/templates/Views/User/PopupsSMimeImport.html diff --git a/dev/Settings/User/Security.js b/dev/Settings/User/Security.js index cabde4a80..f73cfa882 100644 --- a/dev/Settings/User/Security.js +++ b/dev/Settings/User/Security.js @@ -16,6 +16,7 @@ import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport'; import { OpenPgpGeneratePopupView } from 'View/Popup/OpenPgpGenerate'; import { SMimeUserStore } from 'Stores/User/SMime'; +import { SMimeImportPopupView } from 'View/Popup/SMimeImport'; import Remote from 'Remote/User/Fetch'; @@ -70,6 +71,10 @@ export class UserSettingsSecurity extends AbstractViewSettings { ); } + importToSMime() { + showScreenPopup(SMimeImportPopupView); + } + onBuild() { /** * Create an iframe to display the Mailvelope keyring settings. diff --git a/dev/Stores/User/GnuPG.js b/dev/Stores/User/GnuPG.js index cd121194d..f5106588f 100644 --- a/dev/Stores/User/GnuPG.js +++ b/dev/Stores/User/GnuPG.js @@ -35,7 +35,8 @@ export const GnuPGUserStore = new class { this.keyring = null; this.publicKeys([]); this.privateKeys([]); - Remote.request('GnupgGetKeys', + SettingsCapa('GnuPG') + && Remote.request('GnupgGetKeys', (iError, oData) => { if (oData?.Result) { this.keyring = oData.Result; diff --git a/dev/Stores/User/Mailvelope.js b/dev/Stores/User/Mailvelope.js new file mode 100644 index 000000000..e811806f0 --- /dev/null +++ b/dev/Stores/User/Mailvelope.js @@ -0,0 +1,124 @@ +import { SettingsGet } from 'Common/Globals'; + +// https://mailvelope.github.io/mailvelope/Keyring.html +let mailvelopeKeyring = null; + +export const MailvelopeUserStore = { + keyring: null, + + loadKeyring(identifier) { + identifier = identifier || SettingsGet('Email'); + if (window.mailvelope) { + const fn = keyring => { + mailvelopeKeyring = keyring; + console.log('mailvelope ready'); + }; + mailvelope.getKeyring().then(fn, err => { + if (identifier) { + // attempt to create a new keyring for this app/user + mailvelope.createKeyring(identifier).then(fn, err => console.error(err)); + } else { + console.error(err); + } + }); + addEventListener('mailvelope-disconnect', event => { + alert('Mailvelope is updated to version ' + event.detail.version + '. Reload page'); + }, false); + } else { + addEventListener('mailvelope', () => this.loadKeyring(identifier)); + } + }, + + async hasPublicKeyForEmails(recipients) { + const + mailvelope = mailvelopeKeyring && await mailvelopeKeyring.validKeyForAddress(recipients) + /*.then(LookupResult => Object.entries(LookupResult))*/, + entries = mailvelope && Object.entries(mailvelope); + return entries && entries.filter(value => value[1]).length === recipients.length; + }, + + async getPrivateKeyFor(email/*, sign*/) { + if (mailvelopeKeyring && await mailvelopeKeyring.hasPrivateKey({email:email})) { + return ['mailvelope', email]; + } + return false; + }, + + async decrypt(message) { + // Try Mailvelope (does not support inline images) + if (mailvelopeKeyring) { + const sender = message.from[0].email, + armoredText = message.plain(); + try { + let emails = [...message.from,...message.to,...message.cc].validUnique(), + i = emails.length; + while (i--) { + if (await this.getMailvelopePrivateKeyFor(emails[i].email)) { + /** + * https://mailvelope.github.io/mailvelope/Mailvelope.html#createEncryptedFormContainer + * Creates an iframe to display an encrypted form + */ + // mailvelope.createEncryptedFormContainer('#mailvelope-form'); + /** + * https://mailvelope.github.io/mailvelope/Mailvelope.html#createDisplayContainer + * Creates an iframe to display the decrypted content of the encrypted mail. + */ + const body = message.body; + body.textContent = ''; + let result = await mailvelope.createDisplayContainer( + '#'+body.id, + armoredText, + mailvelopeKeyring, + { + senderAddress: sender + // emails[i].email + } + ); + if (result) { + if (result.error?.message) { + if ('PWD_DIALOG_CANCEL' !== result.error.code) { + alert(result.error.code + ': ' + result.error.message); + } + } else { + body.classList.add('mailvelope'); + return true; + } + } + break; + } + } + } catch (err) { + console.error(err); + } + } + } + /** + * Returns headers that should be added to an outgoing email. + * So far this is only the autocrypt header. + */ +/* + mailvelopeKeyring.additionalHeadersForOutgoingEmail(from: 'abc@web.de') + .then(function(additional) { + console.log('additionalHeadersForOutgoingEmail', additional); + // logs: {autocrypt: "addr=abc@web.de; prefer-encrypt=mutual; keydata=..."} + }); + + mailvelopeKeyring.addSyncHandler(syncHandlerObj) + mailvelopeKeyring.createKeyBackupContainer(selector, options) + mailvelopeKeyring.createKeyGenContainer(selector, { +// userIds: [], + keySize: 4096 + }) + + mailvelopeKeyring.exportOwnPublicKey(emailAddr).then() + mailvelopeKeyring.importPublicKey(armored) + + // https://mailvelope.github.io/mailvelope/global.html#SyncHandlerObject + mailvelopeKeyring.addSyncHandler({ + uploadSync + downloadSync + backup + restore + }); +*/ +}; diff --git a/dev/Stores/User/Pgp.js b/dev/Stores/User/Pgp.js index 3895c4194..7eb788464 100644 --- a/dev/Stores/User/Pgp.js +++ b/dev/Stores/User/Pgp.js @@ -8,12 +8,10 @@ import { SettingsCapa, SettingsGet } from 'Common/Globals'; import { GnuPGUserStore } from 'Stores/User/GnuPG'; import { OpenPGPUserStore } from 'Stores/User/OpenPGP'; +import { MailvelopeUserStore } from 'Stores/User/Mailvelope'; import Remote from 'Remote/User/Fetch'; -// https://mailvelope.github.io/mailvelope/Keyring.html -let mailvelopeKeyring = null; - export const BEGIN_PGP_MESSAGE = '-----BEGIN PGP MESSAGE-----', // BEGIN_PGP_SIGNATURE = '-----BEGIN PGP SIGNATURE-----', @@ -37,32 +35,9 @@ export const } loadKeyrings(identifier) { - identifier = identifier || SettingsGet('Email'); - if (window.mailvelope) { - const fn = keyring => { - mailvelopeKeyring = keyring; - console.log('mailvelope ready'); - }; - mailvelope.getKeyring().then(fn, err => { - if (identifier) { - // attempt to create a new keyring for this app/user - mailvelope.createKeyring(identifier).then(fn, err => console.error(err)); - } else { - console.error(err); - } - }); - addEventListener('mailvelope-disconnect', event => { - alert('Mailvelope is updated to version ' + event.detail.version + '. Reload page'); - }, false); - } else { - addEventListener('mailvelope', () => this.loadKeyrings(identifier)); - } - + MailvelopeUserStore.loadKeyring(identifier); OpenPGPUserStore.loadKeyrings(); - - if (SettingsCapa('GnuPG')) { - GnuPGUserStore.loadKeyrings(); - } + GnuPGUserStore.loadKeyrings(); } /** @@ -92,22 +67,14 @@ export const } ); } - OpenPGPUserStore.isSupported() && OpenPGPUserStore.importKey(key); - } - - async mailvelopeHasPublicKeyForEmails(recipients) { - const - mailvelope = mailvelopeKeyring && await mailvelopeKeyring.validKeyForAddress(recipients) - /*.then(LookupResult => Object.entries(LookupResult))*/, - entries = mailvelope && Object.entries(mailvelope); - return entries && entries.filter(value => value[1]).length === recipients.length; + OpenPGPUserStore.importKey(key); } /** * Checks if verifying/encrypting a message is possible with given email addresses. * Returns the first library that can. */ - async hasPublicKeyForEmails(recipients) { + hasPublicKeyForEmails(recipients) { if (recipients.length) { if (GnuPGUserStore.hasPublicKeyForEmails(recipients)) { return 'gnupg'; @@ -119,40 +86,15 @@ export const return false; } - async getMailvelopePrivateKeyFor(email/*, sign*/) { - if (mailvelopeKeyring && await mailvelopeKeyring.hasPrivateKey({email:email})) { - return ['mailvelope', email]; - } - return false; - } - - /** - * Checks if signing a message is possible with given email address. - * Returns the first library that can. - */ - async getKeyForSigning(email) { - let key = OpenPGPUserStore.getPrivateKeyFor(email, 1); - if (key) { - return ['openpgp', key]; - } - - key = GnuPGUserStore.getPrivateKeyFor(email, 1); - if (key) { - return ['gnupg', key]; - } - - // return await this.getMailvelopePrivateKeyFor(email, 1); - } - async decrypt(message) { - const sender = message.from[0].email, - armoredText = message.plain(); + const armoredText = message.plain(); if (!this.isEncrypted(armoredText)) { throw Error('Not armored text'); } // Try OpenPGP.js if (OpenPGPUserStore.isSupported()) { + const sender = message.from[0].email; let result = await OpenPGPUserStore.decrypt(armoredText, sender); if (result) { return result; @@ -160,52 +102,9 @@ export const } // Try Mailvelope (does not support inline images) - if (mailvelopeKeyring) { - try { - let emails = [...message.from,...message.to,...message.cc].validUnique(), - i = emails.length; - while (i--) { - if (await this.getMailvelopePrivateKeyFor(emails[i].email)) { - /** - * https://mailvelope.github.io/mailvelope/Mailvelope.html#createEncryptedFormContainer - * Creates an iframe to display an encrypted form - */ - // mailvelope.createEncryptedFormContainer('#mailvelope-form'); - /** - * https://mailvelope.github.io/mailvelope/Mailvelope.html#createDisplayContainer - * Creates an iframe to display the decrypted content of the encrypted mail. - */ - const body = message.body; - body.textContent = ''; - let result = await mailvelope.createDisplayContainer( - '#'+body.id, - armoredText, - mailvelopeKeyring, - { - senderAddress: sender - // emails[i].email - } - ); - if (result) { - if (result.error?.message) { - if ('PWD_DIALOG_CANCEL' !== result.error.code) { - alert(result.error.code + ': ' + result.error.message); - } - } else { - body.classList.add('mailvelope'); - return true; - } - } - break; - } - } - } catch (err) { - console.error(err); - } - } - - // Now try GnuPG - return GnuPGUserStore.decrypt(message); + return (await MailvelopeUserStore.decrypt(message)) + // Or try GnuPG + || GnuPGUserStore.decrypt(message); } async verify(message) { @@ -248,35 +147,4 @@ export const } return false; } - - /** - * Returns headers that should be added to an outgoing email. - * So far this is only the autocrypt header. - */ - /* - mailvelopeKeyring.additionalHeadersForOutgoingEmail(from: 'abc@web.de') - .then(function(additional) { - console.log('additionalHeadersForOutgoingEmail', additional); - // logs: {autocrypt: "addr=abc@web.de; prefer-encrypt=mutual; keydata=..."} - }); - - mailvelopeKeyring.addSyncHandler(syncHandlerObj) - mailvelopeKeyring.createKeyBackupContainer(selector, options) - mailvelopeKeyring.createKeyGenContainer(selector, { - // userIds: [], - keySize: 4096 - }) - - mailvelopeKeyring.exportOwnPublicKey(emailAddr).then() - mailvelopeKeyring.importPublicKey(armored) - - // https://mailvelope.github.io/mailvelope/global.html#SyncHandlerObject - mailvelopeKeyring.addSyncHandler({ - uploadSync - downloadSync - backup - restore - }); - */ - }; diff --git a/dev/View/Popup/Compose.js b/dev/View/Popup/Compose.js index d5b5de78c..e0eee9391 100644 --- a/dev/View/Popup/Compose.js +++ b/dev/View/Popup/Compose.js @@ -32,6 +32,7 @@ import { FolderUserStore } from 'Stores/User/Folder'; import { PgpUserStore } from 'Stores/User/Pgp'; import { OpenPGPUserStore } from 'Stores/User/OpenPGP'; import { GnuPGUserStore } from 'Stores/User/GnuPG'; +import { MailvelopeUserStore } from 'Stores/User/Mailvelope'; //import { OpenPgpImportPopupView } from 'View/Popup/OpenPgpImport'; import { SMimeUserStore } from 'Stores/User/SMime'; import { Passphrases } from 'Storage/Passphrases'; @@ -255,13 +256,6 @@ export class ComposePopupView extends AbstractViewPopup { doSign: false, doEncrypt: false, - pgpSignKey: false, - canPgpEncrypt: false, - canMailvelope: false, - - canSMimeSign: false, - canSMimeEncrypt: false, - draftsFolder: '', draftUid: 0, sending: false, @@ -284,6 +278,8 @@ export class ComposePopupView extends AbstractViewPopup { }); this.attachments = koArrayWithDestroy(); + this.encryptOptions = koArrayWithDestroy(); + this.signOptions = koArrayWithDestroy(); this.dragAndDropOver = ko.observable(false).extend({ debounce: 1 }); this.dragAndDropVisible = ko.observable(false).extend({ debounce: 1 }); @@ -336,11 +332,9 @@ export class ComposePopupView extends AbstractViewPopup { attachmentsInProcessCount: () => this.attachmentsInProcess.length, isDraft: () => this.draftsFolder() && this.draftUid(), - canSign: () => { - let s = this.canSMimeSign(); - return this.pgpSignKey() || s; - }, - canEncrypt: () => this.canPgpEncrypt() | this.canSMimeEncrypt(), + canEncrypt: () => this.encryptOptions().length, + canMailvelope: () => this.encryptOptions.includes('Mailvelope'), + canSign: () => this.signOptions().length, identitiesOptions: () => IdentityUserStore.map(item => ({ @@ -361,24 +355,14 @@ export class ComposePopupView extends AbstractViewPopup { currentIdentity: value => { if (value) { - const smime = !!(value.smimeKey() && value.smimeCertificate()); this.from(value.formattedName()); this.doEncrypt(value.pgpEncrypt()/* || SettingsUserStore.pgpEncrypt()*/); - this.doSign(smime || value.pgpSign()/* || SettingsUserStore.pgpSign()*/); - this.canSMimeSign(smime); + this.doSign(value.pgpSign()/* || SettingsUserStore.pgpSign()*/); } }, - from: value => { - this.pgpSignKey(false); - value = getEmail(value); - value && PgpUserStore.getKeyForSigning(value).then(result => { - console.log({ - email: value, - pgpSignKey:result - }); - this.pgpSignKey(result) - }); + from: () => { + this.initSign(); this.initEncrypt(); }, @@ -1381,29 +1365,57 @@ export class ComposePopupView extends AbstractViewPopup { ].join(',').split(',').map(value => getEmail(value.trim())).validUnique(); } - initEncrypt() { - const recipients = this.allRecipients(); - PgpUserStore.hasPublicKeyForEmails(recipients).then(result => { - console.log({canPgpEncrypt:result}); - this.canPgpEncrypt(result); - }); - PgpUserStore.mailvelopeHasPublicKeyForEmails(recipients).then(result => { - console.log({canMailvelope:result}); - this.canMailvelope(result); - if (!result) { - 'mailvelope' === this.viewArea() && this.bodyArea(); -// this.dropMailvelope(); - } - }); - const count = recipients.length, + /** + * Checks if signing a message is possible with from email address. + * And sets all that can. + */ + initSign() { + let options = [], identity = this.currentIdentity(), - from = (identity.smimeKey() && identity.smimeCertificate()) ? identity.email() : null, - length = count ? recipients.filter(email => - email == from - || SMimeUserStore.find(certificate => email == certificate.emailAddress && certificate.smimeencrypt) - ).length : 0; - this.canSMimeEncrypt(length && length === count); - console.log({canSMimeEncrypt:this.canSMimeEncrypt()}); + email = getEmail(this.from()), + key = OpenPGPUserStore.getPrivateKeyFor(email, 1); + key && options.push(['OpenPGP', key]); + key = GnuPGUserStore.getPrivateKeyFor(email, 1); + key && options.push(['GnuPG', key]); + identity.smimeKey() && identity.smimeCertificate() && identity.email() === email + && options.push(['S/MIME']); + console.dir({signOptions: options}); + this.signOptions(options); + } + + initEncrypt() { + const recipients = this.allRecipients(), + options = []; + + if (recipients.length) { + GnuPGUserStore.hasPublicKeyForEmails(recipients) + && options.push('GnuPG'); + + OpenPGPUserStore.hasPublicKeyForEmails(recipients) + && options.push('OpenPGP'); + + MailvelopeUserStore.hasPublicKeyForEmails(recipients).then(result => { + if (result) { + options.push('Mailvelope'); + } else { + 'mailvelope' === this.viewArea() && this.bodyArea(); + // this.dropMailvelope(); + } + }); + + const count = recipients.length, + identity = this.currentIdentity(), + from = (identity.smimeKey() && identity.smimeCertificate()) ? identity.email() : null; + count + && count === recipients.filter(email => + email == from + || SMimeUserStore.find(certificate => email == certificate.emailAddress && certificate.smimeencrypt) + ).length + && options.push('S/MIME'); + } + + console.dir({encryptOptions:options}); + this.encryptOptions(options); } async getMessageRequestParams(sSaveFolder, draft) @@ -1464,8 +1476,8 @@ export class ComposePopupView extends AbstractViewPopup { linkedData: [] }, recipients = draft ? [identity.email()] : this.allRecipients(), - sign = !draft && this.doSign() && (this.pgpSignKey() || this.canSMimeSign()), - encrypt = this.doEncrypt() && (this.canPgpEncrypt() || this.canSMimeEncrypt()), + signOptions = !draft && this.doSign() && this.signOptions(), + encryptOptions = this.doEncrypt() && this.encryptOptions(), isHtml = this.oEditor.isHtml(); if (isHtml) { @@ -1492,7 +1504,7 @@ export class ComposePopupView extends AbstractViewPopup { params.autocrypt.push({addr:k, keydata:v.replace(/-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----/g).trim()}) ); */ - } else if (sign || encrypt) { + } else if (signOptions.length || encryptOptions.length) { if (!draft && !hasAttachments && !Text.length) { throw i18n('COMPOSE/ERROR_EMPTY_BODY'); } @@ -1512,9 +1524,10 @@ export class ComposePopupView extends AbstractViewPopup { alternative.children.push(data); data = alternative; } - if (sign) { - if (sign?.[1]) { - if ('openpgp' == sign[0]) { + let sign = true; + 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; @@ -1525,34 +1538,53 @@ export class ComposePopupView extends AbstractViewPopup { let signature = new MimePart; signature.headers['Content-Type'] = 'application/pgp-signature; name="signature.asc"'; signature.headers['Content-Transfer-Encoding'] = '7Bit'; - signature.body = await OpenPGPUserStore.sign(data.toString(), sign[1], 1); + signature.body = await OpenPGPUserStore.sign(data.toString(), signOptions[i][1], 1); signed.children.push(signature); params.signed = signed.toString(); params.boundary = signed.boundary; data = signed; - } else if ('gnupg' == sign[0]) { - // TODO: sign in PHP fails - // params.signData = data.toString(); - params.signFingerprint = sign[1].fingerprint; - params.signPassphrase = await GnuPGUserStore.sign(sign[1]); - } else { - throw 'Signing with ' + sign[0] + ' not yet implemented'; + } catch (e) { + sign = false; + console.error(e); } - } else if (this.canSMimeSign()) { + break; + } + if ('GnuPG' == signOptions[i][0]) { + // TODO: sign in PHP fails + let pass = await GnuPGUserStore.sign(signOptions[i][1]); + if (null != pass) { +// params.signData = data.toString(); + params.signFingerprint = signOptions[i][1].fingerprint; + params.signPassphrase = pass; + } else { + sign = false; + } + break; + } + if ('S/MIME' == signOptions[i][0]) { + // TODO: sign in PHP fails params.signCertificate = identity.smimeCertificate(); params.signPrivateKey = identity.smimeKey(); if (identity.smimeKeyEncrypted()) { const pass = await Passphrases.ask( - params.signPrivateKey, + identity.smimeKey(), i18n('SMIME/PRIVATE_KEY_OF', {EMAIL: identity.email()}), 'CRYPTO/DECRYPT' ); - params.signPassphrase = pass?.password; -// pass && pass.remember && Passphrases.set(identity, pass.password); + if (null != pass) { + params.signPassphrase = pass.password; +// pass.remember && Passphrases.set(identity, pass.password); + } else { + sign = false; + } } } } - if (encrypt) { + if (signOptions.length && !sign) { + throw 'Signing failed'; + } + + if (encryptOptions.length) { const autocrypt = () => Object.entries(PgpUserStore.getPublicKeyOfEmails(recipients) || {}).forEach(([k,v]) => params.autocrypt.push({ @@ -1560,24 +1592,30 @@ export class ComposePopupView extends AbstractViewPopup { keydata: v.replace(/-----(BEGIN|END) PGP PUBLIC KEY BLOCK-----/g, '').trim() }) ); - if ('openpgp' == encrypt) { - // Doesn't encrypt attachments - params.encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients); - params.signed = ''; - autocrypt(); - } else if ('gnupg' == encrypt) { - // Does encrypt attachments - params.encryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients)); - autocrypt(); - } else if (this.canSMimeEncrypt() && identity && identity.smimeKey() && identity.smimeCertificate()) { - params.encryptCertificates = [identity.smimeCertificate()]; - SMimeUserStore.forEach(certificate => { - certificate.emailAddress != identity.email() - && recipients.includes(certificate.emailAddress) - && params.encryptCertificates.push(certificate.id) - }); - } else { - throw 'Encryption with ' + encrypt + ' not yet implemented'; + for (let i = 0; i < encryptOptions.length; ++i) { + if ('OpenPGP' == encryptOptions[i]) { + // Doesn't encrypt attachments + params.encrypted = await OpenPGPUserStore.encrypt(data.toString(), recipients); + params.signed = ''; + autocrypt(); + break; + } + if ('GnuPG' == encryptOptions[i]) { + // Does encrypt attachments + params.encryptFingerprints = JSON.stringify(GnuPGUserStore.getPublicKeyFingerprints(recipients)); + autocrypt(); + break; + } + if ('S/MIME' == encryptOptions[i]) { + params.encryptCertificates = [identity.smimeCertificate()]; + SMimeUserStore.forEach(certificate => { + certificate.emailAddress != identity.email() + && recipients.includes(certificate.emailAddress) + && params.encryptCertificates.push(certificate.id) + }); + break; + } + // We skip Mailvelope as it has its own window } } } diff --git a/dev/View/Popup/SMimeImport.js b/dev/View/Popup/SMimeImport.js new file mode 100644 index 000000000..7ebf721f9 --- /dev/null +++ b/dev/View/Popup/SMimeImport.js @@ -0,0 +1,50 @@ +import { addObservablesTo } from 'External/ko'; +import { getNotification } from 'Common/Translator'; + +import { AbstractViewPopup } from 'Knoin/AbstractViews'; + +import Remote from 'Remote/User/Fetch'; + +export class SMimeImportPopupView extends AbstractViewPopup { + constructor() { + super('SMimeImport'); + + addObservablesTo(this, { + pem: '', + pemError: false, + pemErrorMessage: '', + pemValid: false + }); + + this.pem.subscribe(value => { + this.pemError(false); + this.pemErrorMessage(''); + this.pemValid(value && value.includes('-----BEGIN CERTIFICATE-----')); + }); + } + + submitForm() { + if (this.pemValid()) { + Remote.request('SMimeImportCertificate', + (iError, oData) => { + if (iError) { + this.pemError(true); + this.pemErrorMessage(getNotification(iError, oData?.ErrorMessage)); +// oData?.ErrorMessageAdditional; + } else { + this.close(); + } + }, + {pem:this.pem()} + ); + } else { + this.pemError(true); + } + } + + onShow() { + this.pem(''); + this.pemError(false); + this.pemErrorMessage(''); + } +} diff --git a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php index d5d1437b4..5aed83217 100644 --- a/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php +++ b/snappymail/v/0.0.0/app/libraries/RainLoop/Actions/SMime.php @@ -173,6 +173,15 @@ trait SMime return $this->DefaultResponse($result); } + public function DoSMimeImportCertificate() : array + { + return $this->DefaultResponse( + $this->SMIME()->storeCertificate( + $this->GetActionParam('pem', '') + ) + ); + } + public function DoSMimeImportCertificatesFromMessage() : array { /* diff --git a/snappymail/v/0.0.0/app/localization/ar-SA/user.json b/snappymail/v/0.0.0/app/localization/ar-SA/user.json index 4aed9b45f..a5b5c6c44 100644 --- a/snappymail/v/0.0.0/app/localization/ar-SA/user.json +++ b/snappymail/v/0.0.0/app/localization/ar-SA/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME signed message", "ENCRYPTED_MESSAGE": "S\/MIME encrypted message", diff --git a/snappymail/v/0.0.0/app/localization/bg-BG/user.json b/snappymail/v/0.0.0/app/localization/bg-BG/user.json index d43e119ad..553dc3d84 100644 --- a/snappymail/v/0.0.0/app/localization/bg-BG/user.json +++ b/snappymail/v/0.0.0/app/localization/bg-BG/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Подписано с S\/MIME", "ENCRYPTED_MESSAGE": "Шифровано с S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/cs-CZ/user.json b/snappymail/v/0.0.0/app/localization/cs-CZ/user.json index 57d449b7a..349c021d6 100644 --- a/snappymail/v/0.0.0/app/localization/cs-CZ/user.json +++ b/snappymail/v/0.0.0/app/localization/cs-CZ/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Zpráva podepsaná S\/MIME", "ENCRYPTED_MESSAGE": "Zpráva šifrovaná S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/da-DK/user.json b/snappymail/v/0.0.0/app/localization/da-DK/user.json index 0a2887de5..7f59e18c7 100644 --- a/snappymail/v/0.0.0/app/localization/da-DK/user.json +++ b/snappymail/v/0.0.0/app/localization/da-DK/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME signeret meddelelse", "ENCRYPTED_MESSAGE": "S\/MIME krypteret meddelelse", diff --git a/snappymail/v/0.0.0/app/localization/de-DE/user.json b/snappymail/v/0.0.0/app/localization/de-DE/user.json index 49f560744..a9b9675fc 100644 --- a/snappymail/v/0.0.0/app/localization/de-DE/user.json +++ b/snappymail/v/0.0.0/app/localization/de-DE/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME-signierte Nachricht", "ENCRYPTED_MESSAGE": "S\/MIME-verschlüsselte Nachricht", diff --git a/snappymail/v/0.0.0/app/localization/el-GR/user.json b/snappymail/v/0.0.0/app/localization/el-GR/user.json index 0339d0672..a356d916c 100644 --- a/snappymail/v/0.0.0/app/localization/el-GR/user.json +++ b/snappymail/v/0.0.0/app/localization/el-GR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Μήνυμα υπογεγραμμένο με S\/MIME", "ENCRYPTED_MESSAGE": "Μήνυμα κωδικοποιημένο με S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/en-GB/user.json b/snappymail/v/0.0.0/app/localization/en-GB/user.json index 533853e27..a45ee06a5 100644 --- a/snappymail/v/0.0.0/app/localization/en-GB/user.json +++ b/snappymail/v/0.0.0/app/localization/en-GB/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME signed message", "ENCRYPTED_MESSAGE": "S\/MIME encrypted message", diff --git a/snappymail/v/0.0.0/app/localization/en/user.json b/snappymail/v/0.0.0/app/localization/en/user.json index 650c51006..c4013b6cd 100644 --- a/snappymail/v/0.0.0/app/localization/en/user.json +++ b/snappymail/v/0.0.0/app/localization/en/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S/MIME certificate", "CERTIFICATES": "S/MIME Certificates", "SIGNED_MESSAGE": "S/MIME signed message", "ENCRYPTED_MESSAGE": "S/MIME encrypted message", diff --git a/snappymail/v/0.0.0/app/localization/es-ES/user.json b/snappymail/v/0.0.0/app/localization/es-ES/user.json index d27e0325c..bbf3c8512 100644 --- a/snappymail/v/0.0.0/app/localization/es-ES/user.json +++ b/snappymail/v/0.0.0/app/localization/es-ES/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Mensaje firmado mediante S\/MIME", "ENCRYPTED_MESSAGE": "Mensaje cifrado mediante S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/et-EE/user.json b/snappymail/v/0.0.0/app/localization/et-EE/user.json index fce18d98d..d62282c68 100644 --- a/snappymail/v/0.0.0/app/localization/et-EE/user.json +++ b/snappymail/v/0.0.0/app/localization/et-EE/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME abil signeeritud kiri", "ENCRYPTED_MESSAGE": "S\/MIME abil krüpteeritud kiri", diff --git a/snappymail/v/0.0.0/app/localization/eu/user.json b/snappymail/v/0.0.0/app/localization/eu/user.json index 25261ae8a..a86fcfbc5 100644 --- a/snappymail/v/0.0.0/app/localization/eu/user.json +++ b/snappymail/v/0.0.0/app/localization/eu/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME sinatutako mezua", "ENCRYPTED_MESSAGE": "S\/MIME zifratutako mezua", diff --git a/snappymail/v/0.0.0/app/localization/fa-IR/user.json b/snappymail/v/0.0.0/app/localization/fa-IR/user.json index 5e397af55..39ae02b55 100644 --- a/snappymail/v/0.0.0/app/localization/fa-IR/user.json +++ b/snappymail/v/0.0.0/app/localization/fa-IR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "پیام توسط S\/MIME امضاء شد", "ENCRYPTED_MESSAGE": "پیام توسط S\/MIME رمزنگاری شد", diff --git a/snappymail/v/0.0.0/app/localization/fi-FI/user.json b/snappymail/v/0.0.0/app/localization/fi-FI/user.json index c709c9abf..3218d34d4 100644 --- a/snappymail/v/0.0.0/app/localization/fi-FI/user.json +++ b/snappymail/v/0.0.0/app/localization/fi-FI/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME allekirjoitettu viesti", "ENCRYPTED_MESSAGE": "S\/MIME salattu visti", diff --git a/snappymail/v/0.0.0/app/localization/fr-FR/user.json b/snappymail/v/0.0.0/app/localization/fr-FR/user.json index 035c53052..192e71452 100644 --- a/snappymail/v/0.0.0/app/localization/fr-FR/user.json +++ b/snappymail/v/0.0.0/app/localization/fr-FR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Message signé par S\/MIME", "ENCRYPTED_MESSAGE": "Message chiffré par S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/hu-HU/user.json b/snappymail/v/0.0.0/app/localization/hu-HU/user.json index 63d7aaa0b..05e81b2ba 100644 --- a/snappymail/v/0.0.0/app/localization/hu-HU/user.json +++ b/snappymail/v/0.0.0/app/localization/hu-HU/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME aláírt üzenet", "ENCRYPTED_MESSAGE": "S\/MIME kódolt üzenet", diff --git a/snappymail/v/0.0.0/app/localization/id-ID/user.json b/snappymail/v/0.0.0/app/localization/id-ID/user.json index 744c70033..3a53d77c5 100644 --- a/snappymail/v/0.0.0/app/localization/id-ID/user.json +++ b/snappymail/v/0.0.0/app/localization/id-ID/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Pesan bertanda-tangan S\/MIME", "ENCRYPTED_MESSAGE": "Pesan terenkripsi S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/is-IS/user.json b/snappymail/v/0.0.0/app/localization/is-IS/user.json index fee5de7fa..dab352ccc 100644 --- a/snappymail/v/0.0.0/app/localization/is-IS/user.json +++ b/snappymail/v/0.0.0/app/localization/is-IS/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Skeyti undirritað með S\/MIME", "ENCRYPTED_MESSAGE": "Skeyti dulritað með S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/it-IT/user.json b/snappymail/v/0.0.0/app/localization/it-IT/user.json index cfab3b291..85454dbf7 100644 --- a/snappymail/v/0.0.0/app/localization/it-IT/user.json +++ b/snappymail/v/0.0.0/app/localization/it-IT/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Messaggio firmato con S\/MIME", "ENCRYPTED_MESSAGE": "Messaggio cifrato con S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/ja-JP/user.json b/snappymail/v/0.0.0/app/localization/ja-JP/user.json index e050683cd..d9d3ca459 100644 --- a/snappymail/v/0.0.0/app/localization/ja-JP/user.json +++ b/snappymail/v/0.0.0/app/localization/ja-JP/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME署名済みメッセージ", "ENCRYPTED_MESSAGE": "S\/MIME暗号化メッセージ", diff --git a/snappymail/v/0.0.0/app/localization/ko-KR/user.json b/snappymail/v/0.0.0/app/localization/ko-KR/user.json index b4e0cf497..21ec495a4 100644 --- a/snappymail/v/0.0.0/app/localization/ko-KR/user.json +++ b/snappymail/v/0.0.0/app/localization/ko-KR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME로 서명된 메세지입니다.", "ENCRYPTED_MESSAGE": "S\/MIME로 암호화된 메세지입니다.", diff --git a/snappymail/v/0.0.0/app/localization/lt-LT/user.json b/snappymail/v/0.0.0/app/localization/lt-LT/user.json index 9675c674b..131f0ff17 100644 --- a/snappymail/v/0.0.0/app/localization/lt-LT/user.json +++ b/snappymail/v/0.0.0/app/localization/lt-LT/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME pasirašytas pranešimas", "ENCRYPTED_MESSAGE": "S\/MIME šifruotas pranešimas", diff --git a/snappymail/v/0.0.0/app/localization/lv-LV/user.json b/snappymail/v/0.0.0/app/localization/lv-LV/user.json index 0ca93a400..457f236dd 100644 --- a/snappymail/v/0.0.0/app/localization/lv-LV/user.json +++ b/snappymail/v/0.0.0/app/localization/lv-LV/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME signed message", "ENCRYPTED_MESSAGE": "S\/MIME encrypted message", diff --git a/snappymail/v/0.0.0/app/localization/nb-NO/user.json b/snappymail/v/0.0.0/app/localization/nb-NO/user.json index dd3b2fee3..7c0edcc20 100644 --- a/snappymail/v/0.0.0/app/localization/nb-NO/user.json +++ b/snappymail/v/0.0.0/app/localization/nb-NO/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME-signert melding", "ENCRYPTED_MESSAGE": "S\/MIME-kryptert melding", diff --git a/snappymail/v/0.0.0/app/localization/nl-NL/user.json b/snappymail/v/0.0.0/app/localization/nl-NL/user.json index f2a211bd9..fb4f0bf2f 100644 --- a/snappymail/v/0.0.0/app/localization/nl-NL/user.json +++ b/snappymail/v/0.0.0/app/localization/nl-NL/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Maak een back-up van de privésleutel op de server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Importeer S\/MIME certificaat", "CERTIFICATES": "S\/MIME Certificaten", "SIGNED_MESSAGE": "S\/MIME ondertekend bericht", "ENCRYPTED_MESSAGE": "S\/MIME versleuteld bericht", diff --git a/snappymail/v/0.0.0/app/localization/pl-PL/user.json b/snappymail/v/0.0.0/app/localization/pl-PL/user.json index 68e0a956c..65d6d9809 100644 --- a/snappymail/v/0.0.0/app/localization/pl-PL/user.json +++ b/snappymail/v/0.0.0/app/localization/pl-PL/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Utwórz kopię zapasową klucza prywatnego na serwerze" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Wiadomość podpisana S\/MIME", "ENCRYPTED_MESSAGE": "Wiadomość zaszyfrowana S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/pt-BR/user.json b/snappymail/v/0.0.0/app/localization/pt-BR/user.json index 4e5a61090..b043e1de0 100644 --- a/snappymail/v/0.0.0/app/localization/pt-BR/user.json +++ b/snappymail/v/0.0.0/app/localization/pt-BR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Mensagem assinada com S\/MIME", "ENCRYPTED_MESSAGE": "Mensagem criptografada com S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/pt-PT/user.json b/snappymail/v/0.0.0/app/localization/pt-PT/user.json index e0d1465d3..11b2854d2 100644 --- a/snappymail/v/0.0.0/app/localization/pt-PT/user.json +++ b/snappymail/v/0.0.0/app/localization/pt-PT/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Mensagem assinada com S\/MIME", "ENCRYPTED_MESSAGE": "Mensagem encriptada com S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/pt/user.json b/snappymail/v/0.0.0/app/localization/pt/user.json index e0d1465d3..11b2854d2 100644 --- a/snappymail/v/0.0.0/app/localization/pt/user.json +++ b/snappymail/v/0.0.0/app/localization/pt/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Mensagem assinada com S\/MIME", "ENCRYPTED_MESSAGE": "Mensagem encriptada com S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/ro-RO/user.json b/snappymail/v/0.0.0/app/localization/ro-RO/user.json index 71d0dd768..3b804924a 100644 --- a/snappymail/v/0.0.0/app/localization/ro-RO/user.json +++ b/snappymail/v/0.0.0/app/localization/ro-RO/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME signed message", "ENCRYPTED_MESSAGE": "S\/MIME encrypted message", diff --git a/snappymail/v/0.0.0/app/localization/ru-RU/user.json b/snappymail/v/0.0.0/app/localization/ru-RU/user.json index a32b18735..c306d7226 100644 --- a/snappymail/v/0.0.0/app/localization/ru-RU/user.json +++ b/snappymail/v/0.0.0/app/localization/ru-RU/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME подписанное сообщение", "ENCRYPTED_MESSAGE": "S\/MIME шифрованное сообщение", diff --git a/snappymail/v/0.0.0/app/localization/sk-SK/user.json b/snappymail/v/0.0.0/app/localization/sk-SK/user.json index a7525cdb9..14edc1aab 100644 --- a/snappymail/v/0.0.0/app/localization/sk-SK/user.json +++ b/snappymail/v/0.0.0/app/localization/sk-SK/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Správa podpísaná s S\/MIME", "ENCRYPTED_MESSAGE": "Správa šifrovaná s S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/sl-SI/user.json b/snappymail/v/0.0.0/app/localization/sl-SI/user.json index 86c97df7d..a491aeb58 100644 --- a/snappymail/v/0.0.0/app/localization/sl-SI/user.json +++ b/snappymail/v/0.0.0/app/localization/sl-SI/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Sporočilo, podpisano z S\/MIME", "ENCRYPTED_MESSAGE": "Sporočilo, šifrirano z S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/sv-SE/user.json b/snappymail/v/0.0.0/app/localization/sv-SE/user.json index 45f14d86e..52941c9ed 100644 --- a/snappymail/v/0.0.0/app/localization/sv-SE/user.json +++ b/snappymail/v/0.0.0/app/localization/sv-SE/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME-signerat meddelande", "ENCRYPTED_MESSAGE": "S\/MIME-krypterat meddelande", diff --git a/snappymail/v/0.0.0/app/localization/tr-TR/user.json b/snappymail/v/0.0.0/app/localization/tr-TR/user.json index e268ff335..93e7c1e88 100644 --- a/snappymail/v/0.0.0/app/localization/tr-TR/user.json +++ b/snappymail/v/0.0.0/app/localization/tr-TR/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME imzalı mesaj", "ENCRYPTED_MESSAGE": "S\/MIME şifreli mesaj", diff --git a/snappymail/v/0.0.0/app/localization/uk-UA/user.json b/snappymail/v/0.0.0/app/localization/uk-UA/user.json index 1f0dd8d6c..a7bd28f5b 100644 --- a/snappymail/v/0.0.0/app/localization/uk-UA/user.json +++ b/snappymail/v/0.0.0/app/localization/uk-UA/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "S\/MIME підписане повідомлення", "ENCRYPTED_MESSAGE": "S\/MIME шифроване повідомлення", diff --git a/snappymail/v/0.0.0/app/localization/vi-VN/user.json b/snappymail/v/0.0.0/app/localization/vi-VN/user.json index 00628cedd..dd617e949 100644 --- a/snappymail/v/0.0.0/app/localization/vi-VN/user.json +++ b/snappymail/v/0.0.0/app/localization/vi-VN/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "Thư đã được ký xác nhận bằng mã S\/MIME", "ENCRYPTED_MESSAGE": "Thư đã được mã hóa bởi S\/MIME", diff --git a/snappymail/v/0.0.0/app/localization/zh-CN/user.json b/snappymail/v/0.0.0/app/localization/zh-CN/user.json index 1099eece5..325c7e3b5 100644 --- a/snappymail/v/0.0.0/app/localization/zh-CN/user.json +++ b/snappymail/v/0.0.0/app/localization/zh-CN/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "由 S\/MIME 签名", "ENCRYPTED_MESSAGE": "由 S\/MIME 加密", diff --git a/snappymail/v/0.0.0/app/localization/zh-TW/user.json b/snappymail/v/0.0.0/app/localization/zh-TW/user.json index 6849d86dd..54a15fdee 100644 --- a/snappymail/v/0.0.0/app/localization/zh-TW/user.json +++ b/snappymail/v/0.0.0/app/localization/zh-TW/user.json @@ -302,6 +302,7 @@ "BACKUP_PRIVATE_KEY_ON_SERVER": "Backup private key on server" }, "SMIME": { + "POPUP_IMPORT_TITLE": "Import S\/MIME certificate", "CERTIFICATES": "S\/MIME Certificates", "SIGNED_MESSAGE": "已透過 S\/MIME 簽署郵件", "ENCRYPTED_MESSAGE": "已透過 S\/MIME 加密郵件", diff --git a/snappymail/v/0.0.0/app/templates/Views/User/PopupsSMimeImport.html b/snappymail/v/0.0.0/app/templates/Views/User/PopupsSMimeImport.html new file mode 100644 index 000000000..c7a80814c --- /dev/null +++ b/snappymail/v/0.0.0/app/templates/Views/User/PopupsSMimeImport.html @@ -0,0 +1,13 @@ +
+ × +

+
+ +
+ +
diff --git a/snappymail/v/0.0.0/app/templates/Views/User/SettingsSecurity.html b/snappymail/v/0.0.0/app/templates/Views/User/SettingsSecurity.html index e37e36b4a..68c12379f 100644 --- a/snappymail/v/0.0.0/app/templates/Views/User/SettingsSecurity.html +++ b/snappymail/v/0.0.0/app/templates/Views/User/SettingsSecurity.html @@ -125,6 +125,8 @@
+ +