js: Configuration and Error handling
-- * gpgmejs_openpgpjs - unsuported values with no negative consequences can now reject, warn or be ignored, according to config.unconsidered_params - cleanup of unsupported/supported parameters and TODOS * A src/index.js init() now accepts a configuration object * Errors will now be derived from Error, offering more info and a stacktrace. * Fixed Connection.post() timeout triggering on wrong cases * Added comments in permittedOperations.js, which gpgme interactions are still unimplemented and should be added next
This commit is contained in:
parent
5befa1c975
commit
1fb310cabe
@ -24,7 +24,7 @@
|
|||||||
* expected.
|
* expected.
|
||||||
*/
|
*/
|
||||||
import { permittedOperations } from './permittedOperations'
|
import { permittedOperations } from './permittedOperations'
|
||||||
import { GPGMEJS_Error } from "./Errors"
|
import { gpgme_error } from "./Errors"
|
||||||
import { GPGME_Message } from "./Message";
|
import { GPGME_Message } from "./Message";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,7 +62,7 @@ export class Connection{
|
|||||||
*/
|
*/
|
||||||
connect(){
|
connect(){
|
||||||
if (this._isConnected === true){
|
if (this._isConnected === true){
|
||||||
GPGMEJS_Error('CONN_ALREADY_CONNECTED');
|
gpgme_error('CONN_ALREADY_CONNECTED');
|
||||||
} else {
|
} else {
|
||||||
this._isConnected = true;
|
this._isConnected = true;
|
||||||
this._connection = chrome.runtime.connectNative('gpgmejson');
|
this._connection = chrome.runtime.connectNative('gpgmejson');
|
||||||
@ -83,13 +83,13 @@ export class Connection{
|
|||||||
*/
|
*/
|
||||||
post(message){
|
post(message){
|
||||||
if (!this.isConnected){
|
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){
|
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){
|
if (message.isComplete !== true){
|
||||||
return Promise.reject(GPGMEJS_Error('MSG_INCOMPLETE'));
|
return Promise.reject(gpgme_error('MSG_INCOMPLETE'));
|
||||||
}
|
}
|
||||||
let me = this;
|
let me = this;
|
||||||
return new Promise(function(resolve, reject){
|
return new Promise(function(resolve, reject){
|
||||||
@ -97,7 +97,7 @@ export class Connection{
|
|||||||
let listener = function(msg) {
|
let listener = function(msg) {
|
||||||
if (!msg){
|
if (!msg){
|
||||||
me._connection.onMessage.removeListener(listener)
|
me._connection.onMessage.removeListener(listener)
|
||||||
reject(GPGMEJS_Error('CONN_EMPTY_GPG_ANSWER'));
|
reject(gpgme_error('CONN_EMPTY_GPG_ANSWER'));
|
||||||
} else if (msg.type === "error"){
|
} else if (msg.type === "error"){
|
||||||
me._connection.onMessage.removeListener(listener)
|
me._connection.onMessage.removeListener(listener)
|
||||||
reject(
|
reject(
|
||||||
@ -118,17 +118,18 @@ export class Connection{
|
|||||||
};
|
};
|
||||||
|
|
||||||
me._connection.onMessage.addListener(listener);
|
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){
|
if (permittedOperations[message.operation].pinentry){
|
||||||
return me._connection.postMessage(message.message);
|
return me._connection.postMessage(message.message);
|
||||||
} else {
|
} else {
|
||||||
return Promise.race([timeout,
|
return Promise.race([
|
||||||
me._connection.postMessage(message.message)
|
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
|
* Add the information to the answer
|
||||||
* @param {Object} msg The message as received with nativeMessaging
|
* @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){
|
add(msg){
|
||||||
if (this._response === undefined){
|
if (this._response === undefined){
|
||||||
@ -157,14 +158,14 @@ class Answer{
|
|||||||
let messageKeys = Object.keys(msg);
|
let messageKeys = Object.keys(msg);
|
||||||
let poa = permittedOperations[this.operation].answer;
|
let poa = permittedOperations[this.operation].answer;
|
||||||
if (messageKeys.length === 0){
|
if (messageKeys.length === 0){
|
||||||
return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
|
return gpgme_error('CONN_UNEXPECTED_ANSWER');
|
||||||
}
|
}
|
||||||
for (let i= 0; i < messageKeys.length; i++){
|
for (let i= 0; i < messageKeys.length; i++){
|
||||||
let key = messageKeys[i];
|
let key = messageKeys[i];
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'type':
|
case 'type':
|
||||||
if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){
|
if ( msg.type !== 'error' && poa.type.indexOf(msg.type) < 0){
|
||||||
return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER');
|
return gpgme_error('CONN_UNEXPECTED_ANSWER');
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'more':
|
case 'more':
|
||||||
@ -183,7 +184,7 @@ class Answer{
|
|||||||
this._response[key] = msg[key];
|
this._response[key] = msg[key];
|
||||||
}
|
}
|
||||||
else if (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.
|
//infos may be json objects etc. Not yet defined.
|
||||||
@ -195,7 +196,7 @@ class Answer{
|
|||||||
this._response.push(msg[key]);
|
this._response.push(msg[key]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return GPGMEJS_Error('CONN_UNEXPECTED_ANSWER', key);
|
return gpgme_error('CONN_UNEXPECTED_ANSWER', key);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -18,99 +18,125 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1+
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
const err_list = {
|
||||||
* Checks the given error code and returns some information about it's meaning
|
// Connection
|
||||||
* @param {String} code The error code
|
'CONN_NO_CONNECT': {
|
||||||
* @returns {Object} An object containing string properties code and msg
|
msg:'Connection with the nativeMessaging host could not be'
|
||||||
* TODO: error-like objects with the code 'GNUPG_ERROR' are errors sent
|
+ ' established.',
|
||||||
* directly by gnupg as answer in Connection.post()
|
type: 'error'
|
||||||
*/
|
},
|
||||||
export function GPGMEJS_Error(code = 'GENERIC_ERROR'){
|
'CONN_DISCONNECTED': {
|
||||||
if (!typeof(code) === 'string'){
|
msg:'Connection with the nativeMessaging host was lost.',
|
||||||
code = 'GENERIC_ERROR';
|
type: 'error'
|
||||||
}
|
},
|
||||||
let errors = { //TODO: someplace else
|
'CONN_EMPTY_GPG_ANSWER':{
|
||||||
// Connection
|
msg: 'The nativeMessaging answer was empty.',
|
||||||
'CONN_NO_CONNECT': {
|
type: 'error'
|
||||||
msg:'Connection with the nativeMessaging host could not be'
|
},
|
||||||
+ ' established.',
|
'CONN_TIMEOUT': {
|
||||||
type: 'error'
|
msg: 'A connection timeout was exceeded.',
|
||||||
},
|
type: 'error'
|
||||||
'CONN_EMPTY_GPG_ANSWER':{
|
},
|
||||||
msg: 'The nativeMessaging answer was empty.',
|
'CONN_UNEXPECTED_ANSWER': {
|
||||||
type: 'error'
|
msg: 'The answer from gnupg was not as expected.',
|
||||||
},
|
type: 'error'
|
||||||
'CONN_TIMEOUT': {
|
},
|
||||||
msg: 'A connection timeout was exceeded.',
|
'CONN_ALREADY_CONNECTED':{
|
||||||
type: 'error'
|
msg: 'A connection was already established.',
|
||||||
},
|
type: 'warning'
|
||||||
'CONN_UNEXPECTED_ANSWER': {
|
},
|
||||||
msg: 'The answer from gnupg was not as expected.',
|
// Message/Data
|
||||||
type: 'error'
|
'MSG_INCOMPLETE': {
|
||||||
},
|
msg: 'The Message did not match the minimum requirements for'
|
||||||
'CONN_ALREADY_CONNECTED':{
|
+ ' the interaction.',
|
||||||
msg: 'A connection was already established.',
|
type: 'error'
|
||||||
type: 'warn'
|
},
|
||||||
},
|
'MSG_EMPTY' : {
|
||||||
// Message/Data
|
msg: 'The Message is empty.',
|
||||||
'MSG_INCOMPLETE': {
|
type: 'error'
|
||||||
msg: 'The Message did not match the minimum requirements for'
|
},
|
||||||
+ ' the interaction.',
|
'MSG_OP_PENDING': {
|
||||||
type: 'error'
|
msg: 'There is no operation specified yet. The parameter cannot'
|
||||||
},
|
+ ' be set',
|
||||||
'MSG_EMPTY' : {
|
type: 'warning'
|
||||||
msg: 'The Message is empty.',
|
},
|
||||||
type: 'error'
|
'MSG_WRONG_OP': {
|
||||||
},
|
msg: 'The operation requested could not be found',
|
||||||
'MSG_OP_PENDING': {
|
type: 'warning'
|
||||||
msg: 'There is no operation specified yet. The parameter cannot'
|
},
|
||||||
+ ' be set',
|
'MSG_NO_KEYS' : {
|
||||||
type: 'warning'
|
msg: 'There were no valid keys provided.',
|
||||||
},
|
type: 'warning'
|
||||||
'MSG_WRONG_OP': {
|
},
|
||||||
msg: 'The operation requested could not be found',
|
'MSG_NOT_A_FPR': {
|
||||||
type: 'warning'
|
msg: 'The String is not an accepted fingerprint',
|
||||||
},
|
type: 'warning'
|
||||||
'MSG_NO_KEYS' : {
|
},
|
||||||
msg: 'There were no valid keys provided.',
|
'KEY_INVALID': {
|
||||||
type: 'warn'
|
msg:'Key object is invalid',
|
||||||
},
|
type: 'error'
|
||||||
'MSG_NOT_A_FPR': {
|
},
|
||||||
msg: 'The String is not an accepted fingerprint',
|
// generic
|
||||||
type: 'warn'
|
'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':{
|
* Checks the given error code and returns an error object with some
|
||||||
msg: 'invalid parameter was found',
|
* information about meaning and origin
|
||||||
type: 'error'
|
* @param {*} code Error code. Should be in err_list or 'GNUPG_ERROR'
|
||||||
},
|
* @param {*} info Error message passed through if code is 'GNUPG_ERROR'
|
||||||
'NOT_IMPLEMENTED': {
|
*/
|
||||||
msg: 'A openpgpjs parameter was submitted that is not implemented',
|
export function gpgme_error(code = 'GENERIC_ERROR', info){
|
||||||
type: 'error'
|
if (err_list.hasOwnProperty(code)){
|
||||||
},
|
if (err_list[code].type === 'error'){
|
||||||
'NOT_YET_IMPLEMENTED': {
|
return new GPGME_Error(code);
|
||||||
msg: 'Support of this is probable, but it is not implemented yet',
|
|
||||||
type: 'error'
|
|
||||||
},
|
|
||||||
'GENERIC_ERROR': {
|
|
||||||
msg: 'Unspecified error',
|
|
||||||
type: 'error'
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
if (code === 'TODO'){
|
if (err_list[code].type === 'warning'){
|
||||||
alert('TODO_Error!');
|
console.log(new GPGME_Error(code));
|
||||||
}
|
}
|
||||||
if (errors.hasOwnProperty(code)){
|
return null;
|
||||||
code = 'GENERIC_ERROR';
|
} else if (code === 'GNUPG_ERROR'){
|
||||||
}
|
return new GPGME_Error(code, info.msg);
|
||||||
if (errors.type === 'error'){
|
}
|
||||||
return {code: 'code',
|
else {
|
||||||
msg: errors[code].msg
|
return new GPGME_Error('GENERIC_ERROR');
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
if (errors.type === 'warning'){
|
|
||||||
console.log(code + ': ' + error[code].msg);
|
class GPGME_Error extends Error{
|
||||||
}
|
constructor(code, msg=''){
|
||||||
return undefined;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -17,7 +17,7 @@
|
|||||||
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||||
* SPDX-License-Identifier: LGPL-2.1+
|
* 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
|
* 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){
|
export function toKeyIdArray(input, nocheck){
|
||||||
if (!input){
|
if (!input){
|
||||||
GPGMEJS_Error('MSG_NO_KEYS');
|
gpgme_error('MSG_NO_KEYS');
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
if (!Array.isArray(input)){
|
if (!Array.isArray(input)){
|
||||||
@ -40,7 +40,7 @@ export function toKeyIdArray(input, nocheck){
|
|||||||
if (isFingerprint(input[i]) === true){
|
if (isFingerprint(input[i]) === true){
|
||||||
result.push(input[i]);
|
result.push(input[i]);
|
||||||
} else {
|
} else {
|
||||||
GPGMEJS_Error('MSG_NOT_A_FPR');
|
gpgme_error('MSG_NOT_A_FPR');
|
||||||
}
|
}
|
||||||
} else if (typeof(input[i]) === 'object'){
|
} else if (typeof(input[i]) === 'object'){
|
||||||
let fpr = '';
|
let fpr = '';
|
||||||
@ -53,14 +53,14 @@ export function toKeyIdArray(input, nocheck){
|
|||||||
if (isFingerprint(fpr) === true){
|
if (isFingerprint(fpr) === true){
|
||||||
result.push(fpr);
|
result.push(fpr);
|
||||||
} else {
|
} else {
|
||||||
GPGMEJS_Error('MSG_NOT_A_FPR');
|
gpgme_error('MSG_NOT_A_FPR');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result.length === 0){
|
if (result.length === 0){
|
||||||
GPGMEJS_Error('MSG_NO_KEYS');
|
gpgme_error('MSG_NO_KEYS');
|
||||||
return [];
|
return [];
|
||||||
} else {
|
} else {
|
||||||
return result;
|
return result;
|
||||||
|
@ -27,7 +27,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import {isFingerprint} from './Helpers'
|
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 {
|
export class GPGME_Key {
|
||||||
|
|
||||||
@ -172,32 +174,30 @@ export class GPGME_Key {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
function checkKey(fingerprint, property){
|
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){
|
return new Promise(function(resolve, reject){
|
||||||
if (!isFingerprint(fingerprint)){
|
if (!isFingerprint(fingerprint)){
|
||||||
reject('not a fingerprint'); //TBD
|
reject('KEY_INVALID');
|
||||||
}
|
}
|
||||||
let conn = new Connection();
|
let msg = new GPGME_Message('keyinfo');
|
||||||
conn.post('getkey',{ // TODO not yet implemented in gpgme
|
msg.setParameter('fingerprint', this.fingerprint);
|
||||||
'fingerprint': this.fingerprint})
|
return (this.connection.post(msg)).then(function(result){
|
||||||
.then(function(result){
|
if (result.hasOwnProperty(property)){
|
||||||
if (property !== undefined){
|
resolve(result[property]);
|
||||||
if (result.hasOwnProperty(key)){
|
}
|
||||||
resolve(result[property]);
|
else if (property == 'secret'){
|
||||||
}
|
// TBD property undefined means "not true" in case of secret?
|
||||||
else if (property == 'secret'){
|
resolve(false);
|
||||||
// property undefined means "not true" in case of secret
|
} else {
|
||||||
resolve(false);
|
reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
|
||||||
} else {
|
|
||||||
reject('ERR_INVALID_PROPERTY') //TBD
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
resolve(result);
|
|
||||||
}, function(error){
|
}, function(error){
|
||||||
reject(error);
|
reject({code: 'GNUPG_ERROR',
|
||||||
|
msg: error.msg});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
@ -21,6 +21,7 @@
|
|||||||
import {GPGME_Message} from './Message'
|
import {GPGME_Message} from './Message'
|
||||||
import {GPGME_Key} from './Key'
|
import {GPGME_Key} from './Key'
|
||||||
import { isFingerprint, isLongId } from './Helpers';
|
import { isFingerprint, isLongId } from './Helpers';
|
||||||
|
import { gpgme_error } from './Errors';
|
||||||
|
|
||||||
export class GPGME_Keyring {
|
export class GPGME_Keyring {
|
||||||
constructor(connection){
|
constructor(connection){
|
||||||
@ -37,9 +38,9 @@ export class GPGME_Keyring {
|
|||||||
if (this._connection.isConnected){
|
if (this._connection.isConnected){
|
||||||
return this._connection;
|
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
|
* filters described below. True will filter on the condition, False will
|
||||||
* reverse the filter, if not present or undefined, the filter will not be
|
* reverse the filter, if not present or undefined, the filter will not be
|
||||||
* considered. Please note that some combination may not make sense
|
* 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.secret Only Keys containing a secret part.
|
||||||
* @param {Boolean} flags.valid Valid Keys only
|
|
||||||
* @param {Boolean} flags.revoked revoked Keys only
|
* @param {Boolean} flags.revoked revoked Keys only
|
||||||
* @param {Boolean} flags.expired Expired Keys only
|
* @param {Boolean} flags.expired Expired Keys only
|
||||||
* @param {String} (optional) pattern A pattern to search for, in userIds or KeyIds
|
* @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){
|
} else if (secretflag === false){
|
||||||
anticonditions.push('hasSecret');
|
anticonditions.push('hasSecret');
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
if (flags.defaultKey === true){
|
if (flags.defaultKey === true){
|
||||||
conditions.push('isDefault');
|
conditions.push('isDefault');
|
||||||
} else if (flags.defaultKey === false){
|
} else if (flags.defaultKey === false){
|
||||||
anticonditions.push('isDefault');
|
anticonditions.push('isDefault');
|
||||||
}
|
}
|
||||||
if (flags.valid === true){
|
*/
|
||||||
|
/**
|
||||||
|
* if (flags.valid === true){
|
||||||
anticonditions.push('isInvalid');
|
anticonditions.push('isInvalid');
|
||||||
} else if (flags.valid === false){
|
} else if (flags.valid === false){
|
||||||
conditions.push('isInvalid');
|
conditions.push('isInvalid');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (flags.revoked === true){
|
if (flags.revoked === true){
|
||||||
conditions.push('isRevoked');
|
conditions.push('isRevoked');
|
||||||
} else if (flags.revoked === false){
|
} else if (flags.revoked === false){
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
* SPDX-License-Identifier: LGPL-2.1+
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
*/
|
*/
|
||||||
import { permittedOperations } from './permittedOperations'
|
import { permittedOperations } from './permittedOperations'
|
||||||
import { GPGMEJS_Error } from './Errors'
|
import { gpgme_error } from './Errors'
|
||||||
export class GPGME_Message {
|
export class GPGME_Message {
|
||||||
//TODO getter
|
//TODO getter
|
||||||
|
|
||||||
@ -39,20 +39,20 @@ export class GPGME_Message {
|
|||||||
*/
|
*/
|
||||||
setParameter(param,value){
|
setParameter(param,value){
|
||||||
if (!param || typeof(param) !== 'string'){
|
if (!param || typeof(param) !== 'string'){
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
if (!this._msg || !this._msg.op){
|
if (!this._msg || !this._msg.op){
|
||||||
return GPGMEJS_Error('MSG_OP_PENDING');
|
return gpgme_error('MSG_OP_PENDING');
|
||||||
}
|
}
|
||||||
let po = permittedOperations[this._msg.op];
|
let po = permittedOperations[this._msg.op];
|
||||||
if (!po){
|
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){
|
if (po.required.indexOf(param) >= 0 || po.optional.indexOf(param) >= 0){
|
||||||
this._msg[param] = value;
|
this._msg[param] = value;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,7 +98,7 @@ export class GPGME_Message {
|
|||||||
*/
|
*/
|
||||||
function setOperation (scope, operation){
|
function setOperation (scope, operation){
|
||||||
if (!operation || typeof(operation) !== 'string'){
|
if (!operation || typeof(operation) !== 'string'){
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
if (permittedOperations.hasOwnProperty(operation)){
|
if (permittedOperations.hasOwnProperty(operation)){
|
||||||
if (!scope._msg){
|
if (!scope._msg){
|
||||||
@ -106,6 +106,6 @@ function setOperation (scope, operation){
|
|||||||
}
|
}
|
||||||
scope._msg.op = operation;
|
scope._msg.op = operation;
|
||||||
} else {
|
} else {
|
||||||
return GPGMEJS_Error('MSG_WRONG_OP');
|
return gpgme_error('MSG_WRONG_OP');
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,7 +21,7 @@
|
|||||||
import {Connection} from "./Connection"
|
import {Connection} from "./Connection"
|
||||||
import {GPGME_Message} from './Message'
|
import {GPGME_Message} from './Message'
|
||||||
import {toKeyIdArray} from "./Helpers"
|
import {toKeyIdArray} from "./Helpers"
|
||||||
import {GPGMEJS_Error as Error, GPGMEJS_Error} from "./Errors"
|
import { gpgme_error } from "./Errors"
|
||||||
import { GPGME_Keyring } from "./Keyring";
|
import { GPGME_Keyring } from "./Keyring";
|
||||||
|
|
||||||
export class GpgME {
|
export class GpgME {
|
||||||
@ -35,10 +35,12 @@ export class GpgME {
|
|||||||
|
|
||||||
set connection(connection){
|
set connection(connection){
|
||||||
if (this._connection instanceof Connection){
|
if (this._connection instanceof Connection){
|
||||||
//TODO Warning: Connection already established
|
gpgme_error('CONN_ALREADY_CONNECTED');
|
||||||
}
|
}
|
||||||
if (connection instanceof Connection){
|
if (connection instanceof Connection){
|
||||||
this._connection = connection;
|
this._connection = connection;
|
||||||
|
} else {
|
||||||
|
gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,11 +56,12 @@ export class GpgME {
|
|||||||
|
|
||||||
set Keyring(keyring){
|
set Keyring(keyring){
|
||||||
if (ring && ring instanceof GPGME_Keyring){
|
if (ring && ring instanceof GPGME_Keyring){
|
||||||
this.Keyring = ring;
|
this._Keyring = ring;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get Keyring(){
|
get Keyring(){
|
||||||
|
return this._Keyring;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -96,7 +99,7 @@ export class GpgME {
|
|||||||
|
|
||||||
decrypt(data){
|
decrypt(data){
|
||||||
if (data === undefined){
|
if (data === undefined){
|
||||||
return Promise.reject(GPGMEJS_Error('MSG_EMPTY'));
|
return Promise.reject(gpgme_error('MSG_EMPTY'));
|
||||||
}
|
}
|
||||||
let msg = new GPGME_Message('decrypt');
|
let msg = new GPGME_Message('decrypt');
|
||||||
putData(msg, data);
|
putData(msg, data);
|
||||||
@ -105,7 +108,7 @@ export class GpgME {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deleteKey(key, delete_secret = false, no_confirm = false){
|
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 msg = new GPGME_Message('deletekey');
|
||||||
let key_arr = toKeyIdArray(key);
|
let key_arr = toKeyIdArray(key);
|
||||||
if (key_arr.length !== 1){
|
if (key_arr.length !== 1){
|
||||||
@ -126,7 +129,7 @@ export class GpgME {
|
|||||||
case 'ERR_NO_ERROR':
|
case 'ERR_NO_ERROR':
|
||||||
return Promise.resolve('okay'); //TBD
|
return Promise.resolve('okay'); //TBD
|
||||||
default:
|
default:
|
||||||
return Promise.reject(GPGMEJS_Error('TODO') ); //
|
return Promise.reject(gpgme_error('TODO') ); //
|
||||||
// INV_VALUE,
|
// INV_VALUE,
|
||||||
// GPG_ERR_NO_PUBKEY,
|
// GPG_ERR_NO_PUBKEY,
|
||||||
// GPG_ERR_AMBIGUOUS_NAME,
|
// GPG_ERR_AMBIGUOUS_NAME,
|
||||||
@ -145,7 +148,7 @@ export class GpgME {
|
|||||||
*/
|
*/
|
||||||
function putData(message, data){
|
function putData(message, data){
|
||||||
if (!message || !message instanceof GPGME_Message ) {
|
if (!message || !message instanceof GPGME_Message ) {
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
if (!data){
|
if (!data){
|
||||||
message.setParameter('data', '');
|
message.setParameter('data', '');
|
||||||
@ -164,6 +167,6 @@ function putData(message, data){
|
|||||||
message.setParameter ('data', decoder.decode(txt));
|
message.setParameter ('data', decoder.decode(txt));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return GPGMEJS_Error('PARAM_WRONG');
|
return gpgme_error('PARAM_WRONG');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,13 +28,13 @@
|
|||||||
import {GPGME_Keyring} from "./Keyring"
|
import {GPGME_Keyring} from "./Keyring"
|
||||||
import { GPGME_Key } from "./Key";
|
import { GPGME_Key } from "./Key";
|
||||||
import { isFingerprint } from "./Helpers"
|
import { isFingerprint } from "./Helpers"
|
||||||
import { GPGMEJS_Error } from './Errors'
|
import { gpgme_error } from "./Errors"
|
||||||
|
|
||||||
|
|
||||||
export class GpgME_openpgpmode {
|
export class GpgME_openpgpmode {
|
||||||
|
|
||||||
constructor(connection){
|
constructor(connection, config = {}){
|
||||||
this.initGpgME(connection);
|
this.initGpgME(connection, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
get Keyring(){
|
get Keyring(){
|
||||||
@ -44,9 +44,16 @@
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
initGpgME(connection){
|
initGpgME(connection, config = {}){
|
||||||
this._GpgME = new GpgME(connection);
|
if (connection && typeof(config) ==='object'){
|
||||||
this._Keyring = new GPGME_Keyring_openpgpmode(connection);
|
this._config = config;
|
||||||
|
if (!this._GPGME){
|
||||||
|
this._GpgME = new GpgME(connection, config);
|
||||||
|
}
|
||||||
|
if (!this._Keyring){
|
||||||
|
this._Keyring = new GPGME_Keyring_openpgpmode(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get GpgME(){
|
get GpgME(){
|
||||||
@ -59,19 +66,23 @@
|
|||||||
* Encrypt Message
|
* Encrypt Message
|
||||||
* Supported:
|
* Supported:
|
||||||
* @param {String|Uint8Array} data
|
* @param {String|Uint8Array} data
|
||||||
|
* //an openpgp Message also accepted here. TODO: is this wanted?
|
||||||
* @param {Key|Array<Key>} publicKeys
|
* @param {Key|Array<Key>} publicKeys
|
||||||
|
* //Strings of Fingerprints
|
||||||
* @param {Boolean} wildcard
|
* @param {Boolean} wildcard
|
||||||
* TODO:
|
* TODO:
|
||||||
* @param {Key|Array<Key>} privateKeys
|
* @param {Key|Array<Key>} privateKeys // -> encryptsign
|
||||||
* @param {String} filename
|
* @param {module:enums.compression} compression //TODO accepts integer, if 0 (no compression) it won't compress
|
||||||
* @param {module:enums.compression} compression
|
* @param {Boolean} armor // TODO base64 switch
|
||||||
* @param {Boolean} armor
|
* @param {Boolean} detached // --> encryptsign
|
||||||
* @param {Boolean} detached
|
|
||||||
* unsupported:
|
* unsupported:
|
||||||
* @param {String|Array<String>} passwords
|
* @param {String|Array<String>} passwords
|
||||||
* @param {Object} sessionKey
|
* @param {Object} sessionKey
|
||||||
* @param {Signature} signature
|
* @param {Signature} signature
|
||||||
* @param {Boolean} returnSessionKey
|
* @param {Boolean} returnSessionKey
|
||||||
|
* @param {String} filename
|
||||||
|
*
|
||||||
|
* Can be set, but will be ignored:
|
||||||
*
|
*
|
||||||
* @returns {Promise<Object>}
|
* @returns {Promise<Object>}
|
||||||
* {data: ASCII armored message,
|
* {data: ASCII armored message,
|
||||||
@ -80,57 +91,66 @@
|
|||||||
* @async
|
* @async
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
encrypt({data = '', publicKeys = '', privateKeys, passwords, sessionKey,
|
encrypt({data = '', publicKeys = '', privateKeys, passwords=null,
|
||||||
filename, compression, armor=true, detached=false, signature=null,
|
sessionKey = null, filename, compression, armor=true, detached=false,
|
||||||
returnSessionKey=null, wildcard=false, date=null}) {
|
signature=null, returnSessionKey=null, wildcard=false, date=null}) {
|
||||||
if (passwords !== undefined
|
if (passwords !== null
|
||||||
|| sessionKey !== undefined
|
|| sessionKey !== null
|
||||||
|| signature !== null
|
|| signature !== null
|
||||||
|| returnSessionKey !== null
|
|| returnSessionKey !== null
|
||||||
|| date !== null){
|
|| date !== null
|
||||||
|
){
|
||||||
return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
|
return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
|
||||||
}
|
}
|
||||||
if ( privateKeys
|
if ( privateKeys
|
||||||
|| filename
|
|
||||||
|| compression
|
|| compression
|
||||||
|| armor === false
|
|| armor === false
|
||||||
|| detached == true){
|
|| 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);
|
return this.GpgME.encrypt(data, translateKeyInput(publicKeys), wildcard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Decrypt Message
|
/** Decrypt Message
|
||||||
* supported
|
* supported openpgpjs parameters:
|
||||||
* TODO: @param {Message} message TODO: for now it accepts an armored string only
|
* @param {Message|Uint8Array|String} message Message object from openpgpjs
|
||||||
* Unsupported:
|
* Unsupported:
|
||||||
* @param {String|Array<String>} passwords
|
* @param {String|Array<String>} passwords
|
||||||
|
* @param {Key|Array<Key>} privateKeys
|
||||||
* @param {Object|Array<Object>} sessionKeys
|
* @param {Object|Array<Object>} sessionKeys
|
||||||
* @param {Date} date
|
* Not yet supported, but planned
|
||||||
|
|
||||||
* TODO
|
|
||||||
* @param {Key|Array<Key>} privateKey
|
|
||||||
* @param {Key|Array<Key>} publicKeys
|
|
||||||
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
|
* @param {String} format (optional) return data format either as 'utf8' or 'binary'
|
||||||
* @param {Signature} signature (optional) detached signature for verification
|
* @param {Signature} signature (optional) detached signature for verification
|
||||||
|
* Ignored values: can be safely set, but have no effect
|
||||||
|
* @param {Date} date
|
||||||
|
* @param {Key|Array<Key>} publicKeys
|
||||||
|
*
|
||||||
* @returns {Promise<Object>} decrypted and verified message in the form:
|
* @returns {Promise<Object>} decrypted and verified message in the form:
|
||||||
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
|
* { data:Uint8Array|String, filename:String, signatures:[{ keyid:String, valid:Boolean }] }
|
||||||
* @async
|
* @async
|
||||||
* @static
|
* @static
|
||||||
*/
|
*/
|
||||||
decrypt({ message, privateKeys, passwords, sessionKeys, publicKeys, format='utf8', signature=null, date}) {
|
decrypt({ message, privateKeys, passwords=null, sessionKeys,
|
||||||
if (passwords !== undefined
|
publicKeys, format='utf8', signature=null, date= null}) {
|
||||||
|| sessionKeys
|
if (passwords !== null || sessionKeys || privateKeys){
|
||||||
|| date){
|
return Promise.reject(gpgme_error('NOT_IMPLEMENTED'));
|
||||||
return Promise.reject(GPGMEJS_Error('NOT_IMPLEMENTED'));
|
|
||||||
}
|
}
|
||||||
if ( privateKeys
|
if ( format !== 'utf8' || signature){
|
||||||
|| publicKeys
|
return Promise.reject(gpgme_error('NOT_YET_IMPLEMENTED'));
|
||||||
|| format !== 'utf8'
|
}
|
||||||
|| signature
|
if (date !== null || publicKeys){
|
||||||
){
|
if (this._config.unconsidered_params === 'warn'){
|
||||||
return Promise.reject(GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
|
GPMGEJS_Error('PARAM_IGNORED');
|
||||||
|
} else if (this._config.unconsidered_params === 'reject'){
|
||||||
|
return Promise.reject(GPMGEJS_Error('NOT_IMPLEMENTED'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.GpgME.decrypt(message);
|
return this.GpgME.decrypt(message);
|
||||||
// TODO: translate between:
|
// TODO: translate between:
|
||||||
@ -185,7 +205,7 @@ class GPGME_Keyring_openpgpmode {
|
|||||||
else {
|
else {
|
||||||
// TODO: Can there be "no default key"?
|
// TODO: Can there be "no default key"?
|
||||||
// TODO: Can there be several default keys?
|
// 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){
|
deleteKey(key){
|
||||||
if (typeof(key) !== "object"){
|
if (typeof(key) !== "object"){
|
||||||
return Promise.reject(GPGMEJS_Error('PARAM_WRONG'));
|
return Promise.reject(gpgme_error('PARAM_WRONG'));
|
||||||
}
|
}
|
||||||
if ( !key.fingerprint || ! isFingerprint(key.fingerprint)){
|
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);
|
let key_to_delete = new GPGME_Key(key.fingerprint);
|
||||||
return key_to_delete.deleteKey(key.secret);
|
return key_to_delete.deleteKey(key.secret);
|
||||||
@ -224,8 +244,8 @@ class GPGME_Key_openpgpmode {
|
|||||||
set init (value){
|
set init (value){
|
||||||
if (!this._GPGME_Key && value instanceof GPGME_Key){
|
if (!this._GPGME_Key && value instanceof GPGME_Key){
|
||||||
this._GPGME_Key = value;
|
this._GPGME_Key = value;
|
||||||
} else if (!this._GPGME_Key && isFingerprint(fpr)){
|
} else if (!this._GPGME_Key && isFingerprint(value)){
|
||||||
this._GPGME_Key = new GPGME_Key;
|
this._GPGME_Key = new GPGME_Key(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { GpgME } from "./gpgmejs";
|
import { GpgME } from "./gpgmejs";
|
||||||
import { GPGMEJS_Error } from "./Errors";
|
import { gpgme_error } from "./Errors";
|
||||||
import { GpgME_openpgpmode } from "./gpgmejs_openpgpjs";
|
import { GpgME_openpgpmode } from "./gpgmejs_openpgpjs";
|
||||||
import { Connection } from "./Connection";
|
import { Connection } from "./Connection";
|
||||||
|
|
||||||
@ -29,7 +29,8 @@ import { Connection } from "./Connection";
|
|||||||
*/
|
*/
|
||||||
function init( config = {
|
function init( config = {
|
||||||
api_style: 'gpgme', // | gpgme_openpgpjs
|
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){
|
return new Promise(function(resolve, reject){
|
||||||
let connection = new Connection;
|
let connection = new Connection;
|
||||||
@ -41,12 +42,12 @@ function init( config = {
|
|||||||
let gpgme = null;
|
let gpgme = null;
|
||||||
if (config.api_style && config.api_style === 'gpgme_openpgpjs'){
|
if (config.api_style && config.api_style === 'gpgme_openpgpjs'){
|
||||||
resolve(
|
resolve(
|
||||||
new GpgME_openpgpmode(connection));
|
new GpgME_openpgpmode(connection, config));
|
||||||
} else {
|
} else {
|
||||||
resolve(new GpgME(connection));
|
resolve(new GpgME(connection));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reject(GPGMEJS_Error('CONN_NO_CONNECT'));
|
reject(gpgme_error('CONN_NO_CONNECT'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
setTimeout(delayedreaction, 5);
|
setTimeout(delayedreaction, 5);
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
partial and in need of concatenation
|
partial and in need of concatenation
|
||||||
params: Array<String> Information that do not change throughout
|
params: Array<String> Information that do not change throughout
|
||||||
the message
|
the message
|
||||||
infos: Array<String> arbitrary information that may change
|
infos: Array<*> arbitrary information that may result in a list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
@ -72,7 +72,55 @@ export const permittedOperations = {
|
|||||||
type: ['plaintext'],
|
type: ['plaintext'],
|
||||||
data: ['data'],
|
data: ['data'],
|
||||||
params: ['base64', 'mime'],
|
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?
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user