@tdxvolt/volt-client-grpc 0.16.0-beta.1 → 0.16.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +75 -8
- package/package.json +1 -1
- package/src/volt-client-internal.js +58 -195
- package/src/volt-client.js +0 -1
- package/src/volt-credential.js +7 -3
package/lib/index.cjs
CHANGED
|
@@ -589,8 +589,12 @@ class VoltCredential {
|
|
|
589
589
|
return this._cryptoCache;
|
|
590
590
|
}
|
|
591
591
|
|
|
592
|
-
get
|
|
593
|
-
return this._cryptoCache.
|
|
592
|
+
get sessionId() {
|
|
593
|
+
return this._cryptoCache.session_id;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
get identityId() {
|
|
597
|
+
return this._cryptoCache.identity_id;
|
|
594
598
|
}
|
|
595
599
|
|
|
596
600
|
get voltPublicKey() {
|
|
@@ -678,7 +682,7 @@ class VoltCredential {
|
|
|
678
682
|
aud: audience,
|
|
679
683
|
iat: Math.floor(Date.now() / 1000) - ttl,
|
|
680
684
|
exp: Math.floor(Date.now() / 1000) + ttl,
|
|
681
|
-
sub: this._cryptoCache.
|
|
685
|
+
sub: this._cryptoCache.session_id
|
|
682
686
|
};
|
|
683
687
|
|
|
684
688
|
let sharedKey;
|
|
@@ -1735,7 +1739,8 @@ function issueAuthenticate(authenticateRequest, ttl) {
|
|
|
1735
1739
|
this._credential.cache.ca = authenticateResponse.chain;
|
|
1736
1740
|
|
|
1737
1741
|
// Identity resource id is assigned by the volt.
|
|
1738
|
-
this._credential.cache.
|
|
1742
|
+
this._credential.cache.session_id = authenticateResponse.session_id;
|
|
1743
|
+
|
|
1739
1744
|
this._credential.saveCache();
|
|
1740
1745
|
break;
|
|
1741
1746
|
}
|
|
@@ -1770,8 +1775,7 @@ function findDIDDocumentService(document, serviceType) {
|
|
|
1770
1775
|
return matches;
|
|
1771
1776
|
}
|
|
1772
1777
|
|
|
1773
|
-
|
|
1774
|
-
async function authenticateInternal() {
|
|
1778
|
+
async function authenticateInternal(createDID = true) {
|
|
1775
1779
|
try {
|
|
1776
1780
|
// Check if we need to resolve a Relay volt.
|
|
1777
1781
|
if (
|
|
@@ -1821,8 +1825,7 @@ async function authenticateInternal() {
|
|
|
1821
1825
|
// Form the request message.
|
|
1822
1826
|
const authenticateRequest = {
|
|
1823
1827
|
binding_name: this._config.client_name,
|
|
1824
|
-
|
|
1825
|
-
host: this._credential.cache.bindIp,
|
|
1828
|
+
host: this._credential.cache.bindIp
|
|
1826
1829
|
};
|
|
1827
1830
|
|
|
1828
1831
|
if (this._voltConfig.challenge_code) {
|
|
@@ -1836,6 +1839,70 @@ async function authenticateInternal() {
|
|
|
1836
1839
|
);
|
|
1837
1840
|
}
|
|
1838
1841
|
|
|
1842
|
+
if (!createDID) {
|
|
1843
|
+
authenticateRequest.public_key = publicKeyPem;
|
|
1844
|
+
} else {
|
|
1845
|
+
if (!this._credential.cache.identity_id) {
|
|
1846
|
+
// If we don't have an identity id, then we need to create a DID.
|
|
1847
|
+
this._credential.cache.identity_id = `did:volt:${uuid.v4()}`;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
const did = this._credential.cache.identity_id;
|
|
1851
|
+
|
|
1852
|
+
// Order of properties in the DID document is important,
|
|
1853
|
+
// they must be in alphabetical order throughout the document.
|
|
1854
|
+
// This is because the DID document is signed and the signature
|
|
1855
|
+
// is over the entire document.
|
|
1856
|
+
const didDocument = {
|
|
1857
|
+
"@context": "https://www.w3.org/ns/did/v1",
|
|
1858
|
+
authentication: [`${did}#key-1`],
|
|
1859
|
+
description: this._config.client_name,
|
|
1860
|
+
id: did,
|
|
1861
|
+
verificationMethod: [
|
|
1862
|
+
{
|
|
1863
|
+
controller: did,
|
|
1864
|
+
id: `${did}#key-1`,
|
|
1865
|
+
publicKeyPem: publicKeyPem,
|
|
1866
|
+
type: "RsaSignature2018"
|
|
1867
|
+
}
|
|
1868
|
+
]
|
|
1869
|
+
};
|
|
1870
|
+
|
|
1871
|
+
const signDocument = JSON.stringify(didDocument, null, 2);
|
|
1872
|
+
log$1("signing did document");
|
|
1873
|
+
log$1(signDocument);
|
|
1874
|
+
|
|
1875
|
+
// Sign the DID document.
|
|
1876
|
+
const documentDigest = signBase64(
|
|
1877
|
+
keyPair.privateKey,
|
|
1878
|
+
signDocument
|
|
1879
|
+
);
|
|
1880
|
+
|
|
1881
|
+
const proofSignature = jwsSignature(documentDigest);
|
|
1882
|
+
|
|
1883
|
+
// Create the DID document proof.
|
|
1884
|
+
didDocument.proof = {
|
|
1885
|
+
created: new Date().toISOString(),
|
|
1886
|
+
jws: proofSignature,
|
|
1887
|
+
proofPurpose: "assertionMethod",
|
|
1888
|
+
type: "RsaSignature2018",
|
|
1889
|
+
verificationMethod: `${did}#key-1`
|
|
1890
|
+
};
|
|
1891
|
+
|
|
1892
|
+
// Set the DID document with proof in the authenticate request.
|
|
1893
|
+
authenticateRequest.did_document = JSON.stringify(didDocument, null, 2);
|
|
1894
|
+
|
|
1895
|
+
// Now sign the entire DID document, including the proof and set it in the
|
|
1896
|
+
// bind request. This is required by the Volt to verify that we have the private key for the DID.
|
|
1897
|
+
authenticateRequest.did_document_signature = signBase64(
|
|
1898
|
+
keyPair.privateKey,
|
|
1899
|
+
authenticateRequest.did_document
|
|
1900
|
+
);
|
|
1901
|
+
|
|
1902
|
+
log$1("did document is %s", authenticateRequest.did_document);
|
|
1903
|
+
log$1("did signature is %s", authenticateRequest.did_document_signature);
|
|
1904
|
+
}
|
|
1905
|
+
|
|
1839
1906
|
log$1("authenticate TTL is ", this._config.bindRequestTTL);
|
|
1840
1907
|
|
|
1841
1908
|
// This will block while the request is pending.
|
package/package.json
CHANGED
|
@@ -55,7 +55,8 @@ function issueAuthenticate(authenticateRequest, ttl) {
|
|
|
55
55
|
this._credential.cache.ca = authenticateResponse.chain;
|
|
56
56
|
|
|
57
57
|
// Identity resource id is assigned by the volt.
|
|
58
|
-
this._credential.cache.
|
|
58
|
+
this._credential.cache.session_id = authenticateResponse.session_id;
|
|
59
|
+
|
|
59
60
|
this._credential.saveCache();
|
|
60
61
|
break;
|
|
61
62
|
}
|
|
@@ -81,52 +82,6 @@ function issueAuthenticate(authenticateRequest, ttl) {
|
|
|
81
82
|
});
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
function issueBind(bindRequest, ttl) {
|
|
85
|
-
// eslint-disable-next-line no-use-before-define
|
|
86
|
-
return unaryCallInternal
|
|
87
|
-
.call(this, "Bind", bindRequest)
|
|
88
|
-
.then((bindResponse) => {
|
|
89
|
-
log("got binding request response %j", bindResponse);
|
|
90
|
-
if (bindResponse.status?.code) {
|
|
91
|
-
log("error in bind response: %s", bindResponse.status.message);
|
|
92
|
-
return Promise.reject(new Error(bindResponse.status.message));
|
|
93
|
-
} else {
|
|
94
|
-
switch (bindResponse.decision) {
|
|
95
|
-
case "POLICY_DECISION_PERMIT": {
|
|
96
|
-
//
|
|
97
|
-
// The request status is permit => cache the bind response info.
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
// This is the certificate assigned to us by the volt.
|
|
101
|
-
this._credential.cache.cert = bindResponse.cert;
|
|
102
|
-
|
|
103
|
-
// This is the signing CA used by the volt.
|
|
104
|
-
this._credential.cache.ca = bindResponse.chain;
|
|
105
|
-
|
|
106
|
-
// Identity resource id is assigned by the volt.
|
|
107
|
-
this._credential.cache.client_id = bindResponse.identity_id;
|
|
108
|
-
this._credential.saveCache();
|
|
109
|
-
break;
|
|
110
|
-
}
|
|
111
|
-
case "POLICY_DECISION_DENY": {
|
|
112
|
-
log(">>>>>>>>>>>>>>> access request is DENIED <<<<<<<<<<<<<<<<<<<");
|
|
113
|
-
break;
|
|
114
|
-
}
|
|
115
|
-
case "POLICY_DECISION_PROMPT":
|
|
116
|
-
case "POLICY_DECISION_PENDING": {
|
|
117
|
-
log("access pending approval - waiting...");
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
default:
|
|
121
|
-
log("ignoring unknown bind descision %s", bindResponse.status);
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
return bindResponse.decision;
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
85
|
function findDIDDocumentService(document, serviceType) {
|
|
131
86
|
if (!document.service) {
|
|
132
87
|
return [];
|
|
@@ -136,8 +91,7 @@ function findDIDDocumentService(document, serviceType) {
|
|
|
136
91
|
return matches;
|
|
137
92
|
}
|
|
138
93
|
|
|
139
|
-
|
|
140
|
-
export async function authenticateInternal() {
|
|
94
|
+
export async function authenticateInternal(createDID = true) {
|
|
141
95
|
try {
|
|
142
96
|
// Check if we need to resolve a Relay volt.
|
|
143
97
|
if (
|
|
@@ -187,8 +141,7 @@ export async function authenticateInternal() {
|
|
|
187
141
|
// Form the request message.
|
|
188
142
|
const authenticateRequest = {
|
|
189
143
|
binding_name: this._config.client_name,
|
|
190
|
-
|
|
191
|
-
host: this._credential.cache.bindIp,
|
|
144
|
+
host: this._credential.cache.bindIp
|
|
192
145
|
};
|
|
193
146
|
|
|
194
147
|
if (this._voltConfig.challenge_code) {
|
|
@@ -202,161 +155,71 @@ export async function authenticateInternal() {
|
|
|
202
155
|
);
|
|
203
156
|
}
|
|
204
157
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (decision) {
|
|
212
|
-
// Wait a while before retrying.
|
|
213
|
-
// eslint-disable-next-line no-await-in-loop
|
|
214
|
-
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
158
|
+
if (!createDID) {
|
|
159
|
+
authenticateRequest.public_key = publicKeyPem;
|
|
160
|
+
} else {
|
|
161
|
+
if (!this._credential.cache.identity_id) {
|
|
162
|
+
// If we don't have an identity id, then we need to create a DID.
|
|
163
|
+
this._credential.cache.identity_id = `did:volt:${generateId()}`;
|
|
215
164
|
}
|
|
216
|
-
// eslint-disable-next-line no-await-in-loop
|
|
217
|
-
decision = await issueAuthenticate.call(
|
|
218
|
-
this,
|
|
219
|
-
authenticateRequest,
|
|
220
|
-
this._voltConfig.bindRequestTTL
|
|
221
|
-
);
|
|
222
|
-
log("authenticate decision: %s", decision);
|
|
223
|
-
} while (
|
|
224
|
-
decision === "POLICY_DECISION_PROMPT" ||
|
|
225
|
-
decision === "POLICY_DECISION_PENDING"
|
|
226
|
-
);
|
|
227
|
-
|
|
228
|
-
return decision === "POLICY_DECISION_PERMIT";
|
|
229
|
-
} catch (err) {
|
|
230
|
-
log("failure binding to Volt [%s]", err.message);
|
|
231
|
-
throw err;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
165
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
} else {
|
|
256
|
-
throw new Error("Unable to fetch Relay CA - cannot securely connect.");
|
|
257
|
-
}
|
|
258
|
-
}
|
|
166
|
+
const did = this._credential.cache.identity_id;
|
|
167
|
+
|
|
168
|
+
// Order of properties in the DID document is important,
|
|
169
|
+
// they must be in alphabetical order throughout the document.
|
|
170
|
+
// This is because the DID document is signed and the signature
|
|
171
|
+
// is over the entire document.
|
|
172
|
+
const didDocument = {
|
|
173
|
+
"@context": "https://www.w3.org/ns/did/v1",
|
|
174
|
+
authentication: [`${did}#key-1`],
|
|
175
|
+
description: this._config.client_name,
|
|
176
|
+
id: did,
|
|
177
|
+
verificationMethod: [
|
|
178
|
+
{
|
|
179
|
+
controller: did,
|
|
180
|
+
id: `${did}#key-1`,
|
|
181
|
+
publicKeyPem: publicKeyPem,
|
|
182
|
+
type: "RsaSignature2018"
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
};
|
|
259
186
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
187
|
+
const signDocument = JSON.stringify(didDocument, null, 2);
|
|
188
|
+
log("signing did document");
|
|
189
|
+
log(signDocument);
|
|
263
190
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
191
|
+
// Sign the DID document.
|
|
192
|
+
const documentDigest = voltUtils.signBase64(
|
|
193
|
+
keyPair.privateKey,
|
|
194
|
+
signDocument
|
|
267
195
|
);
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
const keyPair = this._credential.getKey();
|
|
271
|
-
const publicKeyPem = voltUtils.removeCarriageReturn(
|
|
272
|
-
pki.publicKeyToPem(keyPair.publicKey)
|
|
273
|
-
);
|
|
274
196
|
|
|
275
|
-
|
|
276
|
-
// Default the IP address if none is specified. This is used to set the SAN in the
|
|
277
|
-
// certificate issued by the Volt.
|
|
278
|
-
this._credential.cache.bindIp = ip.address();
|
|
279
|
-
}
|
|
197
|
+
const proofSignature = voltUtils.jwsSignature(documentDigest);
|
|
280
198
|
|
|
281
|
-
|
|
199
|
+
// Create the DID document proof.
|
|
200
|
+
didDocument.proof = {
|
|
201
|
+
created: new Date().toISOString(),
|
|
202
|
+
jws: proofSignature,
|
|
203
|
+
proofPurpose: "assertionMethod",
|
|
204
|
+
type: "RsaSignature2018",
|
|
205
|
+
verificationMethod: `${did}#key-1`
|
|
206
|
+
};
|
|
282
207
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
binding_name: this._config.client_name,
|
|
286
|
-
host: this._credential.cache.bindIp
|
|
287
|
-
};
|
|
208
|
+
// Set the DID document with proof in the authenticate request.
|
|
209
|
+
authenticateRequest.did_document = JSON.stringify(didDocument, null, 2);
|
|
288
210
|
|
|
289
|
-
|
|
290
|
-
|
|
211
|
+
// Now sign the entire DID document, including the proof and set it in the
|
|
212
|
+
// bind request. This is required by the Volt to verify that we have the private key for the DID.
|
|
213
|
+
authenticateRequest.did_document_signature = voltUtils.signBase64(
|
|
291
214
|
keyPair.privateKey,
|
|
292
|
-
|
|
293
|
-
);
|
|
294
|
-
} else {
|
|
295
|
-
log(
|
|
296
|
-
"****no Volt challenge code available**** => not sending challenge signature"
|
|
215
|
+
authenticateRequest.did_document
|
|
297
216
|
);
|
|
298
|
-
}
|
|
299
217
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
this._credential.cache.client_id = `did:volt:${generateId()}`;
|
|
218
|
+
log("did document is %s", authenticateRequest.did_document);
|
|
219
|
+
log("did signature is %s", authenticateRequest.did_document_signature);
|
|
303
220
|
}
|
|
304
221
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
// Order of properties in the DID document is important,
|
|
308
|
-
// they must be in alphabetical order throughout the document.
|
|
309
|
-
// This is because the DID document is signed and the signature
|
|
310
|
-
// is over the entire document.
|
|
311
|
-
const didDocument = {
|
|
312
|
-
"@context": "https://www.w3.org/ns/did/v1",
|
|
313
|
-
authentication: [`${did}#key-1`],
|
|
314
|
-
description: this._config.client_name,
|
|
315
|
-
id: did,
|
|
316
|
-
verificationMethod: [
|
|
317
|
-
{
|
|
318
|
-
controller: did,
|
|
319
|
-
id: `${did}#key-1`,
|
|
320
|
-
publicKeyPem: publicKeyPem,
|
|
321
|
-
type: "RsaSignature2018"
|
|
322
|
-
}
|
|
323
|
-
]
|
|
324
|
-
};
|
|
325
|
-
|
|
326
|
-
const signDocument = JSON.stringify(didDocument, null, 2);
|
|
327
|
-
log("signing did document");
|
|
328
|
-
log(signDocument);
|
|
329
|
-
|
|
330
|
-
// Sign the DID document.
|
|
331
|
-
const documentDigest = voltUtils.signBase64(
|
|
332
|
-
keyPair.privateKey,
|
|
333
|
-
signDocument
|
|
334
|
-
);
|
|
335
|
-
|
|
336
|
-
const proofSignature = voltUtils.jwsSignature(documentDigest);
|
|
337
|
-
|
|
338
|
-
// Create the DID document proof.
|
|
339
|
-
didDocument.proof = {
|
|
340
|
-
created: new Date().toISOString(),
|
|
341
|
-
jws: proofSignature,
|
|
342
|
-
proofPurpose: "assertionMethod",
|
|
343
|
-
type: "RsaSignature2018",
|
|
344
|
-
verificationMethod: `${did}#key-1`
|
|
345
|
-
};
|
|
346
|
-
|
|
347
|
-
// Set the DID document with proof in the bind request.
|
|
348
|
-
bindRequest.did_document = JSON.stringify(didDocument, null, 2);
|
|
349
|
-
|
|
350
|
-
// Now sign the entire DID document, including the proof and set it in the
|
|
351
|
-
// bind request. This is required by the Volt to verify that we have the private key for the DID.
|
|
352
|
-
bindRequest.did_document_signature = voltUtils.signBase64(
|
|
353
|
-
keyPair.privateKey,
|
|
354
|
-
bindRequest.did_document
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
log("did document is %s", bindRequest.did_document);
|
|
358
|
-
log("did signature is %s", bindRequest.did_document_signature);
|
|
359
|
-
log("bind TTL is ", this._config.bindRequestTTL);
|
|
222
|
+
log("authenticate TTL is ", this._config.bindRequestTTL);
|
|
360
223
|
|
|
361
224
|
// This will block while the request is pending.
|
|
362
225
|
const pollInterval = 10000;
|
|
@@ -368,12 +231,12 @@ export async function bindInternal() {
|
|
|
368
231
|
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
369
232
|
}
|
|
370
233
|
// eslint-disable-next-line no-await-in-loop
|
|
371
|
-
decision = await
|
|
234
|
+
decision = await issueAuthenticate.call(
|
|
372
235
|
this,
|
|
373
|
-
|
|
236
|
+
authenticateRequest,
|
|
374
237
|
this._voltConfig.bindRequestTTL
|
|
375
238
|
);
|
|
376
|
-
log("
|
|
239
|
+
log("authenticate decision: %s", decision);
|
|
377
240
|
} while (
|
|
378
241
|
decision === "POLICY_DECISION_PROMPT" ||
|
|
379
242
|
decision === "POLICY_DECISION_PENDING"
|
package/src/volt-client.js
CHANGED
package/src/volt-credential.js
CHANGED
|
@@ -69,8 +69,12 @@ export class VoltCredential {
|
|
|
69
69
|
return this._cryptoCache;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
get
|
|
73
|
-
return this._cryptoCache.
|
|
72
|
+
get sessionId() {
|
|
73
|
+
return this._cryptoCache.session_id;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
get identityId() {
|
|
77
|
+
return this._cryptoCache.identity_id;
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
get voltPublicKey() {
|
|
@@ -159,7 +163,7 @@ export class VoltCredential {
|
|
|
159
163
|
aud: audience,
|
|
160
164
|
iat: Math.floor(Date.now() / 1000) - ttl,
|
|
161
165
|
exp: Math.floor(Date.now() / 1000) + ttl,
|
|
162
|
-
sub: this._cryptoCache.
|
|
166
|
+
sub: this._cryptoCache.session_id
|
|
163
167
|
};
|
|
164
168
|
|
|
165
169
|
let sharedKey;
|