-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export const knownDidRegistries = [ | ||
{ | ||
name: 'DCC Pilot Registry', | ||
url: 'https://digitalcredentials.github.io/issuer-registry/registry.json' | ||
}, | ||
{ | ||
name: 'DCC Sandbox Registry', | ||
url: 'https://digitalcredentials.github.io/sandbox-registry/registry.json' | ||
}, | ||
{ | ||
name: 'DCC Community Registry', | ||
url: 'https://digitalcredentials.github.io/community-registry/registry.json' | ||
}, | ||
{ | ||
name: 'DCC Registry', | ||
url: 'https://digitalcredentials.github.io/dcc-registry/registry.json' | ||
} | ||
] | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# isomorphic-lib-template Changelog | ||
|
||
## 1.0.0 - TBD | ||
## 0.0.1 - TBD | ||
|
||
### Added | ||
|
||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// import '@digitalcredentials/data-integrity-rn'; | ||
Check failure on line 1 in src/Verify.ts GitHub Actions / test-karma (16.x)
Check failure on line 1 in src/Verify.ts GitHub Actions / test-node (18.x)
|
||
import { Ed25519Signature2020 } from '@digitalcredentials/ed25519-signature-2020'; | ||
import * as vc from '@digitalcredentials/vc'; | ||
import { securityLoader } from '@digitalcredentials/security-document-loader'; | ||
import { getCredentialStatusChecker } from './credentialStatus'; | ||
import { addTrustedIssuersToVerificationResponse } from './issuerRegistries'; | ||
|
||
import { Credential } from './types/credential'; | ||
|
||
/* | ||
// the new eddsa-rdfc-2022-cryptosuite | ||
import {DataIntegrityProof} from '@digitalbazaar/data-integrity'; | ||
import {cryptosuite as eddsaRdfc2022CryptoSuite} from '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; | ||
const suite = new DataIntegrityProof({ | ||
cryptosuite: eddsaRdfc2022CryptoSuite | ||
}); | ||
*/ | ||
|
||
const documentLoader = securityLoader({ fetchRemoteContexts: true }).build(); | ||
const suite = new Ed25519Signature2020(); | ||
|
||
export interface VerificationError { | ||
"message": string, | ||
"isFatal": boolean | ||
} | ||
|
||
export interface Step { | ||
"id": string, | ||
"valid": boolean, | ||
"foundInRegistries"?: string[], | ||
} | ||
|
||
export interface VerificationResponse { | ||
"verified": boolean, | ||
"isFatal": boolean, | ||
"credential": object, | ||
"errors"?: VerificationError[], | ||
"log"?: Step[] | ||
} | ||
|
||
export async function verifyCredential({credential, reloadIssuerRegistry = true}:{credential: Credential, reloadIssuerRegistry: boolean}): Promise<VerificationResponse> { | ||
|
||
const fatalErrorMessage = checkForFatalErrors(credential) | ||
|
||
if (fatalErrorMessage) return {credential, isFatal: true, verified: false, errors: [{message: fatalErrorMessage, isFatal: true}]} | ||
|
||
const verificationResponse = await vc.verifyCredential({ | ||
credential, | ||
suite, | ||
documentLoader, | ||
checkStatus: getCredentialStatusChecker(credential) | ||
}); | ||
|
||
delete verificationResponse.results | ||
delete verificationResponse.statusResult | ||
|
||
const { issuer } = credential | ||
await addTrustedIssuersToVerificationResponse({verificationResponse, reloadIssuerRegistry, issuer}) | ||
verificationResponse.isFatal = false | ||
|
||
return verificationResponse; | ||
} | ||
|
||
function checkForFatalErrors(credential: Credential) : string | null { | ||
|
||
try { | ||
// eslint-disable-next-line no-new | ||
new URL(credential.id as string); | ||
} catch (e) { | ||
return "The credential's id uses an invalid format. It may have been issued as part of an early pilot. Please contact the issuer to get a replacement." | ||
} | ||
|
||
if (!credential.proof) { | ||
return 'This is not a Verifiable Credential - it does not have a digital signature.' | ||
} | ||
|
||
return null | ||
} | ||
|
||
|
||
// import { purposes } from '@digitalcredentials/jsonld-signatures'; | ||
// import { VerifiablePresentation, PresentationError } from './types/presentation'; | ||
// const presentationPurpose = new purposes.AssertionProofPurpose(); | ||
// import { extractCredentialsFrom } from './verifiableObject'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { checkStatus } from '@digitalcredentials/vc-bitstring-status-list'; | ||
Check failure on line 1 in src/credentialStatus.ts GitHub Actions / test-karma (16.x)
Check failure on line 1 in src/credentialStatus.ts GitHub Actions / test-karma (16.x)
Check failure on line 1 in src/credentialStatus.ts GitHub Actions / test-node (18.x)
Check failure on line 1 in src/credentialStatus.ts GitHub Actions / test-node (18.x)
Check failure on line 1 in src/credentialStatus.ts GitHub Actions / lint (16.x)
|
||
import { checkStatus as checkStatusLegacy } from '@digitalcredentials/vc-status-list'; | ||
import { Credential } from './types/credential'; | ||
|
||
export enum StatusPurpose { | ||
Revocation = 'revocation', | ||
Suspension = 'suspension' | ||
} | ||
|
||
export function getCredentialStatusChecker(credential: Credential) : (() => boolean) | null { | ||
if (!credential.credentialStatus) { | ||
return null; | ||
} | ||
const credentialStatuses = Array.isArray(credential.credentialStatus) ? | ||
credential.credentialStatus : | ||
[credential.credentialStatus]; | ||
const [credentialStatus] = credentialStatuses; | ||
switch (credentialStatus.type) { | ||
case 'BitstringStatusListEntry': | ||
return checkStatus; | ||
case 'StatusList2021Entry': | ||
return checkStatusLegacy; | ||
default: | ||
return null; | ||
} | ||
} | ||
|
||
export function hasStatusPurpose( | ||
credential: Credential, | ||
statusPurpose: StatusPurpose | ||
) : boolean { | ||
if (!credential.credentialStatus) { | ||
return false; | ||
} | ||
const credentialStatuses = Array.isArray(credential.credentialStatus) ? | ||
credential.credentialStatus : | ||
[credential.credentialStatus]; | ||
return credentialStatuses.some(s => s.statusPurpose === statusPurpose); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,11 @@ | ||
// declare module 'jsonld' | ||
declare module '@digitalcredentials/did-io'; | ||
declare module '@digitalcredentials/did-method-key'; | ||
declare module '@digitalcredentials/vc'; | ||
declare module '@digitalcredentials/vc-bitstring-status-list'; | ||
declare module '@digitalcredentials/vc-status-list'; | ||
declare module '@digitalcredentials/vpqr'; | ||
declare module '@digitalcredentials/jsonld-signatures'; | ||
declare module '@digitalbazaar/data-integrity'; | ||
declare module '@digitalbazaar/eddsa-rdfc-2022-cryptosuite'; | ||
declare module '@digitalcredentials/ed25519-signature-2020'; | ||
declare module '@digitalcredentials/ed25519-verification-key-2020'; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
/*! | ||
* Copyright (c) 2022 Digital Credentials Consortium. All rights reserved. | ||
*/ | ||
export { Example } from './Example' | ||
export { verifyCredential, // verifyPresentation | ||
} from './Verify' |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import {RegistryClient} from '@digitalcredentials/issuer-registry-client'; | ||
import {knownDidRegistries} from '../.knownDidRegistries' | ||
import { VerificationResponse } from './Verify'; | ||
const registries = new RegistryClient() | ||
const registryNotYetLoaded = true; | ||
/** | ||
* Checks to see if a VC's issuer appears in any of the known DID registries. | ||
* | ||
* @returns A list of the names of the DID registries in which the issuer appears. | ||
*/ | ||
|
||
export async function getTrustedRegistryListForIssuer({ issuer, reloadIssuerRegistry = false }: { | ||
issuer: string | any, | ||
reloadIssuerRegistry: boolean | null | ||
}): Promise<string[] | null> { | ||
|
||
if (reloadIssuerRegistry ?? registryNotYetLoaded) { | ||
await registries.load({ config: knownDidRegistries }) | ||
} | ||
const issuerDid = typeof issuer === 'string' ? issuer : issuer.id; | ||
const issuerInfo = registries.didEntry(issuerDid); | ||
// See if the issuer DID appears in any of the known registries | ||
// If yes, assemble a list of registries in which it appears | ||
return issuerInfo?.inRegistries | ||
? Array.from(issuerInfo.inRegistries).map(r => r.name) | ||
: null; | ||
} | ||
|
||
export async function addTrustedIssuersToVerificationResponse( {issuer, reloadIssuerRegistry = false, verificationResponse} :{ | ||
issuer: string | any, | ||
reloadIssuerRegistry: boolean | null | ||
verificationResponse: VerificationResponse | ||
}) : Promise<void> | ||
{ | ||
const foundInRegistries = await getTrustedRegistryListForIssuer( {issuer, reloadIssuerRegistry}); | ||
|
||
const registryStep = { | ||
"id": "registered_issuer", | ||
"valid": !!foundInRegistries, | ||
...(foundInRegistries && { foundInRegistries }) | ||
}; | ||
|
||
(verificationResponse.log ??= []).push(registryStep) | ||
|
||
} | ||
|