diff options
Diffstat (limited to '')
-rw-r--r-- | lang/js/src/Key.js | 386 |
1 files changed, 194 insertions, 192 deletions
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index ea6fd883..37ec7f9d 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -40,12 +40,12 @@ export function createKey(fingerprint, async = false, data){ return gpgme_error('PARAM_WRONG'); } if (data !== undefined){ - data = validateKeyData(data); + data = validateKeyData(fingerprint, data); } if (data instanceof Error){ return gpgme_error('KEY_INVALID'); } else { - return Object.freeze(new GPGME_Key(fingerprint, async, data)); + return new GPGME_Key(fingerprint, async, data); } } @@ -65,184 +65,181 @@ class GPGME_Key { /** * @property {Boolean} If true, most answers will be asynchronous */ - this.isAsync = async; + this._async = async; - let _data = {fingerprint: fingerprint.toUpperCase()}; + this._data = {fingerprint: fingerprint.toUpperCase()}; if (data !== undefined - && data.fingerprint.toUpperCase() === _data.fingerprint + && data.fingerprint.toUpperCase() === this._data.fingerprint ) { - _data = data; + this._data = data; } - this.getFingerprint = function(){ - if (!_data.fingerprint || !isFingerprint(_data.fingerprint)){ - return gpgme_error('KEY_INVALID'); - } - return _data.fingerprint; - }; + } - /** - * Query any property of the Key listed in {@link validKeyProperties} - * @param {String} property property to be retreived - * @returns {Boolean| String | Date | Array | Object |GPGME_Error} - * the value of the property. If the Key is set to Async, the value - * will be fetched from gnupg and resolved as a Promise. If Key is not - * async, the armored property is not available (it can still be - * retrieved asynchronously by {@link Key.getArmor}) - */ - this.get = function(property) { - if (this.isAsync === true) { - switch (property){ - case 'armored': - return this.getArmor(); - case 'hasSecret': - return this.getGnupgSecretState(); - default: - return getGnupgState(property); - } + /** + * Query any property of the Key listed in {@link validKeyProperties} + * @param {String} property property to be retreived + * @returns {Boolean| String | Date | Array | Object |GPGME_Error} + * the value of the property. If the Key is set to Async, the value + * will be fetched from gnupg and resolved as a Promise. If Key is not + * async, the armored property is not available (it can still be + * retrieved asynchronously by {@link Key.getArmor}) + */ + get(property) { + if (this._async === true) { + switch (property){ + case 'armored': + return this.getArmor(); + case 'hasSecret': + return this.getGnupgSecretState(); + default: + return getGnupgState(this.fingerprint, property); + } + } else { + if (property === 'armored') { + return gpgme_error('KEY_ASYNC_ONLY'); + } + if (!validKeyProperties.hasOwnProperty(property)){ + return gpgme_error('PARAM_WRONG'); } else { - if (property === 'armored') { - return gpgme_error('KEY_ASYNC_ONLY'); - } - if (!validKeyProperties.hasOwnProperty(property)){ - return gpgme_error('PARAM_WRONG'); - } else { - return (_data[property]); - } + return (this._data[property]); } - }; + } + } - /** - * Reloads the Key information from gnupg. This is only useful if you - * use the GPGME_Keys cached. Note that this is a performance hungry - * operation. If you desire more than a few refreshs, it may be - * advisable to run {@link Keyring.getKeys} instead. - * @returns {Promise<GPGME_Key|GPGME_Error>} - * @async - */ - this.refreshKey = function() { - let me = this; - return new Promise(function(resolve, reject) { - if (!_data.fingerprint){ - reject(gpgme_error('KEY_INVALID')); - } - let msg = createMessage('keylist'); - msg.setParameter('sigs', true); - msg.setParameter('keys', _data.fingerprint); - msg.post().then(function(result){ - if (result.keys.length === 1){ - const newdata = validateKeyData( - _data.fingerprint, result.keys[0]); - if (newdata instanceof Error){ - reject(gpgme_error('KEY_INVALID')); - } else { - _data = newdata; - me.getGnupgSecretState().then(function(){ - me.getArmor().then(function(){ - resolve(me); - }, function(error){ - reject(error); - }); + /** + * Reloads the Key information from gnupg. This is only useful if you + * use the GPGME_Keys cached. Note that this is a performance hungry + * operation. If you desire more than a few refreshs, it may be + * advisable to run {@link Keyring.getKeys} instead. + * @returns {Promise<GPGME_Key|GPGME_Error>} + * @async + */ + refreshKey() { + let me = this; + return new Promise(function(resolve, reject) { + if (!me._data.fingerprint){ + reject(gpgme_error('KEY_INVALID')); + } + let msg = createMessage('keylist'); + msg.setParameter('sigs', true); + msg.setParameter('keys', me._data.fingerprint); + msg.post().then(function(result){ + if (result.keys.length === 1){ + const newdata = validateKeyData( + me._data.fingerprint, result.keys[0]); + if (newdata instanceof Error){ + reject(gpgme_error('KEY_INVALID')); + } else { + me._data = newdata; + me.getGnupgSecretState().then(function(){ + me.getArmor().then(function(){ + resolve(me); }, function(error){ reject(error); }); - } - } else { - reject(gpgme_error('KEY_NOKEY')); + }, function(error){ + reject(error); + }); } - }, function (error) { - reject(gpgme_error('GNUPG_ERROR'), error); - }); - }); - }; - - /** - * Query the armored block of the Key directly from gnupg. Please note - * that this will not get you any export of the secret/private parts of - * a Key - * @returns {Promise<String|GPGME_Error>} - * @async - */ - this.getArmor = function(){ - return new Promise(function(resolve, reject) { - if (!_data.fingerprint){ - reject(gpgme_error('KEY_INVALID')); + } else { + reject(gpgme_error('KEY_NOKEY')); } - let msg = createMessage('export'); - msg.setParameter('armor', true); - msg.setParameter('keys', _data.fingerprint); - msg.post().then(function(result){ - resolve(result.data); - }, function(error){ - reject(error); - }); + }, function (error) { + reject(gpgme_error('GNUPG_ERROR'), error); }); - }; + }); + } - /** - * Find out if the Key is part of a Key pair including public and - * private key(s). If you want this information about more than a few - * Keys in synchronous mode, it may be advisable to run - * {@link Keyring.getKeys} instead, as it performs faster in bulk - * querying this state. - * @returns {Promise<Boolean|GPGME_Error>} True if a private Key is - * available in the gnupg Keyring. - * @async - */ - this.getGnupgSecretState = function (){ - return new Promise(function(resolve, reject) { - if (!_data.fingerprint){ - reject(gpgme_error('KEY_INVALID')); - } else { - let msg = createMessage('keylist'); - msg.setParameter('keys', _data.fingerprint); - msg.setParameter('secret', true); - msg.post().then(function(result){ - _data.hasSecret = null; - if ( - result.keys && - result.keys.length === 1 && - result.keys[0].secret === true - ) { - _data.hasSecret = true; - resolve(true); - } else { - _data.hasSecret = false; - resolve(false); - } - }, function(error){ - reject(error); - }); - } + /** + * Query the armored block of the Key directly from gnupg. Please note + * that this will not get you any export of the secret/private parts of + * a Key + * @returns {Promise<String|GPGME_Error>} + * @async + */ + getArmor() { + const me = this; + return new Promise(function(resolve, reject) { + if (!me._data.fingerprint){ + reject(gpgme_error('KEY_INVALID')); + } + let msg = createMessage('export'); + msg.setParameter('armor', true); + msg.setParameter('keys', me._data.fingerprint); + msg.post().then(function(result){ + resolve(result.data); + }, function(error){ + reject(error); }); - }; + }); + } - /** - * Deletes the (public) Key from the GPG Keyring. Note that a deletion - * of a secret key is not supported by the native backend. - * @returns {Promise<Boolean|GPGME_Error>} Success if key was deleted, - * rejects with a GPG error otherwise. - */ - this.delete= function (){ - return new Promise(function(resolve, reject){ - if (!_data.fingerprint){ - reject(gpgme_error('KEY_INVALID')); - } - let msg = createMessage('delete'); - msg.setParameter('key', _data.fingerprint); + /** + * Find out if the Key is part of a Key pair including public and + * private key(s). If you want this information about more than a few + * Keys in synchronous mode, it may be advisable to run + * {@link Keyring.getKeys} instead, as it performs faster in bulk + * querying this state. + * @returns {Promise<Boolean|GPGME_Error>} True if a private Key is + * available in the gnupg Keyring. + * @async + */ + getGnupgSecretState (){ + const me = this; + return new Promise(function(resolve, reject) { + if (!me._data.fingerprint){ + reject(gpgme_error('KEY_INVALID')); + } else { + let msg = createMessage('keylist'); + msg.setParameter('keys', me._data.fingerprint); + msg.setParameter('secret', true); msg.post().then(function(result){ - resolve(result.success); + me._data.hasSecret = null; + if ( + result.keys && + result.keys.length === 1 && + result.keys[0].secret === true + ) { + me._data.hasSecret = true; + resolve(true); + } else { + me._data.hasSecret = false; + resolve(false); + } }, function(error){ reject(error); }); + } + }); + } + + /** + * Deletes the (public) Key from the GPG Keyring. Note that a deletion + * of a secret key is not supported by the native backend. + * @returns {Promise<Boolean|GPGME_Error>} Success if key was deleted, + * rejects with a GPG error otherwise. + */ + delete(){ + const me = this; + return new Promise(function(resolve, reject){ + if (!me._data.fingerprint){ + reject(gpgme_error('KEY_INVALID')); + } + let msg = createMessage('delete'); + msg.setParameter('key', me._data.fingerprint); + msg.post().then(function(result){ + resolve(result.success); + }, function(error){ + reject(error); }); - }; + }); } /** * @returns {String} The fingerprint defining this Key. Convenience getter */ get fingerprint(){ - return this.getFingerprint(); + return this._data.fingerprint; } } @@ -259,8 +256,9 @@ class GPGME_Subkey { * @private */ constructor(data){ - let _data = {}; + this._data = {}; let keys = Object.keys(data); + const me = this; /** * Validates a subkey property against {@link validSubKeyProperties} and @@ -273,9 +271,9 @@ class GPGME_Subkey { if (validSubKeyProperties.hasOwnProperty(property)){ if (validSubKeyProperties[property](value) === true) { if (property === 'timestamp' || property === 'expires'){ - _data[property] = new Date(value * 1000); + me._data[property] = new Date(value * 1000); } else { - _data[property] = value; + me._data[property] = value; } } } @@ -283,18 +281,19 @@ class GPGME_Subkey { for (let i=0; i< keys.length; i++) { setProperty(keys[i], data[keys[i]]); } + } - /** - * Fetches any information about this subkey - * @param {String} property Information to request - * @returns {String | Number | Date} - */ - this.get = function(property) { - if (_data.hasOwnProperty(property)){ - return (_data[property]); - } - }; + /** + * Fetches any information about this subkey + * @param {String} property Information to request + * @returns {String | Number | Date} + */ + get(property) { + if (this._data.hasOwnProperty(property)){ + return (this._data[property]); + } } + } /** @@ -310,15 +309,16 @@ class GPGME_UserId { * @private */ constructor(data){ - let _data = {}; + this._data = {}; + const me = this; let keys = Object.keys(data); const setProperty = function(property, value){ if (validUserIdProperties.hasOwnProperty(property)){ if (validUserIdProperties[property](value) === true) { if (property === 'last_update'){ - _data[property] = new Date(value*1000); + me._data[property] = new Date(value*1000); } else { - _data[property] = value; + me._data[property] = value; } } } @@ -326,18 +326,19 @@ class GPGME_UserId { for (let i=0; i< keys.length; i++) { setProperty(keys[i], data[keys[i]]); } + } - /** - * Fetches information about the user - * @param {String} property Information to request - * @returns {String | Number} - */ - this.get = function (property) { - if (_data.hasOwnProperty(property)){ - return (_data[property]); - } - }; + /** + * Fetches information about the user + * @param {String} property Information to request + * @returns {String | Number} + */ + get(property) { + if (this._data.hasOwnProperty(property)){ + return (this._data[property]); + } } + } /** @@ -569,10 +570,11 @@ const validKeyProperties = { * an error if something went wrong. * @private */ -function validateKeyData(data){ +function validateKeyData(fingerprint, data){ const key = {}; - if ( typeof(data) !== 'object' - || !data.fingerprint){ + if (!fingerprint || typeof(data) !== 'object' || !data.fingerprint + || fingerprint !== data.fingerprint.toUpperCase() + ){ return gpgme_error('KEY_INVALID'); } let props = Object.keys(data); @@ -588,15 +590,15 @@ function validateKeyData(data){ case 'subkeys': key.subkeys = []; for (let i=0; i< data.subkeys.length; i++) { - key.subkeys.push(Object.freeze( - new GPGME_Subkey(data.subkeys[i]))); + key.subkeys.push( + new GPGME_Subkey(data.subkeys[i])); } break; case 'userids': key.userids = []; for (let i=0; i< data.userids.length; i++) { - key.userids.push(Object.freeze( - new GPGME_UserId(data.userids[i]))); + key.userids.push( + new GPGME_UserId(data.userids[i])); } break; case 'last_update': @@ -623,19 +625,19 @@ function getGnupgState (fingerprint, property){ } else { let msg = createMessage('keylist'); msg.setParameter('keys', fingerprint); - msg.post().then(function(result){ - if (!result.keys || result.keys.length !== 1){ + msg.post().then(function(res){ + if (!res.keys || res.keys.length !== 1){ reject(gpgme_error('KEY_INVALID')); } else { - const key = result.keys[0]; + const key = res.keys[0]; let result; switch (property){ case 'subkeys': result = []; if (key.subkeys.length){ for (let i=0; i < key.subkeys.length; i++) { - result.push(Object.freeze( - new GPGME_Subkey(key.subkeys[i]))); + result.push( + new GPGME_Subkey(key.subkeys[i])); } } resolve(result); @@ -644,8 +646,8 @@ function getGnupgState (fingerprint, property){ result = []; if (key.userids.length){ for (let i=0; i< key.userids.length; i++) { - result.push(Object.freeze( - new GPGME_UserId(key.userids[i]))); + result.push( + new GPGME_UserId(key.userids[i])); } } resolve(result); |