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} * {data: ASCII armored message, @@ -80,57 +91,66 @@ * @async * @static */ - encrypt({data = '', publicKeys = '', privateKeys, passwords, sessionKey, - filename, compression, armor=true, detached=false, signature=null, - returnSessionKey=null, wildcard=false, date=null}) { - if (passwords !== undefined - || sessionKey !== undefined + encrypt({data = '', publicKeys = '', privateKeys, passwords=null, + sessionKey = null, filename, compression, armor=true, detached=false, + signature=null, returnSessionKey=null, wildcard=false, date=null}) { + if (passwords !== null + || sessionKey !== null || signature !== null || returnSessionKey !== null - || date !== null){ + || date !== null + ){ return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED')); } if ( privateKeys - || filename || compression || armor === false || detached == true){ - return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED')); + return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED')); + } + if (filename){ + if (this._config.unconsidered_params === 'warn'){ + GPMGEJS_Error('PARAM_IGNORED'); + } else if (this._config.unconsidered_params === 'error'){ + return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED')); + } } return this.GpgME.encrypt(data, translateKeyInput(publicKeys), wildcard); } /** Decrypt Message - * supported - * TODO: @param {Message} message TODO: for now it accepts an armored string only + * supported openpgpjs parameters: + * @param {Message|Uint8Array|String} message Message object from openpgpjs * Unsupported: * @param {String|Array} passwords + * @param {Key|Array} privateKeys * @param {Object|Array} sessionKeys - * @param {Date} date - - * TODO - * @param {Key|Array} privateKey - * @param {Key|Array} publicKeys + * Not yet supported, but planned * @param {String} format (optional) return data format either as 'utf8' or 'binary' * @param {Signature} signature (optional) detached signature for verification - + * Ignored values: can be safely set, but have no effect + * @param {Date} date + * @param {Key|Array} publicKeys + * * @returns {Promise} decrypted and verified message in the form: * { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] } * @async * @static */ - decrypt({ message, privateKeys, passwords, sessionKeys, publicKeys, format='utf8', signature=null, date}) { - if (passwords !== undefined - || sessionKeys - || date){ - return Promise.reject(GPGMEJS_Error('NOT_IMPLEMENTED')); + decrypt({ message, privateKeys, passwords=null, sessionKeys, + publicKeys, format='utf8', signature=null, date= null}) { + if (passwords !== null || sessionKeys || privateKeys){ + return Promise.reject(gpgme_error('NOT_IMPLEMENTED')); } - if ( privateKeys - || publicKeys - || format !== 'utf8' - || signature - ){ - return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED')); + if ( format !== 'utf8' || signature){ + return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED')); + } + if (date !== null || publicKeys){ + if (this._config.unconsidered_params === 'warn'){ + GPMGEJS_Error('PARAM_IGNORED'); + } else if (this._config.unconsidered_params === 'reject'){ + return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED')); + } } return this.GpgME.decrypt(message); // TODO: translate between: @@ -185,7 +205,7 @@ class GPGME_Keyring_openpgpmode { else { // TODO: Can there be "no default key"? // TODO: Can there be several default keys? - return GPGMEJS_Error('TODO'); + return gpgme_error('TODO'); } }); } @@ -202,10 +222,10 @@ class GPGME_Keyring_openpgpmode { */ deleteKey(key){ if (typeof(key) !== "object"){ - return Promise.reject(GPGMEJS_Error('PARAM_WRONG')); + return Promise.reject(gpgme_error('PARAM_WRONG')); } if ( !key.fingerprint || ! isFingerprint(key.fingerprint)){ - return Promise.reject(GPGMEJS_Error('PARAM_WRONG')); + return Promise.reject(gpgme_error('PARAM_WRONG')); } let key_to_delete = new GPGME_Key(key.fingerprint); return key_to_delete.deleteKey(key.secret); @@ -224,8 +244,8 @@ class GPGME_Key_openpgpmode { set init (value){ if (!this._GPGME_Key && value instanceof GPGME_Key){ this._GPGME_Key = value; - } else if (!this._GPGME_Key && isFingerprint(fpr)){ - this._GPGME_Key = new GPGME_Key; + } else if (!this._GPGME_Key && isFingerprint(value)){ + this._GPGME_Key = new GPGME_Key(value); } } diff --git a/lang/js/src/index.js b/lang/js/src/index.js index a54277c2..48904316 100644 --- a/lang/js/src/index.js +++ b/lang/js/src/index.js @@ -19,7 +19,7 @@ */ import { GpgME } from "./gpgmejs"; -import { GPGMEJS_Error } from "./Errors"; +import { gpgme_error } from "./Errors"; import { GpgME_openpgpmode } from "./gpgmejs_openpgpjs"; import { Connection } from "./Connection"; @@ -29,7 +29,8 @@ import { Connection } from "./Connection"; */ function init( config = { api_style: 'gpgme', // | gpgme_openpgpjs - null_expire_is_never: true // Boolean + null_expire_is_never: true, // Boolean + unconsidered_params: 'warn'//'warn' || 'reject' }){ return new Promise(function(resolve, reject){ let connection = new Connection; @@ -41,12 +42,12 @@ function init( config = { let gpgme = null; if (config.api_style && config.api_style === 'gpgme_openpgpjs'){ resolve( - new GpgME_openpgpmode(connection)); + new GpgME_openpgpmode(connection, config)); } else { resolve(new GpgME(connection)); } } else { - reject(GPGMEJS_Error('CONN_NO_CONNECT')); + reject(gpgme_error('CONN_NO_CONNECT')); } }; setTimeout(delayedreaction, 5); diff --git a/lang/js/src/permittedOperations.js b/lang/js/src/permittedOperations.js index 892f4f2e..79e74223 100644 --- a/lang/js/src/permittedOperations.js +++ b/lang/js/src/permittedOperations.js @@ -31,7 +31,7 @@ partial and in need of concatenation params: Array Information that do not change throughout the message - infos: Array arbitrary information that may change + infos: Array<*> arbitrary information that may result in a list } } */ @@ -72,7 +72,55 @@ export const permittedOperations = { type: ['plaintext'], data: ['data'], params: ['base64', 'mime'], - infos: ['info'] + infos: [] // pending. Info about signatures and validity + //signature: [{Key Fingerprint, valid Boolean}] + } + }, + /** + keyinfo: { // querying the Key's information. + required: ['fingerprint'], + anser: { + type: ['TBD'], + data: [], + params: ['hasSecret', 'isRevoked', 'isExpired', 'armored', + 'timestamp', 'expires', 'pubkey_algo'], + infos: ['subkeys', 'userIds'] + }*/ + + /** + listkeys:{ + optional: ['with-secret', 'pattern'], + answer: { + type: ['TBD'], //Array of fingerprints? + infos: ['TBD'] //the property with infos + }, + */ + + /** + importkey: { + required: ['keyarmored'], + answer: { + type: ['TBD'], + infos: [''], // for each key if import was a success, if it was an update + } + }, + */ + + /** + deletekey: { + required: ['fingerprint'], + answer: { + type ['TBD'], + infos: [''] //success:true? in gpgme, an error NO_ERROR is returned } } + */ + + /** + *get armored secret different treatment from keyinfo! + */ + + /** + * TBD key modification requests? + */ }