-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathvalidate.ts
100 lines (84 loc) · 3.11 KB
/
validate.ts
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// import '@digitalcredentials/data-integrity-rn';
import { Ed25519Signature2020 } from '@digitalcredentials/ed25519-signature-2020';
import { purposes } from '@digitalcredentials/jsonld-signatures';
import * as vc from '@digitalcredentials/vc';
import { VerifiablePresentation, PresentationError } from '../types/presentation';
import { Credential, CredentialError } from '../types/credential';
import { securityLoader } from '@digitalcredentials/security-document-loader';
import { RegistryClient } from '@digitalcredentials/issuer-registry-client';
import { getCredentialStatusChecker } from './credentialStatus';
import { issuerInRegistries } from './issuerInRegistries';
import { extractCredentialsFrom } from './verifiableObject';
const documentLoader = securityLoader({ fetchRemoteContexts: true }).build();
const suite = new Ed25519Signature2020();
const presentationPurpose = new purposes.AssertionProofPurpose();
export type ResultLog = {
id: string,
valid: boolean
}
export type Result = {
verified: boolean;
credential: Credential;
error: CredentialError;
log: ResultLog[];
}
export type VerifyResponse = {
verified: boolean;
results: Result[];
}
export async function verifyPresentation(
presentation: VerifiablePresentation,
unsignedPresentation = true,
): Promise<VerifyResponse> {
try {
const credential = extractCredentialsFrom(presentation)?.find(
vc => vc.credentialStatus);
const checkStatus = credential ? getCredentialStatusChecker(credential) : undefined;
const result = await vc.verify({
presentation,
presentationPurpose,
suite,
documentLoader,
unsignedPresentation,
checkStatus
});
if (!result.verified) {
console.warn('VP not verified:', JSON.stringify(result, null, 2));
}
return result;
} catch (err) {
console.warn(err);
throw new Error(PresentationError.CouldNotBeVerified);
}
}
export async function verifyCredential(credential: Credential, registries: RegistryClient): Promise<VerifyResponse> {
const { issuer } = credential;
const isInRegistry = issuerInRegistries({ issuer, registries });
if (!isInRegistry) {
throw new Error(CredentialError.DidNotInRegistry);
}
try {
const checkStatus = credential.credentialStatus ? getCredentialStatusChecker(credential) : undefined;
const result = await vc.verifyCredential({
credential,
suite,
documentLoader,
// Only check revocation status if VC has a 'credentialStatus' property
checkStatus
});
// This logic catches the case where the verify response does not contain a `log` value
if (result.results?.[0].log === undefined) {
throw result.error || new Error('Verify response does not a `log` value');
}
if (!result.verified) {
console.warn('VC not verified:', JSON.stringify(result, null, 2));
}
return result;
} catch (err) {
console.warn('verifyCredential', err, JSON.stringify(err, removeStackReplacer, 2));
throw new Error(CredentialError.CouldNotBeVerified);
}
}
function removeStackReplacer(key: string, value: unknown) {
return key === 'stack' ? '...' : value;
}