Skip to content

Commit

Permalink
Merge pull request #235 from Sphereon-Opensource/feature/sprind-36_jw…
Browse files Browse the repository at this point in the history
…t_service

Feature/sprind 36 jwt service
  • Loading branch information
nklomp authored Aug 22, 2024
2 parents 39ab047 + 3032883 commit 6c9bb92
Show file tree
Hide file tree
Showing 54 changed files with 1,568 additions and 1,028 deletions.
4 changes: 2 additions & 2 deletions packages/contact-manager-rest-api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
},
"dependencies": {
"@sphereon/ssi-express-support": "workspace:*",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.1-unstable.82",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.1-unstable.82",
"@sphereon/ssi-sdk-ext.key-manager": "0.24.1-next.96",
"@sphereon/ssi-sdk-ext.key-utils": "0.24.1-next.96",
"@sphereon/ssi-sdk.contact-manager": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-sdk.data-store": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/contact-manager/src/types/IContactManager.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { contextHasPlugin } from '@sphereon/ssi-sdk.agent-config'
import { IAgentContext, IPluginMethodMap } from '@veramo/core'
import {
ElectronicAddress,
Expand All @@ -21,7 +22,6 @@ import {
PartyTypeType as ContactTypeType,
PhysicalAddress,
} from '@sphereon/ssi-sdk.data-store'
import { contextHasPlugin } from '../../../agent-config/src/agentContextUtils'

export interface IContactManager extends IPluginMethodMap {
cmGetContact(args: GetContactArgs, context: RequiredContext): Promise<Contact>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro
describe('Credential Store Agent Plugin', (): void => {
const exampleVC: IVerifiableCredential = getFileAsJson('./packages/credential-store/__tests__/vc-examples/vc_driverLicense.json')

const examplePid: string = getFile('./packages/credential-store/__tests__/vc-examples/pid.sd.jwt').replace(/\r/, '').replace(/\n/, '')
let agent: ConfiguredAgent
let defaultCredential: DigitalCredential
let pidSdJwtCredential: DigitalCredential

beforeAll(async (): Promise<void> => {
await testContext.setup()
Expand All @@ -40,6 +42,15 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro
rawDocument: JSON.stringify(exampleVC),
}
defaultCredential = await agent.crsAddCredential({ credential: digitalCredential })

const sdJwtAdd: AddDigitalCredential = {
credentialRole: CredentialRole.HOLDER,
tenantId: 'test-tenant',
issuerCorrelationId: 'CN="test"',
issuerCorrelationType: CredentialCorrelationType.X509_CN,
rawDocument: examplePid,
}
pidSdJwtCredential = await agent.crsAddCredential({ credential: sdJwtAdd })
})

afterAll(testContext.tearDown)
Expand All @@ -49,6 +60,11 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro
expect(result.id).toEqual(defaultCredential.id)
})

it('should get SDJWT PID credential by id', async (): Promise<void> => {
const result = await agent.crsGetCredential({ id: pidSdJwtCredential.id })
expect(result.id).toEqual(pidSdJwtCredential.id)
})

it('should throw error when getting credential with unknown id', async (): Promise<void> => {
const itemId = 'unknownId'
await expect(agent.crsGetCredential({ id: itemId })).rejects.toThrow(`No credential found for arg: {\"id\":\"${itemId}\"}`)
Expand All @@ -64,7 +80,7 @@ export default (testContext: { getAgent: () => ConfiguredAgent; setup: () => Pro
}
const result: Array<DigitalCredential> = await agent.crsGetCredentials(args)

expect(result.length).toBe(1)
expect(result.length).toBe(2)
})

it('should get credentials by id or hash', async (): Promise<void> => {
Expand Down
1 change: 1 addition & 0 deletions packages/credential-store/__tests__/vc-examples/pid.sd.jwt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
eyJ4NWMiOlsiTUlJQ2REQ0NBaHVnQXdJQkFnSUJBakFLQmdncWhrak9QUVFEQWpDQmlERUxNQWtHQTFVRUJoTUNSRVV4RHpBTkJnTlZCQWNNQmtKbGNteHBiakVkTUJzR0ExVUVDZ3dVUW5WdVpHVnpaSEoxWTJ0bGNtVnBJRWR0WWtneEVUQVBCZ05WQkFzTUNGUWdRMU1nU1VSRk1UWXdOQVlEVlFRRERDMVRVRkpKVGtRZ1JuVnVhMlVnUlZWRVNTQlhZV3hzWlhRZ1VISnZkRzkwZVhCbElFbHpjM1ZwYm1jZ1EwRXdIaGNOTWpRd05UTXhNRGd4TXpFM1doY05NalV3TnpBMU1EZ3hNekUzV2pCc01Rc3dDUVlEVlFRR0V3SkVSVEVkTUJzR0ExVUVDZ3dVUW5WdVpHVnpaSEoxWTJ0bGNtVnBJRWR0WWtneENqQUlCZ05WQkFzTUFVa3hNakF3QmdOVkJBTU1LVk5RVWtsT1JDQkdkVzVyWlNCRlZVUkpJRmRoYkd4bGRDQlFjbTkwYjNSNWNHVWdTWE56ZFdWeU1Ga3dFd1lIS29aSXpqMENBUVlJS29aSXpqMERBUWNEUWdBRU9GQnE0WU1LZzR3NWZUaWZzeXR3QnVKZi83RTdWaFJQWGlObTUyUzNxMUVUSWdCZFh5REsza1Z4R3hnZUhQaXZMUDN1dU12UzZpREVjN3FNeG12ZHVLT0JrRENCalRBZEJnTlZIUTRFRmdRVWlQaENrTEVyRFhQTFcyL0owV1ZlZ2h5dyttSXdEQVlEVlIwVEFRSC9CQUl3QURBT0JnTlZIUThCQWY4RUJBTUNCNEF3TFFZRFZSMFJCQ1l3SklJaVpHVnRieTV3YVdRdGFYTnpkV1Z5TG1KMWJtUmxjMlJ5ZFdOclpYSmxhUzVrWlRBZkJnTlZIU01FR0RBV2dCVFVWaGpBaVRqb0RsaUVHTWwyWXIrcnU4V1F2akFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUFiZjVUemtjUXpoZldvSW95aTFWTjdkOEk5QnNGS20xTVdsdVJwaDJieUdRSWdLWWtkck5mMnhYUGpWU2JqVy9VLzVTNXZBRUM1WHhjT2FudXNPQnJvQmJVPSIsIk1JSUNlVENDQWlDZ0F3SUJBZ0lVQjVFOVFWWnRtVVljRHRDaktCL0gzVlF2NzJnd0NnWUlLb1pJemowRUF3SXdnWWd4Q3pBSkJnTlZCQVlUQWtSRk1ROHdEUVlEVlFRSERBWkNaWEpzYVc0eEhUQWJCZ05WQkFvTUZFSjFibVJsYzJSeWRXTnJaWEpsYVNCSGJXSklNUkV3RHdZRFZRUUxEQWhVSUVOVElFbEVSVEUyTURRR0ExVUVBd3d0VTFCU1NVNUVJRVoxYm10bElFVlZSRWtnVjJGc2JHVjBJRkJ5YjNSdmRIbHdaU0JKYzNOMWFXNW5JRU5CTUI0WERUSTBNRFV6TVRBMk5EZ3dPVm9YRFRNME1EVXlPVEEyTkRnd09Wb3dnWWd4Q3pBSkJnTlZCQVlUQWtSRk1ROHdEUVlEVlFRSERBWkNaWEpzYVc0eEhUQWJCZ05WQkFvTUZFSjFibVJsYzJSeWRXTnJaWEpsYVNCSGJXSklNUkV3RHdZRFZRUUxEQWhVSUVOVElFbEVSVEUyTURRR0ExVUVBd3d0VTFCU1NVNUVJRVoxYm10bElFVlZSRWtnVjJGc2JHVjBJRkJ5YjNSdmRIbHdaU0JKYzNOMWFXNW5JRU5CTUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFWUd6ZHdGRG5jNytLbjVpYkF2Q09NOGtlNzdWUXhxZk1jd1pMOElhSUErV0NST2NDZm1ZL2dpSDkycU1ydTVwL2t5T2l2RTBSQy9JYmRNT052RG9VeWFObU1HUXdIUVlEVlIwT0JCWUVGTlJXR01DSk9PZ09XSVFZeVhaaXY2dTd4WkMrTUI4R0ExVWRJd1FZTUJhQUZOUldHTUNKT09nT1dJUVl5WFppdjZ1N3haQytNQklHQTFVZEV3RUIvd1FJTUFZQkFmOENBUUF3RGdZRFZSMFBBUUgvQkFRREFnR0dNQW9HQ0NxR1NNNDlCQU1DQTBjQU1FUUNJR0VtN3drWktIdC9hdGI0TWRGblhXNnlybndNVVQydTEzNmdkdGwxMFk2aEFpQnVURnF2Vll0aDFyYnh6Q1AweFdaSG1RSzlrVnl4bjhHUGZYMjdFSXp6c3c9PSJdLCJraWQiOiJNSUdVTUlHT3BJR0xNSUdJTVFzd0NRWURWUVFHRXdKRVJURVBNQTBHQTFVRUJ3d0dRbVZ5YkdsdU1SMHdHd1lEVlFRS0RCUkNkVzVrWlhOa2NuVmphMlZ5WldrZ1IyMWlTREVSTUE4R0ExVUVDd3dJVkNCRFV5QkpSRVV4TmpBMEJnTlZCQU1NTFZOUVVrbE9SQ0JHZFc1clpTQkZWVVJKSUZkaGJHeGxkQ0JRY205MGIzUjVjR1VnU1hOemRXbHVaeUJEUVFJQkFnPT0iLCJ0eXAiOiJ2YytzZC1qd3QiLCJhbGciOiJFUzI1NiJ9.eyJwbGFjZV9vZl9iaXJ0aCI6eyJfc2QiOlsiWi1lLVdDaXhHcWZZbko2blVEYlpVSlFQNzM2b25GajhUdG5uMHVEVFBfNCJdfSwiX3NkIjpbIjc4QTFpS2hacUZvUHVNNEt2dXYxd2R4RGJrVVhSY0w4dUNZRVRhd1hlZUEiLCJMdl9sTlBuaTVaYWxZMHVpRUZ6ZkJIeGVUb05sMlFFSGJ2X2xGeTFiQ3JzIiwiU0VjQldhc2VtcmlYNkE5VTdaVXVyU24wMEZYSDZ1YXNneW5NTG5xY2lTbyIsIlRoUE80LTRJUGtRZzFZNEpjSkE2ZERxTGl0VlpnS3doNFhyUTdNMXV6VzQiLCJkSVRoc1Utc01mWWJabDlGVy1RUGN6cjRDS3Vmcmk2S0hmb2xpVFNPV2lRIiwicVlVVkJ2bUstSzlsaTNjV1FPQ05oTTFJRWRRVF9qQkVacms2VmV2aTBzZyIsInpzYm1mY09xYU1ZMlM5UGNBZ3BXRzVYNnRKSEg3QVZVdjhWTjZNT0lQT3MiXSwiYWRkcmVzcyI6eyJfc2QiOlsiNjFlOFhoOWROVVFTNDZUTC01aGUzNUJBVjY5c2NVX01NOHhCSGo3WkhUSSIsIkw3UFVrVFhvRlBtUlBJcno0bzF3TEpKYmswRUFmR29MUmtpWll5Q25nN2siLCJfSjltYjZIRktYQkN6QzlHM2RHTXM3RGYtRmprYlg5aFNhdEJpTkpLcnRjIiwiaUo0UnM5M2kxWEdlX1B1TWRiZDU2UzdraVg2aHZ5enZWLWxsMzhXUTMwayJdfSwiaXNzdWluZ19jb3VudHJ5IjoiREUiLCJ2Y3QiOiJ1cm46ZXUuZXVyb3BhLmVjLmV1ZGk6cGlkOjEiLCJpc3N1aW5nX2F1dGhvcml0eSI6IkRFIiwiX3NkX2FsZyI6InNoYS0yNTYiLCJpc3MiOiJodHRwczovL2RlbW8ucGlkLWlzc3Vlci5idW5kZXNkcnVja2VyZWkuZGUvYyIsImNuZiI6eyJqd2siOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsImtpZCI6ImRaZnFiVkZ5MnBpbi1IN2xhbG5NcE9uWjVXWU9KaWdNeHFEcng5N3U3d1kiLCJ4IjoiOXcwVm56bGpNVGh2YW9YUkVMMzNWMnpHcXdDSVRlY1NROWN3VlNYQlVKWSIsInkiOiJqTzZrOFFyUmlpRVNSYTgtbG01Q2JFTTBkTkU2a25wWVo2NWh1cWd4SE9nIiwiYWxnIjoiRVMyNTYifX0sImV4cCI6MTcyNDk3MDA5NiwiaWF0IjoxNzIzNzYwNDk2LCJhZ2VfZXF1YWxfb3Jfb3ZlciI6eyJfc2QiOlsiMS1iMGR1d29kT1pYVmVPc3JreV9xRTNrZFd1XzBNSmJaUFlEakFrREZYMCIsIktKUTdFdktkczhzeFVkM256SjZVTEVCVEZUTERFdEpKNEk0WDlrYWNMUDgiLCJLaFlXQ20wSjF6ZEtUaXBlU2lVUkNIOFprOU4ybzlNSUk3aTJha3V4ZTNzIiwibWpTbkp4dVAxSkswczFCUTJkR2FfbDgwQlZxT1AwME9jUG1hcUdCZWF5QSIsIncwcjJOUXlHeEs0dFNlbnR2SkZTZGhOQTUxYmU2eDB6d3BTSm9iU1E0RWsiLCJ4UktVeE52TmpzTUlvaHpJUWpiUWtDMEUybzFGMEZ2M05CbkRjTmZSV1BjIl19fQ.Fqer0HiQ-CvafR81RTZ8jNGfDre8-v1bh8gdCf0MwAUFbutyH89yJQ0CVjZIFxvYQ5RIrh1YPhWyQ5JRXwb_dA~WyJocDVfVXRZZWhPQzZyNlJPNFR4X3pBIiwiZmFtaWx5X25hbWUiLCJNVVNURVJNQU5OIl0~WyJpLVFhWDNFZWVrSUNuM0VMUG5hQ2lBIiwiZ2l2ZW5fbmFtZSIsIkVSSUtBIl0~WyJnNGdUaTc0a2F5Y2l3T1EzdUVZOFlRIiwiYmlydGhkYXRlIiwiMTk4NC0wMS0yNiJd~WyJZbi1CdTYxWWp6ZUtqOW9JeTFoVGFnIiwiYWdlX2JpcnRoX3llYXIiLDE5ODRd~WyI0MlY1V0ZYWlBpT1RyZU5kTVFXRDJ3IiwiYWdlX2luX3llYXJzIiw0MF0~WyI2WjM4ZWhPenBGazRLUkJqSGtYbkFRIiwiYmlydGhfZmFtaWx5X25hbWUiLCJHQUJMRVIiXQ~WyJzX2s0cWVCSlFtdFdYMlZ3UlpYUDJRIiwibmF0aW9uYWxpdGllcyIsWyJERSJdXQ~WyJaYkR0S1ozVjBiYTdwMHZLWjdodWp3IiwiMTIiLHRydWVd~WyJUZFozczJnTVNCaHp4b0ZCR2pyNjZnIiwiMTQiLHRydWVd~WyJBUkJPbnNvSEw1d2NnMUVab2Nfc053IiwiMTYiLHRydWVd~WyJIMVJFTUpmZkZIVWpsV3VJV3RjTlBRIiwiMTgiLHRydWVd~WyJ6WFVUNE55OGNvRkJZVUJnYmFKSG5BIiwiMjEiLHRydWVd~WyJScTB4VUd0WTRqMGIxN0UzWXdSNzJRIiwiNjUiLGZhbHNlXQ~WyJ5ZC1uMDdDNjhQYjBEOTBNRjBfaTBRIiwibG9jYWxpdHkiLCJCRVJMSU4iXQ~WyJaZ00wMk5YWHpSczVlOWZfc3Y2RHZBIiwibG9jYWxpdHkiLCJLw5ZMTiJd~WyJSMXlyZ0JJdTRQNjVFOTF4OU5PeEJnIiwiY291bnRyeSIsIkRFIl0~WyJxeHJPVncxUWl2VC1oQjlTZjNIRVR3IiwicG9zdGFsX2NvZGUiLCI1MTE0NyJd~WyJPTklYMjZUaTNUb2N0Y0R3SjZYSm53Iiwic3RyZWV0X2FkZHJlc3MiLCJIRUlERVNUUkFTU0UgMTciXQ~
26 changes: 19 additions & 7 deletions packages/credential-store/src/agent/CredentialStore.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { IAgentPlugin } from '@veramo/core'
import crypto from 'crypto'
import {
AddCredentialArgs,
credentialIdOrHashFilter,
Expand Down Expand Up @@ -58,7 +59,7 @@ export class CredentialStore implements IAgentPlugin {

/** {@inheritDoc ICRManager.crmAddCredential} */
private async crsAddCredential(args: AddCredentialArgs): Promise<DigitalCredential> {
return await this.store.addCredential(args.credential)
return await this.store.addCredential({ ...args.credential, opts: { ...args.opts, hasher: args.opts?.hasher ?? this.generateDigest } })
}

/** {@inheritDoc ICRManager.updateCredentialState} */
Expand Down Expand Up @@ -217,6 +218,13 @@ export class CredentialStore implements IAgentPlugin {
return credentialsByClaims.length // FIXME ?
}

private secureParse<Type>(original: string): Type {
if (original.includes('~')) {
return original as Type
}
return JSON.parse(original)
}

private toUniqueCredentials(credentials: Array<DigitalCredential>): Array<UniqueDigitalCredential> {
return Object.values(
credentials.reduce(
Expand All @@ -227,21 +235,21 @@ export class CredentialStore implements IAgentPlugin {
}
switch (credential.documentType) {
case DocumentType.VC:
uniqueCredential.originalVerifiableCredential = JSON.parse(credential.rawDocument)
uniqueCredential.uniformVerifiableCredential = JSON.parse(credential.uniformDocument)
uniqueCredential.originalVerifiableCredential = this.secureParse(credential.rawDocument)
uniqueCredential.uniformVerifiableCredential = this.secureParse(credential.uniformDocument)
uniqueCredential.id = uniqueCredential.uniformVerifiableCredential?.id
break
case DocumentType.VP:
uniqueCredential.originalVerifiablePresentation = JSON.parse(credential.rawDocument)
uniqueCredential.uniformVerifiablePresentation = JSON.parse(credential.uniformDocument)
uniqueCredential.originalVerifiablePresentation = this.secureParse(credential.rawDocument)
uniqueCredential.uniformVerifiablePresentation = this.secureParse(credential.uniformDocument)
uniqueCredential.id = uniqueCredential.uniformVerifiablePresentation?.id
break
case DocumentType.P:
uniqueCredential.originalPresentation = JSON.parse(credential.rawDocument)
uniqueCredential.originalPresentation = this.secureParse(credential.rawDocument)
uniqueCredential.id = uniqueCredential.originalPresentation?.id
break
case DocumentType.C:
uniqueCredential.originalCredential = JSON.parse(credential.rawDocument)
uniqueCredential.originalCredential = this.secureParse(credential.rawDocument)
uniqueCredential.id = uniqueCredential.originalCredential?.id
break
// TODO CBOR support
Expand All @@ -253,4 +261,8 @@ export class CredentialStore implements IAgentPlugin {
),
)
}

private generateDigest = (data: string, algorithm: string): Uint8Array => {
return new Uint8Array(crypto.createHash(algorithm).update(data).digest())
}
}
10 changes: 9 additions & 1 deletion packages/credential-store/src/types/ICredentialStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,14 @@ import {
NonPersistedDigitalCredential,
UpdateCredentialStateArgs,
} from '@sphereon/ssi-sdk.data-store'
import { ICredential, IPresentation, IVerifiableCredential, OriginalVerifiableCredential, OriginalVerifiablePresentation } from '@sphereon/ssi-types'
import {
Hasher,
ICredential,
IPresentation,
IVerifiableCredential,
OriginalVerifiableCredential,
OriginalVerifiablePresentation,
} from '@sphereon/ssi-types'
import { IAgentContext, IPluginMethodMap } from '@veramo/core'
import { FindClaimsArgs } from './claims'

Expand Down Expand Up @@ -113,6 +120,7 @@ export type AddDigitalCredential = Omit<

export type AddCredentialArgs = {
credential: AddDigitalCredential
opts?: { maxTimeSkewInMS?: number; hasher?: Hasher }
}

export interface UniqueDigitalCredential {
Expand Down
4 changes: 2 additions & 2 deletions packages/data-store/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
},
"dependencies": {
"@sphereon/pex": "^4.0.1",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-unstable.82",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-unstable.82",
"@sphereon/ssi-sdk-ext.did-utils": "0.24.1-next.96",
"@sphereon/ssi-sdk-ext.identifier-resolution": "0.24.1-next.96",
"@sphereon/ssi-sdk.agent-config": "workspace:*",
"@sphereon/ssi-sdk.core": "workspace:*",
"@sphereon/ssi-types": "workspace:*",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export class DigitalCredentialStore extends AbstractDigitalCredentialStore {
}

getCredentials = async (args?: GetCredentialsArgs): Promise<GetCredentialsResponse> => {
const { filter = {}, offset, limit, order = 'id.asc' } = args ?? {}
const { filter = {}, offset, limit, order = 'createdAt.asc' } = args ?? {}
const sortOptions: FindOptionsOrder<DigitalCredentialEntity> =
order && typeof order === 'string'
? parseAndValidateOrderOptions<DigitalCredentialEntity>(order)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm'
import { CredentialCorrelationType, CredentialDocumentFormat, CredentialRole, CredentialStateType, DocumentType } from '../../types'
import {
CredentialCorrelationType,
CredentialDocumentFormat,
CredentialRole,
CredentialStateType,
DigitalCredential,
DocumentType,
} from '../../types'
import { typeormDate, typeOrmDateTime } from '@sphereon/ssi-sdk.agent-config'

@Entity('DigitalCredential')
export class DigitalCredentialEntity extends BaseEntity {
export class DigitalCredentialEntity extends BaseEntity implements DigitalCredential {
@PrimaryGeneratedColumn('uuid')
id!: string

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class CreateDigitalCredential1708525189001 implements MigrationInterface
await queryRunner.query(`CREATE TYPE "digital_document_type" AS ENUM('VC', 'VP', 'C', 'P')`)
await queryRunner.query(`CREATE TYPE "digital_credential_document_format" AS ENUM('JSON_LD', 'JWT', 'SD_JWT', 'MDOC')`)
await queryRunner.query(`CREATE TYPE "digital_credential_credential_role" AS ENUM('ISSUER', 'VERIFIER', 'HOLDER')`)
await queryRunner.query(`CREATE TYPE "digital_credential_correlation_type" AS ENUM('DID')`)
await queryRunner.query(`CREATE TYPE "digital_credential_correlation_type" AS ENUM('DID', 'URL', 'X509_CN')`)
await queryRunner.query(`CREATE TYPE "digital_credential_state_type" AS ENUM('REVOKED', 'VERIFIED', 'EXPIRED')`)

await queryRunner.query(`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ export class CreateDigitalCredential1708525189002 implements MigrationInterface
"uniform_document" text NOT NULL,
"credential_id" text,
"hash" text NOT NULL UNIQUE,
"issuer_correlation_type" varchar CHECK( "issuer_correlation_type" IN ('DID') ) NOT NULL,
"subject_correlation_type" varchar CHECK( "subject_correlation_type" IN ('DID') ),
"issuer_correlation_type" varchar CHECK( "issuer_correlation_type" IN ('DID', 'URL', 'X509_CN') ) NOT NULL,
"subject_correlation_type" varchar CHECK( "subject_correlation_type" IN ('DID', 'URL', 'X509_CN') ),
"issuer_correlation_id" text NOT NULL,
"subject_correlation_id" text,
"verified_state" varchar CHECK( "verified_state" IN ('REVOKED', 'VERIFIED', 'EXPIRED') ),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,40 @@ export enum CredentialDocumentFormat {
MDOC = 'MDOC',
}

export namespace CredentialDocumentFormat {
export function fromSpecValue(credentialFormat: string) {
const format = credentialFormat.toLowerCase()
if (format.includes('sd')) {
return CredentialDocumentFormat.SD_JWT
} else if (format.includes('ldp')) {
return CredentialDocumentFormat.JSON_LD
} else if (format.includes('mso') || credentialFormat.includes('mdoc')) {
return CredentialDocumentFormat.MDOC
} else if (format.includes('jwt_')) {
return CredentialDocumentFormat.JWT
} else {
throw Error(`Could not map format ${format} to known format`)
}
}

export function toSpecValue(documentFormat: CredentialDocumentFormat, documentType: DocumentType) {
switch (documentFormat) {
case CredentialDocumentFormat.SD_JWT:
return 'vc+sd-jwt'
case CredentialDocumentFormat.MDOC:
return 'mso_mdoc'
case CredentialDocumentFormat.JSON_LD:
return documentType === DocumentType.C || documentType === DocumentType.VC ? 'ldp_vc' : 'ldp_vp'
case CredentialDocumentFormat.JWT:
return documentType === DocumentType.C || documentType === DocumentType.VC ? 'jwt_vc_json' : 'jwt_vp_json'
}
}
}

export enum CredentialCorrelationType {
DID = 'DID',
X509_CN = 'X509_CN',
URL = 'URL',
}

export enum CredentialRole {
Expand Down
Loading

0 comments on commit 6c9bb92

Please sign in to comment.