Skip to content

Commit

Permalink
fix(anoncreds): unqualified revocation registry processing (#1833)
Browse files Browse the repository at this point in the history
  • Loading branch information
genaris authored Apr 18, 2024
1 parent eb2c513 commit edc5735
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 27 deletions.
26 changes: 19 additions & 7 deletions packages/anoncreds/src/anoncreds-rs/AnonCredsRsHolderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,18 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService {
schema: AnonCredsSchema
credentialDefinition: AnonCredsCredentialDefinition
revocationRegistryDefinition?: AnonCredsRevocationRegistryDefinition
revocationRegistryId?: string
credentialRequestMetadata: AnonCredsCredentialRequestMetadata
}
) {
const { credential, credentialRequestMetadata, schema, credentialDefinition, credentialDefinitionId } = options
const {
credential,
credentialRequestMetadata,
schema,
credentialDefinition,
credentialDefinitionId,
revocationRegistryId,
} = options

const methodName = agentContext.dependencyManager
.resolve(AnonCredsRegistryService)
Expand All @@ -377,15 +385,15 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService {
// this thows an error if the link secret is not found
await getLinkSecret(agentContext, credentialRequestMetadata.link_secret_name)

const { revocationRegistryId, revocationRegistryIndex } = W3cAnonCredsCredential.fromJson(
JsonTransformer.toJSON(credential)
)
const { revocationRegistryIndex } = W3cAnonCredsCredential.fromJson(JsonTransformer.toJSON(credential))

const w3cCredentialService = agentContext.dependencyManager.resolve(W3cCredentialService)
const w3cCredentialRecord = await w3cCredentialService.storeCredential(agentContext, { credential })
if (Array.isArray(credential.credentialSubject)) {
throw new CredoError('Credential subject must be an object, not an array.')
}

const anonCredsTags = getW3cRecordAnonCredsTags({
w3cCredentialRecord,
credentialSubject: credential.credentialSubject,
issuerId: credential.issuerId,
schema,
schemaId: credentialDefinition.schemaId,
credentialDefinitionId,
Expand All @@ -395,6 +403,9 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService {
methodName,
})

const w3cCredentialService = agentContext.dependencyManager.resolve(W3cCredentialService)
const w3cCredentialRecord = await w3cCredentialService.storeCredential(agentContext, { credential })

const anonCredsCredentialMetadata: W3cAnonCredsCredentialMetadata = {
credentialRevocationId: anonCredsTags.anonCredsCredentialRevocationId,
linkSecretId: anonCredsTags.anonCredsLinkSecretId,
Expand Down Expand Up @@ -440,6 +451,7 @@ export class AnonCredsRsHolderService implements AnonCredsHolderService {
schema,
credentialDefinition,
revocationRegistryDefinition: revocationRegistry?.definition,
revocationRegistryId: revocationRegistry?.id,
})

return w3cCredentialRecord.id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,17 +91,13 @@ async function migrateLegacyToW3cCredential(agentContext: AgentContext, legacyRe
issuerId: qualifiedIssuerId,
})

const w3cCredentialService = agentContext.dependencyManager.resolve(W3cCredentialService)
const w3cCredentialRecord = await w3cCredentialService.storeCredential(agentContext, {
credential: w3cJsonLdCredential,
})

for (const [key, meta] of Object.entries(legacyRecord.metadata.data)) {
w3cCredentialRecord.metadata.set(key, meta)
if (Array.isArray(w3cJsonLdCredential.credentialSubject)) {
throw new CredoError('Credential subject must be an object, not an array.')
}

const anonCredsTags = getW3cRecordAnonCredsTags({
w3cCredentialRecord,
credentialSubject: w3cJsonLdCredential.credentialSubject,
issuerId: w3cJsonLdCredential.issuerId,
schemaId: qualifiedSchemaId,
schema: {
issuerId: qualifiedSchemaIssuerId,
Expand All @@ -115,6 +111,15 @@ async function migrateLegacyToW3cCredential(agentContext: AgentContext, legacyRe
methodName: legacyTags.methodName,
})

const w3cCredentialService = agentContext.dependencyManager.resolve(W3cCredentialService)
const w3cCredentialRecord = await w3cCredentialService.storeCredential(agentContext, {
credential: w3cJsonLdCredential,
})

for (const [key, meta] of Object.entries(legacyRecord.metadata.data)) {
w3cCredentialRecord.metadata.set(key, meta)
}

const anonCredsCredentialMetadata: W3cAnonCredsCredentialMetadata = {
credentialRevocationId: anonCredsTags.anonCredsCredentialRevocationId,
linkSecretId: anonCredsTags.anonCredsLinkSecretId,
Expand Down
5 changes: 3 additions & 2 deletions packages/anoncreds/src/utils/indyIdentifiers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -262,8 +262,9 @@ export function getQualifiedDidIndyDid(identifier: string, namespace: string): s
const credentialDefinitionId = `did:indy:${namespace}:${namespaceIdentifier}/anoncreds/v0/CLAIM_DEF/${schemaSeqNo}/${tag}`
return credentialDefinitionId
} else if (isUnqualifiedRevocationRegistryId(identifier)) {
const { namespaceIdentifier, schemaSeqNo, revocationRegistryTag } = parseIndyRevocationRegistryId(identifier)
const revocationRegistryId = `did:indy:${namespace}:${namespaceIdentifier}/anoncreds/v0/REV_REG_DEF/${schemaSeqNo}/${revocationRegistryTag}`
const { namespaceIdentifier, schemaSeqNo, credentialDefinitionTag, revocationRegistryTag } =
parseIndyRevocationRegistryId(identifier)
const revocationRegistryId = `did:indy:${namespace}:${namespaceIdentifier}/anoncreds/v0/REV_REG_DEF/${schemaSeqNo}/${credentialDefinitionTag}/${revocationRegistryTag}`
return revocationRegistryId
} else if (isUnqualifiedIndyDid(identifier)) {
return `did:indy:${namespace}:${identifier}`
Expand Down
16 changes: 6 additions & 10 deletions packages/anoncreds/src/utils/w3cAnonCredsUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import type { W3cAnonCredsCredentialMetadata } from './metadata'
import type { AnonCredsCredentialInfo, AnonCredsSchema } from '../models'
import type { AnonCredsCredentialRecord } from '../repository'
import type { StoreCredentialOptions } from '../services'
import type { DefaultW3cCredentialTags } from '@credo-ts/core'
import type { DefaultW3cCredentialTags, W3cCredentialSubject } from '@credo-ts/core'

import { CredoError, W3cCredentialRecord, utils } from '@credo-ts/core'

Expand Down Expand Up @@ -163,7 +163,8 @@ export function getStoreCredentialOptions(
}

export function getW3cRecordAnonCredsTags(options: {
w3cCredentialRecord: W3cCredentialRecord
credentialSubject: W3cCredentialSubject
issuerId: string
schemaId: string
schema: Omit<AnonCredsSchema, 'attrNames'>
credentialDefinitionId: string
Expand All @@ -173,7 +174,8 @@ export function getW3cRecordAnonCredsTags(options: {
methodName: string
}) {
const {
w3cCredentialRecord,
credentialSubject,
issuerId,
schema,
schemaId,
credentialDefinitionId,
Expand All @@ -183,8 +185,6 @@ export function getW3cRecordAnonCredsTags(options: {
methodName,
} = options

const issuerId = w3cCredentialRecord.credential.issuerId

const anonCredsCredentialRecordTags: AnonCredsCredentialTags = {
anonCredsLinkSecretId: linkSecretId,
anonCredsCredentialDefinitionId: credentialDefinitionId,
Expand All @@ -206,12 +206,8 @@ export function getW3cRecordAnonCredsTags(options: {
}),
}

if (Array.isArray(w3cCredentialRecord.credential.credentialSubject)) {
throw new CredoError('Credential subject must be an object, not an array.')
}

const values = mapAttributeRawValuesToAnonCredsCredentialValues(
(w3cCredentialRecord.credential.credentialSubject.claims as AnonCredsClaimRecord) ?? {}
(credentialSubject.claims as AnonCredsClaimRecord) ?? {}
)

for (const [key, value] of Object.entries(values)) {
Expand Down

0 comments on commit edc5735

Please sign in to comment.