@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.
Files changed (43) hide show
  1. package/build/action-handler.d.ts.map +1 -1
  2. package/build/action-handler.js +2 -2
  3. package/build/action-handler.js.map +1 -1
  4. package/build/index.js +5 -1
  5. package/build/index.js.map +1 -1
  6. package/build/ld-context-loader.d.ts +2 -2
  7. package/build/ld-context-loader.d.ts.map +1 -1
  8. package/build/ld-context-loader.js +9 -2
  9. package/build/ld-context-loader.js.map +1 -1
  10. package/build/ld-credential-module.d.ts +3 -3
  11. package/build/ld-credential-module.d.ts.map +1 -1
  12. package/build/ld-credential-module.js +41 -8
  13. package/build/ld-credential-module.js.map +1 -1
  14. package/build/ld-default-contexts.d.ts +5 -1
  15. package/build/ld-default-contexts.d.ts.map +1 -1
  16. package/build/ld-default-contexts.js +30 -13
  17. package/build/ld-default-contexts.js.map +1 -1
  18. package/build/suites/EcdsaSecp256k1RecoverySignature2020.js +5 -1
  19. package/build/suites/EcdsaSecp256k1RecoverySignature2020.js.map +1 -1
  20. package/build/suites/Ed25519Signature2018.js +5 -1
  21. package/build/suites/Ed25519Signature2018.js.map +1 -1
  22. package/build/tsdoc-metadata.json +1 -1
  23. package/build/types.d.ts +12 -0
  24. package/build/types.d.ts.map +1 -1
  25. package/contexts/X25519KeyAgreementKey2019.json +26 -0
  26. package/contexts/did_v0.11.json +58 -0
  27. package/contexts/ed25519-signature-2018-v1.json +91 -0
  28. package/contexts/kyc-v1.json +8 -0
  29. package/contexts/lds-ecdsa-secp256k1-recovery2020-0.0.json +60 -0
  30. package/contexts/profile-v1.json +8 -0
  31. package/contexts/security_context_v1.json +58 -0
  32. package/contexts/socialmedia-v1.json +7 -0
  33. package/contexts/transmute_v1.json +21 -0
  34. package/contexts/w3_2018_credentials_v1.json +237 -0
  35. package/package.json +14 -13
  36. package/plugin.schema.json +10 -0
  37. package/src/__tests__/context.loader.test.ts +39 -0
  38. package/src/__tests__/issue-verify-flow.test.ts +84 -0
  39. package/src/action-handler.ts +8 -2
  40. package/src/ld-context-loader.ts +7 -6
  41. package/src/ld-credential-module.ts +38 -5
  42. package/src/ld-default-contexts.ts +17 -13
  43. 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
+ })
@@ -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(presentation, args.challenge, args.domain, context)
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(
@@ -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
- // generate-plugin-schema is failing unless we use the cast to `any[]`
15
- Array.from(options.contextsPaths as any[], (mapItem) => {
16
- for (const [key, value] of mapItem) {
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('WARNING: Possible unknown context/identifier for', url)
71
- console.log(`WARNING: Possible unknown context/identifier for: ${url}`)
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 * as fs from 'fs'
2
- import * as path from 'path'
1
+ import { ContextDoc } from './types'
3
2
 
4
- function _read(_path: string) {
5
- return JSON.parse(fs.readFileSync(path.join(__dirname, '../contexts', _path), { encoding: 'utf8' }))
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://veramo.io/contexts/socialmedia/v1', _read('socialmedia-v1.jsonld')],
10
- ['https://veramo.io/contexts/kyc/v1', _read('kyc-v1.jsonld')],
11
- ['https://veramo.io/contexts/profile/v1', _read('profile-v1.jsonld')],
12
- ['https://www.w3.org/ns/did/v1', _read('security_context_v1.jsonld')],
13
- ['https://w3id.org/did/v0.11', _read('did_v0.11.jsonld')],
14
- ['https://ns.did.ai/transmute/v1', _read('transmute_v1.jsonld')],
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.jsonld'),
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.jsonld')],
20
- ['https://w3id.org/security/suites/x25519-2019/v1', _read('X25519KeyAgreementKey2019.jsonld')],
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
  /**