@veramo/credential-ld 3.1.1-next.8 → 3.1.2-next.101
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/build/action-handler.d.ts.map +1 -1
- package/build/action-handler.js +2 -2
- package/build/action-handler.js.map +1 -1
- package/build/index.js +5 -1
- package/build/index.js.map +1 -1
- package/build/ld-context-loader.d.ts +2 -2
- package/build/ld-context-loader.d.ts.map +1 -1
- package/build/ld-context-loader.js +9 -2
- package/build/ld-context-loader.js.map +1 -1
- package/build/ld-credential-module.d.ts +3 -3
- package/build/ld-credential-module.d.ts.map +1 -1
- package/build/ld-credential-module.js +41 -8
- package/build/ld-credential-module.js.map +1 -1
- package/build/ld-default-contexts.d.ts +5 -1
- package/build/ld-default-contexts.d.ts.map +1 -1
- package/build/ld-default-contexts.js +30 -13
- package/build/ld-default-contexts.js.map +1 -1
- package/build/suites/EcdsaSecp256k1RecoverySignature2020.js +5 -1
- package/build/suites/EcdsaSecp256k1RecoverySignature2020.js.map +1 -1
- package/build/suites/Ed25519Signature2018.js +5 -1
- package/build/suites/Ed25519Signature2018.js.map +1 -1
- package/build/tsdoc-metadata.json +1 -1
- package/build/types.d.ts +12 -0
- package/build/types.d.ts.map +1 -1
- package/contexts/X25519KeyAgreementKey2019.json +26 -0
- package/contexts/did_v0.11.json +58 -0
- package/contexts/ed25519-signature-2018-v1.json +91 -0
- package/contexts/kyc-v1.json +8 -0
- package/contexts/lds-ecdsa-secp256k1-recovery2020-0.0.json +60 -0
- package/contexts/profile-v1.json +8 -0
- package/contexts/security_context_v1.json +58 -0
- package/contexts/socialmedia-v1.json +7 -0
- package/contexts/transmute_v1.json +21 -0
- package/contexts/w3_2018_credentials_v1.json +237 -0
- package/package.json +14 -13
- package/plugin.schema.json +10 -0
- package/src/__tests__/context.loader.test.ts +39 -0
- package/src/__tests__/issue-verify-flow.test.ts +84 -0
- package/src/action-handler.ts +8 -2
- package/src/ld-context-loader.ts +7 -6
- package/src/ld-credential-module.ts +38 -5
- package/src/ld-default-contexts.ts +17 -13
- package/src/types.ts +14 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createAgent,
|
|
3
|
+
CredentialPayload,
|
|
4
|
+
IDIDManager,
|
|
5
|
+
IIdentifier,
|
|
6
|
+
IKeyManager,
|
|
7
|
+
IResolver,
|
|
8
|
+
TAgent,
|
|
9
|
+
} from '../../../core/src'
|
|
10
|
+
import { CredentialIssuer, ICredentialIssuer } from '../../../credential-w3c/src'
|
|
11
|
+
import { DIDManager, MemoryDIDStore } from '../../../did-manager/src'
|
|
12
|
+
import { KeyManager, MemoryKeyStore, MemoryPrivateKeyStore } from '../../../key-manager/src'
|
|
13
|
+
import { KeyManagementSystem } from '../../../kms-local/src'
|
|
14
|
+
import { getDidKeyResolver, KeyDIDProvider } from '../../../did-provider-key/src'
|
|
15
|
+
import { DIDResolverPlugin } from '../../../did-resolver/src'
|
|
16
|
+
import { ContextDoc } from '../types'
|
|
17
|
+
import { CredentialIssuerLD } from '../action-handler'
|
|
18
|
+
import { LdDefaultContexts } from '../ld-default-contexts'
|
|
19
|
+
import { VeramoEd25519Signature2018 } from '../suites/Ed25519Signature2018'
|
|
20
|
+
import { Resolver } from 'did-resolver'
|
|
21
|
+
|
|
22
|
+
const customContext: Record<string, ContextDoc> = {
|
|
23
|
+
'custom:example.context': {
|
|
24
|
+
'@context': {
|
|
25
|
+
nothing: 'custom:example.context#blank',
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('credential-LD full flow', () => {
|
|
31
|
+
let didKeyIdentifier: IIdentifier
|
|
32
|
+
let agent: TAgent<IResolver & IKeyManager & IDIDManager & ICredentialIssuer>
|
|
33
|
+
|
|
34
|
+
beforeAll(async () => {
|
|
35
|
+
agent = createAgent({
|
|
36
|
+
plugins: [
|
|
37
|
+
new KeyManager({
|
|
38
|
+
store: new MemoryKeyStore(),
|
|
39
|
+
kms: {
|
|
40
|
+
local: new KeyManagementSystem(new MemoryPrivateKeyStore()),
|
|
41
|
+
},
|
|
42
|
+
}),
|
|
43
|
+
new DIDManager({
|
|
44
|
+
providers: {
|
|
45
|
+
'did:key': new KeyDIDProvider({ defaultKms: 'local' }),
|
|
46
|
+
},
|
|
47
|
+
store: new MemoryDIDStore(),
|
|
48
|
+
defaultProvider: 'did:key',
|
|
49
|
+
}),
|
|
50
|
+
new DIDResolverPlugin({
|
|
51
|
+
resolver: new Resolver({ ...getDidKeyResolver() }),
|
|
52
|
+
}),
|
|
53
|
+
new CredentialIssuer(),
|
|
54
|
+
new CredentialIssuerLD({
|
|
55
|
+
contextMaps: [LdDefaultContexts, customContext],
|
|
56
|
+
suites: [new VeramoEd25519Signature2018()],
|
|
57
|
+
}),
|
|
58
|
+
],
|
|
59
|
+
})
|
|
60
|
+
didKeyIdentifier = await agent.didManagerCreate()
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
it('works with Ed25519Signature2018', async () => {
|
|
64
|
+
const credential: CredentialPayload = {
|
|
65
|
+
issuer: didKeyIdentifier.did,
|
|
66
|
+
'@context': ['custom:example.context'],
|
|
67
|
+
credentialSubject: {
|
|
68
|
+
nothing: 'else matters',
|
|
69
|
+
},
|
|
70
|
+
}
|
|
71
|
+
const verifiableCredential = await agent.createVerifiableCredential({
|
|
72
|
+
credential,
|
|
73
|
+
proofFormat: 'lds',
|
|
74
|
+
})
|
|
75
|
+
|
|
76
|
+
expect(verifiableCredential).toBeDefined()
|
|
77
|
+
|
|
78
|
+
const verified = await agent.verifyCredential({
|
|
79
|
+
credential: verifiableCredential,
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
expect(verified).toBe(true)
|
|
83
|
+
})
|
|
84
|
+
})
|
package/src/action-handler.ts
CHANGED
|
@@ -183,7 +183,7 @@ export class CredentialIssuerLD implements IAgentPlugin {
|
|
|
183
183
|
context: IRequiredContext,
|
|
184
184
|
): Promise<boolean> {
|
|
185
185
|
const credential = args.credential
|
|
186
|
-
return this.ldCredentialModule.verifyCredential(credential, context)
|
|
186
|
+
return this.ldCredentialModule.verifyCredential(credential, args.fetchRemoteContexts || false, context)
|
|
187
187
|
}
|
|
188
188
|
|
|
189
189
|
/** {@inheritdoc ICredentialIssuerLD.verifyPresentationLD} */
|
|
@@ -192,7 +192,13 @@ export class CredentialIssuerLD implements IAgentPlugin {
|
|
|
192
192
|
context: IRequiredContext,
|
|
193
193
|
): Promise<boolean> {
|
|
194
194
|
const presentation = args.presentation
|
|
195
|
-
return this.ldCredentialModule.verifyPresentation(
|
|
195
|
+
return this.ldCredentialModule.verifyPresentation(
|
|
196
|
+
presentation,
|
|
197
|
+
args.challenge,
|
|
198
|
+
args.domain,
|
|
199
|
+
args.fetchRemoteContexts || false,
|
|
200
|
+
context,
|
|
201
|
+
)
|
|
196
202
|
}
|
|
197
203
|
|
|
198
204
|
private async findSigningKeyWithId(
|
package/src/ld-context-loader.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The LdContextLoader is initialized with a List of Map<string, ContextDoc
|
|
2
|
+
* The LdContextLoader is initialized with a List of Map<string, ContextDoc | Promise<ContextDoc>>
|
|
3
3
|
* that it unifies into a single Map to provide to the documentLoader within
|
|
4
4
|
* the w3c credential module.
|
|
5
5
|
*/
|
|
6
|
-
import { OrPromise, RecordLike } from '@veramo/utils'
|
|
6
|
+
import { isIterable, OrPromise, RecordLike } from '@veramo/utils'
|
|
7
7
|
import { ContextDoc } from './types'
|
|
8
8
|
|
|
9
9
|
export class LdContextLoader {
|
|
10
|
-
private contexts: Record<string, OrPromise<ContextDoc>>
|
|
10
|
+
private readonly contexts: Record<string, OrPromise<ContextDoc>>
|
|
11
11
|
|
|
12
12
|
constructor(options: { contextsPaths: RecordLike<OrPromise<ContextDoc>>[] }) {
|
|
13
13
|
this.contexts = {}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
Array.from(options.contextsPaths, (mapItem) => {
|
|
15
|
+
const map = isIterable(mapItem) ? mapItem : Object.entries(mapItem)
|
|
16
|
+
// generate-plugin-schema is failing unless we use the cast to `any[]`
|
|
17
|
+
for (const [key, value] of map as any[]) {
|
|
17
18
|
this.contexts[key] = value
|
|
18
19
|
}
|
|
19
20
|
})
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
VerifiableCredential,
|
|
8
8
|
VerifiablePresentation,
|
|
9
9
|
} from '@veramo/core'
|
|
10
|
+
import fetch from 'cross-fetch'
|
|
10
11
|
import Debug from 'debug'
|
|
11
12
|
import { extendContextLoader, purposes } from 'jsonld-signatures'
|
|
12
13
|
import * as vc from 'vc-js'
|
|
@@ -34,7 +35,7 @@ export class LdCredentialModule {
|
|
|
34
35
|
this.ldSuiteLoader = options.ldSuiteLoader
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
getDocumentLoader(context: IAgentContext<IResolver
|
|
38
|
+
getDocumentLoader(context: IAgentContext<IResolver>, attemptToFetchContexts: boolean = false) {
|
|
38
39
|
return extendContextLoader(async (url: string) => {
|
|
39
40
|
// console.log(`resolving context for: ${url}`)
|
|
40
41
|
|
|
@@ -65,10 +66,29 @@ export class LdCredentialModule {
|
|
|
65
66
|
documentUrl: url,
|
|
66
67
|
document: contextDoc,
|
|
67
68
|
}
|
|
69
|
+
} else {
|
|
70
|
+
if (attemptToFetchContexts) {
|
|
71
|
+
// attempt to fetch the remote context!!!! MEGA FAIL for JSON-LD.
|
|
72
|
+
debug('WARNING: attempting to fetch the doc directly for ', url)
|
|
73
|
+
try {
|
|
74
|
+
const response = await fetch(url)
|
|
75
|
+
if (response.status === 200) {
|
|
76
|
+
const document = await response.json()
|
|
77
|
+
return {
|
|
78
|
+
contextUrl: null,
|
|
79
|
+
documentUrl: url,
|
|
80
|
+
document,
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
} catch (e) {
|
|
84
|
+
debug('WARNING: unable to fetch the doc or interpret it as JSON', e)
|
|
85
|
+
}
|
|
86
|
+
}
|
|
68
87
|
}
|
|
69
88
|
|
|
70
|
-
debug(
|
|
71
|
-
|
|
89
|
+
debug(
|
|
90
|
+
`WARNING: Possible unknown context/identifier for ${url} \n falling back to default documentLoader`,
|
|
91
|
+
)
|
|
72
92
|
|
|
73
93
|
return vc.defaultDocumentLoader(url)
|
|
74
94
|
})
|
|
@@ -122,14 +142,26 @@ export class LdCredentialModule {
|
|
|
122
142
|
|
|
123
143
|
async verifyCredential(
|
|
124
144
|
credential: VerifiableCredential,
|
|
145
|
+
fetchRemoteContexts: boolean = false,
|
|
125
146
|
context: IAgentContext<IResolver>,
|
|
126
147
|
): Promise<boolean> {
|
|
148
|
+
const checkStatusFn =
|
|
149
|
+
typeof context.agent.checkCredentialStatus === 'function'
|
|
150
|
+
? async ({ credential }: any) => {
|
|
151
|
+
const result = await context.agent.checkCredentialStatus({
|
|
152
|
+
credential,
|
|
153
|
+
})
|
|
154
|
+
return { verified: !result.revoked }
|
|
155
|
+
}
|
|
156
|
+
: void 0
|
|
157
|
+
|
|
127
158
|
const result = await vc.verifyCredential({
|
|
128
159
|
credential,
|
|
129
160
|
suite: this.ldSuiteLoader.getAllSignatureSuites().map((x) => x.getSuiteForVerification()),
|
|
130
|
-
documentLoader: this.getDocumentLoader(context),
|
|
161
|
+
documentLoader: this.getDocumentLoader(context, fetchRemoteContexts),
|
|
131
162
|
purpose: new AssertionProofPurpose(),
|
|
132
163
|
compactProof: false,
|
|
164
|
+
checkStatus: checkStatusFn,
|
|
133
165
|
})
|
|
134
166
|
|
|
135
167
|
if (result.verified) return true
|
|
@@ -146,12 +178,13 @@ export class LdCredentialModule {
|
|
|
146
178
|
presentation: VerifiablePresentation,
|
|
147
179
|
challenge: string | undefined,
|
|
148
180
|
domain: string | undefined,
|
|
181
|
+
fetchRemoteContexts: boolean = false,
|
|
149
182
|
context: IAgentContext<IResolver>,
|
|
150
183
|
): Promise<boolean> {
|
|
151
184
|
const result = await vc.verify({
|
|
152
185
|
presentation,
|
|
153
186
|
suite: this.ldSuiteLoader.getAllSignatureSuites().map((x) => x.getSuiteForVerification()),
|
|
154
|
-
documentLoader: this.getDocumentLoader(context),
|
|
187
|
+
documentLoader: this.getDocumentLoader(context, fetchRemoteContexts),
|
|
155
188
|
challenge,
|
|
156
189
|
domain,
|
|
157
190
|
purpose: new AssertionProofPurpose(),
|
|
@@ -1,21 +1,25 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as path from 'path'
|
|
1
|
+
import { ContextDoc } from './types'
|
|
3
2
|
|
|
4
|
-
function _read(_path: string) {
|
|
5
|
-
return
|
|
3
|
+
async function _read(_path: string): Promise<ContextDoc> {
|
|
4
|
+
return await import('../contexts/' + _path);
|
|
6
5
|
}
|
|
7
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Provides a hardcoded map of common context definitions
|
|
9
|
+
*/
|
|
8
10
|
export const LdDefaultContexts = new Map([
|
|
9
|
-
['https://
|
|
10
|
-
['https://
|
|
11
|
-
['https://
|
|
12
|
-
|
|
13
|
-
['https://
|
|
14
|
-
['https://
|
|
11
|
+
['https://www.w3.org/2018/credentials/v1', _read('w3_2018_credentials_v1.json')],
|
|
12
|
+
['https://www.w3.org/ns/did/v1', _read('security_context_v1.json')],
|
|
13
|
+
['https://w3id.org/did/v0.11', _read('did_v0.11.json')],
|
|
14
|
+
|
|
15
|
+
['https://veramo.io/contexts/socialmedia/v1', _read('socialmedia-v1.json')],
|
|
16
|
+
['https://veramo.io/contexts/kyc/v1', _read('kyc-v1.json')],
|
|
17
|
+
['https://veramo.io/contexts/profile/v1', _read('profile-v1.json')],
|
|
18
|
+
['https://ns.did.ai/transmute/v1', _read('transmute_v1.json')],
|
|
15
19
|
[
|
|
16
20
|
'https://identity.foundation/EcdsaSecp256k1RecoverySignature2020/lds-ecdsa-secp256k1-recovery2020-0.0.jsonld',
|
|
17
|
-
_read('lds-ecdsa-secp256k1-recovery2020-0.0.
|
|
21
|
+
_read('lds-ecdsa-secp256k1-recovery2020-0.0.json'),
|
|
18
22
|
],
|
|
19
|
-
['https://w3id.org/security/suites/ed25519-2018/v1', _read('ed25519-signature-2018-v1.
|
|
20
|
-
['https://w3id.org/security/suites/x25519-2019/v1', _read('X25519KeyAgreementKey2019.
|
|
23
|
+
['https://w3id.org/security/suites/ed25519-2018/v1', _read('ed25519-signature-2018-v1.json')],
|
|
24
|
+
['https://w3id.org/security/suites/x25519-2019/v1', _read('X25519KeyAgreementKey2019.json')],
|
|
21
25
|
])
|
package/src/types.ts
CHANGED
|
@@ -161,6 +161,13 @@ export interface IVerifyCredentialLDArgs {
|
|
|
161
161
|
*
|
|
162
162
|
*/
|
|
163
163
|
credential: VerifiableCredential
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Set this to true if you want the '@context' URLs to be fetched in case they are not pre-loaded.
|
|
167
|
+
*
|
|
168
|
+
* @default false
|
|
169
|
+
*/
|
|
170
|
+
fetchRemoteContexts?: boolean
|
|
164
171
|
}
|
|
165
172
|
|
|
166
173
|
/**
|
|
@@ -189,6 +196,13 @@ export interface IVerifyPresentationLDArgs {
|
|
|
189
196
|
* Optional (only for JWT) string domain parameter to verify the verifiable presentation against
|
|
190
197
|
*/
|
|
191
198
|
domain?: string
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Set this to true if you want the '@context' URLs to be fetched in case they are not pre-loaded.
|
|
202
|
+
*
|
|
203
|
+
* @default false
|
|
204
|
+
*/
|
|
205
|
+
fetchRemoteContexts?: boolean
|
|
192
206
|
}
|
|
193
207
|
|
|
194
208
|
/**
|