decentralized-identity / veramo

A JavaScript Framework for Verifiable Data
https://veramo.io
Apache License 2.0
431 stars 131 forks source link

Types are saved as string, not as array #1234

Open cre8 opened 1 year ago

cre8 commented 1 year ago

Bug severity 2

Describe the bug The dataStoreORMGetVerifiableCredentialsCount can be used to count all VCs that have the same type. According to the Implementation the field value from where needs an array like:

agent.dataStoreORMGetVerifiableCredentialsCount({
        where: [
          {
            column: 'type',
            value: ['VerifiableCredential', 'StatusList2021'],
          },
        ],
      });

But this will always return 0 since the values of the field type are stored as a joined string and not as an array: image

There is also no mentioning in the documentation about this handling...

To Reproduce Steps to reproduce the behaviour:

  1. Insert a credential that has more than one type:
    agent.createVerifiableCredential({
        credential: {
          '@context': [
            'https://www.w3.org/2018/credentials/v1',
            'https://w3id.org/vc/status-list/v1',
          ],
          id,
          type: ['VerifiableCredential', 'StatusList2021'],
          issuer: this.configService.get('ISSUER_DID') as string,
          credentialSubject: {
            id: `${id}#list`,
            encodedList,
          },
        },
        proofFormat: 'jwt',
      });
    const res = await this.agentService.agent.dataStoreSaveVerifiableCredential(
      {
        verifiableCredential,
      },
    );
  2. count for the VCs with this type
    agent.dataStoreORMGetVerifiableCredentialsCount({
        where: [
          {
            column: 'type',
            value: ['VerifiableCredential', 'StatusList2021'],
          },
        ],
      });

Joining the value fields works:

agent.dataStoreORMGetVerifiableCredentialsCount({
        where: [
          {
            column: 'type',
            value: ['VerifiableCredential,StatusList2021'],
          },
        ],
      });

Observed behaviour According to the specs the @context field "MUST" be an ordered set, so an array without nested structures should be the case here.

Expected behaviour Treating the field as a json field and not a string should solve the problem

Versions (please complete the following information):

mirceanis commented 1 year ago

We chose to use the simple-array column type defined by TypeORM for the type and @context properties of credentials and presentations because it works essentially with any database driver that TypeORM supports. Otherwise we would be limited to PostgreSQL or CockroachDB only.

Knowing this, here are some example queries to get credentials by type:

Using the "In" operator (default), or "Equal"

const credentialsEqual = await agent.dataStoreORMGetVerifiableCredentials({
        where: [
          {
            column: 'type',
            value: ['VerifiableCredential,StatusList2021'], // join the strings
            op: 'Equal' // if `op` is not specified, "In" is implied
          },
        ],
      });
const credentialsLike = await agent.dataStoreORMGetVerifiableCredentials({
        where: [
          {
            column: 'type',
            value: ['%StatusList2021%'], // use the Like operation with `%` as the wildcard character
            op: 'Like'
          },
        ],
      });