js: code cleanup (eslint)

--
* trying to stick to eslint from now on for readability

* As some attribution was lost in previous git confusions, I added my
  name into some of the licence headers
This commit is contained in:
Maximilian Krambach 2018-06-06 13:05:53 +02:00
parent 0356a667c5
commit bfd3799d39
27 changed files with 597 additions and 500 deletions

View File

@ -24,6 +24,9 @@
"error", "error",
"always" "always"
], ],
"no-var": [
"warn"
],
"max-len": 1 "max-len": 1
} }
} }

View File

@ -16,26 +16,12 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* gpgme.js - Javascript integration for gpgme
* Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik /* global chrome */
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+
*/
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.create({ chrome.tabs.create({

View File

@ -16,6 +16,11 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global mocha */
mocha.run(); mocha.run();

View File

@ -16,6 +16,12 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global Gpgmejs_test, mocha*/
Gpgmejs_test.unittests(); Gpgmejs_test.unittests();
mocha.run(); mocha.run();

View File

@ -16,7 +16,13 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global mocha, chai */
mocha.setup('bdd'); mocha.setup('bdd');
var expect = chai.expect; const expect = chai.expect; //eslint-disable-line no-unused-vars
chai.config.includeStack = true; chai.config.includeStack = true;

View File

@ -16,6 +16,9 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global describe, it, expect, Gpgmejs, ImportablePublicKey */ /* global describe, it, expect, Gpgmejs, ImportablePublicKey */

View File

@ -1,4 +1,3 @@
/* gpgme.js - Javascript integration for gpgme /* gpgme.js - Javascript integration for gpgme
* Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
* *
@ -17,23 +16,31 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global describe, it, expect, Gpgmejs */
/* global inputvalues, encryptedData, bigString, bigBoringString */
describe('Encryption and Decryption', function () { describe('Encryption and Decryption', function () {
it('Successful encrypt and decrypt simple string', function (done) { it('Successful encrypt and decrypt simple string', function (done) {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
prm.then(function (context) { prm.then(function (context) {
context.encrypt( context.encrypt(
inputvalues.encrypt.good.data, inputvalues.encrypt.good.data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(
function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('BEGIN PGP MESSAGE');
expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE');
context.decrypt(answer.data).then(function (result) { context.decrypt(answer.data).then(function (result) {
expect(result).to.not.be.empty; expect(result).to.not.be.empty;
expect(result.data).to.be.a('string'); expect(result.data).to.be.a('string');
expect(result.data).to.equal(inputvalues.encrypt.good.data); expect(result.data).to.equal(
inputvalues.encrypt.good.data);
done(); done();
}); });
}); });
@ -51,7 +58,7 @@ describe('Encryption and Decryption', function () {
expect(result.data).to.equal( expect(result.data).to.equal(
'¡Äußerste µ€ før ñoquis@hóme! Добрый день\n'); '¡Äußerste µ€ før ñoquis@hóme! Добрый день\n');
done(); done();
}); });
}); });
}).timeout(3000); }).timeout(3000);
@ -64,7 +71,7 @@ describe('Encryption and Decryption', function () {
inputvalues.encrypt.good.fingerprint).then( inputvalues.encrypt.good.fingerprint).then(
function (answer) { function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');
expect(answer.data).to.include( expect(answer.data).to.include(
@ -79,39 +86,41 @@ describe('Encryption and Decryption', function () {
}); });
}); });
}); });
}).timeout(5000); }).timeout(5000);
for (let j = 0; j < inputvalues.encrypt.good.data_nonascii_32.length; j++){ for (let j = 0; j < inputvalues.encrypt.good.data_nonascii_32.length; j++){
it('Roundtrip with >1MB non-ascii input meeting default chunksize (' + (j + 1) + '/' + inputvalues.encrypt.good.data_nonascii_32.length + ')', it('Roundtrip with >1MB non-ascii input meeting default chunksize (' +
function (done) { (j + 1) + '/'
let input = inputvalues.encrypt.good.data_nonascii_32[j]; + inputvalues.encrypt.good.data_nonascii_32.length + ')',
expect(input).to.have.length(32); function (done) {
let prm = Gpgmejs.init(); let input = inputvalues.encrypt.good.data_nonascii_32[j];
prm.then(function (context) { expect(input).to.have.length(32);
let data = ''; let prm = Gpgmejs.init();
for (let i=0; i < 34 * 1024; i++){ prm.then(function (context) {
data += input; let data = '';
} for (let i=0; i < 34 * 1024; i++){
context.encrypt(data, data += input;
inputvalues.encrypt.good.fingerprint).then( }
function (answer) { context.encrypt(data,
expect(answer).to.not.be.empty; inputvalues.encrypt.good.fingerprint).then(
expect(answer.data).to.be.a("string"); function (answer) {
expect(answer.data).to.include( expect(answer).to.not.be.empty;
'BEGIN PGP MESSAGE'); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'END PGP MESSAGE'); 'BEGIN PGP MESSAGE');
context.decrypt(answer.data).then( expect(answer.data).to.include(
function (result) { 'END PGP MESSAGE');
expect(result).to.not.be.empty; context.decrypt(answer.data).then(
expect(result.data).to.be.a('string'); function (result) {
expect(result.data).to.equal(data); expect(result).to.not.be.empty;
done(); expect(result.data).to.be.a('string');
}); expect(result.data).to.equal(data);
}); done();
}); });
});
});
}).timeout(3000); }).timeout(3000);
}; }
it('Random data, as string', function (done) { it('Random data, as string', function (done) {
let data = bigString(1000); let data = bigString(1000);
@ -121,7 +130,7 @@ describe('Encryption and Decryption', function () {
inputvalues.encrypt.good.fingerprint).then( inputvalues.encrypt.good.fingerprint).then(
function (answer) { function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');
expect(answer.data).to.include( expect(answer.data).to.include(
@ -143,10 +152,10 @@ describe('Encryption and Decryption', function () {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
prm.then(function (context) { prm.then(function (context) {
context.encrypt(b64data, context.encrypt(b64data,
inputvalues.encrypt.good.fingerprint,).then( inputvalues.encrypt.good.fingerprint).then(
function (answer) { function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');
expect(answer.data).to.include( expect(answer.data).to.include(
@ -171,7 +180,7 @@ describe('Encryption and Decryption', function () {
inputvalues.encrypt.good.fingerprint, true).then( inputvalues.encrypt.good.fingerprint, true).then(
function (answer) { function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');
expect(answer.data).to.include( expect(answer.data).to.include(
@ -196,7 +205,7 @@ describe('Encryption and Decryption', function () {
inputvalues.encrypt.good.fingerprint).then( inputvalues.encrypt.good.fingerprint).then(
function (answer) { function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');

View File

@ -16,7 +16,14 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global describe, it, expect, Gpgmejs */
/* global inputvalues, fixedLengthString */
describe('Encryption', function () { describe('Encryption', function () {
it('Successful encrypt', function (done) { it('Successful encrypt', function (done) {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
@ -24,12 +31,12 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
inputvalues.encrypt.good.data, inputvalues.encrypt.good.data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('BEGIN PGP MESSAGE');
expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE');
done(); done();
}); });
}); });
}); });
@ -40,12 +47,12 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
data, data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('BEGIN PGP MESSAGE');
expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE');
done(); done();
}); });
}); });
}).timeout(10000); }).timeout(10000);
@ -56,12 +63,12 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
data, data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('BEGIN PGP MESSAGE');
expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE');
done(); done();
}); });
}); });
}).timeout(20000); }).timeout(20000);
@ -72,12 +79,12 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
data, data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('BEGIN PGP MESSAGE');
expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE');
done(); done();
}); });
}); });
}).timeout(20000); }).timeout(20000);
@ -87,12 +94,12 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
inputvalues.encrypt.good.data, inputvalues.encrypt.good.data,
null).then(function (answer) { null).then(function (answer) {
expect(answer).to.be.undefined; expect(answer).to.be.undefined;
}, function(error){ }, function(error){
expect(error).to.be.an('Error'); expect(error).to.be.an('Error');
expect(error.code).to.equal('MSG_INCOMPLETE'); expect(error.code).to.equal('MSG_INCOMPLETE');
done(); done();
}); });
}); });
}); });
@ -101,12 +108,12 @@ describe('Encryption', function () {
prm.then(function (context) { prm.then(function (context) {
context.encrypt( context.encrypt(
null, inputvalues.encrypt.good.keyid).then(function (answer) { null, inputvalues.encrypt.good.keyid).then(function (answer) {
expect(answer).to.be.undefined; expect(answer).to.be.undefined;
}, function (error) { }, function (error) {
expect(error).to.be.an.instanceof(Error); expect(error).to.be.an.instanceof(Error);
expect(error.code).to.equal('MSG_INCOMPLETE'); expect(error.code).to.equal('MSG_INCOMPLETE');
done(); done();
}); });
}); });
}); });
@ -116,15 +123,15 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
inputvalues.encrypt.good.data, inputvalues.encrypt.good.data,
inputvalues.encrypt.bad.fingerprint).then(function (answer) { inputvalues.encrypt.bad.fingerprint).then(function (answer) {
expect(answer).to.be.undefined; expect(answer).to.be.undefined;
}, function(error){ }, function(error){
expect(error).to.be.an('Error'); expect(error).to.be.an('Error');
expect(error.code).to.not.be.undefined; expect(error.code).to.not.be.undefined;
expect(error.code).to.equal('GNUPG_ERROR'); expect(error.code).to.equal('GNUPG_ERROR');
done(); done();
}); });
}); });
}).timeout(5000);; }).timeout(5000);
it('Overly large message ( > 65MB) is rejected', function (done) { it('Overly large message ( > 65MB) is rejected', function (done) {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
@ -132,15 +139,15 @@ describe('Encryption', function () {
context.encrypt( context.encrypt(
fixedLengthString(65), fixedLengthString(65),
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.be.undefined; expect(answer).to.be.undefined;
}, function(error){ }, function(error){
expect(error).to.be.an.instanceof(Error); expect(error).to.be.an.instanceof(Error);
// expect(error.code).to.equal('GNUPG_ERROR'); // expect(error.code).to.equal('GNUPG_ERROR');
// TODO: there is a 64 MB hard limit at least in chrome at: // TODO: there is a 64 MB hard limit at least in chrome at:
// chromium//extensions/renderer/messaging_util.cc: // chromium//extensions/renderer/messaging_util.cc:
// kMaxMessageLength // kMaxMessageLength
done(); done();
}); });
}); });
}).timeout(8000); }).timeout(8000);

View File

@ -16,9 +16,12 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
var inputvalues = {// eslint-disable-line no-unused-vars const inputvalues = {// eslint-disable-line no-unused-vars
encrypt: { encrypt: {
good:{ good:{
data : 'Hello World.', data : 'Hello World.',
@ -131,7 +134,7 @@ function slightlyLessBoringString(megabytes, set){
} }
// Data encrypted with testKey // Data encrypted with testKey
var encryptedData =// eslint-disable-line no-unused-vars const encryptedData =// eslint-disable-line no-unused-vars
'-----BEGIN PGP MESSAGE-----\n' + '-----BEGIN PGP MESSAGE-----\n' +
'\n' + '\n' +
'hQEMA6B8jfIUScGEAQgAlANd3uyhmhYLzVcfz4LEqA8tgUC3n719YH0iuKEzG/dv\n' + 'hQEMA6B8jfIUScGEAQgAlANd3uyhmhYLzVcfz4LEqA8tgUC3n719YH0iuKEzG/dv\n' +
@ -146,7 +149,7 @@ var encryptedData =// eslint-disable-line no-unused-vars
'=zap6\n' + '=zap6\n' +
'-----END PGP MESSAGE-----\n'; '-----END PGP MESSAGE-----\n';
var ImportablePublicKey = {// eslint-disable-line no-unused-vars const ImportablePublicKey = {// eslint-disable-line no-unused-vars
fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A', fingerprint: '78034948BA7F5D0E9BDB67E4F63790C11E60278A',
key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' + key:'-----BEGIN PGP PUBLIC KEY BLOCK-----\n' +
'\n' + '\n' +

View File

@ -1,39 +1,78 @@
/* gpgme.js - Javascript integration for gpgme
* Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
*
* This file is part of GPGME.
*
* GPGME is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* GPGME is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/
/* global describe, it, expect, Gpgmejs */
/* global bigString, inputvalues */
describe('Long running Encryption/Decryption', function () { describe('Long running Encryption/Decryption', function () {
for (let i=0; i < 100; i++) { for (let i=0; i < 100; i++) {
it('Successful encrypt/decrypt completely random data ' + (i+1) + '/100', function (done) { it('Successful encrypt/decrypt completely random data ' +
(i+1) + '/100', function (done) {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
let data = bigString(2*1024*1024); let data = bigString(2*1024*1024);
prm.then(function (context) { prm.then(function (context) {
context.encrypt(data, context.encrypt(data,
inputvalues.encrypt.good.fingerprint).then( inputvalues.encrypt.good.fingerprint).then(
function (answer){ function (answer){
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a("string"); expect(answer.data).to.be.a('string');
expect(answer.data).to.include( expect(answer.data).to.include(
'BEGIN PGP MESSAGE'); 'BEGIN PGP MESSAGE');
expect(answer.data).to.include( expect(answer.data).to.include(
'END PGP MESSAGE'); 'END PGP MESSAGE');
context.decrypt(answer.data).then( context.decrypt(answer.data).then(
function(result){ function(result){
expect(result).to.not.be.empty; expect(result).to.not.be.empty;
expect(result.data).to.be.a('string'); expect(result.data).to.be.a('string');
if (result.data.length !== data.length) { if (result.data.length !== data.length) {
console.log('diff: ' + (result.data.length - data.length)); // console.log('diff: ' +
for (let i=0; i < result.data.length; i++){ // (result.data.length - data.length));
if (result.data[i] !== data[i]){ for (let i=0; i < result.data.length; i++){
console.log('position: ' + i); if (result.data[i] !== data[i]){
console.log('result : '+ result.data.charCodeAt(i) + result.data[i-2] + result.data[i-1] + result.data[i] + result.data[i+1] + result.data[i+2]); // console.log('position: ' + i);
console.log('original: ' + data.charCodeAt(i) + data[i-2] + data[i-1] + data[i] + data[i+1] + data[i+2]); // console.log('result : ' +
break; // result.data.charCodeAt(i) +
} // result.data[i-2] +
} // result.data[i-1] +
// result.data[i] +
// result.data[i+1] +
// result.data[i+2]);
// console.log('original: ' +
// data.charCodeAt(i) +
// data[i-2] +
// data[i-1] +
// data[i] +
// data[i+1] +
// data[i+2]);
break;
} }
expect(result.data).to.equal(data); }
done(); }
}); expect(result.data).to.equal(data);
}); done();
}); });
});
});
}).timeout(8000); }).timeout(8000);
}; }
}); });

View File

@ -16,7 +16,14 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global describe, it, expect, Gpgmejs */
/* global bigString, inputvalues */
describe('Signing', function () { describe('Signing', function () {
it('Sign a message', function (done) { it('Sign a message', function (done) {
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
@ -25,12 +32,12 @@ describe('Signing', function () {
context.sign( context.sign(
data, data,
inputvalues.encrypt.good.fingerprint).then(function (answer) { inputvalues.encrypt.good.fingerprint).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a('string'); expect(answer.data).to.be.a('string');
expect(answer.data).to.include('BEGIN PGP SIGNATURE'); expect(answer.data).to.include('BEGIN PGP SIGNATURE');
expect(answer.data).to.include('END PGP SIGNATURE'); expect(answer.data).to.include('END PGP SIGNATURE');
expect(answer.data).to.include(data); expect(answer.data).to.include(data);
done(); done();
}); });
}); });
}); });
@ -43,12 +50,12 @@ describe('Signing', function () {
inputvalues.encrypt.good.fingerprint, inputvalues.encrypt.good.fingerprint,
'detached' 'detached'
).then(function (answer) { ).then(function (answer) {
expect(answer).to.not.be.empty; expect(answer).to.not.be.empty;
expect(answer.data).to.be.a('string'); expect(answer.data).to.be.a('string');
expect(answer.data).to.include(data); expect(answer.data).to.include(data);
expect(answer.signature).to.be.a('string'); expect(answer.signature).to.be.a('string');
expect(answer.signature).to.be.a('string'); expect(answer.signature).to.be.a('string');
done(); done();
}); });
}); });
}); });

View File

@ -16,25 +16,31 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
describe('GPGME context', function(){ /* global describe, it, expect, Gpgmejs */
/* global inputvalues */
describe('GPGME context', function(){
it('Starting a GpgME instance', function(done){ it('Starting a GpgME instance', function(done){
let prm = Gpgmejs.init(); let prm = Gpgmejs.init();
prm.then( prm.then(
function(context){ function(context){
expect(context).to.be.an('object'); expect(context).to.be.an('object');
expect(context.encrypt).to.be.a('function'); expect(context.encrypt).to.be.a('function');
expect(context.decrypt).to.be.a('function'); expect(context.decrypt).to.be.a('function');
done(); done();
}); });
}); });
}); });
describe('GPGME does not start with invalid parameters', function(){ describe('GPGME does not start with invalid parameters', function(){
for (let i=0; i < inputvalues.init.invalid_startups.length; i++){ for (let i=0; i < inputvalues.init.invalid_startups.length; i++){
it('Parameter '+ i, function(done){ it('Parameter '+ i, function(done){
let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]); let prm = Gpgmejs.init(inputvalues.init.invalid_startups[i]);
prm.then(function(context){ prm.then(function(context){
expect(context).to.be.undefined; expect(context).to.be.undefined;
done(); done();
@ -43,6 +49,6 @@ describe('GPGME does not start with invalid parameters', function(){
expect(error.code).to.equal('PARAM_WRONG'); expect(error.code).to.equal('PARAM_WRONG');
done(); done();
}); });
}) });
} }
}); });

View File

@ -6,20 +6,25 @@ receiving an answer
[*] nativeConnection successfull on Windows, macOS, Linux [*] nativeConnection successfull on Windows, macOS, Linux
[X] nativeConnection with delayed, multipart (> 1MB) answer [X] nativeConnection with delayed, multipart (> 1MB) answer
[*] Message handling (encrypt, decrypt verify, sign) [x] Message handling (encrypt, decrypt verify, sign)
[x] encrypt, decrypt [x] encrypt, decrypt
[ ] verify [x] verify
[ ] sign [x] sign
[*] Key handling (import/export, modifying, status queries) [*] Key handling (import/export, modifying, status queries)
[x] Import (not importing secret)
[x] Export (not exporting secret)
[x] status queries
[ ] key generation
[ ] modification
[*] Configuration handling [*] Configuration handling
[ ] check for completeness [ ] check for completeness
Communication with other implementations Communication with other implementations
[-] option to export SECRET Key into localstore used by e.g. mailvelope?
[ ] option to export SECRET Key into localstore used by e.g. mailvelope current discussion states that this won't be possible due to security
concerns
Management: Management:
[*] Define the gpgme interface [*] Define the gpgme interface
[x] check Permissions (e.g. csp) for the different envs [x] check Permissions (e.g. csp) for the different envs
[X] agree on license [x] agree on license
[*] tests [*] tests

View File

@ -17,7 +17,12 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
* *
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global chrome */
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
chrome.tabs.create({ chrome.tabs.create({
url: './mainui.html' url: './mainui.html'

View File

@ -17,39 +17,41 @@
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
* *
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/* global document, Gpgmejs */
document.addEventListener('DOMContentLoaded', function() { document.addEventListener('DOMContentLoaded', function() {
Gpgmejs.init().then(function(gpgmejs){ Gpgmejs.init().then(function(gpgmejs){
document.getElementById("buttonencrypt").addEventListener("click", document.getElementById('buttonencrypt').addEventListener('click',
function(){ function(){
let data = document.getElementById('cleartext').value; let data = document.getElementById('cleartext').value;
let keyId = document.getElementById('pubkey').value; let keyId = document.getElementById('pubkey').value;
gpgmejs.encrypt(data, keyId).then( gpgmejs.encrypt(data, keyId).then(
function(answer){ function(answer){
console.log(answer);
if (answer.data){ if (answer.data){
console.log(answer.data); document.getElementById(
document.getElementById('answer').value = answer.data; 'answer').value = answer.data;
} }
}, function(errormsg){ }, function(errormsg){
alert( errormsg.code + ' ' + errormsg.msg); alert( errormsg.code + ' ' + errormsg.msg);
}); });
}); });
document.getElementById("buttondecrypt").addEventListener("click", document.getElementById('buttondecrypt').addEventListener('click',
function(){ function(){
let data = document.getElementById("ciphertext").value; let data = document.getElementById('ciphertext').value;
gpgmejs.decrypt(data).then( gpgmejs.decrypt(data).then(
function(answer){ function(answer){
console.log(answer); if (answer.data){
if (answer.data){ document.getElementById(
document.getElementById('answer').value = answer.data; 'answer').value = answer.data;
} }
}, function(errormsg){ }, function(errormsg){
alert( errormsg.code + ' ' + errormsg.msg); alert( errormsg.code + ' ' + errormsg.msg);
});
}); });
}); });
},
function(error){console.log(error)});
}); });

View File

@ -1,7 +1,7 @@
{ {
"name": "gpgmejs", "name": "gpgmejs",
"version": "0.0.1", "version": "0.0.1-dev",
"description": "javascript part of a nativeMessaging gnupg integration", "description": "Javascript part of the GPGME nativeMessaging integration",
"main": "src/index.js", "main": "src/index.js",
"private": true, "private": true,
"keywords": [], "keywords": [],

View File

@ -16,6 +16,9 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
export const availableConf = { export const availableConf = {

View File

@ -16,16 +16,16 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/** /* global chrome */
* A connection port will be opened for each communication between gpgmejs and
* gnupg. It should be alive as long as there are additional messages to be import { permittedOperations } from './permittedOperations';
* expected. import { gpgme_error } from './Errors';
*/ import { GPGME_Message, createMessage } from './Message';
import { permittedOperations } from './permittedOperations'
import { gpgme_error } from "./Errors"
import { GPGME_Message, createMessage } from "./Message";
/** /**
* A Connection handles the nativeMessaging interaction. * A Connection handles the nativeMessaging interaction.
@ -55,7 +55,7 @@ export class Connection{
return this.post(createMessage('version')); return this.post(createMessage('version'));
} else { } else {
let me = this; let me = this;
return new Promise(function(resolve,reject) { return new Promise(function(resolve) {
Promise.race([ Promise.race([
me.post(createMessage('version')), me.post(createMessage('version')),
new Promise(function(resolve, reject){ new Promise(function(resolve, reject){
@ -63,9 +63,9 @@ export class Connection{
reject(gpgme_error('CONN_TIMEOUT')); reject(gpgme_error('CONN_TIMEOUT'));
}, 500); }, 500);
}) })
]).then(function(result){ ]).then(function(){ // success
resolve(true); resolve(true);
}, function(reject){ }, function(){ // failure
resolve(false); resolve(false);
}); });
}); });
@ -98,12 +98,10 @@ export class Connection{
* information. * information.
*/ */
post(message){ post(message){
if (!this._connection) { if (!message || !(message instanceof GPGME_Message)){
}
if (!message || !message instanceof GPGME_Message){
this.disconnect(); this.disconnect();
return Promise.reject(gpgme_error('PARAM_WRONG', 'Connection.post')); return Promise.reject(gpgme_error(
'PARAM_WRONG', 'Connection.post'));
} }
if (message.isComplete !== true){ if (message.isComplete !== true){
this.disconnect(); this.disconnect();
@ -114,10 +112,10 @@ export class Connection{
let answer = new Answer(message); let answer = new Answer(message);
let listener = function(msg) { let listener = function(msg) {
if (!msg){ if (!msg){
me._connection.onMessage.removeListener(listener) me._connection.onMessage.removeListener(listener);
me._connection.disconnect(); me._connection.disconnect();
reject(gpgme_error('CONN_EMPTY_GPG_ANSWER')); reject(gpgme_error('CONN_EMPTY_GPG_ANSWER'));
} else if (msg.type === "error"){ } else if (msg.type === 'error'){
me._connection.onMessage.removeListener(listener); me._connection.onMessage.removeListener(listener);
me._connection.disconnect(); me._connection.disconnect();
reject(gpgme_error('GNUPG_ERROR', msg.msg)); reject(gpgme_error('GNUPG_ERROR', msg.msg));
@ -130,7 +128,7 @@ export class Connection{
} else if (msg.more === true){ } else if (msg.more === true){
me._connection.postMessage({'op': 'getmore'}); me._connection.postMessage({'op': 'getmore'});
} else { } else {
me._connection.onMessage.removeListener(listener) me._connection.onMessage.removeListener(listener);
me._connection.disconnect(); me._connection.disconnect();
resolve(answer.message); resolve(answer.message);
} }
@ -148,9 +146,9 @@ export class Connection{
reject(gpgme_error('CONN_TIMEOUT')); reject(gpgme_error('CONN_TIMEOUT'));
}, 5000); }, 5000);
}]).then(function(result){ }]).then(function(result){
return result; return result;
}, function(reject){ }, function(reject){
if(!reject instanceof Error) { if(!(reject instanceof Error)) {
me._connection.disconnect(); me._connection.disconnect();
return gpgme_error('GNUPG_ERROR', reject); return gpgme_error('GNUPG_ERROR', reject);
} else { } else {
@ -159,13 +157,14 @@ export class Connection{
}); });
} }
}); });
} }
}; }
/** /**
* A class for answer objects, checking and processing the return messages of * A class for answer objects, checking and processing the return messages of
* the nativeMessaging communication. * the nativeMessaging communication.
* @param {String} operation The operation, to look up validity of returning messages * @param {String} operation The operation, to look up validity of returning
* messages
*/ */
class Answer{ class Answer{
@ -191,49 +190,49 @@ class Answer{
for (let i= 0; i < messageKeys.length; i++){ for (let i= 0; i < messageKeys.length; i++){
let key = messageKeys[i]; let key = messageKeys[i];
switch (key) { switch (key) {
case 'type': case 'type':
if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){ if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){
return gpgme_error('CONN_UNEXPECTED_ANSWER'); return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
break;
case 'more':
break;
default:
//data should be concatenated
if (poa.data.indexOf(key) >= 0){
if (!this._response.hasOwnProperty(key)){
this._response[key] = '';
} }
break; this._response[key] += msg[key];
case 'more': }
break; //params should not change through the message
default: else if (poa.params.indexOf(key) >= 0){
//data should be concatenated if (!this._response.hasOwnProperty(key)){
if (poa.data.indexOf(key) >= 0){ this._response[key] = msg[key];
if (!this._response.hasOwnProperty(key)){
this._response[key] = '';
}
this._response[key] += msg[key];
} }
//params should not change through the message else if (this._response[key] !== msg[key]){
else if (poa.params.indexOf(key) >= 0){ return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]);
if (!this._response.hasOwnProperty(key)){ }
this._response[key] = msg[key]; }
} //infos may be json objects etc. Not yet defined.
else if (this._response[key] !== msg[key]){ // Pushing them into arrays for now
return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]); else if (poa.infos.indexOf(key) >= 0){
} if (!this._response.hasOwnProperty(key)){
this._response[key] = [];
} }
//infos may be json objects etc. Not yet defined.
// Pushing them into arrays for now
else if (poa.infos.indexOf(key) >= 0){
if (!this._response.hasOwnProperty(key)){
this._response[key] = [];
}
if (Array.isArray(msg[key])) { if (Array.isArray(msg[key])) {
for (let i=0; i< msg[key].length; i++) { for (let i=0; i< msg[key].length; i++) {
this._response[key].push(msg[key][i]); this._response[key].push(msg[key][i]);
}
} else {
this._response[key].push(msg[key]);
} }
} else {
this._response[key].push(msg[key]);
} }
else { }
return gpgme_error('CONN_UNEXPECTED_ANSWER'); else {
} return gpgme_error('CONN_UNEXPECTED_ANSWER');
break; }
break;
} }
} }
return true; return true;
@ -256,10 +255,11 @@ class Answer{
msg[keys[i]] = this._response[keys[i]]; msg[keys[i]] = this._response[keys[i]];
} else { } else {
msg[keys[i]] = decodeURIComponent( msg[keys[i]] = decodeURIComponent(
atob(this._response[keys[i]]).split('').map(function(c) { atob(this._response[keys[i]]).split('').map(
return '%' + function(c) {
return '%' +
('00' + c.charCodeAt(0).toString(16)).slice(-2); ('00' + c.charCodeAt(0).toString(16)).slice(-2);
}).join('')); }).join(''));
} }
} else { } else {
msg[keys[i]] = this._response[keys[i]]; msg[keys[i]] = this._response[keys[i]];

View File

@ -16,6 +16,9 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
const err_list = { const err_list = {
@ -102,6 +105,7 @@ export function gpgme_error(code = 'GENERIC_ERROR', info){
return new GPGME_Error(code); return new GPGME_Error(code);
} }
if (err_list[code].type === 'warning'){ if (err_list[code].type === 'warning'){
// eslint-disable-next-line no-console
console.warn(code + ': ' + err_list[code].msg); console.warn(code + ': ' + err_list[code].msg);
} }
return null; return null;
@ -119,7 +123,7 @@ class GPGME_Error extends Error{
super(msg); super(msg);
} else if (err_list.hasOwnProperty(code)){ } else if (err_list.hasOwnProperty(code)){
if (msg){ if (msg){
super(err_list[code].msg + "--" + msg); super(err_list[code].msg + '--' + msg);
} else { } else {
super(err_list[code].msg); super(err_list[code].msg);
} }

View File

@ -16,14 +16,18 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
import { gpgme_error } from "./Errors";
import { GPGME_Key } from "./Key"; import { gpgme_error } from './Errors';
import { GPGME_Key } from './Key';
/** /**
* Tries to return an array of fingerprints, either from input fingerprints or * Tries to return an array of fingerprints, either from input fingerprints or
* from Key objects * from Key objects (openpgp Keys or GPGME_Keys are both expected)
* @param {Key |Array<Key>| GPGME_Key | Array<GPGME_Key>|String|Array<String>} input * @param {Object |Array<Object>| String|Array<String>} input
* @returns {Array<String>} Array of fingerprints. * @returns {Array<String>} Array of fingerprints.
*/ */
@ -48,7 +52,7 @@ export function toKeyIdArray(input){
fpr = input[i].fingerprint; fpr = input[i].fingerprint;
} else if (input[i].hasOwnProperty('primaryKey') && } else if (input[i].hasOwnProperty('primaryKey') &&
input[i].primaryKey.hasOwnProperty('getFingerprint')){ input[i].primaryKey.hasOwnProperty('getFingerprint')){
fpr = input[i].primaryKey.getFingerprint(); fpr = input[i].primaryKey.getFingerprint();
} }
if (isFingerprint(fpr) === true){ if (isFingerprint(fpr) === true){
result.push(fpr); result.push(fpr);
@ -64,7 +68,7 @@ export function toKeyIdArray(input){
} else { } else {
return result; return result;
} }
}; }
/** /**
* check if values are valid hexadecimal values of a specified length * check if values are valid hexadecimal values of a specified length
@ -72,7 +76,7 @@ export function toKeyIdArray(input){
* @param {int} len the expected length of the value * @param {int} len the expected length of the value
*/ */
function hextest(key, len){ function hextest(key, len){
if (!key || typeof(key) !== "string"){ if (!key || typeof(key) !== 'string'){
return false; return false;
} }
if (key.length !== len){ if (key.length !== len){
@ -80,23 +84,18 @@ function hextest(key, len){
} }
let regexp= /^[0-9a-fA-F]*$/i; let regexp= /^[0-9a-fA-F]*$/i;
return regexp.test(key); return regexp.test(key);
}; }
/** /**
* check if the input is a valid Hex string with a length of 40 * check if the input is a valid Hex string with a length of 40
*/ */
export function isFingerprint(string){ export function isFingerprint(string){
return hextest(string, 40); return hextest(string, 40);
}; }
/** /**
* check if the input is a valid Hex string with a length of 16 * check if the input is a valid Hex string with a length of 16
*/ */
export function isLongId(string){ export function isLongId(string){
return hextest(string, 16); return hextest(string, 16);
}; }
// TODO still not needed anywhere
function isShortId(string){
return hextest(string, 8);
};

View File

@ -16,20 +16,14 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/** import { isFingerprint, isLongId } from './Helpers';
* The key class allows to query the information defined in gpgme Key Objects import { gpgme_error } from './Errors';
* (see https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
*
* This is a stub, as the gpgme-json side is not yet implemented
*
*/
import { isFingerprint, isLongId } from './Helpers'
import { gpgme_error } from './Errors'
import { createMessage } from './Message'; import { createMessage } from './Message';
import { permittedOperations } from './permittedOperations';
/** /**
* Validates the fingerprint. * Validates the fingerprint.
@ -44,6 +38,11 @@ export function createKey(fingerprint){
/** /**
* Representing the Keys as stored in GPG * Representing the Keys as stored in GPG
* It allows to query almost all information defined in gpgme Key Objects
* Refer to validKeyProperties for available information, and the gpgme
* documentation on their meaning
* (https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
*
*/ */
export class GPGME_Key { export class GPGME_Key {
@ -102,22 +101,22 @@ export class GPGME_Key {
return gpgme_error('KEY_INVALID'); return gpgme_error('KEY_INVALID');
} }
switch (dataKeys[i]){ switch (dataKeys[i]){
case 'subkeys': case 'subkeys':
this._data.subkeys = []; this._data.subkeys = [];
for (let i=0; i< data.subkeys.length; i++) { for (let i=0; i< data.subkeys.length; i++) {
this._data.subkeys.push( this._data.subkeys.push(
new GPGME_Subkey(data.subkeys[i])); new GPGME_Subkey(data.subkeys[i]));
} }
break; break;
case 'userids': case 'userids':
this._data.userids = []; this._data.userids = [];
for (let i=0; i< data.userids.length; i++) { for (let i=0; i< data.userids.length; i++) {
this._data.userids.push( this._data.userids.push(
new GPGME_UserId(data.userids[i])); new GPGME_UserId(data.userids[i]));
} }
break; break;
default: default:
this._data[dataKeys[i]] = data[dataKeys[i]]; this._data[dataKeys[i]] = data[dataKeys[i]];
} }
} }
return this; return this;
@ -162,11 +161,6 @@ export class GPGME_Key {
} }
} }
get armored () {
return this.get('armored');
//TODO exception if empty
}
/** /**
* Reloads the Key from gnupg * Reloads the Key from gnupg
*/ */
@ -188,7 +182,7 @@ export class GPGME_Key {
} }
}, function (error) { }, function (error) {
reject(gpgme_error('GNUPG_ERROR'), error); reject(gpgme_error('GNUPG_ERROR'), error);
}) });
}); });
} }
@ -197,7 +191,7 @@ export class GPGME_Key {
* from gpg. * from gpg.
* @returns {Promise<String>} * @returns {Promise<String>}
*/ */
getArmor(){ getArmor(){
let me = this; let me = this;
return new Promise(function(resolve, reject) { return new Promise(function(resolve, reject) {
if (!me._data.fingerprint){ if (!me._data.fingerprint){
@ -249,15 +243,16 @@ export class GPGME_Key {
} }
} }
} else { } else {
reject(gpgme_error('CONN_UNEXPECTED_ANSWER')) reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
} }
}, function(error){ }, function(error){
}) reject(error);
});
}); });
} }
/** /**
* Convenience function to be directly used as properties of the Key * Convenience functions to be directly used as properties of the Key
* Notice that these rely on cached info and may be outdated. Use the async * Notice that these rely on cached info and may be outdated. Use the async
* get(property, false) if you need the most current info * get(property, false) if you need the most current info
*/ */
@ -280,8 +275,8 @@ export class GPGME_Key {
/** /**
* Deletes the public Key from the GPG Keyring. Note that a deletion of a * Deletes the public Key from the GPG Keyring. Note that a deletion of a
* secret key is not supported by the native backend. * secret key is not supported by the native backend.
* @returns {Promise<Boolean>} Success if key was deleted, rejects with a GPG error * @returns {Promise<Boolean>} Success if key was deleted, rejects with a
* otherwise * GPG error otherwise
*/ */
delete(){ delete(){
let me = this; let me = this;
@ -295,7 +290,7 @@ export class GPGME_Key {
resolve(result.success); resolve(result.success);
}, function(error){ }, function(error){
reject(error); reject(error);
}) });
}); });
} }
} }
@ -378,37 +373,37 @@ const validUserIdProperties = {
}, },
'uid': function(value){ 'uid': function(value){
if (typeof(value) === 'string' || value === ''){ if (typeof(value) === 'string' || value === ''){
return true;; return true;
} }
return false; return false;
}, },
'validity': function(value){ 'validity': function(value){
if (typeof(value) === 'string'){ if (typeof(value) === 'string'){
return true;; return true;
} }
return false; return false;
}, },
'name': function(value){ 'name': function(value){
if (typeof(value) === 'string' || value === ''){ if (typeof(value) === 'string' || value === ''){
return true;; return true;
} }
return false; return false;
}, },
'email': function(value){ 'email': function(value){
if (typeof(value) === 'string' || value === ''){ if (typeof(value) === 'string' || value === ''){
return true;; return true;
} }
return false; return false;
}, },
'address': function(value){ 'address': function(value){
if (typeof(value) === 'string' || value === ''){ if (typeof(value) === 'string' || value === ''){
return true;; return true;
} }
return false; return false;
}, },
'comment': function(value){ 'comment': function(value){
if (typeof(value) === 'string' || value === ''){ if (typeof(value) === 'string' || value === ''){
return true;; return true;
} }
return false; return false;
}, },
@ -449,8 +444,8 @@ const validSubKeyProperties = {
return typeof(value) === 'boolean'; return typeof(value) === 'boolean';
}, },
'pubkey_algo_name': function(value){ 'pubkey_algo_name': function(value){
return typeof(value) === 'string'; return typeof(value) === 'string';
// TODO: check against list of known?[''] // TODO: check against list of known?['']
}, },
'pubkey_algo_string': function(value){ 'pubkey_algo_string': function(value){
return typeof(value) === 'string'; return typeof(value) === 'string';
@ -471,7 +466,7 @@ const validSubKeyProperties = {
'expires': function(value){ 'expires': function(value){
return (Number.isInteger(value) && value > 0); return (Number.isInteger(value) && value > 0);
} }
} };
const validKeyProperties = { const validKeyProperties = {
//TODO better validation? //TODO better validation?
'fingerprint': function(value){ 'fingerprint': function(value){
@ -546,4 +541,4 @@ const validKeyProperties = {
return typeof(value) === 'boolean'; return typeof(value) === 'boolean';
} }
} };

View File

@ -16,8 +16,12 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
import {createMessage} from './Message'; import {createMessage} from './Message';
import {createKey} from './Key'; import {createKey} from './Key';
import { isFingerprint } from './Helpers'; import { isFingerprint } from './Helpers';
@ -99,18 +103,22 @@ export class GPGME_Keyring {
/** /**
* *
* @param {String} armored Armored Key block of the Kex(s) to be imported into gnupg * @param {String} armored Armored Key block of the Kex(s) to be imported
* @param {Boolean} prepare_sync prepare the keys for synched use (see getKeys()). * into gnupg
* @returns {Promise<Array<Object>>} An array of objects for the Keys considered. * @param {Boolean} prepare_sync prepare the keys for synched use
* Key.key The key itself as a GPGME_Key * (see getKeys()).
* Key.status String: * @returns {Promise<Array<Object>>} An array of objects for the Keys
* considered:
* Key.key <Object>: The key itself as a GPGME_Key
* Key.status <String>:
* 'nochange' if the Key was not changed, * 'nochange' if the Key was not changed,
* 'newkey' if the Key was imported in gpg, and did not exist previously, * 'newkey' if the Key was imported in gpg, and did not exist
* 'change' if the key existed, but details were updated. For details, * previously,
* Key.changes is available. * 'change' if the key existed, but details were updated. For
* Key.changes.userId: Boolean userIds changed * details, Key.changes is available.
* Key.changes.signature: Boolean signatures changed * Key.changes.userId: <Boolean> userIds changed
* Key.changes.subkey: Boolean subkeys changed * Key.changes.signature: <Boolean> signatures changed
* Key.changes.subkey: <Boolean> subkeys changed
* // TODO: not yet implemented: Information about Keys that failed * // TODO: not yet implemented: Information about Keys that failed
* (e.g. malformed Keys, secretKeys are not accepted) * (e.g. malformed Keys, secretKeys are not accepted)
*/ */
@ -125,7 +133,7 @@ export class GPGME_Keyring {
msg.post().then(function(response){ msg.post().then(function(response){
let infos = {}; let infos = {};
let fprs = []; let fprs = [];
for (var res=0; res < response.result[0].imports.length; res++) { for (let res=0; res < response.result[0].imports.length; res++){
let result = response.result[0].imports[res]; let result = response.result[0].imports[res];
let status = ''; let status = '';
if (result.status === 0){ if (result.status === 0){

View File

@ -16,9 +16,13 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
import { permittedOperations } from './permittedOperations'
import { gpgme_error } from './Errors' import { permittedOperations } from './permittedOperations';
import { gpgme_error } from './Errors';
import { Connection } from './Connection'; import { Connection } from './Connection';
export function createMessage(operation){ export function createMessage(operation){
@ -46,7 +50,7 @@ export class GPGME_Message {
} }
set operation (op){ set operation (op){
if (typeof(op) === "string"){ if (typeof(op) === 'string'){
if (!this._msg){ if (!this._msg){
this._msg = {}; this._msg = {};
} }
@ -67,10 +71,10 @@ export class GPGME_Message {
} }
get expected() { get expected() {
if (this._expected === "base64"){ if (this._expected === 'base64'){
return this._expected; return this._expected;
} }
return "string"; return 'string';
} }
/** /**
@ -98,52 +102,50 @@ export class GPGME_Message {
} }
let checktype = function(val){ let checktype = function(val){
switch(typeof(val)){ switch(typeof(val)){
case 'string': case 'string':
if (poparam.allowed.indexOf(typeof(val)) >= 0 if (poparam.allowed.indexOf(typeof(val)) >= 0
&& val.length > 0) { && val.length > 0) {
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); return gpgme_error('PARAM_WRONG');
break; case 'number':
case 'number': if (
if ( poparam.allowed.indexOf('number') >= 0
poparam.allowed.indexOf('number') >= 0
&& isNaN(value) === false){ && isNaN(value) === false){
return true; return true;
}
return gpgme_error('PARAM_WRONG');
case 'boolean':
if (poparam.allowed.indexOf('boolean') >= 0){
return true;
}
return gpgme_error('PARAM_WRONG');
case 'object':
if (Array.isArray(val)){
if (poparam.array_allowed !== true){
return gpgme_error('PARAM_WRONG');
} }
return gpgme_error('PARAM_WRONG'); for (let i=0; i < val.length; i++){
break; let res = checktype(val[i]);
case 'boolean': if (res !== true){
if (poparam.allowed.indexOf('boolean') >= 0){ return res;
}
}
if (val.length > 0) {
return true;
}
} else if (val instanceof Uint8Array){
if (poparam.allowed.indexOf('Uint8Array') >= 0){
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); return gpgme_error('PARAM_WRONG');
break; } else {
case 'object':
if (Array.isArray(val)){
if (poparam.array_allowed !== true){
return gpgme_error('PARAM_WRONG');
}
for (let i=0; i < val.length; i++){
let res = checktype(val[i]);
if (res !== true){
return res;
}
}
if (val.length > 0) {
return true;
}
} else if (val instanceof Uint8Array){
if (poparam.allowed.indexOf('Uint8Array') >= 0){
return true;
}
return gpgme_error('PARAM_WRONG');
} else {
return gpgme_error('PARAM_WRONG');
}
break;
default:
return gpgme_error('PARAM_WRONG'); return gpgme_error('PARAM_WRONG');
}
break;
default:
return gpgme_error('PARAM_WRONG');
} }
}; };
let typechecked = checktype(value); let typechecked = checktype(value);
@ -173,7 +175,6 @@ export class GPGME_Message {
let msg_params = Object.keys(this._msg); let msg_params = Object.keys(this._msg);
for (let i=0; i < reqParams.length; i++){ for (let i=0; i < reqParams.length; i++){
if (msg_params.indexOf(reqParams[i]) < 0){ if (msg_params.indexOf(reqParams[i]) < 0){
console.log(reqParams[i] + ' missing');
return false; return false;
} }
} }

View File

@ -16,12 +16,16 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
import {GPGME_Message, createMessage} from './Message'
import {toKeyIdArray} from "./Helpers" import {GPGME_Message, createMessage} from './Message';
import { gpgme_error } from "./Errors" import {toKeyIdArray} from './Helpers';
import { GPGME_Keyring } from "./Keyring"; import { gpgme_error } from './Errors';
import { GPGME_Keyring } from './Keyring';
export class GpgME { export class GpgME {
/** /**
@ -32,7 +36,7 @@ export class GpgME {
this._config = config; this._config = config;
} }
set Keyring(keyring){ set Keyring(keyring){
if (keyring && keyring instanceof GPGME_Keyring){ if (keyring && keyring instanceof GPGME_Keyring){
this._Keyring = keyring; this._Keyring = keyring;
} }
@ -47,13 +51,19 @@ export class GpgME {
/** /**
* Encrypt (and optionally sign) a Message * Encrypt (and optionally sign) a Message
* @param {String|Object} data text/data to be encrypted as String. Also accepts Objects with a getText method * @param {String|Object} data text/data to be encrypted as String. Also
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} publicKeys Keys used to encrypt the message * accepts Objects with a getText method
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} secretKeys (optional) Keys used to sign the message * @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} publicKeys
* @param {Boolean} base64 (optional) The data is already considered to be in base64 encoding * Keys used to encrypt the message
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} secretKeys
* (optional) Keys used to sign the message
* @param {Boolean} base64 (optional) The data is already considered to be
* in base64 encoding
* @param {Boolean} armor (optional) Request the output as armored block * @param {Boolean} armor (optional) Request the output as armored block
* @param {Boolean} wildcard (optional) If true, recipient information will not be added to the message * @param {Boolean} wildcard (optional) If true, recipient information will
* @param {Object} additional use additional gpg options (refer to src/permittedOperations) * not be added to the message
* @param {Object} additional use additional gpg options
* (refer to src/permittedOperations)
* @returns {Promise<Object>} Encrypted message: * @returns {Promise<Object>} Encrypted message:
* data: The encrypted message * data: The encrypted message
* base64: Boolean indicating whether data is base64 encoded. * base64: Boolean indicating whether data is base64 encoded.
@ -64,7 +74,7 @@ export class GpgME {
){ ){
let msg = createMessage('encrypt'); let msg = createMessage('encrypt');
if (msg instanceof Error){ if (msg instanceof Error){
return Promise.reject(msg) return Promise.reject(msg);
} }
msg.setParameter('armor', armor); msg.setParameter('armor', armor);
msg.setParameter('always-trust', true); msg.setParameter('always-trust', true);
@ -80,7 +90,7 @@ export class GpgME {
putData(msg, data); putData(msg, data);
if (wildcard === true){ if (wildcard === true){
msg.setParameter('throw-keyids', true); msg.setParameter('throw-keyids', true);
}; }
if (additional){ if (additional){
let additional_Keys = Object.keys(additional); let additional_Keys = Object.keys(additional);
for (let k = 0; k < additional_Keys.length; k++) { for (let k = 0; k < additional_Keys.length; k++) {
@ -97,14 +107,16 @@ export class GpgME {
/** /**
* Decrypt a Message * Decrypt a Message
* @param {String|Object} data text/data to be decrypted. Accepts Strings and Objects with a getText method * @param {String|Object} data text/data to be decrypted. Accepts Strings
* @param {Boolean} base64 (optional) Response is expected to be base64 encoded * and Objects with a getText method
* @param {Boolean} base64 (optional) Response is expected to be base64
* encoded
* @returns {Promise<Object>} decrypted message: * @returns {Promise<Object>} decrypted message:
data: The decrypted data. This may be base64 encoded. data: The decrypted data. This may be base64 encoded.
base64: Boolean indicating whether data is base64 encoded. base64: Boolean indicating whether data is base64 encoded.
mime: A Boolean indicating whether the data is a MIME object. mime: A Boolean indicating whether the data is a MIME object.
signatures: Array of signature Objects TODO not yet implemented. signatures: Array of signature Objects TODO not yet implemented.
// should be an object that can tell if all signatures are valid etc. // should be an object that can tell if all signatures are valid .
* @async * @async
*/ */
decrypt(data, base64=false){ decrypt(data, base64=false){
@ -124,14 +136,16 @@ export class GpgME {
/** /**
* Sign a Message * Sign a Message
* @param {String|Object} data text/data to be decrypted. Accepts Strings and Objects with a gettext methos * @param {String|Object} data text/data to be decrypted. Accepts Strings
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} keys The key/keys to use for signing * and Objects with a gettext methos
* @param {GPGME_Key|String|Array<String>|Array<GPGME_Key>} keys The
* key/keys to use for signing
* @param {*} mode The signing mode. Currently supported: * @param {*} mode The signing mode. Currently supported:
* 'clearsign': (default) The Message is embedded into the signature * 'clearsign': (default) The Message is embedded into the signature
* 'detached': The signature is stored separately * 'detached': The signature is stored separately
* @param {*} base64 input is considered base64 * @param {*} base64 input is considered base64
* @returns {Promise<Object>} * @returns {Promise<Object>}
* data: The resulting data. In clearsign mode this includes the signature * data: The resulting data. Includes the signature in clearsign mode
* signature: The detached signature (if in detached mode) * signature: The detached signature (if in detached mode)
* @async * @async
*/ */
@ -154,7 +168,6 @@ export class GpgME {
if (mode === 'detached') { if (mode === 'detached') {
msg.expected = 'base64'; msg.expected = 'base64';
} }
let me = this;
return new Promise(function(resolve,reject) { return new Promise(function(resolve,reject) {
msg.post().then( function(message) { msg.post().then( function(message) {
if (mode === 'clearsign'){ if (mode === 'clearsign'){
@ -169,7 +182,7 @@ export class GpgME {
} }
}, function(error){ }, function(error){
reject(error); reject(error);
}) });
}); });
} }
} }
@ -180,7 +193,7 @@ export class GpgME {
* @param {*} data The data to enter * @param {*} data The data to enter
*/ */
function putData(message, data){ function putData(message, data){
if (!message || !message instanceof GPGME_Message ) { if (!message || !(message instanceof GPGME_Message) ) {
return gpgme_error('PARAM_WRONG'); return gpgme_error('PARAM_WRONG');
} }
if (!data){ if (!data){

View File

@ -16,16 +16,21 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
import { GpgME } from "./gpgmejs";
import { gpgme_error } from "./Errors"; import { GpgME } from './gpgmejs';
import { Connection } from "./Connection"; import { gpgme_error } from './Errors';
import { defaultConf, availableConf } from "./Config"; import { Connection } from './Connection';
import { defaultConf, availableConf } from './Config';
/** /**
* Initializes a nativeMessaging Connection and returns a GPGMEjs object * Initializes a nativeMessaging Connection and returns a GPGMEjs object
* @param {Object} config Configuration. See Config.js for available parameters. Still TODO * @param {Object} config Configuration. See Config.js for available parameters.
* Still TODO
*/ */
function init(config){ function init(config){
let _conf = parseconfiguration(config); let _conf = parseconfiguration(config);
@ -41,16 +46,16 @@ function init(config){
} else { } else {
reject(gpgme_error('CONN_NO_CONNECT')); reject(gpgme_error('CONN_NO_CONNECT'));
} }
}, function(error){ }, function(){ //unspecific connection error. Should not happen
reject(gpgme_error('CONN_NO_CONNECT')); reject(gpgme_error('CONN_NO_CONNECT'));
}); });
}); });
} }
function parseconfiguration(rawconfig = {}){ function parseconfiguration(rawconfig = {}){
if ( typeof(rawconfig) !== 'object'){ if ( typeof(rawconfig) !== 'object'){
return gpgme_error('PARAM_WRONG'); return gpgme_error('PARAM_WRONG');
}; }
let result_config = {}; let result_config = {};
let conf_keys = Object.keys(rawconfig); let conf_keys = Object.keys(rawconfig);
@ -75,8 +80,8 @@ function parseconfiguration(rawconfig = {}){
} }
} }
return result_config; return result_config;
}; }
export default { export default {
init: init init: init
} };

View File

@ -16,9 +16,12 @@
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>. * License along with this program; if not, see <http://www.gnu.org/licenses/>.
* SPDX-License-Identifier: LGPL-2.1+ * SPDX-License-Identifier: LGPL-2.1+
*
* Author(s):
* Maximilian Krambach <mkrambach@intevation.de>
*/ */
/** /**
* Definition of the possible interactions with gpgme-json. * Definition of the possible interactions with gpgme-json.
* operation: <Object> * operation: <Object>
required: Array<Object> required: Array<Object>
@ -41,7 +44,7 @@
infos: Array<*> arbitrary information that may result in a list infos: Array<*> arbitrary information that may result in a list
} }
} }
*/ */
export const permittedOperations = { export const permittedOperations = {
encrypt: { encrypt: {
@ -65,7 +68,7 @@ export const permittedOperations = {
array_allowed: true array_allowed: true
}, },
'chunksize': { 'chunksize': {
allowed: ['number'] allowed: ['number']
}, },
'base64': { 'base64': {
allowed: ['boolean'] allowed: ['boolean']
@ -154,7 +157,8 @@ export const permittedOperations = {
}, },
'mode': { 'mode': {
allowed: ['string'], allowed: ['string'],
allowed_data: ['detached', 'clearsign'] // TODO 'opaque' not used allowed_data: ['detached', 'clearsign']
// TODO 'opaque' is not used, but available on native app
}, },
'base64': { 'base64': {
allowed: ['boolean'] allowed: ['boolean']
@ -166,14 +170,17 @@ export const permittedOperations = {
answer: { answer: {
type: ['signature', 'ciphertext'], type: ['signature', 'ciphertext'],
data: ['data'], // Unless armor mode is used a Base64 encoded binary data: ['data'], // Unless armor mode is used a Base64 encoded binary
// signature. In armor mode a string with an armored // signature. In armor mode a string with an armored
// OpenPGP or a PEM message. // OpenPGP or a PEM message.
params: ['base64'] params: ['base64']
} }
}, },
// note: For the meaning of the optional keylist flags, refer to
// https://www.gnupg.org/documentation/manuals/gpgme/Key-Listing-Mode.html
keylist:{ keylist:{
required: {}, required: {},
optional: { optional: {
'protocol': { 'protocol': {
allowed: ['string'], allowed: ['string'],
@ -182,8 +189,6 @@ export const permittedOperations = {
'chunksize': { 'chunksize': {
allowed: ['number'], allowed: ['number'],
}, },
// note: For the meaning of the flags, refer to
// https://www.gnupg.org/documentation/manuals/gpgme/Key-Listing-Mode.html
'secret': { 'secret': {
allowed: ['boolean'] allowed: ['boolean']
}, },
@ -305,11 +310,6 @@ export const permittedOperations = {
infos: [] infos: []
} }
}, },
/**
*TBD get armored secret different treatment from keyinfo!
* TBD key modification?
*/
version: { version: {
required: {}, required: {},
@ -321,4 +321,11 @@ export const permittedOperations = {
params:[] params:[]
} }
} }
}
/**
* TBD handling of secrets
* TBD key modification?
* TBD: key generation
*/
};

View File

@ -32,7 +32,7 @@ import { GPGME_Keyring } from './src/Keyring';
import {GPGME_Message, createMessage} from './src/Message'; import {GPGME_Message, createMessage} from './src/Message';
mocha.setup('bdd'); mocha.setup('bdd');
var expect = chai.expect; const expect = chai.expect;
chai.config.includeStack = true; chai.config.includeStack = true;
function unittests (){ function unittests (){
@ -266,79 +266,49 @@ function unittests (){
expect(keyring.getKeys).to.be.a('function'); expect(keyring.getKeys).to.be.a('function');
}); });
it('Loading Keys from Keyring, to be used synchronously', function(done){ it('Loading Keys from Keyring, to be used synchronously',
let keyring = new GPGME_Keyring; function(done){
keyring.getKeys(null, true).then(function(result){ let keyring = new GPGME_Keyring;
expect(result).to.be.an('array'); keyring.getKeys(null, true).then(function(result){
expect(result[0]).to.be.an.instanceof(GPGME_Key); expect(result).to.be.an('array');
expect(result[0].get('armored')).to.be.a('string'); expect(result[0]).to.be.an.instanceof(GPGME_Key);
expect(result[0].get('armored')).to.include( expect(result[0].get('armored')).to.be.a('string');
'-----END PGP PUBLIC KEY BLOCK-----'); expect(result[0].get('armored')).to.include(
done(); '-----END PGP PUBLIC KEY BLOCK-----');
}); done();
}); });
}
);
it('Loading specific Key from Keyring, to be used synchronously', function(done){ it('Loading specific Key from Keyring, to be used synchronously',
let keyring = new GPGME_Keyring; function(done){
keyring.getKeys(kp.validKeyFingerprint, true).then(function(result){ let keyring = new GPGME_Keyring;
expect(result).to.be.an('array'); keyring.getKeys(kp.validKeyFingerprint, true).then(
expect(result[0]).to.be.an.instanceof(GPGME_Key); function(result){
expect(result[0].get('armored')).to.be.a('string'); expect(result).to.be.an('array');
expect(result[0].get('armored')).to.include( expect(result[0]).to.be.an.instanceof(GPGME_Key);
'-----END PGP PUBLIC KEY BLOCK-----'); expect(result[0].get('armored')).to.be.a('string');
done(); expect(result[0].get('armored')).to.include(
}); '-----END PGP PUBLIC KEY BLOCK-----');
}); done();
}
);
}
);
it('Querying non-existing Key from Keyring', function(done){ it('Querying non-existing Key from Keyring', function(done){
let keyring = new GPGME_Keyring; let keyring = new GPGME_Keyring;
keyring.getKeys(kp.invalidKeyFingerprint, true).then(function(result){ keyring.getKeys(kp.invalidKeyFingerprint, true).then(
expect(result).to.be.an('array'); function(result){
expect(result.length).to.equal(0); expect(result).to.be.an('array');
done(); expect(result.length).to.equal(0);
}); done();
}
);
}); });
}); });
// describe('Keyring import/export', function(){
// before(function(done) {
// let keyring = new GPGME_Keyring;
// keyring.getKeys(ak.fingerprint, false).then(function(result){
// if (result.length === 1){
// result[0].delete().then(function(delete_result){
// if (delete_result === true){
// done();
// }
// });
// } else {
// done();
// }
// });
// });
// it('Import Public Key', function(done){
// keyring.importKey(ak.key).then(function(result){
// expect(result).to.be.an('array');
// expect(result[0].key).to.be.an.instanceof(GPGME_Key);
// expect(result[0].changed).to.equal('newkey');
// expect(result[0].key.keyring).to.equal(ak.fingerprint);
// done();
// });
// });
// it('Update Public Key', function(done){
// keyring.importKey(ak.key).then(function(result){
// expect(result).to.be.an('array');
// expect(result[0].key).to.be.an.instanceof(GPGME_Key);
// expect(result[0].changed).to.equal('change');
// expect(result[0].changes.userId).to.be.true;
// expect(result[0].changes.subkeys).to.be.false;
// expect(result[0].key.keyring).to.equal(ak.fingerprint);
// done();
// });
// });
// });
describe('GPGME_Message', function(){ describe('GPGME_Message', function(){
it('creating encrypt Message', function(){ it('creating encrypt Message', function(){