All files / src/parsers parseV3.ts

100% Statements 22/22
100% Branches 9/9
100% Functions 2/2
100% Lines 22/22

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                172x       8x       95x     129x   183x   138x         55x   10x   55x                             111x     111x   111x   6x 6x   105x 105x   4x 4x   105x   51x 51x   103x                            
import domain from '../domain';
import type { Issuer } from '../models/Issuer';
import type { BlockcertsV3, VCProof } from '../models/BlockcertsV3';
import type { ParsedCertificate } from './index';
import { isVerifiablePresentation } from '../models/BlockcertsV3';
 
function getPropertyValueForCurrentLanguage (propertyName: string, field: any, locale: string): string {
  if (typeof field === 'undefined') {
    return '';
  }
 
  if (typeof field === 'string') {
    return field;
  }
 
  if (!Array.isArray(field)) {
    field = [field];
  }
 
  return field
    // find value by exact match
    .find((f) => f['@language'] === locale)?.[propertyName] ??
    // find value by shorthand (ie. 'en-US' -> 'en')
    field.find((f) => f['@language']?.split('-')[0] === locale.split('-')[0])?.[propertyName] ??
    field[0][propertyName];
}
 
function getProofObject (proof: VCProof | VCProof[]): VCProof {
  let proofObject = proof;
  if (Array.isArray(proof)) {
    proofObject = proof[0];
  }
  return proofObject as VCProof;
}
 
export default async function parseV3 (certificateJson: BlockcertsV3, locale: string): Promise<ParsedCertificate> {
  const {
    metadataJson, metadata,
    issuanceDate,
    id,
    expirationDate,
    display,
    validUntil,
    proof,
    name,
    description,
    credentialSubject
  } = certificateJson;
  let {
    issuer: issuerProfileUrl
  } = certificateJson;
  try {
    domain.verifier.validateVerifiableCredential(certificateJson);
  } catch (error) {
    console.error('Error validating the Verifiable Credential format: ', error.message);
    throw new Error(`Document presented is not a valid Verifiable Credential: ${error.message}`);
  }
  let { validFrom } = certificateJson;
  const certificateMetadata = metadata ?? metadataJson;
  if (isVerifiablePresentation(certificateJson)) {
    const proofObject = getProofObject(proof);
    issuerProfileUrl = proofObject.verificationMethod?.split('#')[0];
  }
  const issuer: Issuer = await domain.verifier.getIssuerProfile(issuerProfileUrl);
  if (!validFrom) {
    const proofObject = getProofObject(proof);
    validFrom = proofObject.created;
  }
  return {
    display,
    expires: expirationDate ?? validUntil,
    validFrom,
    issuedOn: issuanceDate ?? validFrom, // maintain backwards compatibility
    id,
    issuer,
    name: getPropertyValueForCurrentLanguage('@value', name, locale),
    description: getPropertyValueForCurrentLanguage('@value', description, locale),
    metadataJson: certificateMetadata,
    recipientFullName: getPropertyValueForCurrentLanguage('name', credentialSubject, locale),
    recordLink: id
  };
}