diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js
index e6ff67be..8bc3d42a 100644
--- a/lang/js/src/Connection.js
+++ b/lang/js/src/Connection.js
@@ -1,5 +1,3 @@
-import { GPGME_Message } from "./Message";
-
/* gpgme.js - Javascript integration for gpgme
* Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
*
@@ -26,7 +24,8 @@ import { GPGME_Message } from "./Message";
* expected.
*/
import { permittedOperations } from './permittedOperations'
-import { GPGMEJS_Error} from "./Errors"
+import { GPGMEJS_Error } from "./Errors"
+import { GPGME_Message } from "./Message";
/**
* A Connection handles the nativeMessaging interaction.
@@ -60,20 +59,20 @@ export class Connection{
/**
* Opens a nativeMessaging port.
- * TODO: Error handling ALREADY_CONNECTED
*/
connect(){
if (this._isConnected === true){
- return new GPGMEJS_Error('ALREADY_CONNECTED');
+ GPGMEJS_Error('CONN_ALREADY_CONNECTED');
+ } else {
+ this._isConnected = true;
+ this._connection = chrome.runtime.connectNative('gpgmejson');
+ let me = this;
+ this._connection.onDisconnect.addListener(
+ function(){
+ me._isConnected = false;
+ }
+ );
}
- this._isConnected = true;
- this._connection = chrome.runtime.connectNative('gpgmejson');
- let me = this;
- this._connection.onDisconnect.addListener(
- function(){
- me._isConnected = false;
- }
- );
}
/**
@@ -84,28 +83,31 @@ export class Connection{
*/
post(message){
if (!this.isConnected){
- return Promise.reject(new GPGMEJS_Error('NO_CONNECT'));
+ return Promise.reject(GPGMEJS_Error('CONN_NO_CONNECT'));
}
if (!message || !message instanceof GPGME_Message){
- return Promise.reject(new GPGMEJS_Error('WRONGPARAM'));
+ return Promise.reject(GPGMEJS_Error('PARAM_WRONG'), message);
}
if (message.isComplete !== true){
- return Promise.reject(new GPGMEJS_Error('MSG_INCOMPLETE'));
+ return Promise.reject(GPGMEJS_Error('MSG_INCOMPLETE'));
}
- // let timeout = 5000; //TODO config
let me = this;
return new Promise(function(resolve, reject){
let answer = new Answer(message.operation);
let listener = function(msg) {
if (!msg){
me._connection.onMessage.removeListener(listener)
- reject(new GPGMEJS_Error('EMPTY_GPG_ANSWER'));
+ reject(GPGMEJS_Error('CONN_EMPTY_GPG_ANSWER'));
} else if (msg.type === "error"){
me._connection.onMessage.removeListener(listener)
- //TODO: GPGMEJS_Error?
- reject(msg.msg);
+ reject(
+ {code: 'GNUPG_ERROR',
+ msg: msg.msg} );
} else {
- answer.add(msg);
+ let answer_result = answer.add(msg);
+ if (answer_result !== true){
+ reject(answer_result);
+ }
if (msg.more === true){
me._connection.postMessage({'op': 'getmore'});
} else {
@@ -117,11 +119,12 @@ export class Connection{
me._connection.onMessage.addListener(listener);
me._connection.postMessage(message.message);
+
//TBD: needs to be aware if there is a pinentry pending
// setTimeout(
// function(){
// me.disconnect();
- // reject(new GPGMEJS_Error('TIMEOUT', 5000));
+ // reject(GPGMEJS_Error('CONN_TIMEOUT'));
// }, timeout);
});
}
@@ -141,6 +144,7 @@ class Answer{
/**
* Add the information to the answer
* @param {Object} msg The message as received with nativeMessaging
+ * returns true if successfull, GPGMEJS_Error otherwise
*/
add(msg){
if (this._response === undefined){
@@ -148,12 +152,15 @@ class Answer{
}
let messageKeys = Object.keys(msg);
let poa = permittedOperations[this.operation].answer;
+ if (messageKeys.length === 0){
+ return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
+ }
for (let i= 0; i < messageKeys.length; i++){
let key = messageKeys[i];
switch (key) {
case 'type':
if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){
- return new GPGMEJS_Error('UNEXPECTED_ANSWER');
+ return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
}
break;
case 'more':
@@ -172,7 +179,7 @@ class Answer{
this._response[key] = msg[key];
}
else if (this._response[key] !== msg[key]){
- return new GPGMEJS_Error('UNEXPECTED_ANSWER',msg[key]);
+ return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER',msg[key]);
}
}
//infos may be json objects etc. Not yet defined.
@@ -184,11 +191,12 @@ class Answer{
this._response.push(msg[key]);
}
else {
- return new GPGMEJS_Error('UNEXPECTED_ANSWER', key);
+ return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER', key);
}
break;
}
}
+ return true;
}
/**
diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js
index c2356f7c..c49bfe21 100644
--- a/lang/js/src/Errors.js
+++ b/lang/js/src/Errors.js
@@ -18,131 +18,99 @@
* SPDX-License-Identifier: LGPL-2.1+
*/
-// This is a preliminary collection of erors and warnings to be thrown and implemented.
-
-// general idea: if throw , throw the NAME
-// return false || 'return' property
-
-//TODO: Connection.NOCONNECT promise
-//connection.timeout: Be aware of pinentry
-
-export class GPGMEJS_Error {
-
- constructor(code = 'GENERIC_ERROR', details){
- let config = { //TODO TEMP
- debug: 'console', // |'alert'
- throw: 'default' // | 'always' | 'never'
- };
+/**
+ * Checks the given error code and returns some information about it's meaning
+ * @param {String} code The error code
+ * @returns {Object} An object containing string properties code and msg
+ * TODO: error-like objects with the code 'GNUPG_ERROR' are errors sent
+ * directly by gnupg as answer in Connection.post()
+ */
+export function GPGMEJS_Error(code = 'GENERIC_ERROR'){
+ if (!typeof(code) === 'string'){
+ code = 'GENERIC_ERROR';
+ }
let errors = { //TODO: someplace else
- //Connection errors
- 'ALREADY_CONNECTED':{
- msg: 'The connection was already established. The action would overwrite the context',
- throw: true
+ // Connection
+ 'CONN_NO_CONNECT': {
+ msg:'Connection with the nativeMessaging host could not be'
+ + ' established.',
+ type: 'error'
},
- 'NO_CONNECT': {
- msg:'Connection with the nativeMessaging host could not be established.',
- throw: true
+ 'CONN_EMPTY_GPG_ANSWER':{
+ msg: 'The nativeMessaging answer was empty.',
+ type: 'error'
},
- 'EMPTY_GPG_ANSWER':{
- msg: 'The nativeMesaging answer was empty',
- throw: true
+ 'CONN_TIMEOUT': {
+ msg: 'A connection timeout was exceeded.',
+ type: 'error'
},
- 'TIMEOUT': {
- msg: 'A timeout was exceeded.',
- throw: false
+ 'CONN_UNEXPECTED_ANSWER': {
+ msg: 'The answer from gnupg was not as expected.',
+ type: 'error'
},
-
- 'UNEXPECTED_ANSWER': {
- msg: 'The answer from gnupg was not as expected',
- throw: true
- },
-
- // Message/Data Errors
-
- 'NO_KEYS' : {
- msg: 'There were no valid keys provided.',
- throw: true
- },
- 'NOT_A_FPR': {
- msg: 'The String is not an accepted fingerprint',
- throw: false
+ 'CONN_ALREADY_CONNECTED':{
+ msg: 'A connection was already established.',
+ type: 'warn'
},
+ // Message/Data
'MSG_INCOMPLETE': {
- msg: 'The Message did not match the minimum requirements for the interaction',
- throw: true
+ msg: 'The Message did not match the minimum requirements for'
+ + ' the interaction.',
+ type: 'error'
},
- 'EMPTY_MSG' : {
- msg: 'The Message has no data.',
- throw: true
- },
- 'MSG_NODATA':{
- msg: 'The data sent is empty. This may be unintentional.',
- throw: false
+ 'MSG_EMPTY' : {
+ msg: 'The Message is empty.',
+ type: 'error'
},
'MSG_OP_PENDING': {
- msg: 'There is no operation specified yet. The parameter cannot be set',
- throw: false
+ msg: 'There is no operation specified yet. The parameter cannot'
+ + ' be set',
+ type: 'warning'
},
- 'WRONG_OP': {
- msg: "The operation requested could not be found",
- throw: true
+ 'MSG_WRONG_OP': {
+ msg: 'The operation requested could not be found',
+ type: 'warning'
+ },
+ 'MSG_NO_KEYS' : {
+ msg: 'There were no valid keys provided.',
+ type: 'warn'
+ },
+ 'MSG_NOT_A_FPR': {
+ msg: 'The String is not an accepted fingerprint',
+ type: 'warn'
},
- //generic errors
-
- 'WRONGPARAM':{
+ // generic
+ 'PARAM_WRONG':{
msg: 'invalid parameter was found',
- throw: true
- },
- 'WRONGTYPE':{
- msg: 'invalid parameter type was found',
- throw: true
+ type: 'error'
},
'NOT_IMPLEMENTED': {
msg: 'A openpgpjs parameter was submitted that is not implemented',
- throw: true
+ type: 'error'
+ },
+ 'NOT_YET_IMPLEMENTED': {
+ msg: 'Support of this is probable, but it is not implemented yet',
+ type: 'error'
},
'GENERIC_ERROR': {
msg: 'Unspecified error',
- throw: true
+ type: 'error'
},
-
- // hopefully temporary errors
-
- 'NOT_YET_IMPLEMENTED': {
- msg: 'Support of this is probable, but it is not implemented yet',
- throw: false
- }
}
- if (!errors.hasOwnProperty(code)){
- throw('GENERIC_ERROR');
+ if (code === 'TODO'){
+ alert('TODO_Error!');
}
- let msg = code;
- if (errors[code].msg !== undefined){
- msg = msg + ': ' + errors[code].msg;
+ if (errors.hasOwnProperty(code)){
+ code = 'GENERIC_ERROR';
}
- if (details){
- msg = msg + ' ' + details;
+ if (error.type === 'error'){
+ return {code: 'code',
+ msg: errors[code].msg
+ };
}
- if (config.debug === 'console'){
- console.log(msg);
- } else if (config.debug === 'alert'){
- alert(msg);
+ if (error.type === 'warning'){
+ console.log(code + ': ' + error[code].msg);
}
- switch (config.throw) {
- case 'default':
- if (errors[code].throw === true){
- throw(code);
- }
- break;
- case 'always':
- throw(code);
- break;
-
- case 'never':
- break;
- default:
- throw('GENERIC_ERROR');
- }
- }
+ return undefined;
}
diff --git a/lang/js/src/Helpers.js b/lang/js/src/Helpers.js
index 922ca06c..d9750ba7 100644
--- a/lang/js/src/Helpers.js
+++ b/lang/js/src/Helpers.js
@@ -1,5 +1,3 @@
-import { GPGMEJS_Error } from "./Errors";
-
/* gpgme.js - Javascript integration for gpgme
* Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
*
@@ -19,18 +17,19 @@ import { GPGMEJS_Error } from "./Errors";
* License along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
+import { GPGMEJS_Error } from "./Errors";
/**
* Tries to return an array of fingerprints, either from input fingerprints or
* from Key objects
* @param {Key |Array| GPGME_Key | Array|String|Array} input
- * @param {Boolean} nocheck if set, an empty result is acceptable
* @returns {Array} Array of fingerprints.
*/
export function toKeyIdArray(input, nocheck){
if (!input){
- return (nocheck ===true)? [] : new GPGMEJS_Error('NO_KEYS');
+ GPGMEJS_Error('MSG_NO_KEYS');
+ return [];
}
if (!Array.isArray(input)){
input = [input];
@@ -41,7 +40,7 @@ export function toKeyIdArray(input, nocheck){
if (isFingerprint(input[i]) === true){
result.push(input[i]);
} else {
- GPGMEJS_Error
+ GPGMEJS_Error('MSG_NOT_A_FPR');
}
} else if (typeof(input[i]) === 'object'){
let fpr = '';
@@ -53,13 +52,16 @@ export function toKeyIdArray(input, nocheck){
}
if (isFingerprint(fpr) === true){
result.push(fpr);
+ } else {
+ GPGMEJS_Error('MSG_NOT_A_FPR');
}
} else {
- return new GPGMEJS_Error('WRONGTYPE');
+ return GPGMEJS_Error('PARAM_WRONG');
}
}
if (result.length === 0){
- return (nocheck===true)? [] : new GPGMEJS_Error('NO_KEYS');
+ GPGMEJS_Error('MSG_NO_KEYS');
+ return [];
} else {
return result;
}
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index f59b9901..5ae80438 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -172,7 +172,7 @@ export class GPGME_Key {
*
*/
function checkKey(fingerprint, property){
- return Promise.reject(new GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
+ return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
return new Promise(function(resolve, reject){
if (!isFingerprint(fingerprint)){
diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js
index f5e21e00..1b36f11d 100644
--- a/lang/js/src/Message.js
+++ b/lang/js/src/Message.js
@@ -39,20 +39,20 @@ export class GPGME_Message {
*/
setParameter(param,value){
if (!param || typeof(param) !== 'string'){
- return new GPGMEJS_Error('WRONGPARAM', 'type check failed');
+ return GPGMEJS_Error('PARAM_WRONG');
}
if (!this._msg || !this._msg.op){
- return new GPGMEJS_Error('MSG_OP_PENDING');
+ return GPGMEJS_Error('MSG_OP_PENDING');
}
let po = permittedOperations[this._msg.op];
if (!po){
- return new GPGMEJS_Error('WRONG_OP', param);
+ return GPGMEJS_Error('MSG_WRONG_OP');
}
if (po.required.indexOf(param) >= 0 || po.optional.indexOf(param) >= 0){
this._msg[param] = value;
return true;
}
- return new GPGMEJS_Error('WRONGPARAM', param);
+ return GPGMEJS_Error('PARAM_WRONG');
}
/**
@@ -98,7 +98,7 @@ export class GPGME_Message {
*/
function setOperation (scope, operation){
if (!operation || typeof(operation) !== 'string'){
- return new GPGMEJS_Error('WRONGTYPE');
+ return GPGMEJS_Error('PARAM_WRONG');
}
if (permittedOperations.hasOwnProperty(operation)){
if (!scope._msg){
@@ -106,6 +106,6 @@ function setOperation (scope, operation){
}
scope._msg.op = operation;
} else {
- return new GPGMEJS_Error('WRONG_OP');
+ return GPGMEJS_Error('MSG_WRONG_OP');
}
}
\ No newline at end of file
diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js
index 03ed5cb6..b20ff0f2 100644
--- a/lang/js/src/gpgmejs.js
+++ b/lang/js/src/gpgmejs.js
@@ -95,9 +95,8 @@ export class GpgME {
*/
decrypt(data){
-
if (data === undefined){
- return Promise.reject(new GPGMEJS_Error ('EMPTY_MSG'));
+ return Promise.reject(GPGMEJS_Error('MSG_EMPTY'));
}
let msg = new GPGME_Message('decrypt');
putData(msg, data);
@@ -106,7 +105,7 @@ export class GpgME {
}
deleteKey(key, delete_secret = false, no_confirm = false){
- return Promise.reject(new GPGMEJS_Error ('NOT_YET_IMPLEMENTED'));
+ return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
let msg = new GPGME_Message('deletekey');
let key_arr = toKeyIdArray(key);
if (key_arr.length !== 1){
@@ -127,7 +126,7 @@ export class GpgME {
case 'ERR_NO_ERROR':
return Promise.resolve('okay'); //TBD
default:
- return Promise.reject(new GPGMEJS_Error);
+ return Promise.reject(GPGMEJS_Error('TODO') ); //
// INV_VALUE,
// GPG_ERR_NO_PUBKEY,
// GPG_ERR_AMBIGUOUS_NAME,
@@ -146,11 +145,9 @@ export class GpgME {
*/
function putData(message, data){
if (!message || !message instanceof GPGME_Message ) {
- return new GPGMEJS_Error('WRONGPARAM');
+ return GPGMEJS_Error('PARAM_WRONG');
}
if (!data){
- //TODO Debug only! No data is legitimate
- console.log('Warning. no data in message');
message.setParameter('data', '');
} else if (data instanceof Uint8Array){
let decoder = new TextDecoder('utf8');
@@ -167,6 +164,6 @@ function putData(message, data){
message.setParameter ('data', decoder.decode(txt));
}
} else {
- return new GPGMEJS_Error('WRONGPARAM');
+ return GPGMEJS_Error('PARAM_WRONG');
}
}
diff --git a/lang/js/src/gpgmejs_openpgpjs.js b/lang/js/src/gpgmejs_openpgpjs.js
index 23076569..e32f43a3 100644
--- a/lang/js/src/gpgmejs_openpgpjs.js
+++ b/lang/js/src/gpgmejs_openpgpjs.js
@@ -88,14 +88,14 @@
|| signature !== null
|| returnSessionKey !== null
|| date !== null){
- return Promise.reject(new GPMGEJS_Error('NOT_IMPLEMENTED'));
+ return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
}
if ( privateKeys
|| filename
|| compression
|| armor === false
|| detached == true){
- return Promise.reject(new GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
+ return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
}
return this.GpgME.encrypt(data, translateKeyInput(publicKeys), wildcard);
}
@@ -123,14 +123,14 @@
if (passwords !== undefined
|| sessionKeys
|| date){
- return Promise.reject(new GPGMEJS_Error('NOT_IMPLEMENTED'));
+ return Promise.reject(GPGMEJS_Error('NOT_IMPLEMENTED'));
}
if ( privateKeys
|| publicKeys
|| format !== 'utf8'
|| signature
){
- return Promise.reject(new GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
+ return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
}
return this.GpgME.decrypt(message);
// TODO: translate between:
@@ -185,7 +185,7 @@ class GPGME_Keyring_openpgpmode {
else {
// TODO: Can there be "no default key"?
// TODO: Can there be several default keys?
- return new GPGMEJS_Error; //TODO
+ return GPGMEJS_Error('TODO');
}
});
}
@@ -202,10 +202,10 @@ class GPGME_Keyring_openpgpmode {
*/
deleteKey(key){
if (typeof(key) !== "object"){
- return Promise.reject(new GPGMEJS_Error('WRONGPARAM'));
+ return Promise.reject(GPGMEJS_Error('PARAM_WRONG'));
}
if ( !key.fingerprint || ! isFingerprint(key.fingerprint)){
- return Promise.reject(new GPGMEJS_Error('WRONGPARAM'));
+ return Promise.reject(GPGMEJS_Error('PARAM_WRONG'));
}
let key_to_delete = new GPGME_Key(key.fingerprint);
return key_to_delete.deleteKey(key.secret);
diff --git a/lang/js/src/index.js b/lang/js/src/index.js
index 0cb2301c..a54277c2 100644
--- a/lang/js/src/index.js
+++ b/lang/js/src/index.js
@@ -19,6 +19,7 @@
*/
import { GpgME } from "./gpgmejs";
+import { GPGMEJS_Error } from "./Errors";
import { GpgME_openpgpmode } from "./gpgmejs_openpgpjs";
import { Connection } from "./Connection";
@@ -45,7 +46,7 @@ function init( config = {
resolve(new GpgME(connection));
}
} else {
- reject('NO_CONNECT');
+ reject(GPGMEJS_Error('CONN_NO_CONNECT'));
}
};
setTimeout(delayedreaction, 5);