diff --git a/lang/js/BrowserTestExtension/tests/KeyImportExport.js b/lang/js/BrowserTestExtension/tests/KeyImportExport.js index f57877f4..b3d95bbc 100644 --- a/lang/js/BrowserTestExtension/tests/KeyImportExport.js +++ b/lang/js/BrowserTestExtension/tests/KeyImportExport.js @@ -1,152 +1,152 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach * Raimund Renkert */ /* global describe, it, expect, before, afterEach, Gpgmejs*/ /* global ImportablePublicKey, inputvalues */ describe('Key importing', function () { const fpr = ImportablePublicKey.fingerprint; const pubKey = ImportablePublicKey.key; const changedKey = ImportablePublicKey.keyChangedUserId; let context = null; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; context.Keyring.getKeys({ pattern: fpr }).then( function (result){ if (result.length === 1) { result[0].delete().then(function (){ done(); },function (){ done(); }); } else { done(); } }); }); }); afterEach(function (done){ // delete the test key if still present context.Keyring.getKeys({ pattern: fpr }).then( function (result){ if (result.length === 1) { result[0].delete().then(function (){ done(); },function (){ done(); }); } else { done(); } }); }); it('Importing Key', function (done) { context.Keyring.getKeys({ pattern: fpr }).then(function (result){ expect(result).to.be.an('array'); expect(result.length).to.equal(0); context.Keyring.importKey(pubKey).then(function (result){ expect(result.Keys).to.be.an('array'); expect(result.Keys[0]).to.not.be.undefined; expect(result.Keys[0].key).to.be.an('object'); expect(result.Keys[0].key.fingerprint).to.equal(fpr); expect(result.Keys[0].status).to.equal('newkey'); expect(result.summary.considered).to.equal(1); expect(result.summary.imported).to.equal(1); done(); }); }); }); it('Updating Key', function (done){ context.Keyring.importKey(pubKey) .then(function (result){ expect(result.Keys[0].key).to.not.be.undefined; expect(result.Keys[0].status).to.equal('newkey'); context.Keyring.importKey(changedKey).then(function (res){ expect(res.Keys[0].key).to.be.an('object'); expect(res.Keys[0].key.fingerprint).to.equal(fpr); expect(res.Keys[0].status).to.equal('change'); expect(res.Keys[0].changes.userId).to.be.true; expect(res.Keys[0].changes.subkey).to.be.false; expect(res.Keys[0].changes.signature).to.be.true; expect(res.summary.considered).to.equal(1); done(); }); }); }); it('Deleting Key', function (done) { context.Keyring.importKey(pubKey).then(function (result){ expect(result.Keys[0].key).to.be.an('object'); expect(result.Keys[0].key.fingerprint).to.equal(fpr); result.Keys[0].key.delete().then(function (result){ expect(result).to.be.true; done(); }); }); }); it('Import result feedback', function (done){ context.Keyring.importKey(pubKey, true).then(function (result){ expect(result).to.be.an('object'); expect(result.Keys[0]).to.be.an('object'); expect(result.Keys[0].key.fingerprint).to.equal(fpr); expect(result.Keys[0].status).to.equal('newkey'); result.Keys[0].key.getArmor().then(function (armor){ expect(armor).to.be.a('string'); done(); }); }); }); it('exporting armored Key with getKeysArmored', function (done) { context.Keyring.importKey(pubKey).then(function (){ context.Keyring.getKeysArmored({ pattern: fpr }) .then(function (result){ expect(result).to.be.an('object'); expect(result.armored).to.be.a('string'); expect(result.secret_fprs).to.be.undefined; done(); }); }); }); it('Exporting Key (including secret fingerprints)', function (done) { const key_secret = inputvalues.encrypt.good.fingerprint; context.Keyring.getKeysArmored({ pattern: key_secret, with_secret_fpr: true }) .then(function (result){ expect(result).to.be.an('object'); expect(result.armored).to.be.a('string'); expect(result.secret_fprs).to.be.an('array'); expect(result.secret_fprs[0]).to.equal(key_secret); done(); }); }); }); \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/tests/KeyInfos.js b/lang/js/BrowserTestExtension/tests/KeyInfos.js index 553aedb9..d1229584 100644 --- a/lang/js/BrowserTestExtension/tests/KeyInfos.js +++ b/lang/js/BrowserTestExtension/tests/KeyInfos.js @@ -1,59 +1,59 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, before, Gpgmejs */ /* global inputvalues*/ describe('Key information', function () { let context = null; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('A fingerprint is consistently returned upper case hex', function (done){ const mixedCase = inputvalues.encrypt.good.fingerprint_mixedcase; context.Keyring.getKeys({ pattern: mixedCase }).then(function (result){ expect(result).to.be.an('array'); expect(result.length).to.equal(1); expect(result[0].fingerprint).to.equal(mixedCase.toUpperCase()); done(); }); }); it('A userId keeps their encoding', function (done){ context.Keyring.importKey(inputvalues.publicKeyNonAscii.key, true) .then(function (result){ expect(result.Keys[0]).to.be.an('object'); const user = result.Keys[0].key.get('userids')[0]; expect(user.get('name')).to.equal( inputvalues.publicKeyNonAscii.userid); result.Keys[0].key.delete().then(function (){ done(); }); }); }); }); diff --git a/lang/js/BrowserTestExtension/tests/decryptTest.js b/lang/js/BrowserTestExtension/tests/decryptTest.js index 61a3fab9..5817eb49 100644 --- a/lang/js/BrowserTestExtension/tests/decryptTest.js +++ b/lang/js/BrowserTestExtension/tests/decryptTest.js @@ -1,114 +1,114 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, before, expect, Gpgmejs */ /* global bigString, inputvalues, sabotageMsg, binaryData, filename_files */ describe('Decryption', function () { let context = null; const good_fpr = inputvalues.encrypt.good.fingerprint; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout:2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('Decryption of random string fails', function (done) { let data = bigString(20 * 1024); context.decrypt({ data: data }).then( function (){}, function (error){ expect(error).to.be.an('error'); expect(error.code).to.equal('GNUPG_ERROR'); done(); }); }); it('Decryption of slightly corrupted message fails', function (done) { const data = bigString(10000); context.encrypt({ data: data, publicKeys:good_fpr }).then( function (enc){ context.decrypt({ data: sabotageMsg(enc.data) }).then( function (){}, function (error){ expect(error).to.be.an('error'); expect(error.code).to.equal('GNUPG_ERROR'); done(); }); }); }).timeout(5000); it('decrypt/verify operations return proper information', function (done){ const data = inputvalues.encryptSignedMessage; context.decrypt({ data: data }).then(function (result){ expect(result).to.be.an('object'); expect(result.signatures).to.be.an('object'); expect(result.signatures.all_valid).to.be.true; expect(result.signatures.count).to.equal(1); expect(result.signatures.signatures.good).to.be.an('array'); expect( result.signatures.signatures.good[0].fingerprint).to.equal( good_fpr); done(); }); }); it('decrypt of a png, result as base64', function (done){ const data = binaryData.encryptedArmored; context.decrypt({ data: data, expect: 'base64' }) .then(function (result){ expect(result.data).to.be.a('String'); expect(result.data).to.equal(binaryData.base64); expect(result.format).to.equal('base64'); done(); }); }); it('decrypt of a png, result as Uint8Array', function (done){ const data = binaryData.encryptedArmored; context.decrypt({ data: data, expect: 'uint8' }) .then(function (result){ expect(result.data).to.be.an('Uint8Array'); expect(result.format).to.equal('uint8'); done(); }); }); for (let i=0; i < filename_files.length; i++) { it ( 'decrypted file_names keep correct encoding (' + i + ')', function (done){ context.decrypt({ data:filename_files[i].data }) .then(function (answer){ expect(answer.file_name).to.equal( filename_files[i].name); done(); }); }); } }); \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js index c10c5d06..b4e4f3fb 100644 --- a/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptDecryptTest.js @@ -1,200 +1,200 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, before, Gpgmejs */ /* global inputvalues, encryptedData, bigString, bigBoringString */ describe('Encryption and Decryption', function (){ let context = null; let good_fpr = inputvalues.encrypt.good.fingerprint; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('Successful encrypt and decrypt simple string', function (done) { let data = inputvalues.encrypt.good.data; context.encrypt({ data: data, publicKeys: good_fpr }).then( function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); context.decrypt({ data: answer.data }).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal( inputvalues.encrypt.good.data); done(); }); }); }); it('Decrypt simple non-ascii', function (done) { let data = encryptedData; context.decrypt({ data: data }).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal( '¡Äußerste µ€ før ñoquis@hóme! Добрый день\n'); done(); }); }).timeout(3000); it('Trailing whitespace and different line endings', function (done) { const data = 'Keks. \rKeks \n Keks \r\n'; context.encrypt({ data: data, publicKeys: good_fpr }).then( function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); context.decrypt({ data: answer.data }).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(5000); it('Random data, as string', function (done) { let data = bigString(1000); context.encrypt({ data:data, publicKeys: good_fpr }).then( function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); context.decrypt({ data: answer.data }).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(3000); it('Data, input as base64', function (done) { let data = inputvalues.encrypt.good.data; let b64data = btoa(data); context.encrypt({ data: b64data, publicKeys: good_fpr, base64: true }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); context.decrypt({ data: answer.data }).then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(3000); it('Random data, input as base64', function (done) { let data = bigBoringString(0.001); let b64data = btoa(data); context.encrypt( { data: b64data, publicKeys: good_fpr, base64: true }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); context.decrypt({ data:answer.data }).then( function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(3000); it('Random data, original data is and should stay base64 encoded', function (done) { let data = bigBoringString(0.001); let b64data = btoa(data); context.encrypt( { data: b64data, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); context.decrypt({ data:answer.data, expect: 'base64' }) .then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(b64data); done(); }); }); }).timeout(3000); 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 + ')', function (done) { let input = inputvalues.encrypt.good.data_nonascii_32[j]; expect(input).to.have.length(32); let data = ''; for (let i=0; i < 34 * 1024; i++){ data += input; } context.encrypt({ data: data, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include( 'BEGIN PGP MESSAGE'); expect(answer.data).to.include( 'END PGP MESSAGE'); context.decrypt({ data: answer.data }) .then(function (result) { expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(5000); } }); diff --git a/lang/js/BrowserTestExtension/tests/encryptTest.js b/lang/js/BrowserTestExtension/tests/encryptTest.js index d97b458d..1017d714 100644 --- a/lang/js/BrowserTestExtension/tests/encryptTest.js +++ b/lang/js/BrowserTestExtension/tests/encryptTest.js @@ -1,159 +1,159 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, before, Gpgmejs */ /* global inputvalues, fixedLengthString, bigString */ describe('Encryption', function () { let context = null; const good_fpr = inputvalues.encrypt.good.fingerprint; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('Successful encrypt', function (done) { const data = inputvalues.encrypt.good.data; context.encrypt({ data: data, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); done(); }); }); it( 'encrypt with \'armor\': true should returned an armored block', function (done){ const data = bigString(1000); context.encrypt({ data: data, publicKeys: good_fpr, armor: true }) .then(function (answer){ expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); expect(answer.format).to.equal('ascii'); done(); }); }); it( 'encrypt with \'armor\': false and \'expected\': \'uint8\' returns ' + 'an Uint8Array', function (done) { const data = bigString(1000); context.encrypt({ data: data, publicKeys: good_fpr, armor: false, expect: 'uint8' }).then(function (answer){ expect(answer).to.not.be.empty; expect(answer.data).to.be.a('Uint8Array'); expect(answer.format).to.equal('uint8'); done(); }); }); it( 'encrypt with \'armor\': false and \'expected\': \'base64\' returns ' + 'a base64 string', function (done) { const data = bigString(1000); context.encrypt({ data: data, publicKeys: good_fpr, armor: false, expect: 'base64' }).then(function (answer){ expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.format).to.equal('base64'); done(); }); }); const sizes = [5,20,50]; for (let i=0; i < sizes.length; i++) { it('Successful encrypt a ' + sizes[i] + 'MB message', function (done) { const data = fixedLengthString(sizes[i]); context.encrypt({ data: data, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); done(); }); }).timeout(20000); } it('Sending encryption without keys fails', function (done) { const data = inputvalues.encrypt.good.data; context.encrypt({ data: data }).then(function (answer) { expect(answer).to.be.undefined; }, function (error){ expect(error).to.be.an('Error'); expect(error.code).to.equal('MSG_INCOMPLETE'); done(); }); }); it('Sending encryption without data fails', function (done) { context.encrypt({ data: null, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.be.undefined; }, function (error) { expect(error).to.be.an.instanceof(Error); expect(error.code).to.equal('MSG_INCOMPLETE'); done(); }); }); it('Sending encryption with non existing keys fails', function (done) { const data = inputvalues.encrypt.good.data; const bad_fpr = inputvalues.encrypt.bad.fingerprint; context.encrypt({ data:data, publicKeys: bad_fpr }) .then(function (answer) { expect(answer).to.be.undefined; }, function (error){ expect(error).to.be.an('Error'); expect(error.code).to.not.be.undefined; expect(error.code).to.equal('GNUPG_ERROR'); done(); }); }).timeout(5000); it('Overly large message ( > 64MB) is rejected', function (done) { const data = fixedLengthString(65); context.encrypt({ data: data, publicKeys: good_fpr }) .then(function (answer) { expect(answer).to.be.undefined; }, function (error){ expect(error).to.be.an.instanceof(Error); // TODO: there is a 64 MB hard limit at least in chrome at: // chromium//extensions/renderer/messaging_util.cc: // kMaxMessageLength // The error will be a browser error, not from gnupg or from // this library done(); }); }).timeout(8000); }); diff --git a/lang/js/BrowserTestExtension/tests/longRunningTests.js b/lang/js/BrowserTestExtension/tests/longRunningTests.js index f28a6e78..534a95aa 100644 --- a/lang/js/BrowserTestExtension/tests/longRunningTests.js +++ b/lang/js/BrowserTestExtension/tests/longRunningTests.js @@ -1,58 +1,58 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, before, expect, Gpgmejs */ /* global bigString, inputvalues */ describe('Long running Encryption/Decryption', function () { let context = null; const good_fpr = inputvalues.encrypt.good.fingerprint; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); for (let i=1; i < 101; i++) { it('Successful encrypt/decrypt completely random data ' + (i) + '/100', function (done) { const data = bigString(2*1024*1024); context.encrypt({ data: data, publicKeys: good_fpr }) .then(function (answer){ expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP MESSAGE'); expect(answer.data).to.include('END PGP MESSAGE'); context.decrypt({ data: answer.data }) .then(function (result){ expect(result).to.not.be.empty; expect(result.data).to.be.a('string'); expect(result.data).to.equal(data); done(); }); }); }).timeout(15000); } }); diff --git a/lang/js/BrowserTestExtension/tests/signTest.js b/lang/js/BrowserTestExtension/tests/signTest.js index bd8db807..1e269e6a 100644 --- a/lang/js/BrowserTestExtension/tests/signTest.js +++ b/lang/js/BrowserTestExtension/tests/signTest.js @@ -1,64 +1,64 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, before, Gpgmejs */ /* global bigString, inputvalues */ describe('Signing', function () { let context = null; const good_fpr = inputvalues.encrypt.good.fingerprint; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('Sign a message', function (done) { const data = bigString(100); context.sign({ data: data, keys: good_fpr }).then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include('BEGIN PGP SIGNATURE'); expect(answer.data).to.include('END PGP SIGNATURE'); expect(answer.data).to.include(data); done(); }); }); it('Detached sign a message', function (done) { const data = bigString(100); context.sign({ data: data, keys: good_fpr, mode: 'detached' }) .then(function (answer) { expect(answer).to.not.be.empty; expect(answer.data).to.be.a('string'); expect(answer.data).to.include(data); expect(answer.signature).to.be.a('string'); expect(answer.signature).to.be.a('string'); done(); }); }); }); diff --git a/lang/js/BrowserTestExtension/tests/startup.js b/lang/js/BrowserTestExtension/tests/startup.js index cf5b0999..e7c74782 100644 --- a/lang/js/BrowserTestExtension/tests/startup.js +++ b/lang/js/BrowserTestExtension/tests/startup.js @@ -1,47 +1,47 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, Gpgmejs, inputvalues */ describe('GPGME context', function (){ it('Starting a GpgME instance', function (done){ - let prm = Gpgmejs.init(); + let prm = Gpgmejs.init({ timeout: 2000 }); const input = inputvalues.someInputParameter; prm.then( function (context){ expect(context).to.be.an('object'); expect(context.encrypt).to.be.a('function'); expect(context.decrypt).to.be.a('function'); expect(context.sign).to.be.a('function'); expect(context.verify).to.be.a('function'); context.Keyring = input; expect(context.Keyring).to.be.an('object'); expect(context.Keyring).to.not.equal(input); expect(context.Keyring.getKeys).to.be.a('function'); expect(context.Keyring.getDefaultKey).to.be.a('function'); expect(context.Keyring.importKey).to.be.a('function'); expect(context.Keyring.generateKey).to.be.a('function'); done(); }); }); }); \ No newline at end of file diff --git a/lang/js/BrowserTestExtension/tests/verifyTest.js b/lang/js/BrowserTestExtension/tests/verifyTest.js index 04c7a77a..c63f6849 100644 --- a/lang/js/BrowserTestExtension/tests/verifyTest.js +++ b/lang/js/BrowserTestExtension/tests/verifyTest.js @@ -1,90 +1,90 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global describe, it, expect, before, bigString, inputvalues, Gpgmejs */ describe('Verifying data', function () { let context = null; before(function (done){ - const prm = Gpgmejs.init(); + const prm = Gpgmejs.init({ timeout: 2000 }); prm.then(function (gpgmejs){ context = gpgmejs; done(); }); }); it('Successful verify message', function (done) { const message = inputvalues.signedMessage.good; context.verify({ data: message }).then(function (result){ expect(result.data).to.be.a('string'); expect(result.signatures.all_valid).to.be.true; expect(result.signatures.count).to.equal(1); expect(result.signatures.signatures.good).to.be.an('array'); expect(result.signatures.signatures.good.length).to.equal(1); expect(result.signatures.signatures.good[0].fingerprint).to.be.a('string'); expect(result.signatures.signatures.good[0].valid).to.be.true; done(); }); }); it('Successfully recognize changed cleartext', function (done) { const message = inputvalues.signedMessage.bad; context.verify({ data: message }).then(function (result){ expect(result.data).to.be.a('string'); expect(result.signatures.all_valid).to.be.false; expect(result.signatures.count).to.equal(1); expect(result.signatures.signatures.bad).to.be.an('array'); expect(result.signatures.signatures.bad.length).to.equal(1); expect(result.signatures.signatures.bad[0].fingerprint) .to.be.a('string'); expect(result.signatures.signatures.bad[0].valid) .to.be.false; done(); }); }); it('Encrypt-Sign-Verify random message', function (done) { const message = bigString(2000); let fpr = inputvalues.encrypt.good.fingerprint; context.encrypt({ data: message, publicKeys: fpr }) .then(function (message_enc){ context.sign({ data: message_enc.data, keys: fpr }) .then(function (message_encsign){ context.verify({ data: message_encsign.data }) .then(function (result){ expect(result.data).to.equal(message_enc.data); expect(result.data).to.be.a('string'); expect(result.signatures.all_valid).to.be.true; expect(result.signatures.count).to.equal(1); const arr = result.signatures.signatures.good; expect(arr).to.be.an('array'); expect(arr.length).to.equal(1); expect(arr[0].fingerprint).to.equal(fpr); expect(arr[0].valid).to.be.true; done(); }); }); }); }); }); \ No newline at end of file diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js index 4055da6a..d43d55f1 100644 --- a/lang/js/src/Connection.js +++ b/lang/js/src/Connection.js @@ -1,316 +1,320 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ /* global chrome */ import { permittedOperations } from './permittedOperations'; import { gpgme_error } from './Errors'; import { GPGME_Message, createMessage } from './Message'; import { decode, atobArray, Utf8ArrayToStr } from './Helpers'; /** * A Connection handles the nativeMessaging interaction via a port. As the * protocol only allows up to 1MB of message sent from the nativeApp to the * browser, the connection will stay open until all parts of a communication * are finished. For a new request, a new port will open, to avoid mixing * contexts. * @class * @private */ export class Connection{ constructor (){ this._connection = chrome.runtime.connectNative('gpgmejson'); } /** * Immediately closes an open port. */ disconnect () { if (this._connection){ this._connection.disconnect(); this._connection = null; } } /** * @typedef {Object} backEndDetails * @property {String} gpgme Version number of gpgme * @property {Array} info Further information about the backend * and the used applications (Example: *
     * {
     *          "protocol":     "OpenPGP",
     *          "fname":        "/usr/bin/gpg",
     *          "version":      "2.2.6",
     *          "req_version":  "1.4.0",
     *          "homedir":      "default"
     * }
     * 
*/ /** * Retrieves the information about the backend. * @param {Boolean} details (optional) If set to false, the promise will * just return if a connection was successful. + * @param {Number} timeout (optional) * @returns {Promise|Promise} Details from the * backend * @async */ - checkConnection (details = true){ + checkConnection (details = true, timeout = 1000){ + if (typeof timeout !== 'number' && timeout <= 0) { + timeout = 1000; + } const msg = createMessage('version'); if (details === true) { return this.post(msg); } else { let me = this; return new Promise(function (resolve) { Promise.race([ me.post(msg), new Promise(function (resolve, reject){ setTimeout(function (){ reject(gpgme_error('CONN_TIMEOUT')); - }, 500); + }, timeout); }) ]).then(function (){ // success resolve(true); }, function (){ // failure resolve(false); }); }); } } /** * Sends a {@link GPGME_Message} via the nativeMessaging port. It * resolves with the completed answer after all parts have been * received and reassembled, or rejects with an {@link GPGME_Error}. * * @param {GPGME_Message} message * @returns {Promise<*>} The collected answer, depending on the messages' * operation * @private * @async */ post (message){ if (!message || !(message instanceof GPGME_Message)){ this.disconnect(); return Promise.reject(gpgme_error( 'PARAM_WRONG', 'Connection.post')); } if (message.isComplete() !== true){ this.disconnect(); return Promise.reject(gpgme_error('MSG_INCOMPLETE')); } let chunksize = message.chunksize; const me = this; return new Promise(function (resolve, reject){ let answer = new Answer(message); let listener = function (msg) { if (!msg){ me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(gpgme_error('CONN_EMPTY_GPG_ANSWER')); } else { let answer_result = answer.collect(msg); if (answer_result !== true){ me._connection.onMessage.removeListener(listener); me._connection.disconnect(); reject(answer_result); } else { if (msg.more === true){ me._connection.postMessage({ 'op': 'getmore', 'chunksize': chunksize }); } else { me._connection.onMessage.removeListener(listener); me._connection.disconnect(); const message = answer.getMessage(); if (message instanceof Error){ reject(message); } else { resolve(message); } } } } }; me._connection.onMessage.addListener(listener); if (permittedOperations[message.operation].pinentry){ return me._connection.postMessage(message.message); } else { return Promise.race([ me._connection.postMessage(message.message), function (resolve, reject){ setTimeout(function (){ me._connection.disconnect(); reject(gpgme_error('CONN_TIMEOUT')); }, 5000); } ]).then(function (result){ return result; }, function (reject){ if (!(reject instanceof Error)) { me._connection.disconnect(); return gpgme_error('GNUPG_ERROR', reject); } else { return reject; } }); } }); } } /** * A class for answer objects, checking and processing the return messages of * the nativeMessaging communication. * @private */ class Answer{ /** * @param {GPGME_Message} message */ constructor (message){ this._operation = message.operation; this._expected = message.expected; this._response_b64 = null; } get operation (){ return this._operation; } get expected (){ return this._expected; } /** * Adds incoming base64 encoded data to the existing response * @param {*} msg base64 encoded data. * @returns {Boolean} * * @private */ collect (msg){ if (typeof (msg) !== 'object' || !msg.hasOwnProperty('response')) { return gpgme_error('CONN_UNEXPECTED_ANSWER'); } if (!this._response_b64){ this._response_b64 = msg.response; return true; } else { this._response_b64 += msg.response; return true; } } /** * Decodes and verifies the base64 encoded answer data. Verified against * {@link permittedOperations}. * @returns {Object} The readable gpnupg answer */ getMessage (){ if (this._response_b64 === null){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } let _decodedResponse = JSON.parse(atob(this._response_b64)); let _response = { format: 'ascii' }; let messageKeys = Object.keys(_decodedResponse); let poa = permittedOperations[this.operation].answer; if (messageKeys.length === 0){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } for (let i= 0; i < messageKeys.length; i++){ let key = messageKeys[i]; switch (key) { case 'type': { if (_decodedResponse.type === 'error'){ return (gpgme_error('GNUPG_ERROR', decode(_decodedResponse.msg))); } else if (poa.type.indexOf(_decodedResponse.type) < 0){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } break; } case 'base64': { break; } case 'msg': { if (_decodedResponse.type === 'error'){ return (gpgme_error('GNUPG_ERROR', _decodedResponse.msg)); } break; } default: { let answerType = null; if (poa.payload && poa.payload.hasOwnProperty(key)){ answerType = 'p'; } else if (poa.info && poa.info.hasOwnProperty(key)){ answerType = 'i'; } if (answerType !== 'p' && answerType !== 'i'){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } if (answerType === 'i') { if ( typeof (_decodedResponse[key]) !== poa.info[key] ){ return gpgme_error('CONN_UNEXPECTED_ANSWER'); } _response[key] = decode(_decodedResponse[key]); } else if (answerType === 'p') { if (_decodedResponse.base64 === true && poa.payload[key] === 'string' ) { if (this.expected === 'uint8'){ _response[key] = atobArray(_decodedResponse[key]); _response.format = 'uint8'; } else if (this.expected === 'base64'){ _response[key] = _decodedResponse[key]; _response.format = 'base64'; } else { // no 'expected' _response[key] = Utf8ArrayToStr( atobArray(_decodedResponse[key])); _response.format = 'string'; } } else if (poa.payload[key] === 'string') { _response[key] = _decodedResponse[key]; } else { // fallthrough, should not be reached // (payload is always string) return gpgme_error('CONN_UNEXPECTED_ANSWER'); } } break; } } } return _response; } } diff --git a/lang/js/src/index.js b/lang/js/src/index.js index c52460cc..b8e4274d 100644 --- a/lang/js/src/index.js +++ b/lang/js/src/index.js @@ -1,54 +1,58 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ * * Author(s): * Maximilian Krambach */ import { GpgME } from './gpgmejs'; import { gpgme_error } from './Errors'; import { Connection } from './Connection'; /** * Main entry point for gpgme.js. It initializes by testing the nativeMessaging * connection once, and then offers the available functions as method of the * response object. * An unsuccessful attempt will reject as a GPGME_Error. + * @param {Object} config (optional) configuration options + * @param {Number} config.timeout set the timeout for the initial connection + * check. On some machines and operating systems a default timeout of 500 ms is + * too low, so a higher number might be attempted. * @returns {Promise} * @async */ -function init (){ +function init ({ timeout = 500 } = {}){ return new Promise(function (resolve, reject){ const connection = new Connection; - connection.checkConnection(false).then( + connection.checkConnection(false, timeout).then( function (result){ if (result === true) { resolve(new GpgME()); } else { reject(gpgme_error('CONN_NO_CONNECT')); } }, function (){ // unspecific connection error. Should not happen reject(gpgme_error('CONN_NO_CONNECT')); }); }); } const exportvalue = { init:init }; export default exportvalue; \ No newline at end of file diff --git a/lang/js/unittests.js b/lang/js/unittests.js index de06320e..f28be76a 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -1,382 +1,386 @@ /* 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 . * SPDX-License-Identifier: LGPL-2.1+ */ import './node_modules/mocha/mocha'; /* global mocha, it, describe*/ import './node_modules/chai/chai';/* global chai*/ import { helper_params as hp } from './unittest_inputvalues'; import { message_params as mp } from './unittest_inputvalues'; import { whatever_params as wp } from './unittest_inputvalues'; import { key_params as kp } from './unittest_inputvalues'; import { Connection } from './src/Connection'; import { gpgme_error, err_list } from './src/Errors'; import { toKeyIdArray , isFingerprint } from './src/Helpers'; import { createKey } from './src/Key'; import { GPGME_Keyring } from './src/Keyring'; import { GPGME_Message, createMessage } from './src/Message'; mocha.setup('bdd'); const expect = chai.expect; chai.config.includeStack = true; +const connectionTimeout = 2000; function unittests (){ describe('Connection testing', function (){ it('Connecting', function (done) { let conn0 = new Connection; - conn0.checkConnection().then(function (answer) { - expect(answer).to.not.be.empty; - expect(answer.gpgme).to.not.be.undefined; - expect(answer.gpgme).to.be.a('string'); - expect(answer.info).to.be.an('Array'); - expect(conn0.disconnect).to.be.a('function'); - expect(conn0.post).to.be.a('function'); - done(); - }); + conn0.checkConnection(true, connectionTimeout).then( + function (answer) { + expect(answer).to.not.be.empty; + expect(answer.gpgme).to.not.be.undefined; + expect(answer.gpgme).to.be.a('string'); + expect(answer.info).to.be.an('Array'); + expect(conn0.disconnect).to.be.a('function'); + expect(conn0.post).to.be.a('function'); + done(); + }); }); it('Disconnecting', function (done) { let conn0 = new Connection; - conn0.checkConnection(false).then(function (answer) { - expect(answer).to.be.true; - conn0.disconnect(); - conn0.checkConnection(false).then(function (result) { - expect(result).to.be.false; - done(); + conn0.checkConnection(false, connectionTimeout).then( + function (answer) { + expect(answer).to.be.true; + conn0.disconnect(); + conn0.checkConnection(false, connectionTimeout).then( + function (result) { + expect(result).to.be.false; + done(); + }); }); - }); }); }); describe('Error Object handling', function (){ // TODO: new GPGME_Error codes it('check the Timeout error', function (){ let test0 = gpgme_error('CONN_TIMEOUT'); expect(test0).to.be.an.instanceof(Error); expect(test0.code).to.equal('CONN_TIMEOUT'); }); it('Error Object returns generic code if code is not listed', function (){ let test0 = gpgme_error(hp.invalidErrorCode); expect(test0).to.be.an.instanceof(Error); expect(test0.code).to.equal('GENERIC_ERROR'); } ); it('Warnings like PARAM_IGNORED should not return errors', function (){ let test0 = gpgme_error('PARAM_IGNORED'); expect(test0).to.be.null; }); }); describe('Fingerprint checking', function (){ it('isFingerprint(): valid Fingerprint', function (){ let test0 = isFingerprint(hp.validFingerprint); expect(test0).to.be.true; }); it('isFingerprint(): invalid Fingerprints', function (){ for (let i=0; i < hp.invalidFingerprints.length; i++){ let test0 = isFingerprint(hp.invalidFingerprints[i]); expect(test0).to.be.false; } }); }); describe('toKeyIdArray() (converting input to fingerprint)', function (){ it('Correct fingerprint string', function (){ let test0 = toKeyIdArray(hp.validFingerprint); expect(test0).to.be.an('array'); expect(test0).to.include(hp.validFingerprint); }); it('openpgpjs-like object', function (){ let test0 = toKeyIdArray(hp.valid_openpgplike); expect(test0).to.be.an('array').with.lengthOf(1); expect(test0).to.include( hp.valid_openpgplike.primaryKey.getFingerprint()); }); it('Array of valid inputs', function (){ let test0 = toKeyIdArray(hp.validKeys); expect(test0).to.be.an('array'); expect(test0).to.have.lengthOf(hp.validKeys.length); }); it('Incorrect inputs', function (){ it('valid Long ID', function (){ let test0 = toKeyIdArray(hp.validLongId); expect(test0).to.be.empty; }); it('invalidFingerprint', function (){ let test0 = toKeyIdArray(hp.invalidFingerprint); expect(test0).to.be.empty; }); it('invalidKeyArray', function (){ let test0 = toKeyIdArray(hp.invalidKeyArray); expect(test0).to.be.empty; }); it('Partially invalid array', function (){ let test0 = toKeyIdArray(hp.invalidKeyArray_OneBad); expect(test0).to.be.an('array'); expect(test0).to.have.lengthOf( hp.invalidKeyArray_OneBad.length - 1); }); }); }); describe('GPGME_Key', function (){ it('Key has data after a first refresh', function (done) { let key = createKey(kp.validKeyFingerprint); key.refreshKey().then(function (key2){ expect(key2.get).to.be.a('function'); for (let i=0; i < kp.validKeyProperties.length; i++) { let prop = key2.get(kp.validKeyProperties[i]); expect(prop).to.not.be.undefined; expect(prop).to.be.a('boolean'); } expect(isFingerprint(key2.get('fingerprint'))).to.be.true; expect( key2.get('fingerprint')).to.equal(kp.validKeyFingerprint); expect( key2.get('fingerprint')).to.equal(key.fingerprint); done(); }); }); it('Non-cached key async data retrieval', function (done){ let key = createKey(kp.validKeyFingerprint, true); key.get('can_authenticate').then(function (result){ expect(result).to.be.a('boolean'); done(); }); }); it('Non-cached key async armored Key', function (done){ let key = createKey(kp.validKeyFingerprint, true); key.get('armored').then(function (result){ expect(result).to.be.a('string'); expect(result).to.include('KEY BLOCK-----'); done(); }); }); it('Non-cached key async hasSecret', function (done){ let key = createKey(kp.validKeyFingerprint, true); key.get('hasSecret').then(function (result){ expect(result).to.be.a('boolean'); done(); }); }); it('Non-cached key async hasSecret (no secret in Key)', function (done){ let key = createKey(kp.validFingerprintNoSecret, true); key.get('hasSecret').then(function (result){ expect(result).to.be.a('boolean'); expect(result).to.equal(false); done(); }); }); it('Querying non-existing Key returns an error', function (done) { let key = createKey(kp.invalidKeyFingerprint); key.refreshKey().then(function (){}, function (error){ expect(error).to.be.an.instanceof(Error); expect(error.code).to.equal('KEY_NOKEY'); done(); }); }); it('createKey returns error if parameters are wrong', function (){ for (let i=0; i< 4; i++){ expect(function (){ createKey(wp.four_invalid_params[i]); }).to.throw( err_list.PARAM_WRONG.msg ); } }); // it('Overwriting getFingerprint does not work', function(){ // const evilFunction = function(){ // return 'bad Data'; // }; // let key = createKey(kp.validKeyFingerprint, true); // expect(key.fingerprint).to.equal(kp.validKeyFingerprint); // try { // key.getFingerprint = evilFunction; // } // catch(e) { // expect(e).to.be.an.instanceof(TypeError); // } // expect(key.fingerprint).to.equal(kp.validKeyFingerprint); // expect(key.getFingerprint).to.not.equal(evilFunction); // }); }); describe('GPGME_Keyring', function (){ it('correct Keyring initialization', function (){ let keyring = new GPGME_Keyring; expect(keyring).to.be.an.instanceof(GPGME_Keyring); expect(keyring.getKeys).to.be.a('function'); }); it('Loading Keys from Keyring, to be used synchronously', function (done){ let keyring = new GPGME_Keyring; keyring.getKeys({ prepare_sync: true }).then(function (result){ expect(result).to.be.an('array'); expect(result[0].get('hasSecret')).to.be.a('boolean'); done(); }); } ); it('Loading specific Key from Keyring, to be used synchronously', function (done){ let keyring = new GPGME_Keyring; keyring.getKeys({ pattern: kp.validKeyFingerprint, prepare_sync: true }).then( function (result){ expect(result).to.be.an('array'); expect(result[0].get('hasSecret')).to.be.a('boolean'); done(); } ); } ); it('Querying non-existing Key from Keyring', function (done){ let keyring = new GPGME_Keyring; keyring.getKeys({ pattern: kp.invalidKeyFingerprint, prepare_sync: true }).then(function (result){ expect(result).to.be.an('array'); expect(result.length).to.equal(0); done(); }); }); }); describe('GPGME_Message', function (){ it('creating encrypt Message', function (){ let test0 = createMessage('encrypt'); expect(test0).to.be.an.instanceof(GPGME_Message); expect(test0.isComplete()).to.be.false; }); it('Message is complete after setting mandatory data', function (){ let test0 = createMessage('encrypt'); test0.setParameter('data', mp.valid_encrypt_data); test0.setParameter('keys', hp.validFingerprints); expect(test0.isComplete()).to.be.true; }); it('Message is not complete after mandatory data is empty', function (){ let test0 = createMessage('encrypt'); test0.setParameter('keys', hp.validFingerprints); expect(test0.isComplete()).to.be.false; expect(function (){ test0.setParameter('data', ''); }).to.throw( err_list.PARAM_WRONG.msg); }); it('Complete Message contains the data that was set', function (){ let test0 = createMessage('encrypt'); test0.setParameter('data', mp.valid_encrypt_data); test0.setParameter('keys', hp.validFingerprints); expect(test0.message).to.not.be.null; expect(test0.message).to.have.keys('op', 'data', 'keys', 'chunksize'); expect(test0.message.op).to.equal('encrypt'); expect(test0.message.data).to.equal( mp.valid_encrypt_data); }); it ('Not accepting non-allowed operation', function (){ expect(function () { createMessage(mp.invalid_op_action); }).to.throw( err_list.MSG_WRONG_OP.msg); }); it('Not accepting wrong parameter type', function (){ expect(function () { createMessage(mp.invalid_op_type); }).to.throw( err_list.PARAM_WRONG.msg); }); it('Not accepting wrong parameter name', function (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let i=0; i < mp.invalid_param_test.invalid_param_names.length; i++){ expect(function (){ test0.setParameter( mp.invalid_param_test.invalid_param_names[i], 'Somevalue');} ).to.throw(err_list.PARAM_WRONG.msg); } }); it('Not accepting wrong parameter value', function (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let j=0; j < mp.invalid_param_test.invalid_values_0.length; j++){ expect(function (){ test0.setParameter( mp.invalid_param_test.validparam_name_0, mp.invalid_param_test.invalid_values_0[j]); }).to.throw(err_list.PARAM_WRONG.msg); } }); }); } export default { unittests }; \ No newline at end of file