aboutsummaryrefslogtreecommitdiffstats
path: root/lang/js/src/Key.js
diff options
context:
space:
mode:
Diffstat (limited to 'lang/js/src/Key.js')
-rw-r--r--lang/js/src/Key.js287
1 files changed, 135 insertions, 152 deletions
diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js
index b024a77b..a7f7dd26 100644
--- a/lang/js/src/Key.js
+++ b/lang/js/src/Key.js
@@ -28,13 +28,16 @@ import { createMessage } from './Message';
/**
* Validates the given fingerprint and creates a new {@link GPGME_Key}
* @param {String} fingerprint
+ * @param {Boolean} async If True, Key properties (except fingerprint) will be
+ * queried from gnupg on each call, making the operation up-to-date, the
+ * answers will be Promises, and the performance will likely suffer
* @returns {GPGME_Key|GPGME_Error}
*/
-export function createKey(fingerprint){
- if (!isFingerprint(fingerprint)){
+export function createKey(fingerprint, async = false){
+ if (!isFingerprint(fingerprint) || typeof(async) !== 'boolean'){
return gpgme_error('PARAM_WRONG');
}
- else return new GPGME_Key(fingerprint);
+ else return new GPGME_Key(fingerprint, async);
}
/**
@@ -48,31 +51,30 @@ export function createKey(fingerprint){
*/
export class GPGME_Key {
- constructor(fingerprint){
- this.fingerprint = fingerprint;
- }
+ constructor(fingerprint, async){
- set fingerprint(fpr){
- if (isFingerprint(fpr) === true) {
- if (this._data === undefined) {
- this._data = {fingerprint: fpr};
- } else {
- if (this._data.fingerprint === undefined){
- this._data.fingerprint = fpr;
- }
+ /**
+ * @property {Boolean} If true, most answers will be asynchronous
+ */
+ this.isAsync = async;
+
+ let _data = {fingerprint: fingerprint};
+ this.getFingerprint = function(){
+ if (!_data.fingerprint || !isFingerprint(_data.fingerprint)){
+ return gpgme_error('KEY_INVALID');
}
- }
- }
+ return _data.fingerprint;
+ };
/**
- * @returns {String} The fingerprint defining this Key
+ * Property indicating if the Key possesses a private/secret part. If this
+ * information is not yet cached, it returns an {@link GPGME_Error} with
+ * code 'KEY_NO_INIT'. Running {@link refreshKey} may help in this case.
+ * @returns {Boolean} If the Key has a secret subkey.
*/
- get fingerprint(){
- if (!this._data || !this._data.fingerprint){
- return gpgme_error('KEY_INVALID');
- }
- return this._data.fingerprint;
- }
+ this.hasSecret= function (){
+ return this.get('hasSecret', true);
+ };
/**
* @param {Object} data Bulk set the data for this key, with an Object sent
@@ -81,97 +83,89 @@ export class GPGME_Key {
* error if something went wrong
* @private
*/
- setKeyData(data){
- if (this._data === undefined) {
- this._data = {};
+ this.setKeyData = function (data){
+ if (typeof(data) !== 'object') {
+ return gpgme_error('KEY_INVALID');
}
- if (
- typeof(data) !== 'object') {
+ if (!data.fingerprint || data.fingerprint !== _data.fingerprint){
return gpgme_error('KEY_INVALID');
}
- if (!this._data.fingerprint && isFingerprint(data.fingerprint)){
- if (data.fingerprint !== this.fingerprint){
- return gpgme_error('KEY_INVALID');
- }
- this._data.fingerprint = data.fingerprint;
- } else if (this._data.fingerprint !== data.fingerprint){
+ let keys = Object.keys(data);
+ for (let i=0; i< keys.length; i++){
+ if (!validKeyProperties.hasOwnProperty(keys[i])){
return gpgme_error('KEY_INVALID');
}
- let dataKeys = Object.keys(data);
- for (let i=0; i< dataKeys.length; i++){
- if (!validKeyProperties.hasOwnProperty(dataKeys[i])){
- return gpgme_error('KEY_INVALID');
- }
- if (validKeyProperties[dataKeys[i]](data[dataKeys[i]]) !== true ){
- return gpgme_error('KEY_INVALID');
- }
- switch (dataKeys[i]){
+ //running the defined validation function
+ if (validKeyProperties[keys[i]](data[keys[i]]) !== true ){
+ return gpgme_error('KEY_INVALID');
+ }
+ switch (keys[i]){
case 'subkeys':
- this._data.subkeys = [];
+ _data.subkeys = [];
for (let i=0; i< data.subkeys.length; i++) {
- this._data.subkeys.push(
+ _data.subkeys.push(
new GPGME_Subkey(data.subkeys[i]));
}
break;
case 'userids':
- this._data.userids = [];
+ _data.userids = [];
for (let i=0; i< data.userids.length; i++) {
- this._data.userids.push(
+ _data.userids.push(
new GPGME_UserId(data.userids[i]));
}
break;
case 'last_update':
- this._data[dataKeys[i]] = new Date( data[dataKeys[i]] * 1000 );
+ _data[keys[i]] = new Date( data[keys[i]] * 1000 );
break;
default:
- this._data[dataKeys[i]] = data[dataKeys[i]];
+ _data[keys[i]] = data[keys[i]];
}
}
return this;
- }
+ };
/**
* Query any property of the Key listed in {@link validKeyProperties}
* @param {String} property property to be retreived
- * @param {Boolean} cached (optional) if false, the data will be directly
- * queried from gnupg, and the operation will be asynchronous. Else, the
- * data will be fetched from the state of the initialization of the Key.
- * The cached mode may contain outdated information, but can be used as
- * synchronous operation, where the backend is not expected to change Keys
- * during a session. The key still can be reloaded by invoking
- * {@link refreshKey}.
* @returns {*|Promise<*>} the value (Boolean, String, Array, Object).
* If 'cached' is false, the value will be resolved as a Promise.
*/
- get(property, cached=true) {
- if (cached === false) {
+ this.get = function(property) {
+ if (this.isAsync === true) {
let me = this;
return new Promise(function(resolve, reject) {
- if (!validKeyProperties.hasOwnProperty(property)){
- reject('PARAM_WRONG');
- } else if (property === 'armored'){
+ if (property === 'armored'){
resolve(me.getArmor());
} else if (property === 'hasSecret'){
resolve(me.getHasSecret());
- } else {
- me.refreshKey().then(function(key){
- resolve(key.get(property, true));
+ } else if (validKeyProperties.hasOwnProperty(property)){
+ let msg = createMessage('keylist');
+ msg.setParameter('keys', _data.fingerprint);
+ msg.post().then(function(result){
+ if (result.keys && result.keys.length === 1 &&
+ result.keys[0].hasOwnProperty(property)){
+ resolve(result.keys[0][property]);
+ } else {
+ reject(gpgme_error('CONN_UNEXPECTED_ANSWER'));
+ }
}, function(error){
- reject(error);
+ reject(gpgme_error(error));
});
+ } else {
+ reject(gpgme_error('PARAM_WRONG'));
}
});
} else {
if (!validKeyProperties.hasOwnProperty(property)){
return gpgme_error('PARAM_WRONG');
}
- if (!this._data.hasOwnProperty(property)){
+ if (!_data.hasOwnProperty(property)){
return gpgme_error('KEY_NO_INIT');
} else {
- return (this._data[property]);
+ return (_data[property]);
}
}
- }
+ };
/**
* Reloads the Key information from gnupg. This is only useful if you use
@@ -181,15 +175,15 @@ export class GPGME_Key {
* @returns {Promise<GPGME_Key|GPGME_Error>}
* @async
*/
- refreshKey() {
+ this.refreshKey = function() {
let me = this;
return new Promise(function(resolve, reject) {
- if (!me._data.fingerprint){
+ if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
msg.setParameter('sigs', true);
- msg.setParameter('keys', me._data.fingerprint);
+ msg.setParameter('keys', _data.fingerprint);
msg.post().then(function(result){
if (result.keys.length === 1){
me.setKeyData(result.keys[0]);
@@ -209,7 +203,7 @@ export class GPGME_Key {
reject(gpgme_error('GNUPG_ERROR'), error);
});
});
- }
+ };
/**
* Query the armored block of the Key directly from gnupg. Please note that
@@ -217,23 +211,22 @@ export class GPGME_Key {
* @returns {Promise<String|GPGME_Error>}
* @async
*/
- getArmor(){
- let me = this;
+ this.getArmor = function(){
return new Promise(function(resolve, reject) {
- if (!me._data.fingerprint){
+ if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('export');
msg.setParameter('armor', true);
- msg.setParameter('keys', me._data.fingerprint);
+ msg.setParameter('keys', _data.fingerprint);
msg.post().then(function(result){
- me._data.armored = result.data;
+ _data.armored = result.data;
resolve(result.data);
}, function(error){
reject(error);
});
});
- }
+ };
/**
* Find out if the Key includes a secret part. Note that this is a rather
@@ -244,59 +237,32 @@ export class GPGME_Key {
* available in the gnupg Keyring
* @async
*/
- getHasSecret(){
- let me = this;
+ this.getHasSecret = function (){
return new Promise(function(resolve, reject) {
- if (!me._data.fingerprint){
+ if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('keylist');
- msg.setParameter('keys', me._data.fingerprint);
+ msg.setParameter('keys', _data.fingerprint);
msg.setParameter('secret', true);
msg.post().then(function(result){
- me._data.hasSecret = null;
+ _data.hasSecret = null;
if (
result.keys &&
result.keys.length === 1 &&
result.keys[0].secret === true
) {
- me._data.hasSecret = true;
+ _data.hasSecret = true;
resolve(true);
} else {
- me._data.hasSecret = false;
+ _data.hasSecret = false;
resolve(false);
}
}, function(error){
reject(error);
});
});
- }
-
- /**
- * Convenience functions to be directly used as properties of the Key
- * Notice that these rely on cached info and may be outdated. Use the async
- * get(property, false) if you need the most current info
- */
-
- /**
- * Property for the export of armored Key. If the armored Key is not
- * cached, it returns an {@link GPGME_Error} with code 'KEY_NO_INIT'.
- * Running {@link refreshKey} may help in this case.
- * @returns {String|GPGME_Error} The armored public Key block.
- */
- get armored(){
- return this.get('armored', true);
- }
-
- /**
- * Property indicating if the Key possesses a private/secret part. If this
- * information is not yet cached, it returns an {@link GPGME_Error} with
- * code 'KEY_NO_INIT'. Running {@link refreshKey} may help in this case.
- * @returns {Boolean} If the Key has a secret subkey.
- */
- get hasSecret(){
- return this.get('hasSecret', true);
- }
+ };
/**
* Deletes the (public) Key from the GPG Keyring. Note that a deletion of a
@@ -304,20 +270,37 @@ export class GPGME_Key {
* @returns {Promise<Boolean|GPGME_Error>} Success if key was deleted,
* rejects with a GPG error otherwise.
*/
- delete(){
- let me = this;
+ this.delete= function (){
return new Promise(function(resolve, reject){
- if (!me._data.fingerprint){
+ if (!_data.fingerprint){
reject(gpgme_error('KEY_INVALID'));
}
let msg = createMessage('delete');
- msg.setParameter('key', me._data.fingerprint);
+ msg.setParameter('key', _data.fingerprint);
msg.post().then(function(result){
resolve(result.success);
}, function(error){
reject(error);
});
});
+ };
+ }
+
+ /**
+ * @returns {String} The fingerprint defining this Key
+ */
+ get fingerprint(){
+ return this.getFingerprint();
+ }
+
+ /**
+ * Property for the export of armored Key. If the armored Key is not
+ * cached, it returns an {@link GPGME_Error} with code 'KEY_NO_INIT'.
+ * Running {@link refreshKey} may help in this case.
+ * @returns {String|GPGME_Error} The armored public Key block.
+ */
+ get armored(){
+ return this.get('armored', true);
}
}
@@ -334,44 +317,45 @@ class GPGME_Subkey {
* @private
*/
constructor(data){
+ let _data = {};
let keys = Object.keys(data);
- for (let i=0; i< keys.length; i++) {
- this.setProperty(keys[i], data[keys[i]]);
- }
- }
- /**
+ /**
* Validates a subkey property against {@link validSubKeyProperties} and
* sets it if validation is successful
* @param {String} property
* @param {*} value
* @param private
*/
- setProperty(property, value){
- if (!this._data){
- this._data = {};
- }
+ const setProperty = function (property, value){
if (validSubKeyProperties.hasOwnProperty(property)){
if (validSubKeyProperties[property](value) === true) {
if (property === 'timestamp' || property === 'expires'){
- this._data[property] = new Date(value * 1000);
+ _data[property] = new Date(value * 1000);
} else {
- this._data[property] = value;
+ _data[property] = value;
}
}
}
+ };
+ 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}
*/
- get(property) {
- if (this._data.hasOwnProperty(property)){
- return (this._data[property]);
+ this.get = function(property) {
+ if (_data.hasOwnProperty(property)){
+ return (_data[property]);
}
- }
+ };
+}
+
}
/**
@@ -387,11 +371,23 @@ class GPGME_UserId {
* @private
*/
constructor(data){
+ let _data = {};
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);
+ } else {
+ _data[property] = value;
+ }
+ }
+ }
+ };
for (let i=0; i< keys.length; i++) {
- this.setProperty(keys[i], data[keys[i]]);
+ setProperty(keys[i], data[keys[i]]);
}
- }
+
/**
* Validates a subkey property against {@link validUserIdProperties} and
* sets it if validation is successful
@@ -399,34 +395,21 @@ class GPGME_UserId {
* @param {*} value
* @param private
*/
- setProperty(property, value){
- if (!this._data){
- this._data = {};
- }
- if (validUserIdProperties.hasOwnProperty(property)){
- if (validUserIdProperties[property](value) === true) {
- if (property === 'last_update'){
- this._data[property] = new Date(value*1000);
- } else {
- this._data[property] = value;
- }
- }
- }
- }
/**
* 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]);
+ this.get = function (property) {
+ if (_data.hasOwnProperty(property)){
+ return (_data[property]);
}
- }
+ };
}
+}
/**
* Validation definition for userIds. Each valid userId property is represented
* as a key- Value pair, with their value being a validation function to check