js: Key handling stubs, Error handling, refactoring
[gpgme.git] / lang / js / src / Key.js
1 /* gpgme.js - Javascript integration for gpgme
2  * Copyright (C) 2018 Bundesamt für Sicherheit in der Informationstechnik
3  *
4  * This file is part of GPGME.
5  *
6  * GPGME is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * GPGME is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  * SPDX-License-Identifier: LGPL-2.1+
19  */
20
21 /**
22  * The key class allows to query the information defined in gpgme Key Objects
23  * (see https://www.gnupg.org/documentation/manuals/gpgme/Key-objects.html)
24  *
25  * This is a stub, as the gpgme-json side is not yet implemented
26  *
27  */
28
29 import {isFingerprint} from './Helpers'
30 import {GPGMEJS_Error} from './Errors'
31
32 export class GPGME_Key {
33
34     constructor(fingerprint){
35         if (isFingerprint(fingerprint) === true){
36             this._fingerprint = fingerprint;
37         } else {
38             return new GPGMEJS_Error('WRONGPARAM', 'Key.js: invalid fingerprint');
39         }
40     }
41
42     get fingerprint(){
43         return this._fingerprint;
44     }
45
46     /**
47      * hasSecret returns true if a secret subkey is included in this Key
48      */
49     get hasSecret(){
50         checkKey(this._fingerprint, 'secret').then( function(result){
51             return Promise.resolve(result);
52         });
53
54     }
55
56     get isRevoked(){
57         return checkKey(this._fingerprint, 'revoked');
58     }
59
60     get isExpired(){
61         return checkKey(this._fingerprint, 'expired');
62     }
63
64     get isDisabled(){
65         return checkKey(this._fingerprint, 'disabled');
66     }
67
68     get isInvalid(){
69         return checkKey(this._fingerprint, 'invalid');
70     }
71
72     get canEncrypt(){
73         return checkKey(this._fingerprint, 'can_encrypt');
74     }
75
76     get canSign(){
77         return checkKey(this._fingerprint, 'can_sign');
78     }
79
80     get canCertify(){
81         return checkKey(this._fingerprint, 'can_certify');
82     }
83
84     get canAuthenticate(){
85         return checkKey(this._fingerprint, 'can_authenticate');
86     }
87
88     get isQualified(){
89         return checkKey(this._fingerprint, 'is_qualified');
90     }
91
92     get armored(){
93         let me = this;
94         return new Promise(function(resolve, reject){
95             let conn = new Connection();
96             conn.setFlag('armor', true);
97             conn.post('export',{'fpr': me._fingerprint});
98         });
99         // TODO return value not yet checked. Should result in an armored block
100         // in correct encoding
101         // TODO openpgpjs also returns secKey if private = true?
102     }
103
104     /**
105      * TODO returns true if this is the default key used to sign
106      */
107     get isDefault(){
108         throw('NOT_YET_IMPLEMENTED');
109     }
110
111     /**
112      * get the Key's subkeys as GPGME_Key objects
113      * @returns {Array<GPGME_Key>}
114      */
115     get subkeys(){
116         return checkKey(this._fingerprint, 'subkeys').then(function(result){
117             // TBD expecting a list of fingerprints
118             if (!Array.isArray(result)){
119                 result = [result];
120             }
121             let resultset = [];
122             for (let i=0; i < result.length; i++){
123                 let subkey = new GPGME_Key(result[i]);
124                 if (subkey instanceof GPGME_Key){
125                     resultset.push(subkey);
126                 }
127             }
128             return Promise.resolve(resultset);
129         });
130     }
131
132     /**
133      * creation time stamp of the key
134      * @returns {Date|null} TBD
135      */
136     get timestamp(){
137         return checkKey(this._fingerprint, 'timestamp');
138         //TODO GPGME: -1 if the timestamp is invalid, and 0 if it is not available.
139     }
140
141     /**
142      * The expiration timestamp of this key TBD
143      *  @returns {Date|null} TBD
144      */
145     get expires(){
146         return checkKey(this._fingerprint, 'expires');
147         // TODO convert to Date; check for 0
148     }
149
150     /**
151      * getter name TBD
152      * @returns {String|Array<String>} The user ids associated with this key
153      */
154     get userIds(){
155         return checkKey(this._fingerprint, 'uids');
156     }
157
158     /**
159      * @returns {String} The public key algorithm supported by this subkey
160      */
161     get pubkey_algo(){
162         return checkKey(this._fingerprint, 'pubkey_algo');
163     }
164 };
165
166 /**
167  * generic function to query gnupg information on a key.
168  * @param {*} fingerprint The identifier of the Keyring
169  * @param {*} property The gpgme-json property to check
170  *
171  */
172 function checkKey(fingerprint, property){
173     return Promise.reject(new GPGMEJS_Error('NOT_YET_IMPLEMENTED'));
174
175     return new Promise(function(resolve, reject){
176         if (!isFingerprint(fingerprint)){
177             reject('not a fingerprint'); //TBD
178         }
179         let conn = new Connection();
180         conn.post('getkey',{ // TODO not yet implemented in gpgme
181             'fingerprint': this.fingerprint})
182         .then(function(result){
183             if (property !== undefined){
184                 if (result.hasOwnProperty(key)){
185                     resolve(result[property]);
186                 }
187                 else if (property == 'secret'){
188                     // property undefined means "not true" in case of secret
189                     resolve(false);
190                 } else {
191                     reject('ERR_INVALID_PROPERTY') //TBD
192                 }
193             }
194
195
196             resolve(result);
197         }, function(error){
198             reject(error);
199         });
200     });
201 };