diff --git a/lang/js/src/Connection.js b/lang/js/src/Connection.js
index 4270be58..5b092ab0 100644
--- a/lang/js/src/Connection.js
+++ b/lang/js/src/Connection.js
@@ -24,7 +24,7 @@
* expected.
*/
import { permittedOperations } from './permittedOperations'
-import { GPGMEJS_Error } from "./Errors"
+import { gpgme_error } from "./Errors"
import { GPGME_Message } from "./Message";
/**
@@ -62,7 +62,7 @@ export class Connection{
*/
connect(){
if (this._isConnected === true){
- GPGMEJS_Error('CONN_ALREADY_CONNECTED');
+ gpgme_error('CONN_ALREADY_CONNECTED');
} else {
this._isConnected = true;
this._connection = chrome.runtime.connectNative('gpgmejson');
@@ -83,13 +83,13 @@ export class Connection{
*/
post(message){
if (!this.isConnected){
- return Promise.reject(GPGMEJS_Error('CONN_NO_CONNECT'));
+ return Promise.reject(gpgme_error('CONN_NO_CONNECT'));
}
if (!message || !message instanceof GPGME_Message){
- return Promise.reject(GPGMEJS_Error('PARAM_WRONG'), message);
+ return Promise.reject(gpgme_error('PARAM_WRONG'), message);
}
if (message.isComplete !== true){
- return Promise.reject(GPGMEJS_Error('MSG_INCOMPLETE'));
+ return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
}
let me = this;
return new Promise(function(resolve, reject){
@@ -97,7 +97,7 @@ export class Connection{
let listener = function(msg) {
if (!msg){
me._connection.onMessage.removeListener(listener)
- reject(GPGMEJS_Error('CONN_EMPTY_GPG_ANSWER'));
+ reject(gpgme_error('CONN_EMPTY_GPG_ANSWER'));
} else if (msg.type === "error"){
me._connection.onMessage.removeListener(listener)
reject(
@@ -118,17 +118,18 @@ export class Connection{
};
me._connection.onMessage.addListener(listener);
- let timeout = new Promise(function(resolve, reject){
- setTimeout(function(){
- reject(GPGMEJS_Error('CONN_TIMEOUT'));
- }, 5000);
- });
if (permittedOperations[message.operation].pinentry){
return me._connection.postMessage(message.message);
} else {
- return Promise.race([timeout,
- me._connection.postMessage(message.message)
- ]);
+ return Promise.race([
+ me._connection.postMessage(message.message),
+ function(resolve, reject){
+ setTimeout(function(){
+ reject(gpgme_error('CONN_TIMEOUT'));
+ }, 5000);
+ }]).then(function(result){
+ return result;
+ });
}
});
}
@@ -148,7 +149,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
+ * returns true if successfull, gpgme_error otherwise
*/
add(msg){
if (this._response === undefined){
@@ -157,14 +158,14 @@ class Answer{
let messageKeys = Object.keys(msg);
let poa = permittedOperations[this.operation].answer;
if (messageKeys.length === 0){
- return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
+ return gpgme_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 GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
+ return gpgme_error('CONN_UNEXPECTED_ANSWER');
}
break;
case 'more':
@@ -183,7 +184,7 @@ class Answer{
this._response[key] = msg[key];
}
else if (this._response[key] !== msg[key]){
- return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER',msg[key]);
+ return gpgme_error('CONN_UNEXPECTED_ANSWER',msg[key]);
}
}
//infos may be json objects etc. Not yet defined.
@@ -195,7 +196,7 @@ class Answer{
this._response.push(msg[key]);
}
else {
- return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER', key);
+ return gpgme_error('CONN_UNEXPECTED_ANSWER', key);
}
break;
}
diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js
index 04b13e10..2f53aa89 100644
--- a/lang/js/src/Errors.js
+++ b/lang/js/src/Errors.js
@@ -18,99 +18,125 @@
* SPDX-License-Identifier: LGPL-2.1+
*/
-/**
- * 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
- 'CONN_NO_CONNECT': {
- msg:'Connection with the nativeMessaging host could not be'
- + ' established.',
- type: 'error'
- },
- 'CONN_EMPTY_GPG_ANSWER':{
- msg: 'The nativeMessaging answer was empty.',
- type: 'error'
- },
- 'CONN_TIMEOUT': {
- msg: 'A connection timeout was exceeded.',
- type: 'error'
- },
- 'CONN_UNEXPECTED_ANSWER': {
- msg: 'The answer from gnupg was not as expected.',
- type: 'error'
- },
- '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.',
- type: 'error'
- },
- 'MSG_EMPTY' : {
- msg: 'The Message is empty.',
- type: 'error'
- },
- 'MSG_OP_PENDING': {
- msg: 'There is no operation specified yet. The parameter cannot'
- + ' be set',
- type: 'warning'
- },
- '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'
- },
+const err_list = {
+ // Connection
+ 'CONN_NO_CONNECT': {
+ msg:'Connection with the nativeMessaging host could not be'
+ + ' established.',
+ type: 'error'
+ },
+ 'CONN_DISCONNECTED': {
+ msg:'Connection with the nativeMessaging host was lost.',
+ type: 'error'
+ },
+ 'CONN_EMPTY_GPG_ANSWER':{
+ msg: 'The nativeMessaging answer was empty.',
+ type: 'error'
+ },
+ 'CONN_TIMEOUT': {
+ msg: 'A connection timeout was exceeded.',
+ type: 'error'
+ },
+ 'CONN_UNEXPECTED_ANSWER': {
+ msg: 'The answer from gnupg was not as expected.',
+ type: 'error'
+ },
+ 'CONN_ALREADY_CONNECTED':{
+ msg: 'A connection was already established.',
+ type: 'warning'
+ },
+ // Message/Data
+ 'MSG_INCOMPLETE': {
+ msg: 'The Message did not match the minimum requirements for'
+ + ' the interaction.',
+ type: 'error'
+ },
+ 'MSG_EMPTY' : {
+ msg: 'The Message is empty.',
+ type: 'error'
+ },
+ 'MSG_OP_PENDING': {
+ msg: 'There is no operation specified yet. The parameter cannot'
+ + ' be set',
+ type: 'warning'
+ },
+ 'MSG_WRONG_OP': {
+ msg: 'The operation requested could not be found',
+ type: 'warning'
+ },
+ 'MSG_NO_KEYS' : {
+ msg: 'There were no valid keys provided.',
+ type: 'warning'
+ },
+ 'MSG_NOT_A_FPR': {
+ msg: 'The String is not an accepted fingerprint',
+ type: 'warning'
+ },
+ 'KEY_INVALID': {
+ msg:'Key object is invalid',
+ type: 'error'
+ },
+ // generic
+ 'PARAM_WRONG':{
+ msg: 'invalid parameter was found',
+ type: 'error'
+ },
+ 'PARAM_IGNORED': {
+ msg: 'An parameter was set that has no effect in gpgmejs',
+ type: 'warning'
+ },
+ 'NOT_IMPLEMENTED': {
+ msg: 'A openpgpjs parameter was submitted that is not implemented',
+ type: 'error'
+ },
+ 'NOT_YET_IMPLEMENTED': {
+ msg: 'Support of this is probable, but it is not implemented yet',
+ type: 'error'
+ },
+ 'GENERIC_ERROR': {
+ msg: 'Unspecified error',
+ type: 'error'
+ }
+};
- // generic
- 'PARAM_WRONG':{
- msg: 'invalid parameter was found',
- type: 'error'
- },
- 'NOT_IMPLEMENTED': {
- msg: 'A openpgpjs parameter was submitted that is not implemented',
- type: 'error'
- },
- 'NOT_YET_IMPLEMENTED': {
- msg: 'Support of this is probable, but it is not implemented yet',
- type: 'error'
- },
- 'GENERIC_ERROR': {
- msg: 'Unspecified error',
- type: 'error'
- },
+/**
+ * Checks the given error code and returns an error object with some
+ * information about meaning and origin
+ * @param {*} code Error code. Should be in err_list or 'GNUPG_ERROR'
+ * @param {*} info Error message passed through if code is 'GNUPG_ERROR'
+ */
+export function gpgme_error(code = 'GENERIC_ERROR', info){
+ if (err_list.hasOwnProperty(code)){
+ if (err_list[code].type === 'error'){
+ return new GPGME_Error(code);
}
- if (code === 'TODO'){
- alert('TODO_Error!');
+ if (err_list[code].type === 'warning'){
+ console.log(new GPGME_Error(code));
}
- if (errors.hasOwnProperty(code)){
- code = 'GENERIC_ERROR';
- }
- if (errors.type === 'error'){
- return {code: 'code',
- msg: errors[code].msg
- };
- }
- if (errors.type === 'warning'){
- console.log(code + ': ' + error[code].msg);
- }
- return undefined;
+ return null;
+ } else if (code === 'GNUPG_ERROR'){
+ return new GPGME_Error(code, info.msg);
+ }
+ else {
+ return new GPGME_Error('GENERIC_ERROR');
+ }
}
+
+class GPGME_Error extends Error{
+ constructor(code, msg=''){
+ if (code === 'GNUPG_ERROR' && typeof(msg) === 'string'){
+ super(msg);
+ } else if (err_list.hasOwnProperty(code)){
+ super(err_list[code].msg);
+ } else {
+ super(err_list['GENERIC_ERROR'].msg);
+ }
+ this.code = code || 'GENERIC_ERROR';
+ }
+ set code(value){
+ this._code = value;
+ }
+ get code(){
+ return this._code;
+ }
+}
\ No newline at end of file
diff --git a/lang/js/src/Helpers.js b/lang/js/src/Helpers.js
index d9750ba7..841c0eda 100644
--- a/lang/js/src/Helpers.js
+++ b/lang/js/src/Helpers.js
@@ -17,7 +17,7 @@
* License along with this program; if not, see .
* SPDX-License-Identifier: LGPL-2.1+
*/
-import { GPGMEJS_Error } from "./Errors";
+import { gpgme_error } from "./Errors";
/**
* Tries to return an array of fingerprints, either from input fingerprints or
@@ -28,7 +28,7 @@ import { GPGMEJS_Error } from "./Errors";
export function toKeyIdArray(input, nocheck){
if (!input){
- GPGMEJS_Error('MSG_NO_KEYS');
+ gpgme_error('MSG_NO_KEYS');
return [];
}
if (!Array.isArray(input)){
@@ -40,7 +40,7 @@ export function toKeyIdArray(input, nocheck){
if (isFingerprint(input[i]) === true){
result.push(input[i]);
} else {
- GPGMEJS_Error('MSG_NOT_A_FPR');
+ gpgme_error('MSG_NOT_A_FPR');
}
} else if (typeof(input[i]) === 'object'){
let fpr = '';
@@ -53,14 +53,14 @@ export function toKeyIdArray(input, nocheck){
if (isFingerprint(fpr) === true){
result.push(fpr);
} else {
- GPGMEJS_Error('MSG_NOT_A_FPR');
+ gpgme_error('MSG_NOT_A_FPR');
}
} else {
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
}
if (result.length === 0){
- GPGMEJS_Error('MSG_NO_KEYS');
+ gpgme_error('MSG_NO_KEYS');
return [];
} else {
return result;
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index 5ae80438..f6fa7ae3 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -27,7 +27,9 @@
*/
import {isFingerprint} from './Helpers'
-import {GPGMEJS_Error} from './Errors'
+import {gpgme_error} from './Errors'
+import { GPGME_Message } from './Message';
+import { permittedOperations } from './permittedOperations';
export class GPGME_Key {
@@ -172,32 +174,30 @@ export class GPGME_Key {
*
*/
function checkKey(fingerprint, property){
- return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
-
+ return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
+ if (!property ||
+ permittedOperations[keyinfo].indexOf(property) < 0){
+ return Promise.reject(gpgme_error('PARAM_WRONG'));
+ }
return new Promise(function(resolve, reject){
if (!isFingerprint(fingerprint)){
- reject('not a fingerprint'); //TBD
+ reject('KEY_INVALID');
}
- let conn = new Connection();
- conn.post('getkey',{ // TODO not yet implemented in gpgme
- 'fingerprint': this.fingerprint})
- .then(function(result){
- if (property !== undefined){
- if (result.hasOwnProperty(key)){
- resolve(result[property]);
- }
- else if (property == 'secret'){
- // property undefined means "not true" in case of secret
- resolve(false);
- } else {
- reject('ERR_INVALID_PROPERTY') //TBD
- }
+ let msg = new GPGME_Message('keyinfo');
+ msg.setParameter('fingerprint', this.fingerprint);
+ return (this.connection.post(msg)).then(function(result){
+ if (result.hasOwnProperty(property)){
+ resolve(result[property]);
+ }
+ else if (property == 'secret'){
+ // TBD property undefined means "not true" in case of secret?
+ resolve(false);
+ } else {
+ reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
}
-
-
- resolve(result);
}, function(error){
- reject(error);
+ reject({code: 'GNUPG_ERROR',
+ msg: error.msg});
});
});
};
\ No newline at end of file
diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js
index ef8028ff..e1f0a50f 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -21,6 +21,7 @@
import {GPGME_Message} from './Message'
import {GPGME_Key} from './Key'
import { isFingerprint, isLongId } from './Helpers';
+import { gpgme_error } from './Errors';
export class GPGME_Keyring {
constructor(connection){
@@ -37,9 +38,9 @@ export class GPGME_Keyring {
if (this._connection.isConnected){
return this._connection;
}
- return undefined; //TODO: connection was lost!
+ return gpgme_error('CONN_DISCONNECTED');
}
- return undefined; //TODO: no connection there
+ return gpgme_error('CONN_NO_CONNECT');
}
/**
@@ -81,9 +82,7 @@ export class GPGME_Keyring {
* filters described below. True will filter on the condition, False will
* reverse the filter, if not present or undefined, the filter will not be
* considered. Please note that some combination may not make sense
- * @param {Boolean} flags.defaultKey Only Keys marked as Default Keys
* @param {Boolean} flags.secret Only Keys containing a secret part.
- * @param {Boolean} flags.valid Valid Keys only
* @param {Boolean} flags.revoked revoked Keys only
* @param {Boolean} flags.expired Expired Keys only
* @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
@@ -108,16 +107,20 @@ export class GPGME_Keyring {
} else if (secretflag === false){
anticonditions.push('hasSecret');
}
+ /**
if (flags.defaultKey === true){
conditions.push('isDefault');
} else if (flags.defaultKey === false){
anticonditions.push('isDefault');
}
- if (flags.valid === true){
+ */
+ /**
+ * if (flags.valid === true){
anticonditions.push('isInvalid');
} else if (flags.valid === false){
conditions.push('isInvalid');
}
+ */
if (flags.revoked === true){
conditions.push('isRevoked');
} else if (flags.revoked === false){
diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js
index 1b36f11d..06ac8db2 100644
--- a/lang/js/src/Message.js
+++ b/lang/js/src/Message.js
@@ -18,7 +18,7 @@
* SPDX-License-Identifier: LGPL-2.1+
*/
import { permittedOperations } from './permittedOperations'
-import { GPGMEJS_Error } from './Errors'
+import { gpgme_error } from './Errors'
export class GPGME_Message {
//TODO getter
@@ -39,20 +39,20 @@ export class GPGME_Message {
*/
setParameter(param,value){
if (!param || typeof(param) !== 'string'){
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
if (!this._msg || !this._msg.op){
- return GPGMEJS_Error('MSG_OP_PENDING');
+ return gpgme_error('MSG_OP_PENDING');
}
let po = permittedOperations[this._msg.op];
if (!po){
- return GPGMEJS_Error('MSG_WRONG_OP');
+ return gpgme_error('MSG_WRONG_OP');
}
if (po.required.indexOf(param) >= 0 || po.optional.indexOf(param) >= 0){
this._msg[param] = value;
return true;
}
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
/**
@@ -98,7 +98,7 @@ export class GPGME_Message {
*/
function setOperation (scope, operation){
if (!operation || typeof(operation) !== 'string'){
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
if (permittedOperations.hasOwnProperty(operation)){
if (!scope._msg){
@@ -106,6 +106,6 @@ function setOperation (scope, operation){
}
scope._msg.op = operation;
} else {
- return GPGMEJS_Error('MSG_WRONG_OP');
+ return gpgme_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 b20ff0f2..b504a457 100644
--- a/lang/js/src/gpgmejs.js
+++ b/lang/js/src/gpgmejs.js
@@ -21,7 +21,7 @@
import {Connection} from "./Connection"
import {GPGME_Message} from './Message'
import {toKeyIdArray} from "./Helpers"
-import {GPGMEJS_Error as Error, GPGMEJS_Error} from "./Errors"
+import { gpgme_error } from "./Errors"
import { GPGME_Keyring } from "./Keyring";
export class GpgME {
@@ -35,10 +35,12 @@ export class GpgME {
set connection(connection){
if (this._connection instanceof Connection){
- //TODO Warning: Connection already established
+ gpgme_error('CONN_ALREADY_CONNECTED');
}
if (connection instanceof Connection){
this._connection = connection;
+ } else {
+ gpgme_error('PARAM_WRONG');
}
}
@@ -54,11 +56,12 @@ export class GpgME {
set Keyring(keyring){
if (ring && ring instanceof GPGME_Keyring){
- this.Keyring = ring;
+ this._Keyring = ring;
}
}
get Keyring(){
+ return this._Keyring;
}
/**
@@ -96,7 +99,7 @@ export class GpgME {
decrypt(data){
if (data === undefined){
- return Promise.reject(GPGMEJS_Error('MSG_EMPTY'));
+ return Promise.reject(gpgme_error('MSG_EMPTY'));
}
let msg = new GPGME_Message('decrypt');
putData(msg, data);
@@ -105,7 +108,7 @@ export class GpgME {
}
deleteKey(key, delete_secret = false, no_confirm = false){
- return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
+ return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
let msg = new GPGME_Message('deletekey');
let key_arr = toKeyIdArray(key);
if (key_arr.length !== 1){
@@ -126,7 +129,7 @@ export class GpgME {
case 'ERR_NO_ERROR':
return Promise.resolve('okay'); //TBD
default:
- return Promise.reject(GPGMEJS_Error('TODO') ); //
+ return Promise.reject(gpgme_error('TODO') ); //
// INV_VALUE,
// GPG_ERR_NO_PUBKEY,
// GPG_ERR_AMBIGUOUS_NAME,
@@ -145,7 +148,7 @@ export class GpgME {
*/
function putData(message, data){
if (!message || !message instanceof GPGME_Message ) {
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
if (!data){
message.setParameter('data', '');
@@ -164,6 +167,6 @@ function putData(message, data){
message.setParameter ('data', decoder.decode(txt));
}
} else {
- return GPGMEJS_Error('PARAM_WRONG');
+ return gpgme_error('PARAM_WRONG');
}
}
diff --git a/lang/js/src/gpgmejs_openpgpjs.js b/lang/js/src/gpgmejs_openpgpjs.js
index e32f43a3..4e5e1ea0 100644
--- a/lang/js/src/gpgmejs_openpgpjs.js
+++ b/lang/js/src/gpgmejs_openpgpjs.js
@@ -28,13 +28,13 @@
import {GPGME_Keyring} from "./Keyring"
import { GPGME_Key } from "./Key";
import { isFingerprint } from "./Helpers"
- import { GPGMEJS_Error } from './Errors'
+ import { gpgme_error } from "./Errors"
export class GpgME_openpgpmode {
- constructor(connection){
- this.initGpgME(connection);
+ constructor(connection, config = {}){
+ this.initGpgME(connection, config);
}
get Keyring(){
@@ -44,9 +44,16 @@
return undefined;
}
- initGpgME(connection){
- this._GpgME = new GpgME(connection);
- this._Keyring = new GPGME_Keyring_openpgpmode(connection);
+ initGpgME(connection, config = {}){
+ if (connection && typeof(config) ==='object'){
+ this._config = config;
+ if (!this._GPGME){
+ this._GpgME = new GpgME(connection, config);
+ }
+ if (!this._Keyring){
+ this._Keyring = new GPGME_Keyring_openpgpmode(connection);
+ }
+ }
}
get GpgME(){
@@ -59,19 +66,23 @@
* Encrypt Message
* Supported:
* @param {String|Uint8Array} data
+ * //an openpgp Message also accepted here. TODO: is this wanted?
* @param {Key|Array} publicKeys
+ * //Strings of Fingerprints
* @param {Boolean} wildcard
* TODO:
- * @param {Key|Array} privateKeys
- * @param {String} filename
- * @param {module:enums.compression} compression
- * @param {Boolean} armor
- * @param {Boolean} detached
+ * @param {Key|Array} privateKeys // -> encryptsign
+ * @param {module:enums.compression} compression //TODO accepts integer, if 0 (no compression) it won't compress
+ * @param {Boolean} armor // TODO base64 switch
+ * @param {Boolean} detached // --> encryptsign
* unsupported:
* @param {String|Array} passwords
* @param {Object} sessionKey
* @param {Signature} signature
* @param {Boolean} returnSessionKey
+ * @param {String} filename
+ *
+ * Can be set, but will be ignored:
*
* @returns {Promise