mirror of
https://github.com/the-djmaze/snappymail.git
synced 2025-10-11 06:06:29 +08:00
revert decrypt button enabling; allow to select sign key
This commit is contained in:
parent
12f619bda7
commit
412ba464c8
5 changed files with 129 additions and 37 deletions
|
@ -83,10 +83,10 @@
|
||||||
|
|
||||||
if (0 === aResult.length && Utils.isNonEmptyArray(aRecipients))
|
if (0 === aResult.length && Utils.isNonEmptyArray(aRecipients))
|
||||||
{
|
{
|
||||||
aResult = _.compact(_.flatten(_.map(aRecipients, function (sEmail) {
|
aResult = _.uniq(_.compact(_.flatten(_.map(aRecipients, function (sEmail) {
|
||||||
var oKey = sEmail ? self.findPrivateKeyByEmailNotNative(sEmail) : null;
|
var aKeys = sEmail ? self.findAllPrivateKeysByEmailNotNative(sEmail) : null;
|
||||||
return oKey ? (bReturnWrapKeys ? [oKey] : oKey.getNativeKeys()) : [null];
|
return aKeys ? (bReturnWrapKeys ? aKeys : _.flatten(_.map(aKeys, function (oKey) { return oKey.getNativeKeys(); }), true)) : [null];
|
||||||
}), true));
|
}), true)), function (oKey) { return oKey.id; });
|
||||||
}
|
}
|
||||||
|
|
||||||
return aResult;
|
return aResult;
|
||||||
|
@ -114,6 +114,28 @@
|
||||||
}) || null;
|
}) || null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sEmail
|
||||||
|
* @return {?}
|
||||||
|
*/
|
||||||
|
PgpUserStore.prototype.findAllPublicKeysByEmailNotNative = function (sEmail)
|
||||||
|
{
|
||||||
|
return _.filter(this.openpgpkeysPublic(), function (oItem) {
|
||||||
|
return oItem && -1 !== oItem.emails.indexOf(sEmail);
|
||||||
|
}) || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} sEmail
|
||||||
|
* @return {?}
|
||||||
|
*/
|
||||||
|
PgpUserStore.prototype.findAllPrivateKeysByEmailNotNative = function (sEmail)
|
||||||
|
{
|
||||||
|
return _.filter(this.openpgpkeysPrivate(), function (oItem) {
|
||||||
|
return oItem && -1 !== oItem.emails.indexOf(sEmail);
|
||||||
|
}) || null;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} sEmail
|
* @param {string} sEmail
|
||||||
* @param {string=} sPassword
|
* @param {string=} sPassword
|
||||||
|
|
|
@ -30,7 +30,8 @@
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
this.optionsCaption = Translator.i18n('PGP_NOTIFICATIONS/ADD_A_PUBLICK_KEY');
|
this.publicKeysOptionsCaption = Translator.i18n('PGP_NOTIFICATIONS/ADD_A_PUBLICK_KEY');
|
||||||
|
this.privateKeysOptionsCaption = Translator.i18n('PGP_NOTIFICATIONS/SELECT_A_PRIVATE_KEY');
|
||||||
this.addOptionClass = function (oDomOption, oItem)
|
this.addOptionClass = function (oDomOption, oItem)
|
||||||
{
|
{
|
||||||
self.defautOptionsAfterRender(oDomOption, oItem);
|
self.defautOptionsAfterRender(oDomOption, oItem);
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
this.buttonFocus = ko.observable(false);
|
this.buttonFocus = ko.observable(false);
|
||||||
|
|
||||||
this.text = ko.observable('');
|
this.text = ko.observable('');
|
||||||
|
this.selectedPrivateKey = ko.observable(null);
|
||||||
this.selectedPublicKey = ko.observable(null);
|
this.selectedPublicKey = ko.observable(null);
|
||||||
|
|
||||||
this.signKey = ko.observable(null);
|
this.signKey = ko.observable(null);
|
||||||
|
@ -61,6 +63,20 @@
|
||||||
}));
|
}));
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
|
this.privateKeysOptions = ko.computed(function () {
|
||||||
|
return _.compact(_.flatten(_.map(PgpStore.openpgpkeysPrivate(), function (oKey, iIndex) {
|
||||||
|
return self.signKey() && self.signKey().key.id === oKey.id ? null :
|
||||||
|
_.map(oKey.users, function (sUser) {
|
||||||
|
return {
|
||||||
|
'id': oKey.guid,
|
||||||
|
'name': '(' + oKey.id.substr(-8).toUpperCase() + ') ' + sUser,
|
||||||
|
'key': oKey,
|
||||||
|
'class': iIndex % 2 ? 'odd' : 'even'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}), true));
|
||||||
|
});
|
||||||
|
|
||||||
this.publicKeysOptions = ko.computed(function () {
|
this.publicKeysOptions = ko.computed(function () {
|
||||||
return _.compact(_.flatten(_.map(PgpStore.openpgpkeysPublic(), function (oKey, iIndex) {
|
return _.compact(_.flatten(_.map(PgpStore.openpgpkeysPublic(), function (oKey, iIndex) {
|
||||||
return -1 < Utils.inArray(oKey, self.encryptKeysView()) ? null :
|
return -1 < Utils.inArray(oKey, self.encryptKeysView()) ? null :
|
||||||
|
@ -233,6 +249,31 @@
|
||||||
return !this.submitRequest() && (this.sign() || this.encrypt());
|
return !this.submitRequest() && (this.sign() || this.encrypt());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.selectCommand = Utils.createCommand(this, function () {
|
||||||
|
|
||||||
|
var
|
||||||
|
sKeyId = this.selectedPrivateKey(),
|
||||||
|
oKey = null,
|
||||||
|
aKeys = this.encryptKeys(),
|
||||||
|
oOption = sKeyId ? _.find(this.privateKeysOptions(), function (oItem) {
|
||||||
|
return oItem && sKeyId === oItem.id;
|
||||||
|
}) : null
|
||||||
|
;
|
||||||
|
|
||||||
|
if (oOption)
|
||||||
|
{
|
||||||
|
oKey = {
|
||||||
|
'empty': !oOption.key,
|
||||||
|
'selected': ko.observable(!!oOption.key),
|
||||||
|
'users': oOption.key.users,
|
||||||
|
'hash': oOption.key.id.substr(-8).toUpperCase(),
|
||||||
|
'key': oOption.key
|
||||||
|
};
|
||||||
|
|
||||||
|
this.signKey(oKey);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
this.addCommand = Utils.createCommand(this, function () {
|
this.addCommand = Utils.createCommand(this, function () {
|
||||||
|
|
||||||
var
|
var
|
||||||
|
@ -248,7 +289,7 @@
|
||||||
aKeys.push({
|
aKeys.push({
|
||||||
'empty': !oOption.key,
|
'empty': !oOption.key,
|
||||||
'selected': ko.observable(!!oOption.key),
|
'selected': ko.observable(!!oOption.key),
|
||||||
'removable': this.signKey().id !== oOption.key.id,
|
'removable': ko.observable(!this.sign() || !this.signKey() || this.signKey().key.id !== oOption.key.id),
|
||||||
'users': oOption.key.users,
|
'users': oOption.key.users,
|
||||||
'hash': oOption.key.id.substr(-8).toUpperCase(),
|
'hash': oOption.key.id.substr(-8).toUpperCase(),
|
||||||
'key': oOption.key
|
'key': oOption.key
|
||||||
|
@ -258,6 +299,24 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.updateCommand = Utils.createCommand(this, function () {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
_.each(this.encryptKeys(), function (oKey) {
|
||||||
|
oKey.removable(!self.sign() || !self.signKey() || self.signKey().key.id !== oKey.key.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
this.selectedPrivateKey.subscribe(function (sValue) {
|
||||||
|
if (sValue)
|
||||||
|
{
|
||||||
|
this.selectCommand();
|
||||||
|
this.updateCommand();
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
|
||||||
this.selectedPublicKey.subscribe(function (sValue) {
|
this.selectedPublicKey.subscribe(function (sValue) {
|
||||||
if (sValue)
|
if (sValue)
|
||||||
{
|
{
|
||||||
|
@ -340,8 +399,10 @@
|
||||||
this.clearPopup();
|
this.clearPopup();
|
||||||
|
|
||||||
var
|
var
|
||||||
|
self = this,
|
||||||
aRec = [],
|
aRec = [],
|
||||||
sEmail = '',
|
sEmail = '',
|
||||||
|
aKeys = [],
|
||||||
oKey = null,
|
oKey = null,
|
||||||
oEmail = new EmailModel()
|
oEmail = new EmailModel()
|
||||||
;
|
;
|
||||||
|
@ -374,9 +435,10 @@
|
||||||
{
|
{
|
||||||
sEmail = oIdentity.email();
|
sEmail = oIdentity.email();
|
||||||
aRec.unshift(sEmail);
|
aRec.unshift(sEmail);
|
||||||
oKey = PgpStore.findPrivateKeyByEmailNotNative(sEmail);
|
aKeys = PgpStore.findAllPrivateKeysByEmailNotNative(sEmail);
|
||||||
if (oKey)
|
if (aKeys)
|
||||||
{
|
{
|
||||||
|
var oKey = aKeys[0];
|
||||||
this.signKey({
|
this.signKey({
|
||||||
'users': oKey.users || [sEmail],
|
'users': oKey.users || [sEmail],
|
||||||
'hash': oKey.id.substr(-8).toUpperCase(),
|
'hash': oKey.id.substr(-8).toUpperCase(),
|
||||||
|
@ -392,17 +454,19 @@
|
||||||
|
|
||||||
if (aRec && 0 < aRec.length)
|
if (aRec && 0 < aRec.length)
|
||||||
{
|
{
|
||||||
this.encryptKeys(_.uniq(_.compact(_.map(aRec, function (sEmail) {
|
this.encryptKeys(_.uniq(_.compact(_.flatten(_.map(aRec, function (sEmail) {
|
||||||
var oKey = PgpStore.findPublicKeyByEmailNotNative(sEmail) || null;
|
var aKeys = PgpStore.findAllPublicKeysByEmailNotNative(sEmail);
|
||||||
|
return aKeys ? _.map(aKeys, function (oKey) {
|
||||||
return {
|
return {
|
||||||
'empty': !oKey,
|
'empty': !oKey,
|
||||||
'selected': ko.observable(!!oKey),
|
'selected': ko.observable(!!oKey),
|
||||||
'removable': oIdentity && oIdentity.email() && oIdentity.email() !== sEmail,
|
'removable': ko.observable(!self.sign() || !self.signKey() || self.signKey().key.id !== oKey.id),
|
||||||
'users': oKey ? (oKey.users || [sEmail]) : [sEmail],
|
'users': oKey ? (oKey.users || [sEmail]) : [sEmail],
|
||||||
'hash': oKey ? oKey.id.substr(-8).toUpperCase() : '',
|
'hash': oKey ? oKey.id.substr(-8).toUpperCase() : '',
|
||||||
'key': oKey
|
'key': oKey
|
||||||
};
|
};
|
||||||
})), function (oEncryptKey) {
|
}) : [];
|
||||||
|
}), true)), function (oEncryptKey) {
|
||||||
return oEncryptKey.hash;
|
return oEncryptKey.hash;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
|
@ -620,6 +620,7 @@ en:
|
||||||
NO_PRIVATE_KEY_FOUND: "No private key found"
|
NO_PRIVATE_KEY_FOUND: "No private key found"
|
||||||
NO_PRIVATE_KEY_FOUND_FOR: "No private key found for \"%EMAIL%\" email"
|
NO_PRIVATE_KEY_FOUND_FOR: "No private key found for \"%EMAIL%\" email"
|
||||||
ADD_A_PUBLICK_KEY: "Add a public key"
|
ADD_A_PUBLICK_KEY: "Add a public key"
|
||||||
|
SELECT_A_PRIVATE_KEY: "Select a private key"
|
||||||
UNVERIFIRED_SIGNATURE: "Unverified signature"
|
UNVERIFIRED_SIGNATURE: "Unverified signature"
|
||||||
DECRYPTION_ERROR: "OpenPGP decryption error"
|
DECRYPTION_ERROR: "OpenPGP decryption error"
|
||||||
GOOD_SIGNATURE: "Good signature from %USER%"
|
GOOD_SIGNATURE: "Good signature from %USER%"
|
||||||
|
|
|
@ -20,23 +20,23 @@
|
||||||
label: 'POPUPS_COMPOSE_OPEN_PGP/LABEL_SIGN',
|
label: 'POPUPS_COMPOSE_OPEN_PGP/LABEL_SIGN',
|
||||||
value: sign
|
value: sign
|
||||||
}
|
}
|
||||||
}"></div>
|
}, click: updateCommand "></div>
|
||||||
|
|
||||||
<div class="key-list" data-bind="visible: sign">
|
<div class="key-list" data-bind="visible: sign">
|
||||||
<div class="key-list-wrp empty" data-bind="visible: !signKey()">
|
<div class="key-list-wrp empty" data-bind="visible: !signKey()">
|
||||||
No private key found
|
No private key found
|
||||||
</div>
|
</div>
|
||||||
<div class="key-list-wrp" data-bind="visible: signKey">
|
<div class="key-list-wrp" data-bind="visible: signKey()">
|
||||||
<div class="key-list__item row-fluid">
|
<div class="key-list__item row-fluid">
|
||||||
<div class="key-list__item-hash span4">
|
<div class="key-list__item-hash span4">
|
||||||
(<span data-bind="text: signKey() ? signKey().hash : ''"></span>)
|
(<span data-bind="text: signKey() ? signKey().hash : ''"></span>)
|
||||||
</div>
|
</div>
|
||||||
<div class="key-list__item-names span8">
|
<div class="key-list__item-names span8">
|
||||||
<div data-bind="if: signKey()">
|
<!-- ko if: signKey() -->
|
||||||
<div data-bind="foreach: signKey().users">
|
<!-- ko foreach: signKey().users -->
|
||||||
<div class="key-list__item-name" data-bind="text: $data"></div>
|
<div class="key-list__item-name" data-bind="text: $data"></div>
|
||||||
</div>
|
<!-- /ko -->
|
||||||
</div>
|
<!-- /ko -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -57,9 +57,9 @@
|
||||||
No public keys selected
|
No public keys selected
|
||||||
</div>
|
</div>
|
||||||
<div class="key-list-wrp" data-bind="visible: encryptKeys() && encryptKeys().length > 0">
|
<div class="key-list-wrp" data-bind="visible: encryptKeys() && encryptKeys().length > 0">
|
||||||
<div data-bind="foreach: encryptKeys">
|
<!-- ko foreach: encryptKeys -->
|
||||||
<div class="key-list__item row-fluid">
|
<div class="key-list__item row-fluid">
|
||||||
<div class="key-list__item-delete span1" data-bind="click: removable ? $parent.deletePublickKey : null, css: {'disabled': !removable}">
|
<div class="key-list__item-delete span1" data-bind="click: removable() ? $parent.deletePublickKey : null, css: {'disabled': !removable()}">
|
||||||
<i class="icon-trash"></i>
|
<i class="icon-trash"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="key-list__item-hash span3" data-bind="visible: !empty">
|
<div class="key-list__item-hash span3" data-bind="visible: !empty">
|
||||||
|
@ -67,31 +67,36 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="span8">
|
<div class="span8">
|
||||||
<span class="key-list__item-names" data-bind="css: {'empty': empty}">
|
<span class="key-list__item-names" data-bind="css: {'empty': empty}">
|
||||||
<span data-bind="foreach: users">
|
<!-- ko foreach: users -->
|
||||||
<div class="key-list__item-name" data-bind="text: $data"></div>
|
<div class="key-list__item-name" data-bind="text: $data"></div>
|
||||||
</span>
|
<!-- /ko -->
|
||||||
</span>
|
</span>
|
||||||
<span class="key-list__item-error" data-bind="visible: empty">
|
<span class="key-list__item-error" data-bind="visible: empty">
|
||||||
(Public key not found)
|
(Public key not found)
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<!-- /ko -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row-fluid key-actions">
|
<div class="row-fluid key-actions">
|
||||||
<div class="span5">
|
<div class="span5" data-bind="visible: sign() && 0 < privateKeysOptions().length">
|
||||||
<input type="password" class="inputPassword input-block-level i18n"
|
<input type="password" class="inputPassword input-block-level i18n"
|
||||||
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
autocomplete="off" autocorrect="off" autocapitalize="off" spellcheck="false"
|
||||||
data-i18n="[placeholder]POPUPS_COMPOSE_OPEN_PGP/LABEL_PASSWORD"
|
data-i18n="[placeholder]POPUPS_COMPOSE_OPEN_PGP/LABEL_PASSWORD"
|
||||||
data-bind="visible: sign, textInput: password, hasfocus: password.focus, onEnter: doCommand" />
|
data-bind="textInput: password, hasfocus: password.focus, onEnter: doCommand" />
|
||||||
|
<div class="form-inline">
|
||||||
|
<select class="input-block-level" data-bind="options: privateKeysOptions, value: selectedPrivateKey,
|
||||||
|
optionsCaption: privateKeysOptionsCaption, optionsText: 'name', optionsValue: 'id',
|
||||||
|
optionsAfterRender: addOptionClass"></select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="span7" data-bind="visible: encrypt() && 0 < publicKeysOptions().length">
|
<div class="span7" data-bind="visible: encrypt() && 0 < publicKeysOptions().length">
|
||||||
<div class="form-inline">
|
<div class="form-inline">
|
||||||
<select class="input-block-level" data-bind="options: publicKeysOptions, value: selectedPublicKey,
|
<select class="input-block-level" data-bind="options: publicKeysOptions, value: selectedPublicKey,
|
||||||
optionsCaption: optionsCaption, optionsText: 'name', optionsValue: 'id',
|
optionsCaption: publicKeysOptionsCaption, optionsText: 'name', optionsValue: 'id',
|
||||||
optionsAfterRender: addOptionClass"></select>
|
optionsAfterRender: addOptionClass"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -99,7 +104,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn buttonDo" data-bind="command: doCommand, hasfocus: buttonFocus,
|
<button class="btn buttonDo" data-bind="command: doCommand, hasfocus: buttonFocus,
|
||||||
enable: (sign() || encrypt()) && (!sign() || (sign() && password().length)) && (!encrypt() || encrypt() && encryptKeys().length > 0)">
|
enable: (sign() || encrypt()) && (!encrypt() || encrypt() && encryptKeys().length > 0)">
|
||||||
<i data-bind="css: {'icon-key': !submitRequest(), 'icon-spinner animated': submitRequest()}"></i>
|
<i data-bind="css: {'icon-key': !submitRequest(), 'icon-spinner animated': submitRequest()}"></i>
|
||||||
|
|
||||||
<span class="i18n" data-bind="visible: sign() && !encrypt()" data-i18n="POPUPS_COMPOSE_OPEN_PGP/BUTTON_SIGN"></span>
|
<span class="i18n" data-bind="visible: sign() && !encrypt()" data-i18n="POPUPS_COMPOSE_OPEN_PGP/BUTTON_SIGN"></span>
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button class="btn buttonDo" data-bind="command: doCommand, hasfocus: buttonFocus, enable: password().length > 0">
|
<button class="btn buttonDo" data-bind="command: doCommand, hasfocus: buttonFocus">
|
||||||
<i data-bind="css: {'icon-key': !submitRequest(), 'icon-spinner animated': submitRequest()}"></i>
|
<i data-bind="css: {'icon-key': !submitRequest(), 'icon-spinner animated': submitRequest()}"></i>
|
||||||
|
|
||||||
<span class="i18n" data-i18n="POPUPS_MESSAGE_OPEN_PGP/BUTTON_DECRYPT"></span>
|
<span class="i18n" data-i18n="POPUPS_MESSAGE_OPEN_PGP/BUTTON_DECRYPT"></span>
|
||||||
|
|
Loading…
Add table
Reference in a new issue