@digitalbazaar/vc 3.0.0 → 4.0.0

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.
Files changed (2) hide show
  1. package/lib/index.js +52 -15
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -107,6 +107,8 @@ export const dateRegex = new RegExp('^(\\d{4})-(0[1-9]|1[0-2])-' +
107
107
  * Other optional params passed to `sign()`:
108
108
  * @param {object} [options.documentLoader] - A document loader.
109
109
  * @param {object} [options.expansionMap] - An expansion map.
110
+ * @param {string|Date} [options.now] - A string representing date time in
111
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
110
112
  *
111
113
  * @throws {Error} If missing required properties.
112
114
  *
@@ -115,7 +117,8 @@ export const dateRegex = new RegExp('^(\\d{4})-(0[1-9]|1[0-2])-' +
115
117
  export async function issue({
116
118
  credential, suite, expansionMap,
117
119
  purpose = new CredentialIssuancePurpose(),
118
- documentLoader = defaultDocumentLoader
120
+ documentLoader = defaultDocumentLoader,
121
+ now
119
122
  } = {}) {
120
123
  // check to make sure the `suite` has required params
121
124
  // Note: verificationMethod defaults to publicKey.id, in suite constructor
@@ -137,7 +140,7 @@ export async function issue({
137
140
  }
138
141
 
139
142
  // run common credential checks
140
- _checkCredential(credential);
143
+ _checkCredential({credential, now});
141
144
 
142
145
  return jsigs.sign(credential, {purpose, documentLoader, suite, expansionMap});
143
146
  }
@@ -179,6 +182,8 @@ export async function issue({
179
182
  * @param {Function} [options.documentLoader] - A document loader.
180
183
  * @param {Function} [options.checkStatus] - Optional function for checking
181
184
  * credential status if `credentialStatus` is present on the credential.
185
+ * @param {string|Date} [options.now] - A string representing date time in
186
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
182
187
  *
183
188
  * @returns {Promise<VerifyPresentationResult>} The verification result.
184
189
  */
@@ -222,6 +227,8 @@ export async function verify(options = {}) {
222
227
  * @param {Function} [options.documentLoader] - A document loader.
223
228
  * @param {Function} [options.checkStatus] - Optional function for checking
224
229
  * credential status if `credentialStatus` is present on the credential.
230
+ * @param {string|Date} [options.now] - A string representing date time in
231
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
225
232
  *
226
233
  * @returns {Promise<VerifyCredentialResult>} The verification result.
227
234
  */
@@ -251,6 +258,8 @@ export async function verifyCredential(options = {}) {
251
258
  * @param {object} options.credential - Verifiable credential.
252
259
  * @param {LinkedDataSignature|LinkedDataSignature[]} options.suite - See the
253
260
  * definition in the `verify()` docstring, for this param.
261
+ * @param {string|Date} [options.now] - A string representing date time in
262
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
254
263
  *
255
264
  * @throws {Error} If required parameters are missing (in `_checkCredential`).
256
265
  *
@@ -262,10 +271,10 @@ export async function verifyCredential(options = {}) {
262
271
  * @returns {Promise<VerifyCredentialResult>} The verification result.
263
272
  */
264
273
  async function _verifyCredential(options = {}) {
265
- const {credential, checkStatus} = options;
274
+ const {credential, checkStatus, now} = options;
266
275
 
267
276
  // run common credential checks
268
- _checkCredential(credential);
277
+ _checkCredential({credential, now});
269
278
 
270
279
  // if credential status is provided, a `checkStatus` function must be given
271
280
  if(credential.credentialStatus && typeof options.checkStatus !== 'function') {
@@ -307,6 +316,8 @@ async function _verifyCredential(options = {}) {
307
316
  * verifiable credential.
308
317
  * @param {string} [options.id] - Optional VP id.
309
318
  * @param {string} [options.holder] - Optional presentation holder url.
319
+ * @param {string|Date} [options.now] - A string representing date time in
320
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
310
321
  *
311
322
  * @throws {TypeError} If verifiableCredential param is missing.
312
323
  * @throws {Error} If the credential (or the presentation params) are missing
@@ -315,7 +326,9 @@ async function _verifyCredential(options = {}) {
315
326
  * @returns {Presentation} The credential wrapped inside of a
316
327
  * VerifiablePresentation.
317
328
  */
318
- export function createPresentation({verifiableCredential, id, holder} = {}) {
329
+ export function createPresentation({
330
+ verifiableCredential, id, holder, now
331
+ } = {}) {
319
332
  const presentation = {
320
333
  '@context': [CREDENTIALS_CONTEXT_V1_URL],
321
334
  type: ['VerifiablePresentation']
@@ -324,7 +337,7 @@ export function createPresentation({verifiableCredential, id, holder} = {}) {
324
337
  const credentials = [].concat(verifiableCredential);
325
338
  // ensure all credentials are valid
326
339
  for(const credential of credentials) {
327
- _checkCredential(credential);
340
+ _checkCredential({credential, now});
328
341
  }
329
342
  presentation.verifiableCredential = credentials;
330
343
  }
@@ -405,6 +418,8 @@ export async function signPresentation(options = {}) {
405
418
  * @param {Function} [options.documentLoader] - A document loader.
406
419
  * @param {Function} [options.checkStatus] - Optional function for checking
407
420
  * credential status if `credentialStatus` is present on the credential.
421
+ * @param {string|Date} [options.now] - A string representing date time in
422
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
408
423
  *
409
424
  * @throws {Error} If presentation is missing required params.
410
425
  *
@@ -487,6 +502,7 @@ function _getId(obj) {
487
502
  // export for testing
488
503
  /**
489
504
  * @param {object} presentation - An object that could be a presentation.
505
+ *
490
506
  * @throws {Error}
491
507
  * @private
492
508
  */
@@ -512,11 +528,19 @@ export function _checkPresentation(presentation) {
512
528
 
513
529
  // export for testing
514
530
  /**
515
- * @param {object} credential - An object that could be a VerifiableCredential.
531
+ * @param {object} options - The options.
532
+ * @param {object} options.credential - An object that could be a
533
+ * VerifiableCredential.
534
+ * @param {string|Date} [options.now] - A string representing date time in
535
+ * ISO 8601 format or an instance of Date. Defaults to current date time.
536
+ *
516
537
  * @throws {Error}
517
538
  * @private
518
539
  */
519
- export function _checkCredential(credential) {
540
+ export function _checkCredential({credential, now = new Date()}) {
541
+ if(typeof now === 'string') {
542
+ now = new Date(now);
543
+ }
520
544
  // ensure first context is 'https://www.w3.org/2018/credentials/v1'
521
545
  if(credential['@context'][0] !== CREDENTIALS_CONTEXT_V1_URL) {
522
546
  throw new Error(
@@ -559,9 +583,16 @@ export function _checkCredential(credential) {
559
583
  }
560
584
 
561
585
  if('issuanceDate' in credential) {
562
- if(!dateRegex.test(credential.issuanceDate)) {
586
+ let {issuanceDate} = credential;
587
+ if(!dateRegex.test(issuanceDate)) {
588
+ throw new Error(`"issuanceDate" must be a valid date: ${issuanceDate}`);
589
+ }
590
+ // check if `now` is before `issuanceDate`
591
+ issuanceDate = new Date(issuanceDate);
592
+ if(now < issuanceDate) {
563
593
  throw new Error(
564
- `"issuanceDate" must be a valid date: ${credential.issuanceDate}`);
594
+ `The current date time (${now.toISOString()}) is before the ` +
595
+ `"issuanceDate" (${issuanceDate.toISOString()}).`);
565
596
  }
566
597
  }
567
598
 
@@ -596,11 +627,17 @@ export function _checkCredential(credential) {
596
627
  }
597
628
  });
598
629
 
599
- // check expires is a date
600
- if('expirationDate' in credential &&
601
- !dateRegex.test(credential.expirationDate)) {
602
- throw new Error(
603
- `"expirationDate" must be a valid date: ${credential.expirationDate}`);
630
+ if('expirationDate' in credential) {
631
+ const {expirationDate} = credential;
632
+ // check if `expirationDate` property is a date
633
+ if(!dateRegex.test(expirationDate)) {
634
+ throw new Error(
635
+ `"expirationDate" must be a valid date: ${expirationDate}`);
636
+ }
637
+ // check if `now` is after `expirationDate`
638
+ if(now > new Date(expirationDate)) {
639
+ throw new Error('Credential has expired.');
640
+ }
604
641
  }
605
642
  }
606
643
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@digitalbazaar/vc",
3
- "version": "3.0.0",
3
+ "version": "4.0.0",
4
4
  "description": "Verifiable Credentials JavaScript library.",
5
5
  "homepage": "https://github.com/digitalbazaar/vc-js",
6
6
  "author": {