[git] GPGME - branch, javascript-binding, updated. gpgme-1.11.1-8-g461dd0c

by Maximilian Krambach cvs at cvs.gnupg.org
Tue Apr 24 18:49:13 CEST 2018


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG Made Easy".

The branch, javascript-binding has been updated
       via  461dd0c8b41683a91073b362d100ee5217ec53f6 (commit)
      from  727340b295f25e04cb595022ba143cda48364697 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 461dd0c8b41683a91073b362d100ee5217ec53f6
Author: Maximilian Krambach <maximilian.krambach at intevation.de>
Date:   Tue Apr 24 18:44:30 2018 +0200

    js: change in initialization ancd connection handling
    
    --
    
    * The Connection will now be started before an object is created, to
      better account for failures.
    * index.js: now exposes an init(), which returns a Promise of
      configurable <GpgME | gpgmeGpgME_openPGPCompatibility> with an
      established connection.
    * TODO: There is currently no way to recover from a "connection lost"
    * Connection.js offers Connection.isConnected, which toggles on port
      closing.

diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js
index 87ec8cf..e6ff67b 100644
--- a/lang/js/src/Connection.js
+++ b/lang/js/src/Connection.js
@@ -35,6 +35,18 @@ export class Connection{
 
     constructor(){
         this.connect();
+        let me = this;
+    }
+
+    /**
+     * (Simple) Connection check.
+     * @returns {Boolean} true if the onDisconnect event has not been fired.
+     * Please note that the event listener of the port takes some time
+     * (5 ms seems enough) to react after the port is created. Then this will
+     * return undefined
+     */
+    get isConnected(){
+        return this._isConnected;
     }
 
     /**
@@ -48,28 +60,20 @@ export class Connection{
 
     /**
      * Opens a nativeMessaging port.
-     * returns nothing, but triggers errors if not successfull:
-     * NO_CONNECT: connection not successfull, chrome.runtime.lastError may be
-     * available
-     * ALREADY_CONNECTED: There is already a connection present.
+     * TODO: Error handling ALREADY_CONNECTED
      */
     connect(){
-        if (this._connection){
+        if (this._isConnected === true){
             return new GPGMEJS_Error('ALREADY_CONNECTED');
         }
+        this._isConnected = true;
         this._connection = chrome.runtime.connectNative('gpgmejson');
-        if (!this._connection){
-            return new GPGMEJS_Error('NO_CONNECT');
-        }
-    }
-
-    /**
-     * checks if the connection is established
-     * TODO: some kind of ping to see if the other side responds as expected?
-     * @returns {Boolean}
-     */
-    get connected(){
-        return this._connection ? true: false;
+        let me = this;
+        this._connection.onDisconnect.addListener(
+            function(){
+                me._isConnected = false;
+            }
+        );
     }
 
     /**
@@ -79,6 +83,9 @@ export class Connection{
      * information.
      */
     post(message){
+        if (!this.isConnected){
+            return Promise.reject(new GPGMEJS_Error('NO_CONNECT'));
+        }
         if (!message || !message instanceof GPGME_Message){
             return Promise.reject(new GPGMEJS_Error('WRONGPARAM'));
         }
diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js
index d8cb84b..ef8028f 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -19,27 +19,27 @@
  */
 
 import {GPGME_Message} from './Message'
-import {Connection} from './Connection'
 import {GPGME_Key} from './Key'
 import { isFingerprint, isLongId } from './Helpers';
 
 export class GPGME_Keyring {
-    constructor(){
-        this.reconnect();
+    constructor(connection){
+        this.connection = connection;
     }
 
-    /**
-     * (Re)-establishes the connection
-     * TODO TEMP: should we better use the connection of our parent,
-     * which we do not control?
-     */
-    reconnect(){
-        if (!this._connection || ! this._connection instanceof Connection){
-            this._connection = new Connection;
-        } else {
-            this._connection.disconnect();
-            this._connection.connect();
+    set connection(connection){
+        if (!this._connection && connection instanceof Connection){
+            this._connection = connection;
+        }
+    }
+    get connection(){
+        if (this._connection instanceof Connection){
+            if (this._connection.isConnected){
+                return this._connection;
+            }
+            return undefined; //TODO: connection was lost!
         }
+        return undefined; //TODO: no connection there
     }
 
     /**
@@ -57,7 +57,7 @@ export class GPGME_Keyring {
             msg.setParameter('with-secret', true);
         }
 
-        this._connection.post(msg).then(function(result){
+        this.connection.post(msg).then(function(result){
             let fpr_list = [];
             let resultset = [];
             if (!Array.isArray(result.keys)){
diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js
index b15477f..4b2a03a 100644
--- a/lang/js/src/gpgmejs.js
+++ b/lang/js/src/gpgmejs.js
@@ -22,59 +22,51 @@ import {Connection} from "./Connection"
 import {GPGME_Message} from './Message'
 import {toKeyIdArray} from "./Helpers"
 import {GPGMEJS_Error as Error, GPGMEJS_Error} from "./Errors"
+import { GPGME_Keyring } from "./Keyring";
 
 export class GpgME {
     /**
      * initializes GpgME by opening a nativeMessaging port
      * TODO: add configuration
      */
-    constructor(configuration = {
-        null_expire_is_never: false
-    }){
-        this._connection = new Connection;
+    constructor(connection){
+        this.connection = connection;
     }
 
-    /**
-     * refreshes the nativeApp connection
-     */
-    reconnect(){
-        if (!this._connection || ! this._connection instanceof Connection){
-            this._connection = new Connection;
-        } else {
-            this._connection.disconnect();
-            this._connection.connect();
+    set connection(connection){
+        if (this._connection instanceof Connection){
+            //TODO Warning: Connection already established
+        }
+        if (connection instanceof Connection){
+            this._connection = connection;
         }
     }
 
-    /**
-     * inmediately tries to destroy the nativeMessaging connection.
-     * TODO: may not be included in final API, as it is redundant.
-     * For now, it just serves paranoia
-     */
-    disconnect(){
-        if (this._connection){
-            this._connection.disconnect();
-            this._connection = null;
+    get connection(){
+        if (this._connection instanceof Connection){
+            if (this._connection.isConnected){
+                return this._connection;
+            }
+            return undefined; //TODO: connection was lost!
         }
+        return undefined; //TODO: no connection there
     }
 
-    /**
-     * tests the nativeApp connection
-     */
-    get connected(){
-        if (!this._connection || ! this._connection instanceof Connection){
-            return false;
+    set Keyring(keyring){
+        if (ring && ring instanceof GPGME_Keyring){
+            this.Keyring = ring;
         }
-        return this._connection.connected;
     }
 
+    get Keyring(){
+    }
 
     /**
      * @param {String|Uint8Array} data text/data to be encrypted as String/Uint8Array
      * @param  {GPGME_Key|String|Array<String>|Array<GPGME_Key>} publicKeys Keys used to encrypt the message
      * @param {Boolean} wildcard (optional) If true, recipient information will not be added to the message
      */
-    encrypt (data, publicKeys, wildcard=false){
+    encrypt(data, publicKeys, wildcard=false){
 
         let msg = new GPGME_Message('encrypt');
 
@@ -89,7 +81,7 @@ export class GpgME {
         if (wildcard === true){msg.setParameter('throw-keyids', true);
         };
 
-        return (this._connection.post(msg));
+        return (this.connection.post(msg));
     }
 
     /**
@@ -109,7 +101,7 @@ export class GpgME {
         }
         let msg = new GPGME_Message('decrypt');
         putData(msg, data);
-        return this._connection.post(msg);
+        return this.connection.post(msg);
 
     }
 
@@ -128,7 +120,7 @@ export class GpgME {
         if (no_confirm === true){ //TODO: Do we want this hidden deep in the code?
             msg.setParameter('delete_force', true); //TBD
         }
-        this._connection.post(msg).then(function(success){
+        this.connection.post(msg).then(function(success){
             //TODO: it seems that there is always errors coming back:
         }, function(error){
             switch (error.msg){
@@ -143,7 +135,6 @@ export class GpgME {
             }
         });
     }
-
 }
 
 /**
@@ -171,4 +162,4 @@ function putData(message, data){
     } else {
         return new GPGMEJS_Error('WRONGPARAM');
     }
-}
\ No newline at end of file
+}
diff --git a/lang/js/src/gpgmejs_openpgpjs.js b/lang/js/src/gpgmejs_openpgpjs.js
index 54b9dd4..f1ddb5d 100644
--- a/lang/js/src/gpgmejs_openpgpjs.js
+++ b/lang/js/src/gpgmejs_openpgpjs.js
@@ -30,13 +30,29 @@
  import { isFingerprint } from "./Helpers"
  import { GPGMEJS_Error } from './Errors'
 
+
 export class GpgME_openPGPCompatibility {
 
-    constructor(){
-        this._gpgme =  new GpgME({
-            null_expire_is_never: false
-        });
-        this.Keyring = this.initKeyring();
+    constructor(connection){
+        this.initGpgME(connection);
+    }
+
+    get Keyring(){
+        if (this._keyring){
+            return this._keyring;
+        }
+        return undefined;
+    }
+
+    initGpgME(connection){
+        this._GpgME = new GpgME(connection);
+        this._Keyring = new GPGME_Keyring_openPGPCompatibility(connection);
+    }
+
+    get GpgME(){
+        if (this._GpGME){
+            return this._GpGME;
+        }
     }
 
     /**
@@ -128,9 +144,6 @@ export class GpgME_openPGPCompatibility {
         // mime:   A Boolean indicating whether the data is a MIME object.
         // info:   An optional object with extra information.
     }
-    initKeyring(){
-        return new GPGME_Keyring_openPGPCompatibility;
-    }
 }
 
 /**
@@ -138,8 +151,8 @@ export class GpgME_openPGPCompatibility {
  * It may still be changed/expanded/merged with GPGME_Keyring
  */
 class GPGME_Keyring_openPGPCompatibility {
-    constructor(){
-        this._gpgme_keyring = new GPGME_Keyring;
+    constructor(connection){
+        this._gpgme_keyring = new GPGME_Keyring(connection);
     }
 
     /**
diff --git a/lang/js/src/index.js b/lang/js/src/index.js
index f70bd2d..0e2beda 100644
--- a/lang/js/src/index.js
+++ b/lang/js/src/index.js
@@ -18,6 +18,40 @@
  * SPDX-License-Identifier: LGPL-2.1+
  */
 
-import { GpgME as gpgmejs } from "./gpgmejs";
-// import { GpgME_openPGPCompatibility as gpgmejs } from "./gpgmejs_openpgpjs";
-export default gpgmejs;
+import { GpgME } from "./gpgmejs";
+import { GpgME_openPGPCompatibility } from "./gpgmejs_openpgpjs";
+import { Connection } from "./Connection";
+
+/**
+ * Initializes a nativeMessaging Connection and returns a GPGMEjs object
+ * @param {*} conf Configuration. TBD
+ */
+function init( config = {
+    api_style: 'gpgme', //  | gpgme_openpgpjs
+    null_expire_is_never: true // Boolean
+    }){
+        return new Promise(function(resolve, reject){
+            let connection = new Connection;
+            // TODO: Delayed reaction is ugly. We need to listen to the port's
+            // event listener in isConnected, but this takes some time (<5ms) to
+            // disconnect if there is no successfull connection.
+            let delayedreaction = function(){
+                if (connection.isConnected === true){
+                    let gpgme = null;
+                    if (config.api_style && config.api_style === 'gpgme_openpgpjs'){
+                        resolve(
+                            new GpgME_openPGPCompatibility(connection));
+                    } else {
+                        resolve(new GpgME(connection));
+                    }
+                } else {
+                    reject('NO_CONNECT');
+                }
+            };
+            setTimeout(delayedreaction, 5);
+    });
+};
+
+export default {
+    init: init
+}
\ No newline at end of file
diff --git a/lang/js/testapplication.js b/lang/js/testapplication.js
index 97b3552..f47299e 100644
--- a/lang/js/testapplication.js
+++ b/lang/js/testapplication.js
@@ -19,39 +19,37 @@
  *
  */
 
-function encryptbuttonclicked(event){
-    let data = document.getElementById('cleartext').value;
-    let keyId = document.getElementById('pubkey').value;
-    let communication = new Gpgmejs;
-    let enc = communication.encrypt(data, keyId).then(
-        function(answer){
-            console.log(answer);
-            if (answer.data){
-                console.log(answer.data);
-                document.getElementById('answer').value = answer.data;
-            }
-        }, function(errormsg){
-            alert('Error: '+ errormsg);
-    });
-};
-
-function decryptbuttonclicked(event){
-    let data = document.getElementById("ciphertext").value;
-    let communication = new Gpgmejs;
-    let enc = communication.decrypt(data).then(
-        function(answer){
-            console.log(answer);
-            if (answer.data){
-                document.getElementById('answer').value = answer.data;
-            }
-        }, function(errormsg){
-            alert('Error: '+ errormsg);
-    });
-};
-
 document.addEventListener('DOMContentLoaded', function() {
-    document.getElementById("buttonencrypt").addEventListener("click",
-            encryptbuttonclicked);
-    document.getElementById("buttondecrypt").addEventListener("click",
-        decryptbuttonclicked);
+    Gpgmejs.init().then(function(gpgmejs){
+        document.getElementById("buttonencrypt").addEventListener("click",
+            function(){
+                let data = document.getElementById('cleartext').value;
+                let keyId = document.getElementById('pubkey').value;
+                gpgmejs.encrypt(data, keyId).then(
+                    function(answer){
+                        console.log(answer);
+                        if (answer.data){
+                            console.log(answer.data);
+                        document.getElementById('answer').value = answer.data;
+                        }
+                    }, function(errormsg){
+                        alert('Error: '+ errormsg);
+                });
+            });
+
+        document.getElementById("buttondecrypt").addEventListener("click",
+        function(){
+            let data = document.getElementById("ciphertext").value;
+            gpgmejs.decrypt(data).then(
+                function(answer){
+                    console.log(answer);
+                    if (answer.data){
+                        document.getElementById('answer').value = answer.data;
+                    }
+                }, function(errormsg){
+                    alert('Error: '+ errormsg);
+            });
+        });
+    },
+    function(error){console.log(error)});
 });

-----------------------------------------------------------------------

Summary of changes:
 lang/js/src/Connection.js        | 41 ++++++++++++++-----------
 lang/js/src/Keyring.js           | 30 +++++++++---------
 lang/js/src/gpgmejs.js           | 61 ++++++++++++++++---------------------
 lang/js/src/gpgmejs_openpgpjs.js | 33 ++++++++++++++------
 lang/js/src/index.js             | 40 ++++++++++++++++++++++--
 lang/js/testapplication.js       | 66 +++++++++++++++++++---------------------
 6 files changed, 157 insertions(+), 114 deletions(-)


hooks/post-receive
-- 
GnuPG Made Easy
http://git.gnupg.org




More information about the Gnupg-commits mailing list