Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: normalizeCredential overwrites "evidence" when "vc" is missing #86

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion src/__tests__/converters.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,27 @@ describe('credential', () => {
expect(result).toMatchObject({ evidence: 'foo', vc: { evidence: 'foo' } })
})

it('does not insert evidence when using credentialSubject instead of vc object', () => {
const result = normalizeCredential({
credentialSubject: {
id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
},
})
expect(result).not.toHaveProperty('evidence')
})

it('does not overwrite evidence when passed at top-level', () => {
const result = normalizeCredential({
credentialSubject: {
id: 'did:example:ebfeb1f712ebc6f1c276e12ec21',
},
evidence: {
foo: 'bar',
},
})
expect(result.evidence).toMatchObject({ foo: 'bar' })
})

it('uses credentialStatus from vc', () => {
const result = normalizeCredential({ vc: { credentialStatus: 'foo' } })
expect(result).toMatchObject({ credentialStatus: 'foo' })
Expand Down Expand Up @@ -957,7 +978,7 @@ describe('credential', () => {
})
})

describe('other fields W3C fields', () => {
describe('other W3C fields', () => {
it('maps evidence to vc', () => {
const result = transformCredentialInput({ evidence: 'foo' })
expect(result).toMatchObject({ vc: { evidence: 'foo' } })
Expand Down
34 changes: 17 additions & 17 deletions src/converters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ import {
} from './types'
import { decodeJWT } from 'did-jwt'

/*
* Additional W3C VC fields:
* These are defined as optional top-level properties in the W3C spec but are not mapped to top-level JWT names,
* so they should be moved inside the "vc" object when transforming to a JWT.
* Conversely, they should be moved out of the "vc" object when transforming from a JWT to W3C JSON.
*/
const additionalPropNames = ['evidence', 'termsOfUse', 'refreshService', 'credentialSchema', 'credentialStatus']

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function asArray(arg: any | any[]): any[] {
return Array.isArray(arg) ? arg : [arg]
Expand Down Expand Up @@ -111,19 +119,15 @@ function normalizeJwtCredentialPayload(
delete result.vc?.type
}

result.evidence = input.vc?.evidence
if (removeOriginalFields) {
delete result.vc?.evidence
}

result.credentialStatus = input.vc?.credentialStatus
if (removeOriginalFields) {
delete result.vc?.credentialStatus
}

result.termsOfUse = input.vc?.termsOfUse
if (removeOriginalFields) {
delete result.vc?.termsOfUse
for (const prop of additionalPropNames) {
if (input.vc && input.vc[prop]) {
if (!result[prop]) {
result[prop] = input.vc[prop]
}
if (removeOriginalFields) {
delete result.vc[prop]
}
}
}

const contextArray: string[] = [
Expand Down Expand Up @@ -313,10 +317,6 @@ export function transformCredentialInput(
delete result.credentialSubject
}

// additional W3C VC fields to map:
// these may exist at the top-level of a W3C credential, but should be moved inside vc when transforming to JWT
const additionalPropNames = ['evidence', 'termsOfUse', 'refreshService', 'credentialSchema', 'credentialStatus']

for (const prop of additionalPropNames) {
if (input[prop]) {
if (!result.vc[prop]) {
Expand Down