diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js
index 52fa7f71..d8cb84b2 100644
--- a/lang/js/src/Keyring.js
+++ b/lang/js/src/Keyring.js
@@ -1,151 +1,150 @@
/* 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 {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();
}
/**
* (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();
}
}
/**
* @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
* @param {Boolean} (optional) Include listing of secret keys
* @returns {Promise.>}
*
*/
getKeys(pattern, include_secret){
- let msg = new GPGME_Message;
- msg.operation = 'listkeys';
+ let msg = new GPGME_Message('listkeys');
if (pattern && typeof(pattern) === 'string'){
msg.setParameter('pattern', pattern);
}
if (include_secret){
msg.setParameter('with-secret', true);
}
this._connection.post(msg).then(function(result){
let fpr_list = [];
let resultset = [];
if (!Array.isArray(result.keys)){
//TODO check assumption keys = Array
fpr_list = [result.keys];
} else {
fpr_list = result.keys;
}
for (let i=0; i < fpr_list.length; i++){
let newKey = new GPGME_Key(fpr_list[i]);
if (newKey instanceof GPGME_Key){
resultset.push(newKey);
}
}
return Promise.resolve(resultset);
});
}
/**
* @param {Object} flags subset filter expecting at least one of the
* 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
* @returns {Promise Array}
*
*/
getSubset(flags, pattern){
if (flags === undefined) {
throw('ERR_WRONG_PARAM');
};
let secretflag = false;
if (flags.hasOwnProperty(secret) && flags.secret){
secretflag = true;
}
this.getKeys(pattern, secretflag).then(function(queryset){
let resultset = [];
for (let i=0; i < queryset.length; i++ ){
let conditions = [];
let anticonditions = [];
if (secretflag === true){
conditions.push('hasSecret');
} 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){
anticonditions.push('isInvalid');
} else if (flags.valid === false){
conditions.push('isInvalid');
}
if (flags.revoked === true){
conditions.push('isRevoked');
} else if (flags.revoked === false){
anticonditions.push('isRevoked');
}
if (flags.expired === true){
conditions.push('isExpired');
} else if (flags.expired === false){
anticonditions.push('isExpired');
}
let decision = undefined;
for (let con = 0; con < conditions.length; con ++){
if (queryset[i][conditions[con]] !== true){
decision = false;
}
}
for (let acon = 0; acon < anticonditions.length; acon ++){
if (queryset[i][anticonditions[acon]] === true){
decision = false;
}
}
if (decision !== false){
resultset.push(queryset[i]);
}
}
return Promise.resolve(resultset);
});
}
};
diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js
index 6a93b6f4..f5e21e00 100644
--- a/lang/js/src/Message.js
+++ b/lang/js/src/Message.js
@@ -1,113 +1,111 @@
/* 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 { permittedOperations } from './permittedOperations'
import { GPGMEJS_Error } from './Errors'
export class GPGME_Message {
//TODO getter
constructor(operation){
- if (operation){
- this.operation(operation);
- }
- }
-
- /**
- * Defines the operation this message will have
- * @param {String} operation Must be defined in permittedOperations
- * TODO: move to constructor?
- */
- set operation (operation){
- if (!operation || typeof(operation) !== 'string'){
- return new GPGMEJS_Error('WRONGPARAM');
- }
- if (operation in permittedOperations){
- if (!this._msg){
- this._msg = {};
- }
- this._msg.op = operation;
- } else {
- return new GPGMEJS_Error('WRONG_OP');
- }
+ setOperation(this, operation);
}
get operation(){
return this._msg.op;
}
/**
* Sets a parameter for the message. Note that the operation has to be set
* first, to be able to check if the parameter is permittted
* @param {String} param Parameter to set
* @param {any} value Value to set //TODO: Some type checking
* @returns {Boolean} If the parameter was set successfully
*/
setParameter(param,value){
if (!param || typeof(param) !== 'string'){
return new GPGMEJS_Error('WRONGPARAM', 'type check failed');
}
if (!this._msg || !this._msg.op){
return new GPGMEJS_Error('MSG_OP_PENDING');
}
let po = permittedOperations[this._msg.op];
if (!po){
return new GPGMEJS_Error('WRONG_OP', param);
}
if (po.required.indexOf(param) >= 0 || po.optional.indexOf(param) >= 0){
this._msg[param] = value;
return true;
}
return new GPGMEJS_Error('WRONGPARAM', param);
}
/**
* Check if the message has the minimum requirements to be sent, according
* to the definitions in permittedOperations
* @returns {Boolean}
*/
get isComplete(){
if (!this._msg.op){
return false;
}
let reqParams = permittedOperations[this._msg.op].required;
for (let i=0; i < reqParams.length; i++){
if (!this._msg.hasOwnProperty(reqParams[i])){
console.log(reqParams[i] + 'missing');
return false;
}
}
return true;
}
/**
* Returns the prepared message with parameters and completeness checked
* @returns {Object|null} Object to be posted to gnupg, or null if
* incomplete
*/
get message(){
if (this.isComplete === true){
return this._msg;
}
else {
return null;
}
}
+}
+
+/**
+ * Defines the operation this message will have
+ * @param {String} operation Must be defined in permittedOperations
+ * TODO: move to constructor?
+ */
+function setOperation (scope, operation){
+ if (!operation || typeof(operation) !== 'string'){
+ return new GPGMEJS_Error('WRONGTYPE');
+ }
+ if (permittedOperations.hasOwnProperty(operation)){
+ if (!scope._msg){
+ scope._msg = {};
+ }
+ scope._msg.op = operation;
+ } else {
+ return new GPGMEJS_Error('WRONG_OP');
+ }
}
\ No newline at end of file
diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js
index c23a356b..b15477f0 100644
--- a/lang/js/src/gpgmejs.js
+++ b/lang/js/src/gpgmejs.js
@@ -1,177 +1,174 @@
/* 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 {Connection} from "./Connection"
import {GPGME_Message} from './Message'
import {toKeyIdArray} from "./Helpers"
import {GPGMEJS_Error as Error, GPGMEJS_Error} from "./Errors"
export class GpgME {
/**
* initializes GpgME by opening a nativeMessaging port
* TODO: add configuration
*/
constructor(configuration = {
null_expire_is_never: false
}){
this._connection = new Connection;
}
/**
* refreshes the nativeApp connection
*/
reconnect(){
if (!this._connection || ! this._connection instanceof Connection){
this._connection = new Connection;
} else {
this._connection.disconnect();
this._connection.connect();
}
}
/**
* 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;
}
}
/**
* tests the nativeApp connection
*/
get connected(){
if (!this._connection || ! this._connection instanceof Connection){
return false;
}
return this._connection.connected;
}
/**
* @param {String|Uint8Array} data text/data to be encrypted as String/Uint8Array
* @param {GPGME_Key|String|Array|Array} 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){
- let msg = new GPGME_Message;
- msg.operation = 'encrypt';
+ let msg = new GPGME_Message('encrypt');
// TODO temporary
msg.setParameter('armor', true);
msg.setParameter('always-trust', true);
let pubkeys = toKeyIdArray(publicKeys);
msg.setParameter('keys', pubkeys);
putData(msg, data);
if (wildcard === true){msg.setParameter('throw-keyids', true);
};
return (this._connection.post(msg));
}
/**
* @param {String} data TODO Format: base64? String? Message with the encrypted data
* @returns {Promise