import { SettingsCapa, SettingsGet } from 'Common/Globals'; //import { staticLink } from 'Common/Links'; //import { showScreenPopup } from 'Knoin/Knoin'; //import { EmailModel } from 'Model/Email'; //import { OpenPgpKeyModel } from 'Model/OpenPgpKey'; import { GnuPGUserStore } from 'Stores/User/GnuPG'; import { OpenPGPUserStore } from 'Stores/User/OpenPGP'; import { MailvelopeUserStore } from 'Stores/User/Mailvelope'; import Remote from 'Remote/User/Fetch'; export const BEGIN_PGP_MESSAGE = '-----BEGIN PGP MESSAGE-----', // BEGIN_PGP_SIGNATURE = '-----BEGIN PGP SIGNATURE-----', // BEGIN_PGP_SIGNED = '-----BEGIN PGP SIGNED MESSAGE-----', // BEGIN_PGP_PUBLIC_KEY = '-----BEGIN PGP PUBLIC KEY BLOCK-----', // END_PGP_PUBLIC_KEY = '-----END PGP PUBLIC KEY BLOCK-----', PgpUserStore = new class { init() { if (SettingsCapa('OpenPGP') && window.crypto && crypto.getRandomValues) { rl.loadScript(SettingsGet('StaticLibsJs').replace('/libs.', '/openpgp.')) // rl.loadScript(staticLink('js/min/openpgp.min.js')) .then(() => this.loadKeyrings()) .catch(e => { this.loadKeyrings(); console.error(e); }); } else { this.loadKeyrings(); } } loadKeyrings(identifier) { MailvelopeUserStore.loadKeyring(identifier); OpenPGPUserStore.loadKeyrings(); GnuPGUserStore.loadKeyrings(); } /** * @returns {boolean} */ isSupported() { return !!(OpenPGPUserStore.isSupported() || GnuPGUserStore.isSupported() || window.mailvelope); } /** * @returns {boolean} */ isEncrypted(text) { return 0 === text.trim().indexOf(BEGIN_PGP_MESSAGE); } importKey(key, gnuPG, backup) { if (gnuPG || backup) { Remote.request('PgpImportKey', (iError, oData) => { if (gnuPG && oData?.Result/* && (oData.Result.imported || oData.Result.secretimported)*/) { GnuPGUserStore.loadKeyrings(); } iError && alert(oData.message); }, { key, gnuPG, backup } ); } OpenPGPUserStore.importKey(key); } /** * Checks if verifying/encrypting a message is possible with given email addresses. * Returns the first library that can. */ hasPublicKeyForEmails(recipients) { if (recipients.length) { if (GnuPGUserStore.hasPublicKeyForEmails(recipients)) { return 'gnupg'; } if (OpenPGPUserStore.hasPublicKeyForEmails(recipients)) { return 'openpgp'; } } return false; } async decrypt(message) { 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; } } // Try Mailvelope (does not support inline images) return (await MailvelopeUserStore.decrypt(message)) // Or try GnuPG || GnuPGUserStore.decrypt(message); } async verify(message) { const signed = message.pgpSigned(), sender = message.from[0].email; if (signed) { // OpenPGP only when inline, else we must download the whole message if (!signed.sigPartId && OpenPGPUserStore.hasPublicKeyForEmails([sender])) { return OpenPGPUserStore.verify(message); } if (GnuPGUserStore.hasPublicKeyForEmails([sender])) { return GnuPGUserStore.verify(message); } // Mailvelope can't // https://github.com/mailvelope/mailvelope/issues/434 } } getPublicKeyOfEmails(recipients) { if (recipients.length) { let result = {}; recipients.forEach(email => { OpenPGPUserStore.publicKeys().forEach(key => { if (key.for(email)) { result[email] = key.armor; } }); GnuPGUserStore.publicKeys.map(async key => { if (!result[email] && key.for(email)) { result[email] = await key.fetch(); } }); }); return result; } return false; } };