Many more changes for #89

This commit is contained in:
the-djmaze 2022-01-20 16:38:27 +01:00
parent 3cc3a76b23
commit a7eeeb4f55
18 changed files with 310 additions and 236 deletions

View file

@ -4,7 +4,7 @@
* @enum {string}
*/
export const Capa = {
GnuPGP: 'GNUGP',
GnuPG: 'GNUPG',
OpenPGP: 'OPEN_PGP',
Prefetch: 'PREFETCH',
Contacts: 'CONTACTS',

View file

@ -21,8 +21,9 @@ import { AbstractModel } from 'Knoin/AbstractModel';
import PreviewHTML from 'Html/PreviewMessage.html';
const
/*eslint-disable max-len*/
// eslint-disable-next-line max-len
url = /(^|[\s\n]|\/?>)(https:\/\/[-A-Z0-9+\u0026\u2019#/%?=()~_|!:,.;]*[-A-Z0-9+\u0026#/%=~()_|])/gi,
// eslint-disable-next-line max-len
email = /(^|[\s\n]|\/?>)((?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x21\x23-\x5b\x5d-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x21-\x5a\x53-\x7f]|\\[\x21\x23-\x5b\x5d-\x7f])+)\]))/gi,
// Removes background and color
@ -644,30 +645,4 @@ export class MessageModel extends AbstractModel {
].join(',');
}
pgpDecrypt() {
// const message = self.message();
// message && pgpClickHelper(message.body, message.plain(), message.getEmails(['from', 'to', 'cc']));
/*
pgpEncrypted: () => PgpUserStore.isSupported()
&& MessageUserStore.message() && MessageUserStore.message().isPgpEncrypted(),
*/
}
pgpVerify() {
let params = this.pgpSigned(); // { BodyPartId: "1", SigPartId: "2", MicAlg: "pgp-sha256" }
if (params) {
params.Folder = this.folder;
params.Uid = this.uid;
rl.app.Remote.post('MessagePgpVerify', null, params)
.then(data => {
// TODO
console.dir(data);
})
.catch(error => {
// TODO
console.dir(error);
});
}
}
}

View file

@ -5,20 +5,17 @@ import { AbstractModel } from 'Knoin/AbstractModel';
export class OpenPgpKeyModel extends AbstractModel {
/**
* @param {string} index
* @param {string} guID
* @param {string} ID
* @param {array} IDs
* @param {array} userIDs
* @param {array} emails
* @param {boolean} isPrivate
* @param {string} armor
* @param {string} userID
*/
constructor(index, guID, ID, IDs, userIDs, emails, isPrivate, armor, userID) {
constructor(guID, ID, IDs, userIDs, emails, armor, userID) {
super();
this.index = index;
this.id = ID;
this.ids = arrayLength(IDs) ? IDs : [ID];
this.guid = guID;
@ -27,7 +24,6 @@ export class OpenPgpKeyModel extends AbstractModel {
this.email = '';
this.emails = emails;
this.armor = armor;
this.isPrivate = !!isPrivate;
if (this.users) {
const index = this.users.indexOf(userID);

View file

@ -57,7 +57,7 @@ export class SettingsUserScreen extends AbstractSettingsScreen {
settingsAddViewModel(ThemesUserSettings, 'SettingsThemes', 'SETTINGS_LABELS/LABEL_THEMES_NAME', 'themes');
}
if (Settings.capa(Capa.OpenPGP) || Settings.capa(Capa.GnuPGP)) {
if (Settings.capa(Capa.OpenPGP) || Settings.capa(Capa.GnuPG)) {
settingsAddViewModel(OpenPgpUserSettings, 'SettingsOpenPGP', 'OpenPGP', 'openpgp');
}

View file

@ -1,7 +1,5 @@
import ko from 'ko';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import { PgpUserStore } from 'Stores/User/Pgp';
import { SettingsUserStore } from 'Stores/User/Settings';
@ -15,12 +13,15 @@ import { ViewOpenPgpKeyPopupView } from 'View/Popup/ViewOpenPgpKey';
export class OpenPgpUserSettings /*extends AbstractViewSettings*/ {
constructor() {
this.openpgpkeys = PgpUserStore.openpgpkeys;
this.openpgpkeysPublic = PgpUserStore.openpgpkeysPublic;
this.openpgpkeysPrivate = PgpUserStore.openpgpkeysPrivate;
this.gnupgkeys = PgpUserStore.gnupgKeys;
this.openpgpkeysPublic = PgpUserStore.openpgpPublicKeys;
this.openpgpkeysPrivate = PgpUserStore.openpgpPrivateKeys;
this.openPgpKeyForDeletion = ko.observable(null).deleteAccessHelper();
this.canOpenPGP = !!PgpUserStore.openpgpKeyring;
// this.canOpenPGP = Settings.capa(Capa.OpenPGP);
this.allowDraftAutosave = SettingsUserStore.allowDraftAutosave;
this.allowDraftAutosave.subscribe(value => Remote.saveSetting('AllowDraftAutosave', value ? 1 : 0))
@ -47,20 +48,7 @@ export class OpenPgpUserSettings /*extends AbstractViewSettings*/ {
deleteOpenPgpKey(openPgpKeyToRemove) {
if (openPgpKeyToRemove && openPgpKeyToRemove.deleteAccess()) {
this.openPgpKeyForDeletion(null);
if (openPgpKeyToRemove && PgpUserStore.openpgpKeyring) {
const findedItem = PgpUserStore.openpgpkeys.find(key => openPgpKeyToRemove === key);
if (findedItem) {
PgpUserStore.openpgpkeys.remove(findedItem);
delegateRunOnDestroy(findedItem);
PgpUserStore.openpgpKeyring[findedItem.isPrivate ? 'privateKeys' : 'publicKeys'].removeForId(findedItem.guid);
PgpUserStore.openpgpKeyring.store();
}
PgpUserStore.reloadOpenPgpKeys();
}
PgpUserStore.deleteKey(openPgpKeyToRemove);
}
}
}

View file

@ -3,7 +3,7 @@ import ko from 'ko';
import { Capa } from 'Common/Enums';
import { doc, createElement, Settings } from 'Common/Globals';
import { openPgpJs, openPgpWorkerJs } from 'Common/Links';
import { isArray, arrayLength, pString, addComputablesTo } from 'Common/Utils';
import { isArray, arrayLength } from 'Common/Utils';
import { delegateRunOnDestroy } from 'Common/UtilsUser';
import { showScreenPopup } from 'Knoin/Knoin';
@ -16,27 +16,25 @@ import { OpenPgpKeyModel } from 'Model/OpenPgpKey';
import Remote from 'Remote/User/Fetch';
const
findKeyByHex = (keys, hash, isPrivate) =>
keys.find(item => item && isPrivate == item.isPrivate && (hash === item.id || item.ids.includes(hash))),
findAllKeysByEmail = (keys, email, isPrivate) =>
keys.filter(item => item && isPrivate == item.isPrivate && item.emails.includes(email));
findKeyByHex = (keys, hash) =>
keys.find(item => item && (hash === item.id || item.ids.includes(hash)));
export const PgpUserStore = new class {
constructor() {
// PECL gnupg / PEAR Crypt_GPG
this.gnupgkeys;
/**
* PECL gnupg / PEAR Crypt_GPG
* [ {email, can_encrypt, can_sign}, ... ]
*/
this.gnupgKeyring;
this.gnupgKeys = ko.observableArray();
// OpenPGP.js
this.openpgpkeys = ko.observableArray();
this.openpgpKeyring = null;
this.openpgpPublicKeys = ko.observableArray();
this.openpgpPrivateKeys = ko.observableArray();
// https://mailvelope.github.io/mailvelope/Keyring.html
this.mailvelopeKeyring = null;
addComputablesTo(this, {
openpgpkeysPublic: () => this.openpgpkeys.filter(item => item && !item.isPrivate),
openpgpkeysPrivate: () => this.openpgpkeys.filter(item => item && item.isPrivate)
});
}
init() {
@ -88,12 +86,14 @@ export const PgpUserStore = new class {
this.reloadOpenPgpKeys();
}
if (Settings.capa(Capa.GnuPGP)) {
this.gnupgkeys = [];
Remote.request('GnupgGetKeysEmails',
if (Settings.capa(Capa.GnuPG)) {
this.gnupgKeyring = null;
this.gnupgKeys([]);
Remote.request('GnupgGetKeys',
(iError, oData) => {
if (oData.Result) {
this.gnupgkeys = oData.Result;
if (oData && oData.Result) {
this.gnupgKeyring = oData.Result;
this.gnupgKeys(Object.values(oData.Result));
console.log('gnupg ready');
}
}
@ -103,10 +103,11 @@ export const PgpUserStore = new class {
reloadOpenPgpKeys() {
if (this.openpgpKeyring) {
const keys = [],
const publicKeys = [],
privateKeys = [],
email = new EmailModel();
this.openpgpKeyring.getAllKeys().forEach((oItem, iIndex) => {
this.openpgpKeyring.getAllKeys().forEach(oItem => {
if (oItem && oItem.primaryKey) {
const aEmails = [],
aUsers = [],
@ -132,9 +133,8 @@ export const PgpUserStore = new class {
}
if (aEmails.length) {
keys.push(
(oItem.isPrivate() ? privateKeys : publicKeys).push(
new OpenPgpKeyModel(
iIndex,
oItem.primaryKey.getFingerprint(),
oItem.primaryKey
.getKeyId()
@ -154,8 +154,12 @@ export const PgpUserStore = new class {
}
});
delegateRunOnDestroy(this.openpgpkeys());
this.openpgpkeys(keys);
delegateRunOnDestroy(this.openpgpPublicKeys());
this.openpgpPublicKeys(publicKeys);
delegateRunOnDestroy(this.openpgpPrivateKeys());
this.openpgpPrivateKeys(privateKeys);
console.log('openpgp.js ready');
}
}
@ -167,48 +171,19 @@ export const PgpUserStore = new class {
return !!(window.openpgp || window.mailvelope);
}
findPublicKeyByHex(hash) {
return findKeyByHex(this.openpgpkeys, hash, 0);
}
findPrivateKeyByHex(hash) {
return findKeyByHex(this.openpgpkeys, hash, 1);
}
findPublicKeysByEmail(email) {
return this.openpgpkeysPublic().map(item => {
const key = item && item.emails.includes(email) ? item : null;
return key ? key.getNativeKeys() : [null];
}).flat().filter(v => v);
}
findPublicKeysBySigningKeyIds(signingKeyIds) {
return signingKeyIds.map(id => {
const key = id && id.toHex ? this.findPublicKeyByHex(id.toHex()) : null;
return key ? key.getNativeKeys() : [null];
}).flat().filter(v => v);
}
findPrivateKeysByEncryptionKeyIds(encryptionKeyIds, recipients, returnWrapKeys) {
let result = isArray(encryptionKeyIds)
? encryptionKeyIds.map(id => {
const key = id && id.toHex ? this.findPrivateKeyByHex(id.toHex()) : null;
return key ? (returnWrapKeys ? [key] : key.getNativeKeys()) : [null];
}).flat().filter(v => v)
: [];
if (!result.length && arrayLength(recipients)) {
result = recipients.map(sEmail => {
const keys = sEmail ? this.findAllPrivateKeysByEmailNotNative(sEmail) : null;
return keys
? returnWrapKeys
? keys
: keys.map(key => key.getNativeKeys()).flat()
: [null];
}).flat().validUnique(key => key.id);
gnupgImportKey(key, callback) {
if (Settings.capa(Capa.GnuPG)) {
Remote.request('GnupgImportKey',
(iError, oData) => {
if (oData && oData.Result) {
// this.gnupgKeyring = oData.Result;
}
callback && callback(iError, oData);
}, {
Key: key
}
);
}
return result;
}
/**
@ -216,45 +191,43 @@ export const PgpUserStore = new class {
* Returns the first library that can.
*/
async hasPublicKeyForEmails(recipients, all) {
const
count = recipients.length,
openpgp = count && this.openpgpkeys && recipients.filter(email =>
this.openpgpkeys.find(item => item && !item.isPrivate && item.emails.includes(email))
);
if (this.gnupgkeys) {
let length = recipients.filter(email => this.gnupgkeys[email] && this.gnupgkeys[email].can_encrypt).length;
const count = recipients.length;
if (count) {
let length = this.gnupgKeyring && recipients.filter(email =>
this.gnupgKeyring[email] && this.gnupgKeyring[email].can_encrypt).length;
if (length && (!all || length === count)) {
return 'gnupg';
}
}
if (openpgp && openpgp.length && (!all || openpgp.length === count)) {
return 'openpgp';
}
length = this.openpgpKeyring && recipients.filter(email =>
this.openpgpKeyring.publicKeys.getForAddress(email).length
).length;
if (openpgp && (!all || openpgp === count)) {
return 'openpgp';
}
let mailvelope = count && this.mailvelopeKeyring && await this.mailvelopeKeyring.validKeyForAddress(recipients)
/*.then(LookupResult => Object.entries(LookupResult))*/;
mailvelope = Object.entries(mailvelope);
if (mailvelope && mailvelope.length
&& (all ? (mailvelope.filter(([, value]) => value).length === count) : mailvelope.find(([, value]) => value))
) {
return 'mailvelope';
let mailvelope = this.mailvelopeKeyring && await this.mailvelopeKeyring.validKeyForAddress(recipients)
/*.then(LookupResult => Object.entries(LookupResult))*/;
mailvelope = Object.entries(mailvelope);
if (mailvelope && mailvelope.length
&& (all ? (mailvelope.filter(([, value]) => value).length === count) : mailvelope.find(([, value]) => value))
) {
return 'mailvelope';
}
}
return false;
}
/**
* Checks if signing/decrypting a message is possible with given email address.
* Checks if signing a message is possible with given email address.
* Returns the first library that can.
*/
async hasPrivateKeyForEmail(email) {
if (this.gnupgkeys && this.gnupgkeys[email] && this.gnupgkeys[email].can_sign) {
async hasPrivateKeyFor(email, sign) {
if (this.gnupgKeyring && this.gnupgKeyring[email] && this.gnupgKeyring[email][sign?'can_sign':'can_decrypt']) {
return 'gnupg';
}
if (this.openpgpkeys && this.openpgpkeys.find(item => item && item.isPrivate && item.emails.includes(email))) {
if (this.openpgpKeyring && this.openpgpKeyring.privateKeys.getForAddress(email).length) {
return 'openpgp';
}
@ -273,47 +246,70 @@ export const PgpUserStore = new class {
}
/**
* @param {string} email
* @returns {?}
* Checks if signing a message is possible with given email address.
* Returns the first library that can.
*/
findAllPublicKeysByEmailNotNative(email) {
return findAllKeysByEmail(this.openpgpkeys, email, 0);
async hasKeyForSigning(email) {
return await this.hasPrivateKeyFor(email, 1);
}
/**
* @param {string} email
* @returns {?}
* Checks if decrypting a message is possible with given email address.
* Returns the first library that can.
*/
findAllPrivateKeysByEmailNotNative(email) {
return findAllKeysByEmail(this.openpgpkeys, email, 1);
async hasKeyForDecrypting(email) {
return await this.hasPrivateKeyFor(email, 0);
}
/**
* @param {string} email
* @param {string=} password
* @returns {?}
* OpenPGP.js
*/
findPrivateKeyByEmail(email, password) {
let privateKey = null;
const key = this.openpgpkeys.find(item => item && item.isPrivate && item.emails.includes(email));
if (key) {
try {
privateKey = key.getNativeKeys()[0] || null;
if (privateKey) {
privateKey.decrypt(pString(password));
/**
* @param {OpenPgpKeyModel} openPgpKeyToRemove
* @returns {void}
*/
deleteKey(openPgpKeyToRemove) {
if (openPgpKeyToRemove && openPgpKeyToRemove.deleteAccess() && this.openpgpKeyring) {
let findedItem = this.openpgpPublicKeys.find(key => openPgpKeyToRemove === key);
if (findedItem) {
this.openpgpPublicKeys.remove(findedItem);
this.openpgpKeyring.publicKeys.removeForId(findedItem.guid);
} else {
findedItem = this.openpgpPrivateKeys.find(key => openPgpKeyToRemove === key);
if (findedItem) {
this.openpgpPrivateKeys.remove(findedItem);
this.openpgpKeyring.privateKeys.removeForId(findedItem.guid);
}
} catch (e) {
privateKey = null;
}
if (findedItem) {
delegateRunOnDestroy(findedItem);
this.openpgpKeyring.store();
}
// this.reloadOpenPgpKeys();
}
return privateKey;
}
decryptMessage(message, recipients, fCallback) {
if (message && message.getEncryptionKeyIds) {
const privateKeys = this.findPrivateKeysByEncryptionKeyIds(message.getEncryptionKeyIds(), recipients, true);
// findPrivateKeysByEncryptionKeyIds
const encryptionKeyIds = message.getEncryptionKeyIds();
let privateKeys = isArray(encryptionKeyIds)
? encryptionKeyIds.map(id => {
// openpgpKeyring.publicKeys.getForId(id.toHex())
// openpgpKeyring.privateKeys.getForId(id.toHex())
const key = id && id.toHex ? findKeyByHex(this.openpgpPrivateKeys, id.toHex()) : null;
return key ? [key] : [null];
}).flat().filter(v => v)
: [];
if (!privateKeys.length && arrayLength(recipients)) {
privateKeys = recipients.map(sEmail =>
(sEmail
? this.openpgpPrivateKeys.filter(item => item && item.emails.includes(sEmail)) : 0)
|| [null]
).flat().validUnique(key => key.id);
}
if (privateKeys && privateKeys.length) {
showScreenPopup(MessageOpenPgpPopupView, [
(decryptedKey) => {
@ -322,7 +318,7 @@ export const PgpUserStore = new class {
(decryptedMessage) => {
let privateKey = null;
if (decryptedMessage) {
privateKey = this.findPrivateKeyByHex(decryptedKey.primaryKey.keyid.toHex());
privateKey = findKeyByHex(this.openpgpPrivateKeys, decryptedKey.primaryKey.keyid.toHex());
if (privateKey) {
this.verifyMessage(decryptedMessage, (oValidKey, aSigningKeyIds) => {
fCallback(privateKey, decryptedMessage, oValidKey || null, aSigningKeyIds || null);
@ -358,14 +354,18 @@ export const PgpUserStore = new class {
if (message && message.getSigningKeyIds) {
const signingKeyIds = message.getSigningKeyIds();
if (signingKeyIds && signingKeyIds.length) {
const publicKeys = this.findPublicKeysBySigningKeyIds(signingKeyIds);
// findPublicKeysBySigningKeyIds
const publicKeys = signingKeyIds.map(id => {
const key = id && id.toHex ? findKeyByHex(this.openpgpPublicKeys, id.toHex()) : null;
return key ? key.getNativeKeys() : [null];
}).flat().filter(v => v);
if (publicKeys && publicKeys.length) {
try {
const result = message.verify(publicKeys),
valid = (isArray(result) ? result : []).find(item => item && item.valid && item.keyid);
if (valid && valid.keyid && valid.keyid && valid.keyid.toHex) {
fCallback(this.findPublicKeyByHex(valid.keyid.toHex()));
fCallback(findKeyByHex(this.openpgpPublicKeys, valid.keyid.toHex()));
return true;
}
} catch (e) {

View file

@ -3,6 +3,9 @@ import { PgpUserStore } from 'Stores/User/Pgp';
import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
import { Capa } from 'Common/Enums';
import { Settings } from 'Common/Globals';
class AddOpenPgpKeyPopupView extends AbstractViewPopup {
constructor() {
super('AddOpenPgpKey');
@ -10,9 +13,15 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
this.addObservables({
key: '',
keyError: false,
keyErrorMessage: ''
keyErrorMessage: '',
saveGnuPG: true,
saveOpenPGP: true
});
this.canGnuPG = Settings.capa(Capa.GnuPG);
this.canOpenPGP = Settings.capa(Capa.OpenPGP);
this.key.subscribe(() => {
this.keyError(false);
this.keyErrorMessage('');
@ -24,36 +33,40 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
}
addOpenPgpKeyCommand() {
// eslint-disable-next-line max-len
const reg = /[-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}[\s\S]+?[-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}/gi,
openpgpKeyring = PgpUserStore.openpgpKeyring;
let keyTrimmed = this.key().trim();
if (/[\n]/.test(keyTrimmed)) {
keyTrimmed = keyTrimmed.replace(/[\r]+/g, '').replace(/[\n]{2,}/g, '\n\n');
if (/\n/.test(keyTrimmed)) {
keyTrimmed = keyTrimmed.replace(/\r+/g, '').replace(/\n{2,}/g, '\n\n');
}
this.keyError(!keyTrimmed);
this.keyErrorMessage('');
if (!openpgpKeyring || this.keyError()) {
if (!keyTrimmed) {
return false;
}
let match = null,
count = 30,
done = false;
// eslint-disable-next-line max-len
const reg = /[-]{3,6}BEGIN[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}[\s\S]+?[-]{3,6}END[\s]PGP[\s](PRIVATE|PUBLIC)[\s]KEY[\s]BLOCK[-]{3,6}/gi,
keyring = PgpUserStore.openpgpKeyring;
do {
match = reg.exec(keyTrimmed);
if (match && 0 < count) {
if (match[0] && match[1] && match[2] && match[1] === match[2]) {
let err = null;
if ('PRIVATE' === match[1]) {
err = openpgpKeyring.privateKeys.importKey(match[0]);
} else if ('PUBLIC' === match[1]) {
err = openpgpKeyring.publicKeys.importKey(match[0]);
if (this.saveGnuPG()) {
PgpUserStore.gnupgImportKey(this.key());
}
if (this.canOpenPGP && this.saveOpenPGP()) {
if ('PRIVATE' === match[1]) {
err = keyring.privateKeys.importKey(match[0]);
} else if ('PUBLIC' === match[1]) {
err = keyring.publicKeys.importKey(match[0]);
}
}
if (err) {
@ -70,9 +83,11 @@ class AddOpenPgpKeyPopupView extends AbstractViewPopup {
}
} while (!done);
openpgpKeyring.store();
if (this.canOpenPGP && this.saveOpenPGP()) {
keyring.store();
}
PgpUserStore.reloadOpenPgpKeys();
// PgpUserStore.reloadOpenPgpKeys();
if (this.keyError()) {
return false;

View file

@ -133,8 +133,6 @@ class ComposePopupView extends AbstractViewPopup {
this.capaOpenPGP = PgpUserStore.isSupported();
this.identities = IdentityUserStore;
this.addObservables({
identitiesDropdownTrigger: false,
@ -189,7 +187,7 @@ class ComposePopupView extends AbstractViewPopup {
// div.textAreaParent
composeEditorArea: null,
currentIdentity: this.identities()[0] ? this.identities()[0] : null
currentIdentity: IdentityUserStore()[0] || null
});
// this.to.subscribe((v) => console.log(v));
@ -281,7 +279,7 @@ class ComposePopupView extends AbstractViewPopup {
currentIdentity: value => {
this.canPgpSign(false);
value && PgpUserStore.hasPrivateKeyForEmail(value.email()).then(result => {
value && PgpUserStore.hasKeyForSigning(value.email()).then(result => {
console.log({canPgpSign:result});
this.canPgpSign(result)
});

View file

@ -1,6 +1,7 @@
import { pInt } from 'Common/Utils';
import { PgpUserStore } from 'Stores/User/Pgp';
import { IdentityUserStore } from 'Stores/User/Identity';
import { decorateKoCommands } from 'Knoin/Knoin';
import { AbstractViewPopup } from 'Knoin/AbstractViews';
@ -9,6 +10,8 @@ class NewOpenPgpKeyPopupView extends AbstractViewPopup {
constructor() {
super('NewOpenPgpKey');
this.identities = IdentityUserStore;
this.addObservables({
email: '',
emailError: false,
@ -63,6 +66,9 @@ class NewOpenPgpKeyPopupView extends AbstractViewPopup {
openpgpKeyring.store();
PgpUserStore.reloadOpenPgpKeys();
PgpUserStore.gnupgImportKey(keyPair.privateKeyArmored);
this.cancelCommand();
}
})
@ -87,13 +93,11 @@ class NewOpenPgpKeyPopupView extends AbstractViewPopup {
}
onShow() {
this.name('');
this.name(IdentityUserStore()[0].name());
this.password('');
this.email('');
this.email(IdentityUserStore()[0].email());
this.emailError(false);
this.keyBitLength(4096);
this.submitError('');
}
}

View file

@ -180,8 +180,7 @@ export class MailMessageView extends AbstractViewRight {
pgpSigned: () => MessageUserStore.message() && !!MessageUserStore.message().pgpSigned(),
pgpEncrypted: () => PgpUserStore.isSupported()
&& MessageUserStore.message() && MessageUserStore.message().isPgpEncrypted(),
pgpEncrypted: () => MessageUserStore.message() && MessageUserStore.message().isPgpEncrypted(),
messageListOrViewLoading:
() => MessageUserStore.listIsLoading() | MessageUserStore.messageLoading()
@ -624,11 +623,65 @@ export class MailMessageView extends AbstractViewRight {
pgpDecrypt(self) {
const message = self.message();
message && message.pgpDecrypt();
if (message && PgpUserStore.isSupported()) {
// pgpClickHelper(message.body, message.plain(), message.getEmails(['from', 'to', 'cc']));
/*
pgpEncrypted: () => PgpUserStore.isSupported()
&& MessageUserStore.message() && MessageUserStore.message().isPgpEncrypted(),
*/
}
}
pgpVerify(self) {
const message = self.message();
message && message.pgpVerify();
if (message && PgpUserStore.isSupported()) {
const mode = PgpUserStore.hasPublicKeyForEmails([message.from[0].email()]);
if ('gnupg' === mode) {
let params = message.pgpSigned(); // { BodyPartId: "1", SigPartId: "2", MicAlg: "pgp-sha256" }
if (params) {
params.Folder = message.folder;
params.Uid = message.uid;
rl.app.Remote.post('MessagePgpVerify', null, params)
.then(data => {
// TODO
console.dir(data);
})
.catch(error => {
// TODO
console.dir(error);
});
}
} else if ('openpgp' === mode) {
let text = null;
try {
text = PgpUserStore.openpgp.cleartext.readArmored(message.plain);
} catch (e) {
console.error(e);
}
if (text && text.getText && text.verify) {
PgpUserStore.verifyMessage(text, (validKey, signingKeyIds) => {
console.dir([validKey, signingKeyIds]);
/*
if (validKey) {
i18n('PGP_NOTIFICATIONS/GOOD_SIGNATURE', {
USER: validKey.user + ' (' + validKey.id + ')'
});
message.getText()
} else {
const keyIds = arrayLength(signingKeyIds) ? signingKeyIds : null,
additional = keyIds
? keyIds.map(item => (item && item.toHex ? item.toHex() : null)).filter(v => v).join(', ')
: '';
i18n('PGP_NOTIFICATIONS/UNVERIFIRED_SIGNATURE') + (additional ? ' (' + additional + ')' : '');
}
*/
});
} else {
// controlsHelper(dom, this, false, i18n('PGP_NOTIFICATIONS/DECRYPTION_ERROR'));
}
}
}
}
}