Skip to content

Commit

Permalink
Merge pull request #155 from Sphereon-Opensource/develop
Browse files Browse the repository at this point in the history
new release
  • Loading branch information
nklomp authored Jan 19, 2024
2 parents afad00b + db354a9 commit fceaea3
Show file tree
Hide file tree
Showing 6 changed files with 4,017 additions and 3,832 deletions.
6 changes: 6 additions & 0 deletions packages/data-store/src/contact/ContactStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ConnectionEntity } from '../entities/contact/ConnectionEntity'
import { BaseConfigEntity } from '../entities/contact/BaseConfigEntity'
import { PartyRelationshipEntity } from '../entities/contact/PartyRelationshipEntity'
import { PartyTypeEntity } from '../entities/contact/PartyTypeEntity'
import { BaseContactEntity } from '../entities/contact/BaseContactEntity'
import {
identityEntityFrom,
identityFrom,
Expand Down Expand Up @@ -159,6 +160,11 @@ export class ContactStore extends AbstractContactStore {
await partyRepository
.delete({ id: partyId })
.catch((error) => Promise.reject(Error(`Unable to remove party with id: ${partyId}. ${error}`)))

const partyContactRepository: Repository<BaseContactEntity> = (await this.dbConnection).getRepository(BaseContactEntity)
await partyContactRepository
.delete({ id: party.contact.id })
.catch((error) => Promise.reject(Error(`Unable to remove party contact with id: ${party.contact.id}. ${error}`)))
}
})
.catch((error) => Promise.reject(Error(`Unable to remove party with id: ${partyId}. ${error}`)))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export class CreateContacts1690925872693 implements MigrationInterface {

// migrate existing data
await queryRunner.query(
`INSERT INTO "BaseConfig"("id", "identifier", "redirect_url", "session_id", "client_id", "client_secret", "scopes", "issuer", "dangerously_allow_insecure_http_requests", "client_auth_method", "type", "connection_id") SELECT "id", "identifier", "redirect_url", "session_id", "client_id", "client_secret", "scopes", "issuer", "dangerously_allow_insecure_http_requests", "client_auth_method", "type", "connection_id" FROM "BaseConfigEntity"`
`INSERT INTO "BaseConfig"("id", "identifier", "redirect_url", "session_id", "client_id", "client_secret", "scopes", "issuer", "dangerously_allow_insecure_http_requests", "client_auth_method", "type", "connection_id") SELECT "id", "identifier", "redirect_url", "session_id", "client_id", "client_secret", "scopes", "issuer", "dangerously_allow_insecure_http_requests", "client_auth_method", "type", "connectionId" FROM "BaseConfigEntity"`
)
await queryRunner.query(`DROP TABLE "BaseConfigEntity"`)
await queryRunner.query(
Expand Down
183 changes: 183 additions & 0 deletions packages/ssi-types/__tests__/encoding.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { createHash } from 'crypto'
import * as fs from 'fs'
import {
CredentialMapper,
decodeSdJwtVc,
decodeSdJwtVcAsync,
IVerifiableCredential,
IVerifiablePresentation,
JwtDecodedVerifiableCredential,
Expand Down Expand Up @@ -103,4 +106,184 @@ describe('Encoding - Decoding', () => {
const uniform = CredentialMapper.jwtDecodedCredentialToUniformCredential(decodedJwtVc)
expect(uniform.credentialSubject).toBeDefined()
})

it('decode sd-jwt-vc', () => {
const decoded = decodeSdJwtVc(
'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6Ii1kTUd4OGZhUnpOQm91a2EwU0R6V2JkS3JYckw1TFVmUlNQTHN2Q2xPMFkifQ.TQQLqc4ZzoKjQfAghAzC_4aaU3KCS8YqzxAJtzT124guzkv9XSHtPN8d3z181_v-ca2ATXjTRoRciozitE6wBA',
(data, algorithm) => createHash(algorithm).update(data).digest()
)

expect(decoded).toEqual({
compactSdJwtVc:
'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6Ii1kTUd4OGZhUnpOQm91a2EwU0R6V2JkS3JYckw1TFVmUlNQTHN2Q2xPMFkifQ.TQQLqc4ZzoKjQfAghAzC_4aaU3KCS8YqzxAJtzT124guzkv9XSHtPN8d3z181_v-ca2ATXjTRoRciozitE6wBA',
decodedPayload: {
address: {
country: 'US',
locality: 'Anytown',
street_address: '123 Main St',
},
cnf: {
jwk: {
crv: 'Ed25519',
kty: 'OKP',
x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo',
},
},
email: '[email protected]',
family_name: 'Doe',
given_name: 'John',
iat: 1698151532,
is_over_21: true,
is_over_65: true,
iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW',
phone_number: '+1-202-555-0101',
vct: 'IdentityCredential',
},
disclosures: [
{
decoded: ['salt', 'is_over_65', true],
digest: 'sN_ge0pHXF6qmsYnX1A9SdwJ8ch8aENkxbODsT74YwI',
encoded: 'WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0',
},
{
decoded: ['salt', 'is_over_21', true],
digest: 'R1zTUvOYHgcepj0jHypGHz9EHttVKft0yswbc9ETPbU',
encoded: 'WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0',
},
{
decoded: ['salt', 'email', '[email protected]'],
digest: 'psauKUNWEi09nu3Cl89xKXgmpWENZl5uy1N1nyn_jMk',
encoded: 'WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0',
},
{
decoded: ['salt', 'country', 'US'],
digest: 'om5ZztZHB-Gd00LG21CV_xM4FaENSoiaOXnTAJNczB4',
encoded: 'WyJzYWx0IiwiY291bnRyeSIsIlVTIl0',
},
{
decoded: ['salt', 'given_name', 'John'],
digest: 'eDqQpdTXJXbWhf-EsI7zw5X6OvYmFN-UZQQMesXwKPw',
encoded: 'WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ',
},
],
signedPayload: {
_sd: [
'1Cur2k2A2oIB5CshSIf_A_Kg-l26u_qKuWQ79P0Vdas',
'R1zTUvOYHgcepj0jHypGHz9EHttVKft0yswbc9ETPbU',
'eDqQpdTXJXbWhf-EsI7zw5X6OvYmFN-UZQQMesXwKPw',
'pdDk2_XAKHo7gOAfwF1b7OdCUVTit2kJHaxSECQ9xfc',
'psauKUNWEi09nu3Cl89xKXgmpWENZl5uy1N1nyn_jMk',
'sN_ge0pHXF6qmsYnX1A9SdwJ8ch8aENkxbODsT74YwI',
],
_sd_alg: 'sha-256',
address: {
_sd: ['NJnmct0BqBME1JfBlC6jRQVRuevpEONiYw7A7MHuJyQ', 'om5ZztZHB-Gd00LG21CV_xM4FaENSoiaOXnTAJNczB4'],
locality: 'Anytown',
street_address: '123 Main St',
},
cnf: {
jwk: {
crv: 'Ed25519',
kty: 'OKP',
x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo',
},
},
family_name: 'Doe',
iat: 1698151532,
iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW',
phone_number: '+1-202-555-0101',
vct: 'IdentityCredential',
},
})
})

it('decode sd-jwt-vc async', async () => {
const decoded = await decodeSdJwtVcAsync(
'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6Ii1kTUd4OGZhUnpOQm91a2EwU0R6V2JkS3JYckw1TFVmUlNQTHN2Q2xPMFkifQ.TQQLqc4ZzoKjQfAghAzC_4aaU3KCS8YqzxAJtzT124guzkv9XSHtPN8d3z181_v-ca2ATXjTRoRciozitE6wBA',
(data, algorithm) => Promise.resolve(createHash(algorithm).update(data).digest())
)

expect(decoded).toEqual({
compactSdJwtVc:
'eyJhbGciOiJFZERTQSIsInR5cCI6InZjK3NkLWp3dCIsImtpZCI6IiN6Nk1rdHF0WE5HOENEVVk5UHJydG9TdEZ6ZUNuaHBNbWd4WUwxZ2lrY1czQnp2TlcifQ.eyJ2Y3QiOiJJZGVudGl0eUNyZWRlbnRpYWwiLCJmYW1pbHlfbmFtZSI6IkRvZSIsInBob25lX251bWJlciI6IisxLTIwMi01NTUtMDEwMSIsImFkZHJlc3MiOnsic3RyZWV0X2FkZHJlc3MiOiIxMjMgTWFpbiBTdCIsImxvY2FsaXR5IjoiQW55dG93biIsIl9zZCI6WyJOSm5tY3QwQnFCTUUxSmZCbEM2alJRVlJ1ZXZwRU9OaVl3N0E3TUh1SnlRIiwib201Wnp0WkhCLUdkMDBMRzIxQ1ZfeE00RmFFTlNvaWFPWG5UQUpOY3pCNCJdfSwiY25mIjp7Imp3ayI6eyJrdHkiOiJPS1AiLCJjcnYiOiJFZDI1NTE5IiwieCI6Im9FTlZzeE9VaUg1NFg4d0pMYVZraWNDUmswMHdCSVE0c1JnYms1NE44TW8ifX0sImlzcyI6ImRpZDprZXk6ejZNa3RxdFhORzhDRFVZOVBycnRvU3RGemVDbmhwTW1neFlMMWdpa2NXM0J6dk5XIiwiaWF0IjoxNjk4MTUxNTMyLCJfc2RfYWxnIjoic2hhLTI1NiIsIl9zZCI6WyIxQ3VyMmsyQTJvSUI1Q3NoU0lmX0FfS2ctbDI2dV9xS3VXUTc5UDBWZGFzIiwiUjF6VFV2T1lIZ2NlcGowakh5cEdIejlFSHR0VktmdDB5c3diYzlFVFBiVSIsImVEcVFwZFRYSlhiV2hmLUVzSTd6dzVYNk92WW1GTi1VWlFRTWVzWHdLUHciLCJwZERrMl9YQUtIbzdnT0Fmd0YxYjdPZENVVlRpdDJrSkhheFNFQ1E5eGZjIiwicHNhdUtVTldFaTA5bnUzQ2w4OXhLWGdtcFdFTlpsNXV5MU4xbnluX2pNayIsInNOX2dlMHBIWEY2cW1zWW5YMUE5U2R3SjhjaDhhRU5reGJPRHNUNzRZd0kiXX0.coOK8NzJmEWz4qx-qRhjo-RK7aejrSkQM9La9Cw3eWmzcja9DXrkBoQZKbIJtNoSzSPLjwK2V71W78z0miZsDQ~WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0~WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0~WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0~WyJzYWx0IiwiY291bnRyeSIsIlVTIl0~WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ~eyJhbGciOiJFZERTQSIsInR5cCI6ImtiK2p3dCJ9.eyJpYXQiOjE2OTgxNTE1MzIsIm5vbmNlIjoic2FsdCIsImF1ZCI6ImRpZDprZXk6elVDNzRWRXFxaEVIUWNndjR6YWdTUGtxRkp4dU5XdW9CUEtqSnVIRVRFVWVITG9TcVd0OTJ2aVNzbWFXank4MnkiLCJfc2RfaGFzaCI6Ii1kTUd4OGZhUnpOQm91a2EwU0R6V2JkS3JYckw1TFVmUlNQTHN2Q2xPMFkifQ.TQQLqc4ZzoKjQfAghAzC_4aaU3KCS8YqzxAJtzT124guzkv9XSHtPN8d3z181_v-ca2ATXjTRoRciozitE6wBA',
decodedPayload: {
address: {
country: 'US',
locality: 'Anytown',
street_address: '123 Main St',
},
cnf: {
jwk: {
crv: 'Ed25519',
kty: 'OKP',
x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo',
},
},
email: '[email protected]',
family_name: 'Doe',
given_name: 'John',
iat: 1698151532,
is_over_21: true,
is_over_65: true,
iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW',
phone_number: '+1-202-555-0101',
vct: 'IdentityCredential',
},
disclosures: [
{
decoded: ['salt', 'is_over_65', true],
digest: 'sN_ge0pHXF6qmsYnX1A9SdwJ8ch8aENkxbODsT74YwI',
encoded: 'WyJzYWx0IiwiaXNfb3Zlcl82NSIsdHJ1ZV0',
},
{
decoded: ['salt', 'is_over_21', true],
digest: 'R1zTUvOYHgcepj0jHypGHz9EHttVKft0yswbc9ETPbU',
encoded: 'WyJzYWx0IiwiaXNfb3Zlcl8yMSIsdHJ1ZV0',
},
{
decoded: ['salt', 'email', '[email protected]'],
digest: 'psauKUNWEi09nu3Cl89xKXgmpWENZl5uy1N1nyn_jMk',
encoded: 'WyJzYWx0IiwiZW1haWwiLCJqb2huZG9lQGV4YW1wbGUuY29tIl0',
},
{
decoded: ['salt', 'country', 'US'],
digest: 'om5ZztZHB-Gd00LG21CV_xM4FaENSoiaOXnTAJNczB4',
encoded: 'WyJzYWx0IiwiY291bnRyeSIsIlVTIl0',
},
{
decoded: ['salt', 'given_name', 'John'],
digest: 'eDqQpdTXJXbWhf-EsI7zw5X6OvYmFN-UZQQMesXwKPw',
encoded: 'WyJzYWx0IiwiZ2l2ZW5fbmFtZSIsIkpvaG4iXQ',
},
],
signedPayload: {
_sd: [
'1Cur2k2A2oIB5CshSIf_A_Kg-l26u_qKuWQ79P0Vdas',
'R1zTUvOYHgcepj0jHypGHz9EHttVKft0yswbc9ETPbU',
'eDqQpdTXJXbWhf-EsI7zw5X6OvYmFN-UZQQMesXwKPw',
'pdDk2_XAKHo7gOAfwF1b7OdCUVTit2kJHaxSECQ9xfc',
'psauKUNWEi09nu3Cl89xKXgmpWENZl5uy1N1nyn_jMk',
'sN_ge0pHXF6qmsYnX1A9SdwJ8ch8aENkxbODsT74YwI',
],
_sd_alg: 'sha-256',
address: {
_sd: ['NJnmct0BqBME1JfBlC6jRQVRuevpEONiYw7A7MHuJyQ', 'om5ZztZHB-Gd00LG21CV_xM4FaENSoiaOXnTAJNczB4'],
locality: 'Anytown',
street_address: '123 Main St',
},
cnf: {
jwk: {
crv: 'Ed25519',
kty: 'OKP',
x: 'oENVsxOUiH54X8wJLaVkicCRk00wBIQ4sRgbk54N8Mo',
},
},
family_name: 'Doe',
iat: 1698151532,
iss: 'did:key:z6MktqtXNG8CDUY9PrrtoStFzeCnhpMmgxYL1gikcW3BzvNW',
phone_number: '+1-202-555-0101',
vct: 'IdentityCredential',
},
})
})
})
2 changes: 1 addition & 1 deletion packages/ssi-types/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"build:clean": "tsc --build --clean && tsc --build"
},
"dependencies": {
"@sd-jwt/core": "0.1.2-alpha.0",
"@sd-jwt/decode": "^0.2.0",
"jwt-decode": "^3.1.2"
},
"devDependencies": {
Expand Down
68 changes: 26 additions & 42 deletions packages/ssi-types/src/types/sd-jwt-vc.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { OriginalType, WrappedVerifiableCredential, WrappedVerifiablePresentation } from './vc'
import { SdJwtVc } from '@sd-jwt/core'
import { swapClaims } from '@sd-jwt/core/build/sdJwt/swapClaim'
import { decodeSdJwtVc as _decodeSdJwtVc } from '@sd-jwt/decode'

type JsonValue = string | number | boolean | { [x: string]: JsonValue | undefined } | Array<JsonValue>

type SdJwtJsonValue =
Expand Down Expand Up @@ -189,27 +189,20 @@ export type AsyncHasher = (data: string, alg: string) => Promise<Uint8Array>
* this method hides the actual implementation of SD-JWT (which is currently based on @sd-jwt/core)
*/
export function decodeSdJwtVc(compactSdJwtVc: CompactSdJwtVc, hasher: Hasher): SdJwtDecodedVerifiableCredential {
const sdJwtVc = SdJwtVc.fromCompact(compactSdJwtVc)

// Default (should be handled by the sd-jwt library)
let sdAlg = 'sha-256'
try {
sdAlg = sdJwtVc.getClaimInPayload('_sd_alg')
} catch {
/* no-op */
}

const disclosuresWithDigests = sdJwtVc.disclosures?.map((d) => d.withCalculateDigest((data: string) => hasher(data, sdAlg))) ?? []
const { signedPayload, decodedPayload, disclosures } = _decodeSdJwtVc(compactSdJwtVc, hasher)

return {
compactSdJwtVc: compactSdJwtVc,
decodedPayload: swapClaims(sdJwtVc.payload, disclosuresWithDigests) as SdJwtDecodedVerifiableCredentialPayload,
disclosures: disclosuresWithDigests.map((d) => ({
decoded: d.decoded as SdJwtDecodedDisclosure,
digest: d.digest,
encoded: d.encoded,
})),
signedPayload: sdJwtVc.payload as SdJwtDecodedVerifiableCredentialPayload,
compactSdJwtVc,
decodedPayload: decodedPayload as SdJwtDecodedVerifiableCredentialPayload,
disclosures: disclosures.map((d) => {
const decoded = d.key ? [d.salt, d.key, d.value] : [d.salt, d.value]
return {
decoded: decoded as SdJwtDecodedDisclosure,
digest: d.digest,
encoded: d.encoded,
} satisfies SdJwtDisclosure
}),
signedPayload: signedPayload as SdJwtDecodedVerifiableCredentialPayload,
}
}

Expand All @@ -221,28 +214,19 @@ export function decodeSdJwtVc(compactSdJwtVc: CompactSdJwtVc, hasher: Hasher): S
* this method hides the actual implementation of SD-JWT (which is currently based on @sd-jwt/core)
*/
export async function decodeSdJwtVcAsync(compactSdJwtVc: CompactSdJwtVc, hasher: AsyncHasher): Promise<SdJwtDecodedVerifiableCredential> {
const sdJwtVc = SdJwtVc.fromCompact(compactSdJwtVc)

// Default (should be handled by the sd-jwt library)
let sdAlg = 'sha-256'
try {
sdAlg = sdJwtVc.getClaimInPayload('_sd_alg')
} catch {
/* no-op */
}

const disclosuresWithDigests = await Promise.all(
sdJwtVc.disclosures?.map((d) => d.withCalculateDigest((data: string) => hasher(data, sdAlg))) ?? []
)
const { signedPayload, decodedPayload, disclosures } = await _decodeSdJwtVc(compactSdJwtVc, hasher)

return {
compactSdJwtVc: compactSdJwtVc,
decodedPayload: swapClaims(sdJwtVc.payload, disclosuresWithDigests) as SdJwtDecodedVerifiableCredentialPayload,
disclosures: disclosuresWithDigests.map((d) => ({
decoded: d.decoded as SdJwtDecodedDisclosure,
digest: d.digest,
encoded: d.encoded,
})),
signedPayload: sdJwtVc.payload as SdJwtDecodedVerifiableCredentialPayload,
compactSdJwtVc,
decodedPayload: decodedPayload as SdJwtDecodedVerifiableCredentialPayload,
disclosures: disclosures.map((d) => {
const decoded = d.key ? [d.salt, d.key, d.value] : [d.salt, d.value]
return {
decoded: decoded as SdJwtDecodedDisclosure,
digest: d.digest,
encoded: d.encoded,
} satisfies SdJwtDisclosure
}),
signedPayload: signedPayload as SdJwtDecodedVerifiableCredentialPayload,
}
}
Loading

0 comments on commit fceaea3

Please sign in to comment.