From 699ad395c1f247f278b6e88181b20cd834756c61 Mon Sep 17 00:00:00 2001 From: Oleg Lomaka Date: Tue, 11 Jul 2023 04:42:18 -0400 Subject: [PATCH] Set custom document loader (#54) * Set custom document loader * Add new WithDIDResolver option for Verifier --- .github/workflows/ci-test.yaml | 3 - auth.go | 102 +++++++-- auth_test.go | 360 ++++++++++---------------------- go.mod | 5 +- go.sum | 13 +- loaders/schema.go | 43 ---- pubsignals/atomicMtpV2.go | 4 +- pubsignals/atomicSigV2.go | 4 +- pubsignals/authV2.go | 4 +- pubsignals/circuitVerifier.go | 4 +- pubsignals/query.go | 81 ++++--- pubsignals/query_test.go | 311 +++++++++++++++------------ testdata/credentials-v1.json-ld | 237 +++++++++++++++++++++ testdata/kyc-v101.json-ld | 79 +++++++ testdata/kyc-v2.json-ld | 48 +++++ testdata/kyc-v3.json-ld | 48 +++++ testdata/kyc-v4.json-ld | 48 +++++ 17 files changed, 884 insertions(+), 510 deletions(-) delete mode 100644 loaders/schema.go create mode 100644 testdata/credentials-v1.json-ld create mode 100644 testdata/kyc-v101.json-ld create mode 100644 testdata/kyc-v2.json-ld create mode 100644 testdata/kyc-v3.json-ld create mode 100644 testdata/kyc-v4.json-ld diff --git a/.github/workflows/ci-test.yaml b/.github/workflows/ci-test.yaml index 4e50018..7b12b88 100644 --- a/.github/workflows/ci-test.yaml +++ b/.github/workflows/ci-test.yaml @@ -6,9 +6,6 @@ on: - main - develop pull_request: - branches: - - main - - develop jobs: test: strategy: diff --git a/auth.go b/auth.go index 833c9d0..cc5d092 100644 --- a/auth.go +++ b/auth.go @@ -21,15 +21,26 @@ import ( "github.com/iden3/go-iden3-auth/v2/pubsignals" "github.com/iden3/go-iden3-auth/v2/state" "github.com/iden3/go-jwz/v2" - "github.com/iden3/go-schema-processor/merklize" + "github.com/iden3/go-schema-processor/v2/merklize" "github.com/iden3/go-schema-processor/v2/verifiable" "github.com/iden3/iden3comm/v2" "github.com/iden3/iden3comm/v2/packers" "github.com/iden3/iden3comm/v2/protocol" shell "github.com/ipfs/go-ipfs-api" + "github.com/piprate/json-gold/ld" "github.com/pkg/errors" ) +var defaultSchemaLoader ld.DocumentLoader + +// SetDocumentLoader sets the default schema loader that would be used if +// other is not set with WithDocumentLoader option. Also, this document loader +// is set for go-schema-processor library to use it for merklize. +func SetDocumentLoader(schemaLoader ld.DocumentLoader) { + defaultSchemaLoader = schemaLoader + merklize.SetDocumentLoader(schemaLoader) +} + // UniversalResolverURL is a url for universal resolver const UniversalResolverURL = "https://dev.uniresolver.io/1.0/identifiers" @@ -86,39 +97,86 @@ var UniversalDIDResolver = packers.DIDResolverHandlerFunc(func(did string) (*ver // Verifier is a struct for auth instance type Verifier struct { verificationKeyLoader loaders.VerificationKeyLoader - claimSchemaLoader loaders.SchemaLoader + documentLoader ld.DocumentLoader stateResolver map[string]pubsignals.StateResolver packageManager iden3comm.PackageManager } +// VerifierOption is a function to set options for Verifier instance +type VerifierOption func(opts *verifierOpts) + +// WithDocumentLoader sets the document loader for Verifier instance +func WithDocumentLoader(docLoader ld.DocumentLoader) VerifierOption { + return func(opts *verifierOpts) { + opts.docLoader = docLoader + } +} + +// WithIPFSClient sets the IPFS client for document loader of Verifier instance. +// If document loader is set with WithDocumentLoader function, this option is +// ignored. +func WithIPFSClient(ipfsCli *shell.Shell) VerifierOption { + return func(opts *verifierOpts) { + opts.ipfsCli = ipfsCli + } +} + +// WithIPFSGateway sets the IPFS gateway for document loader of Verifier +// instance. If document loader is set with WithDocumentLoader function, this +// option is ignored. If WithIPFSClient is set, this option is ignored also. +func WithIPFSGateway(ipfsGW string) VerifierOption { + return func(opts *verifierOpts) { + opts.ipfsGW = ipfsGW + } +} + +// WithDIDResolver sets the DID resolver for Verifier instance. The default +// value is UniversalDIDResolver. +func WithDIDResolver(resolver packers.DIDResolverHandlerFunc) VerifierOption { + return func(opts *verifierOpts) { + opts.didResolver = resolver + } +} + +type verifierOpts struct { + docLoader ld.DocumentLoader + ipfsCli *shell.Shell + ipfsGW string + didResolver packers.DIDResolverHandlerFunc +} + +func newOpts() verifierOpts { + return verifierOpts{ + didResolver: UniversalDIDResolver, + } +} + // NewVerifier returns setup instance of auth library func NewVerifier( keyLoader loaders.VerificationKeyLoader, - claimSchemaLoader loaders.SchemaLoader, resolver map[string]pubsignals.StateResolver, + opts ...VerifierOption, ) (*Verifier, error) { + vOpts := newOpts() + for _, optFn := range opts { + optFn(&vOpts) + } + + docLoader := getDocumentLoader(vOpts.docLoader, vOpts.ipfsCli, + vOpts.ipfsGW) v := &Verifier{ verificationKeyLoader: keyLoader, - claimSchemaLoader: claimSchemaLoader, + documentLoader: docLoader, stateResolver: resolver, packageManager: *iden3comm.NewPackageManager(), } - // try to extract IPFS_URL if the schema loader is the default one - if impl, ok := claimSchemaLoader.(loaders.DefaultSchemaLoader); ok && - impl.IpfsURL != "" { - - ipfsCli := shell.NewShell(impl.IpfsURL) - documentLoader := merklize.NewDocumentLoader(ipfsCli, "") - merklize.SetDocumentLoader(documentLoader) - } - err := v.SetupAuthV2ZKPPacker() if err != nil { return nil, err } - err = v.SetupJWSPacker(UniversalDIDResolver) + err = v.SetupJWSPacker(vOpts.didResolver) if err != nil { return nil, err } @@ -276,7 +334,7 @@ func (v *Verifier) VerifyAuthResponse( rawMessage = nil } - err = cv.VerifyQuery(ctx, query, v.claimSchemaLoader, rawMessage) + err = cv.VerifyQuery(ctx, query, v.documentLoader, rawMessage) if err != nil { return err } @@ -411,3 +469,17 @@ func findProofByRequestID(arr []protocol.ZeroKnowledgeProofResponse, id uint32) } return nil } + +func getDocumentLoader(docLoader ld.DocumentLoader, ipfsCli *shell.Shell, + ipfsGW string) ld.DocumentLoader { + + if docLoader != nil { + return docLoader + } + + if ipfsCli == nil && ipfsGW == "" && defaultSchemaLoader != nil { + return defaultSchemaLoader + } + + return merklize.NewDocumentLoader(ipfsCli, ipfsGW) +} diff --git a/auth_test.go b/auth_test.go index 32a5268..0669fa6 100644 --- a/auth_test.go +++ b/auth_test.go @@ -2,7 +2,10 @@ package auth import ( "context" + "encoding/json" + "fmt" "math/big" + "os" "testing" "github.com/google/uuid" @@ -11,9 +14,11 @@ import ( "github.com/iden3/go-iden3-auth/v2/pubsignals" "github.com/iden3/go-iden3-auth/v2/state" "github.com/iden3/go-rapidsnark/types" - "github.com/iden3/iden3comm/v2" + "github.com/iden3/go-schema-processor/v2/verifiable" "github.com/iden3/iden3comm/v2/packers" "github.com/iden3/iden3comm/v2/protocol" + "github.com/piprate/json-gold/ld" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -25,239 +30,29 @@ import ( var verificationKeyloader = &loaders.FSKeyLoader{Dir: "./testdata"} -const kycV2Schema = `{ - "@context": [ - { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "KYCAgeCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld#KYCAgeCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "serialization": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/serialization.md#", - "birthday": { - "@id": "kyc-vocab:birthday", - "@type": "serialization:IndexDataSlotA" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "serialization:IndexDataSlotB" - } - } - }, - "KYCCountryOfResidenceCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld#KYCCountryOfResidenceCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "serialization": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/serialization.md#", - "countryCode": { - "@id": "kyc-vocab:countryCode", - "@type": "serialization:IndexDataSlotA" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "serialization:IndexDataSlotB" - } - } - } - } - ] -}` - -const kycV3Schema = `{ - "@context": [ - { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "KYCAgeCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCAgeCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "birthday": { - "@id": "kyc-vocab:birthday", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCCountryOfResidenceCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "countryCode": { - "@id": "kyc-vocab:countryCode", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - } - } - ] -}` - -const kycV4Schema = `{ - "@context": [ - { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "KYCAgeCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld#KYCAgeCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "birthday": { - "@id": "kyc-vocab:birthday", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCCountryOfResidenceCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld#KYCCountryOfResidenceCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "countryCode": { - "@id": "kyc-vocab:countryCode", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - } - } - ] -}` - -const kycV101Schema = `{ - "@context": [ - { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "KYCAgeCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCAgeCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "birthday": { - "@id": "kyc-vocab:birthday", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCCountryOfResidenceCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCCountryOfResidenceCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "countryCode": { - "@id": "kyc-vocab:countryCode", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCEmployee": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - }, - "ZKPexperiance": { - "@id": "kyc-vocab:hasZKPexperiance", - "@type": "xsd:boolean" - }, - "hireDate": { - "@id": "kyc-vocab:hireDate", - "@type": "xsd:dateTime" - }, - "position": { - "@id": "kyc-vocab:position", - "@type": "xsd:string" - }, - "salary": { - "@id": "kyc-vocab:salary", - "@type": "xsd:double" - } - } - } - } - ] -}` - type mockJSONLDSchemaLoader struct { - schema string + schemas map[string]string + seen map[string]bool +} + +func (r *mockJSONLDSchemaLoader) LoadDocument(u string) (*ld.RemoteDocument, error) { + if body, ok := r.schemas[u]; ok { + if r.seen == nil { + r.seen = make(map[string]bool) + } + r.seen[u] = true + var doc = ld.RemoteDocument{DocumentURL: u} + err := json.Unmarshal([]byte(body), &doc.Document) + return &doc, err + } + return nil, fmt.Errorf("schema not found: %v", u) } -func (r *mockJSONLDSchemaLoader) Load(_ context.Context, _ string) (schema []byte, ext string, err error) { - return []byte(r.schema), "json-ld", nil +// assert that all schemas were loaded +func (r *mockJSONLDSchemaLoader) assert(t testing.TB) { + for url := range r.schemas { + require.True(t, r.seen[url], "schema not loaded: %v", url) + } } /* @@ -431,11 +226,17 @@ func TestVerifyMessageWithSigProof_NonMerkalized(t *testing.T) { }, } - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV2Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld": loadSchema("kyc-v2.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) err = authInstance.VerifyAuthResponse(context.Background(), message, request) require.Nil(t, err) + schemaLoader.assert(t) } func TestVerifyMessageWithMTPProof_Merkalized(t *testing.T) { @@ -594,23 +395,29 @@ func TestVerifyMessageWithMTPProof_Merkalized(t *testing.T) { }, } - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV3Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{"https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld")}, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) err = authInstance.VerifyAuthResponse(context.Background(), message, request) require.NoError(t, err) + schemaLoader.assert(t) } func TestVerifier_VerifyJWZ(t *testing.T) { token := `eyJhbGciOiJncm90aDE2IiwiY2lyY3VpdElkIjoiYXV0aFYyIiwiY3JpdCI6WyJjaXJjdWl0SWQiXSwidHlwIjoiYXBwbGljYXRpb24vaWRlbjMtemtwLWpzb24ifQ.eyJpZCI6IjljMGY5NjIzLWM1NmMtNDEwNC04ODk2LWVjMjgyYTNiMmExNyIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1wbGFpbi1qc29uIiwidHlwZSI6Imh0dHBzOi8vaWRlbjMtY29tbXVuaWNhdGlvbi5pby9hdXRob3JpemF0aW9uLzEuMC9yZXNwb25zZSIsInRoaWQiOiI3ZjM4YTE5My0wOTE4LTRhNDgtOWZhYy0zNmFkZmRiOGI1NDIiLCJmcm9tIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycVBETFhEYVUxeGExRVJUYjFYS0JmUENCM28yd0E0NnE0OW5laVhXd1kiLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFKNjg5a3BvSnhjU3pCNXNBRkp0UHNTQlNySEY1ZHE3MjJCSE1xVVJMIiwiYm9keSI6eyJkaWRfZG9jIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiXSwiaWQiOiJkaWQ6cG9seWdvbmlkOnBvbHlnb246bXVtYmFpOjJxUERMWERhVTF4YTFFUlRiMVhLQmZQQ0IzbzJ3QTQ2cTQ5bmVpWFd3WSIsInNlcnZpY2UiOlt7ImlkIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycVBETFhEYVUxeGExRVJUYjFYS0JmUENCM28yd0E0NnE0OW5laVhXd1kjcHVzaCIsInR5cGUiOiJwdXNoLW5vdGlmaWNhdGlvbiIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vcHVzaC1zdGFnaW5nLnBvbHlnb25pZC5jb20vYXBpL3YxIiwibWV0YWRhdGEiOnsiZGV2aWNlcyI6W3siY2lwaGVydGV4dCI6InhZK3RHWHUrOWlHMHZ6dFpMTTlKN25PcDNRbE1Uci85TmI3Qjl5Q0prbDlxcUpiZ1AvMExOL1VmTkxxQUk4RWZIcFhJVlVlTmVVUmNCNm82bWVMVlpJK2VvMlhvcDM2SE1iK2JyQnJTTjRqVHZWVkRDQXVXSkI2akV5Q3ZNRzlMaXp6blBsS3VQSE15dEdCVnZnV0laRFZBeVdZbTFyMk9PUzc4OU5DZm41MnNjV0VRVW5VRWdnTmpyWjlLdFpmb09RMlBDbUpqRXpDejg0ZUc3RGM2bEFvbi8ycTJJNVlLQk12RkhnT3c4N25wb0owczVrQ1RVVENjeVRlQmg2VXpLQk5aNElibndvR3ZYcG9FelBVZXZRdjRGbXVTaExYYVF3Vk9nalRBUXR0T2g2SjZhcmE4UHNndVFGQ3dNUTlxV2JjTjZYdXlScjk4TVlqbGxpL0VEN09TZzBsWVU5cUdLa1RaL2ZZN2VWZkYyeFFhOWZXK01WVzlxM2NJMjJzbkRwV28xY1ZYNWt1TWhpbmFsajZXV1Q0OTAvblNXak1rZ3JkL25CdXNiMHR4eG1jWDU3QUowcVlyMkNsK0pQb1FhcExiOEFTT3dGYU5kRDRZV3pKWXRXVmlDbktMZ3dQNDFHaGl5NVNWZE1vbU1sUy9kSGo2TVZPMjNyOVRiTDFrRy8rdkFIZWF0YkdvZ3p1OWd3SzlJckF3WS95THhMYVpQcHZzdlJLWjVBa2E1b1pkbmRNNkdLUkM0OVhoVXloQnNlY0N2Z1hNeGZGNVBnWGhROVFTb1drMzFXSWRiWG5vbmU2YmVNQkpLUVYzemg2MmpoZUFuV3czZW16dndKajRUUHU4WTJQZ2lDL3FaZXhlUVlKdFNkelJXZUFjK2N5a2ZwTXA0SmdrV2hBPSIsImFsZyI6IlJTQS1PQUVQLTUxMiJ9XX19XX0sIm1lc3NhZ2UiOm51bGwsInNjb3BlIjpbeyJpZCI6MjMsImNpcmN1aXRJZCI6ImNyZWRlbnRpYWxBdG9taWNRdWVyeU1UUFYyIiwicHJvb2YiOnsicGlfYSI6WyIyNjEwNjg1Nzc1MTY0Mzc0MDE2MTM5NDQwNTM4NzMxODI0NTgzNjQyODg0MTQxMzA5MTQwNDgzNDU0ODMzNzcyMjYxNDQ2NTI2NTEiLCIxNDE5MTI2MDA3MTY5NTk4MDAxMTY3OTUwMTgwODQ1MzIyMjI2NzUyMDcyMTc2Nzc1Nzc1OTE1MDEwMTk3NDM4MjA1MzE2MTY3NDYxMSIsIjEiXSwicGlfYiI6W1siNzY3MDg0Nzg0NDAxNTExNjk1NzUyNjE4MzcyODE5Njk3Nzk1NzMxMjYyNzMwNzc5NzkxOTU1NDEzNDY4NDkwMTQwMTQzNjAyMTk3NyIsIjE0OTU3ODQ1NDcyNjMwMDE3MDk1ODIxODMzMjIyNTgwMTk0MDYxMjY2MTg2ODUxNjM0MDUzODk3NzY4NzM4MjUzNjYzMjUzNjUwODM1Il0sWyIxNzgzNTY0MjQ1ODQ4NDYyODYyNzU1NjMyOTg3NjkxOTA3NzMzMzkxMjAxMTIzNTMwODc1ODgzMjE3Mjg4MDAxMjgxMzM5NzAyMjEwNCIsIjE4MTAwODYxMTMwMTQ5Njc4MTUzMTMzMDI1MDMxNzA5ODk3MTIwMDk3MDk4NTkxMjk4ODE3MzY3NDkxOTIwNTUzMDM3MDExNjUwMjI4Il0sWyIxIiwiMCJdXSwicGlfYyI6WyI2MjE3ODY1OTQ5Mjk5OTkwNjQyODMyNTIzMjU2ODYzMDQ4OTMyMjEwNTQ2MDQ5MjAzMTg5MTEzMzYyODUxNDc2OTY2ODI0MTYyMTkxIiwiMTkwMTY5NDkyMjUyNzc3NTU2OTAwMTk2NDczODU4NTU5MzY5Njk5Mjg5OTQyMTA5MDU5OTI2MjgzMDE5Njc4ODM4MDM2NzA0MzY1MTAiLCIxIl0sInByb3RvY29sIjoiZ3JvdGgxNiIsImN1cnZlIjoiYm4xMjgifSwicHViX3NpZ25hbHMiOlsiMSIsIjI3MTUyNjc2OTg3MTI4NTQyMDY2ODA4NTkxOTk4NTczMDAwMzcwNDM2NDY0NzIyNTE5NTEzMzQ4ODkxMDQ5NjQ0ODEzNzE4MDE4IiwiMjMiLCIyNzc1Mjc2NjgyMzM3MTQ3MTQwODI0ODIyNTcwODY4MTMxMzc2NDg2NjIzMTY1NTE4NzM2NjA3MTg4MTA3MDkxODk4NDQ3MTA0MiIsIjIxNTQ1NzY4ODgzNTA5NjU3MzQwMjA5MTcxNTQ5NDQxMDA1NjAzMzA2MDEyNTEzOTMyMjIxMzcxNTk5NTAxNDk4NTM0ODA3NzE5Njg5IiwiMSIsIjIxNTQ1NzY4ODgzNTA5NjU3MzQwMjA5MTcxNTQ5NDQxMDA1NjAzMzA2MDEyNTEzOTMyMjIxMzcxNTk5NTAxNDk4NTM0ODA3NzE5Njg5IiwiMTY3OTMyMzAzOCIsIjMzNjYxNTQyMzkwMDkxOTQ2NDE5MzA3NTU5Mjg1MDQ4MzcwNDYwMCIsIjAiLCIxNzAwMjQzNzExOTQzNDYxODc4MzU0NTY5NDYzMzAzODUzNzM4MDcyNjMzOTk5NDI0NDY4NDM0ODkxMzg0NDkyMzQyMjQ3MDgwNjg0NCIsIjAiLCI1IiwiODQwIiwiMTIwIiwiMzQwIiwiNTA5IiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIl19XX19.eyJwcm9vZiI6eyJwaV9hIjpbIjcwMjI2MTEzODk5MzY1MDEzNDI2NTkwMjQ2Njk0NTczNTA3OTUwMTU5ODkzOTI1NzAzMDMwODQ4MzcyMTQ4MDc1MzYyNDg4NTE5MzYiLCIxMzg1OTcwODc3NTU0Mzk0Mjk3MTYxNTcxNTA1MTczNjM4MTc4NTEzODkzMjQ3ODc1Mzg3MjU5MTU0NDQxODk1ODkwOTU2MDQyOTU3NCIsIjEiXSwicGlfYiI6W1siMTE1MzQ5NjMxNDgwODQ0OTk0NDg5MDc3NzQxMTMxNjg1OTEyNDYyMjQ4OTg0MTU4ODAwMzY5NTA1MDYyMjU0ODkyMDA1NTc2NTA2NjUiLCIxNDA3MjA4Mjk1MTQ0Njc5NDk5MDk4NDcwNTE3ODA1OTY2NjI4NzM1NTEwNjc5MzUwMTg5MTE2ODgwNjE2NjUwMTUxMDkzMDY0MzQ0MSJdLFsiNDY3ODgyNDc3ODQ5ODA0NzE2OTEzNTk2NTg3MTYwNDgzNjkwMTQ1NjI5MDQ0NjQ0NjUzMzEyNzUwOTU4Mzg5MDU5MDkzNTY5ODQxNCIsIjEyODE5NzMwNTMyMDg0MTM4NDI0ODQ0MjExNDg4NjcxMTUyNDgwOTU1MzQ0MTA2NzU4NTE3NDEzODAxOTIzNTM3OTU3MzYzOTgwMjA0Il0sWyIxIiwiMCJdXSwicGlfYyI6WyIxNTUyMDYzNjk4OTY2MTg3NzExNDUwNjkwNDgxMDQxMzExNDI4NzQ5ODE1OTk2NDA5OTU2MTY5ODUyNjc4MzUwMDE1NjU1MjQzMDAwNCIsIjEyNjkyNzA3NDA3MTczMDg0OTM5NzQ1ODU5NzE0ODMxNDYyMDQ1ODg5NDA4NTk4NTI3MjU0ODA3NzkwNDk0NDY2Mjc5Njg3ODU5MjQ3IiwiMSJdLCJwcm90b2NvbCI6Imdyb3RoMTYiLCJjdXJ2ZSI6ImJuMTI4In0sInB1Yl9zaWduYWxzIjpbIjI3MTUyNjc2OTg3MTI4NTQyMDY2ODA4NTkxOTk4NTczMDAwMzcwNDM2NDY0NzIyNTE5NTEzMzQ4ODkxMDQ5NjQ0ODEzNzE4MDE4IiwiMTIxODQ5NzQwNzE0Mjc3NjgzNTIwMjcwMDM4NzgzMTkzMzgyNDkzODM4NDYxNjQ3MzAyMDQ1MDUzMjY5NTM1NTA2NDczOTExNzg4MDAiLCI4NzU2MDYwMjA1MDg2ODAzMzM1MjUyMzE5NzQ4NzQ4MzU0NzYxOTYxODE0MDEyNzI1NDk5ODczMzgyOTg4MDU2NDE4NjgwNjI4NjE5Il19` - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV101Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{} + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) parsedToken, err := authInstance.VerifyJWZ(context.Background(), token) require.NoError(t, err) require.Equal(t, parsedToken.Alg, "groth16") + schemaLoader.assert(t) } func TestVerifier_FullVerify(t *testing.T) { @@ -646,11 +453,17 @@ func TestVerifier_FullVerify(t *testing.T) { token := `eyJhbGciOiJncm90aDE2IiwiY2lyY3VpdElkIjoiYXV0aFYyIiwiY3JpdCI6WyJjaXJjdWl0SWQiXSwidHlwIjoiYXBwbGljYXRpb24vaWRlbjMtemtwLWpzb24ifQ.eyJpZCI6IjljMGY5NjIzLWM1NmMtNDEwNC04ODk2LWVjMjgyYTNiMmExNyIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1wbGFpbi1qc29uIiwidHlwZSI6Imh0dHBzOi8vaWRlbjMtY29tbXVuaWNhdGlvbi5pby9hdXRob3JpemF0aW9uLzEuMC9yZXNwb25zZSIsInRoaWQiOiI3ZjM4YTE5My0wOTE4LTRhNDgtOWZhYy0zNmFkZmRiOGI1NDIiLCJmcm9tIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycVBETFhEYVUxeGExRVJUYjFYS0JmUENCM28yd0E0NnE0OW5laVhXd1kiLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFKNjg5a3BvSnhjU3pCNXNBRkp0UHNTQlNySEY1ZHE3MjJCSE1xVVJMIiwiYm9keSI6eyJkaWRfZG9jIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiXSwiaWQiOiJkaWQ6cG9seWdvbmlkOnBvbHlnb246bXVtYmFpOjJxUERMWERhVTF4YTFFUlRiMVhLQmZQQ0IzbzJ3QTQ2cTQ5bmVpWFd3WSIsInNlcnZpY2UiOlt7ImlkIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycVBETFhEYVUxeGExRVJUYjFYS0JmUENCM28yd0E0NnE0OW5laVhXd1kjcHVzaCIsInR5cGUiOiJwdXNoLW5vdGlmaWNhdGlvbiIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vcHVzaC1zdGFnaW5nLnBvbHlnb25pZC5jb20vYXBpL3YxIiwibWV0YWRhdGEiOnsiZGV2aWNlcyI6W3siY2lwaGVydGV4dCI6InhZK3RHWHUrOWlHMHZ6dFpMTTlKN25PcDNRbE1Uci85TmI3Qjl5Q0prbDlxcUpiZ1AvMExOL1VmTkxxQUk4RWZIcFhJVlVlTmVVUmNCNm82bWVMVlpJK2VvMlhvcDM2SE1iK2JyQnJTTjRqVHZWVkRDQXVXSkI2akV5Q3ZNRzlMaXp6blBsS3VQSE15dEdCVnZnV0laRFZBeVdZbTFyMk9PUzc4OU5DZm41MnNjV0VRVW5VRWdnTmpyWjlLdFpmb09RMlBDbUpqRXpDejg0ZUc3RGM2bEFvbi8ycTJJNVlLQk12RkhnT3c4N25wb0owczVrQ1RVVENjeVRlQmg2VXpLQk5aNElibndvR3ZYcG9FelBVZXZRdjRGbXVTaExYYVF3Vk9nalRBUXR0T2g2SjZhcmE4UHNndVFGQ3dNUTlxV2JjTjZYdXlScjk4TVlqbGxpL0VEN09TZzBsWVU5cUdLa1RaL2ZZN2VWZkYyeFFhOWZXK01WVzlxM2NJMjJzbkRwV28xY1ZYNWt1TWhpbmFsajZXV1Q0OTAvblNXak1rZ3JkL25CdXNiMHR4eG1jWDU3QUowcVlyMkNsK0pQb1FhcExiOEFTT3dGYU5kRDRZV3pKWXRXVmlDbktMZ3dQNDFHaGl5NVNWZE1vbU1sUy9kSGo2TVZPMjNyOVRiTDFrRy8rdkFIZWF0YkdvZ3p1OWd3SzlJckF3WS95THhMYVpQcHZzdlJLWjVBa2E1b1pkbmRNNkdLUkM0OVhoVXloQnNlY0N2Z1hNeGZGNVBnWGhROVFTb1drMzFXSWRiWG5vbmU2YmVNQkpLUVYzemg2MmpoZUFuV3czZW16dndKajRUUHU4WTJQZ2lDL3FaZXhlUVlKdFNkelJXZUFjK2N5a2ZwTXA0SmdrV2hBPSIsImFsZyI6IlJTQS1PQUVQLTUxMiJ9XX19XX0sIm1lc3NhZ2UiOm51bGwsInNjb3BlIjpbeyJpZCI6MjMsImNpcmN1aXRJZCI6ImNyZWRlbnRpYWxBdG9taWNRdWVyeU1UUFYyIiwicHJvb2YiOnsicGlfYSI6WyIyNjEwNjg1Nzc1MTY0Mzc0MDE2MTM5NDQwNTM4NzMxODI0NTgzNjQyODg0MTQxMzA5MTQwNDgzNDU0ODMzNzcyMjYxNDQ2NTI2NTEiLCIxNDE5MTI2MDA3MTY5NTk4MDAxMTY3OTUwMTgwODQ1MzIyMjI2NzUyMDcyMTc2Nzc1Nzc1OTE1MDEwMTk3NDM4MjA1MzE2MTY3NDYxMSIsIjEiXSwicGlfYiI6W1siNzY3MDg0Nzg0NDAxNTExNjk1NzUyNjE4MzcyODE5Njk3Nzk1NzMxMjYyNzMwNzc5NzkxOTU1NDEzNDY4NDkwMTQwMTQzNjAyMTk3NyIsIjE0OTU3ODQ1NDcyNjMwMDE3MDk1ODIxODMzMjIyNTgwMTk0MDYxMjY2MTg2ODUxNjM0MDUzODk3NzY4NzM4MjUzNjYzMjUzNjUwODM1Il0sWyIxNzgzNTY0MjQ1ODQ4NDYyODYyNzU1NjMyOTg3NjkxOTA3NzMzMzkxMjAxMTIzNTMwODc1ODgzMjE3Mjg4MDAxMjgxMzM5NzAyMjEwNCIsIjE4MTAwODYxMTMwMTQ5Njc4MTUzMTMzMDI1MDMxNzA5ODk3MTIwMDk3MDk4NTkxMjk4ODE3MzY3NDkxOTIwNTUzMDM3MDExNjUwMjI4Il0sWyIxIiwiMCJdXSwicGlfYyI6WyI2MjE3ODY1OTQ5Mjk5OTkwNjQyODMyNTIzMjU2ODYzMDQ4OTMyMjEwNTQ2MDQ5MjAzMTg5MTEzMzYyODUxNDc2OTY2ODI0MTYyMTkxIiwiMTkwMTY5NDkyMjUyNzc3NTU2OTAwMTk2NDczODU4NTU5MzY5Njk5Mjg5OTQyMTA5MDU5OTI2MjgzMDE5Njc4ODM4MDM2NzA0MzY1MTAiLCIxIl0sInByb3RvY29sIjoiZ3JvdGgxNiIsImN1cnZlIjoiYm4xMjgifSwicHViX3NpZ25hbHMiOlsiMSIsIjI3MTUyNjc2OTg3MTI4NTQyMDY2ODA4NTkxOTk4NTczMDAwMzcwNDM2NDY0NzIyNTE5NTEzMzQ4ODkxMDQ5NjQ0ODEzNzE4MDE4IiwiMjMiLCIyNzc1Mjc2NjgyMzM3MTQ3MTQwODI0ODIyNTcwODY4MTMxMzc2NDg2NjIzMTY1NTE4NzM2NjA3MTg4MTA3MDkxODk4NDQ3MTA0MiIsIjIxNTQ1NzY4ODgzNTA5NjU3MzQwMjA5MTcxNTQ5NDQxMDA1NjAzMzA2MDEyNTEzOTMyMjIxMzcxNTk5NTAxNDk4NTM0ODA3NzE5Njg5IiwiMSIsIjIxNTQ1NzY4ODgzNTA5NjU3MzQwMjA5MTcxNTQ5NDQxMDA1NjAzMzA2MDEyNTEzOTMyMjIxMzcxNTk5NTAxNDk4NTM0ODA3NzE5Njg5IiwiMTY3OTMyMzAzOCIsIjMzNjYxNTQyMzkwMDkxOTQ2NDE5MzA3NTU5Mjg1MDQ4MzcwNDYwMCIsIjAiLCIxNzAwMjQzNzExOTQzNDYxODc4MzU0NTY5NDYzMzAzODUzNzM4MDcyNjMzOTk5NDI0NDY4NDM0ODkxMzg0NDkyMzQyMjQ3MDgwNjg0NCIsIjAiLCI1IiwiODQwIiwiMTIwIiwiMzQwIiwiNTA5IiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIl19XX19.eyJwcm9vZiI6eyJwaV9hIjpbIjcwMjI2MTEzODk5MzY1MDEzNDI2NTkwMjQ2Njk0NTczNTA3OTUwMTU5ODkzOTI1NzAzMDMwODQ4MzcyMTQ4MDc1MzYyNDg4NTE5MzYiLCIxMzg1OTcwODc3NTU0Mzk0Mjk3MTYxNTcxNTA1MTczNjM4MTc4NTEzODkzMjQ3ODc1Mzg3MjU5MTU0NDQxODk1ODkwOTU2MDQyOTU3NCIsIjEiXSwicGlfYiI6W1siMTE1MzQ5NjMxNDgwODQ0OTk0NDg5MDc3NzQxMTMxNjg1OTEyNDYyMjQ4OTg0MTU4ODAwMzY5NTA1MDYyMjU0ODkyMDA1NTc2NTA2NjUiLCIxNDA3MjA4Mjk1MTQ0Njc5NDk5MDk4NDcwNTE3ODA1OTY2NjI4NzM1NTEwNjc5MzUwMTg5MTE2ODgwNjE2NjUwMTUxMDkzMDY0MzQ0MSJdLFsiNDY3ODgyNDc3ODQ5ODA0NzE2OTEzNTk2NTg3MTYwNDgzNjkwMTQ1NjI5MDQ0NjQ0NjUzMzEyNzUwOTU4Mzg5MDU5MDkzNTY5ODQxNCIsIjEyODE5NzMwNTMyMDg0MTM4NDI0ODQ0MjExNDg4NjcxMTUyNDgwOTU1MzQ0MTA2NzU4NTE3NDEzODAxOTIzNTM3OTU3MzYzOTgwMjA0Il0sWyIxIiwiMCJdXSwicGlfYyI6WyIxNTUyMDYzNjk4OTY2MTg3NzExNDUwNjkwNDgxMDQxMzExNDI4NzQ5ODE1OTk2NDA5OTU2MTY5ODUyNjc4MzUwMDE1NjU1MjQzMDAwNCIsIjEyNjkyNzA3NDA3MTczMDg0OTM5NzQ1ODU5NzE0ODMxNDYyMDQ1ODg5NDA4NTk4NTI3MjU0ODA3NzkwNDk0NDY2Mjc5Njg3ODU5MjQ3IiwiMSJdLCJwcm90b2NvbCI6Imdyb3RoMTYiLCJjdXJ2ZSI6ImJuMTI4In0sInB1Yl9zaWduYWxzIjpbIjI3MTUyNjc2OTg3MTI4NTQyMDY2ODA4NTkxOTk4NTczMDAwMzcwNDM2NDY0NzIyNTE5NTEzMzQ4ODkxMDQ5NjQ0ODEzNzE4MDE4IiwiMTIxODQ5NzQwNzE0Mjc3NjgzNTIwMjcwMDM4NzgzMTkzMzgyNDkzODM4NDYxNjQ3MzAyMDQ1MDUzMjY5NTM1NTA2NDczOTExNzg4MDAiLCI4NzU2MDYwMjA1MDg2ODAzMzM1MjUyMzE5NzQ4NzQ4MzU0NzYxOTYxODE0MDEyNzI1NDk5ODczMzgyOTg4MDU2NDE4NjgwNjI4NjE5Il19` - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV3Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) _, err = authInstance.FullVerify(context.Background(), token, request) require.NoError(t, err) + schemaLoader.assert(t) } func TestVerifier_FullVerify_JWS(t *testing.T) { @@ -677,17 +490,32 @@ func TestVerifier_FullVerify_JWS(t *testing.T) { token := `eyJhbGciOiJFUzI1NkstUiIsImtpZCI6ImRpZDpwa2g6cG9seToweDcxNDFFNGQyMEY3NjQ0REM4YzBBZENBOGE1MjBFQzgzQzZjQUJENjUjUmVjb3ZlcnkyMDIwIiwidHlwIjoiYXBwbGljYXRpb24vaWRlbjNjb21tLXNpZ25lZC1qc29uIn0.eyJpZCI6IjJjOGQ5NzQ3LTQ0MTAtNGU5My1iZjg0LTRlYTNjZmY4MmY0MCIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1zaWduZWQtanNvbiIsInR5cGUiOiJodHRwczovL2lkZW4zLWNvbW11bmljYXRpb24uaW8vYXV0aG9yaXphdGlvbi8xLjAvcmVzcG9uc2UiLCJ0aGlkIjoiN2YzOGExOTMtMDkxOC00YTQ4LTlmYWMtMzZhZGZkYjhiNTQyIiwiYm9keSI6eyJzY29wZSI6W3siaWQiOjEsImNpcmN1aXRJZCI6ImNyZWRlbnRpYWxBdG9taWNRdWVyeVNpZ1YyIiwicHJvb2YiOnsicGlfYSI6WyIxMzI3Njk4Nzc5MjQ5MjM0OTA2MDcxMDc3NTEyOTUxMjYxNzY1NjMzODcxMDkxMzE3NDA0NzE0NTcyMDY4Mjk4NzU0MzUwNjY3NDY0IiwiMjA1NDcyOTI1MzQ0MDgxNzA4NDQwODc3MzY2MDQ0OTYyNjQ3MzI2NjUxNDkxMDEzMzMxNzk3NTg5NTAwMjM0NTgwMjA1Njg5NzMzNTYiLCIxIl0sInBpX2IiOltbIjcyNTI1MDEyNjE5ODM1NTYwMjM1NjA3MzI1MjIzODk2MjIxMDY4MTA5OTUxNzkxNjI0MjY2NzcyNDM2MjQwNTQ0Mzc2Nzc1ODI4MCIsIjgyNDU2MTQzMTExNjUzNTUyNzcyNTgyNTg1NTA0MTI5MTUzNjAzNTc2MjEyMDY5OTA0Mjk3NTE3ODk2NTgwNTI1ODY0Mjc2NjgyMDMiXSxbIjg0MjA4OTI3MTI5OTMyMTU5OTU3NjkwMDQ3MzU2Njc5MzY3MDk4MzY5MTY4MzU4MDM2Njc2NjI1NzQxMTcyNjEzNjI2OTgxMzI1MjkiLCIxMDgyOTQzMjI5MDkyODY3MjM1NjAzNjExMTgxNjE4NTQ0MDU3NTgwMDI1NDQzODAyMzUzNTA3MzUzNTY1ODMzOTE0MzMzODAzNDAyNyJdLFsiMSIsIjAiXV0sInBpX2MiOlsiMTIwNTc1NzM1NDQ2Mzc1NDA1MzE2MjIxNDc2NDg2NjE0MDc1NzM1MzY2MjU0MjM0MzY1ODE0MTk2OTY3NzYwOTMxOTY5Nzc5OTg2MzkiLCIxNTIwMzMwMjIxNjcyOTEzOTcwNjQyNjcyMzc5Mzk5Mjk0MjI5NjY1NTU0NDA4MTEwODkzMTE2MjIwMTQxOTcxNzI0MjU4NTQzOTg2NSIsIjEiXSwicHJvdG9jb2wiOiJncm90aDE2IiwiY3VydmUiOiJibjEyOCJ9LCJwdWJfc2lnbmFscyI6WyIxIiwiMjgwMTg1ODg4MjE0NzE5Mzk2MjQ3MTE0MjE5MjIwNzkzOTU0NTE1MDc3NTQzNzU5Nzg0MDgyMzA1MjQ3OTI3ODY4NjI5OTc1MDMiLCIxNDE5MzMwNDc0NzUwMTMzMTE4MTgwOTcxNTkxMjQ4NzIzNjUyNzAwMzkyNTA4MjEwNjc1MjM3Njc5NjA5OTg5MDIwMTkyODE4NTY5MCIsIjEiLCIyMjk0MjU5NDE1NjI2NjY2NTQyNjYxMzQ2Mjc3MTcyNTMyNzMxNDM4MjY0NzQyNjk1OTA0NDg2MzQ0Njg2NjYxMzAwMzc1MTkzOCIsIjEiLCIzMTY5NjEyMzY4MDg3OTA1MzQyNzg2NTE0MDk5NDQ5Mjk3NDA0MzgzODc0MzcxMzU2OTI0ODI4MDgyMTQzNjExOTUzNjIxODU5NzU5IiwiMTY4NzQzMzc0OCIsIjI2NzgzMTUyMTkyMjU1ODAyNzIwNjA4MjM5MDA0MzMyMTc5Njk0NCIsIjAiLCIyMDM3NjAzMzgzMjM3MTEwOTE3NzY4MzA0ODQ1NjAxNDUyNTkwNTExOTE3MzY3NDk4NTg0MzkxNTQ0NTYzNDcyNjE2NzQ1MDk4OTYzMCIsIjIiLCIyIiwiMjAwMDAxMDEiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiXX1dfSwiZnJvbSI6ImRpZDpwa2g6cG9seToweDcxNDFFNGQyMEY3NjQ0REM4YzBBZENBOGE1MjBFQzgzQzZjQUJENjUiLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFMUHF2YXlOUXo5VEEycjVWUHhVdWdvRjE4dGVHVTU4M3pKODU5d2Z5In0.bWc2ECABj7nvHatD8AXWNJM2VtfhkIjNwz5BBIK9zBMsP0-UWLEWdAWcosiLkYoL0KWwZpgEOrPPepl6T5gC-AA` - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV4Schema} - v, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) - require.NoError(t, err) - pm := *iden3comm.NewPackageManager() - jwsPacker := packers.NewJWSPacker(UniversalDIDResolver, nil) + schemaLoader := &mockJSONLDSchemaLoader{schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld": loadSchema("kyc-v4.json-ld"), + }} + + mockedResolver := func(did string) (*verifiable.DIDDocument, error) { + if did != "did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65" { + return nil, errors.Errorf("unexpected DID: %v", did) + } + data := `{"@context":["https://www.w3.org/ns/did/v1",{"EcdsaSecp256k1RecoveryMethod2020":"https://identity.foundation/EcdsaSecp256k1RecoverySignature2020#EcdsaSecp256k1RecoveryMethod2020","blockchainAccountId":"https://w3id.org/security#blockchainAccountId"}],"id":"did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65","verificationMethod":[{"id":"did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65#Recovery2020","type":"EcdsaSecp256k1RecoveryMethod2020","controller":"did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65","blockchainAccountId":"eip155:137:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65"}],"authentication":["did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65#Recovery2020"],"assertionMethod":["did:pkh:poly:0x7141E4d20F7644DC8c0AdCA8a520EC83C6cABD65#Recovery2020"]}` + var doc verifiable.DIDDocument + err := json.Unmarshal([]byte(data), &doc) + if err != nil { + return nil, err + } + return &doc, nil + } - err = pm.RegisterPackers(jwsPacker) + v, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader), + WithDIDResolver(mockedResolver)) require.NoError(t, err) - v.SetPackageManager(pm) + _, err = v.FullVerify(context.Background(), token, request) require.NoError(t, err) + + schemaLoader.assert(t) } func TestVerifyAuthResponseWithEmptyReq(t *testing.T) { @@ -840,11 +668,17 @@ func TestVerifyAuthResponseWithEmptyReq(t *testing.T) { To: authReq.From, } - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV2Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld": loadSchema("kyc-v2.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) err = authInstance.VerifyAuthResponse(context.Background(), resp, authReq) require.NoError(t, err) + schemaLoader.assert(t) } func TestCreateAuthorizationRequest(t *testing.T) { @@ -902,11 +736,18 @@ func TestVerifier_FullVerifySelectiveDisclosure(t *testing.T) { token := `eyJhbGciOiJncm90aDE2IiwiY2lyY3VpdElkIjoiYXV0aFYyIiwiY3JpdCI6WyJjaXJjdWl0SWQiXSwidHlwIjoiYXBwbGljYXRpb24vaWRlbjMtemtwLWpzb24ifQ.eyJpZCI6ImE2ZWM2ZTE5LWQwYzAtNDUxYi04NDg3LWRhODAwZGMzMDgxOCIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1wbGFpbi1qc29uIiwidHlwZSI6Imh0dHBzOi8vaWRlbjMtY29tbXVuaWNhdGlvbi5pby9hdXRob3JpemF0aW9uLzEuMC9yZXNwb25zZSIsInRoaWQiOiI3ZjM4YTE5My0wOTE4LTRhNDgtOWZhYy0zNmFkZmRiOGI1NDIiLCJmcm9tIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycUpwUnFaTlJUeGtpQ1VONFZTZkxRN0tBNFB6SFN3d1Z3blNLU0ZLdHciLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFKNjg5a3BvSnhjU3pCNXNBRkp0UHNTQlNySEY1ZHE3MjJCSE1xVVJMIiwiYm9keSI6eyJkaWRfZG9jIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiXSwiaWQiOiJkaWQ6cG9seWdvbmlkOnBvbHlnb246bXVtYmFpOjJxSnBScVpOUlR4a2lDVU40VlNmTFE3S0E0UHpIU3d3VnduU0tTRkt0dyIsInNlcnZpY2UiOlt7ImlkIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycUpwUnFaTlJUeGtpQ1VONFZTZkxRN0tBNFB6SFN3d1Z3blNLU0ZLdHcjcHVzaCIsInR5cGUiOiJwdXNoLW5vdGlmaWNhdGlvbiIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vcHVzaC1zdGFnaW5nLnBvbHlnb25pZC5jb20vYXBpL3YxIiwibWV0YWRhdGEiOnsiZGV2aWNlcyI6W3siY2lwaGVydGV4dCI6IlBoeGlRbVRqQjg1MmsvSGV1by9Wd0NuZE9keUdvblVaQThmbUN3L0pWZC9rajNGMG9uUUtwRWFUZXVsZnBMM0p3cnF1RVplT0RyVm1VOU9hbWo3eEpMV3pNOC9RSmptUG5aMzIyMmFGbGVtTGlSNnhGNk5ZZzNZMUZtVitMdlYrUUUwV0lsVHByUlVUSGhYNDJWQTcveWUvSGI5bStZSFJiUXNSa3FiQzVCYjQ2bE9IOFFjWjJ5OTEzOXVCYTlGUk9ERE5XNzViRytNR1ZjMUhBMnJ3aFQzNjVGMkIvSEtaWkpKVE02TEZhL1U3bjVjaVFMb2lyam5tei9RYVFvRmpVWHI5QUFtdkFkbFl3VkNIeDZhdVp1SnlXUjRRT1kxYm0rdG5mSWJmYnFBL2pNUUVlcE9ydittZENSY2VLaFI1ZDMzaFVld1VRakJrNFdxNHZQUy9HMlhLUUlUa1BCNnM5aGFwSkpYL3YrRHVBUWE2MnVEcFQ5UExYWjRBbW1PUUdlYXZWd1BTOE1QSHdoUHZHS0wxbWluVmlxY1BIUDU5dHZTUVlxRTVncU5lQVpPSVY3RW4wcU1SMHVDb0RFQ0Q1Sk55VFJvRXFIeTlIR2hjZ0tOTXdlL3VyZTlJdGV6UlZmSm9KbzgxcHVSZE82Y1daZnVjY2s0U1VndTJGRFdCUndrWU9McGFlempvbEZOZ0xyU2ltbzJZQ2t5U0lFRHRNcjAyR0h0T0RSS25vMFZjUTdLZkUyQ0VNSStZVXlQTkQ4Mk9OeDBGc0ZMQU9qMXAxNVBjbDF0bnhWWUJKZmJYNXNZM3BpcDI5NU5jY3VIT3RFQndwQzhoS0toWjJ5SHpsOGhQNlpGcWJlckM0TlRPMFo4a2NtZFVEd01vM1pJS2QyNDZiRnlxV2dNPSIsImFsZyI6IlJTQS1PQUVQLTUxMiJ9XX19XX0sIm1lc3NhZ2UiOm51bGwsInNjb3BlIjpbeyJpZCI6MSwiY2lyY3VpdElkIjoiY3JlZGVudGlhbEF0b21pY1F1ZXJ5TVRQVjIiLCJwcm9vZiI6eyJwaV9hIjpbIjE3MDc5OTEzMTQ1NzIwMjExODY5OTc4Njk3NTQ1NzkzNDc3OTc4ODc2NzUzNjE4MDA4NjAxNzI3MjA5NjU2MjU2NDAzOTg0MTE5MDEzIiwiMTg5MjU4NTgyNzkxMDg5ODMxMTAwMjU5NTc4NTM5MTI1NTU5MDU5Nzg2OTg5ODE5NjA5MDc0NTg0OTUyNDUyODYzMDQ4MDUwNzA5NjgiLCIxIl0sInBpX2IiOltbIjcyMDM2MzA2NTA5NzQ2MDUxODg0MTc5Mjc2Mzk1NTIxMjEwMDUyMTg5NTM2Njg5NDE5MDQxOTQyMjg1MDYzOTE4NTAyMDA0NjkzMDUiLCIxNDIzNTM0OTU2MzkzOTc3ODE1ODI3OTM2MzExMjQ1MTM2MjI1MTI1MTQyMzk0MTE5ODczODI2MzIxNzkzOTYwNzg0ODk0MTc2ODQ5MCJdLFsiMjA1NjkyMjYyNzYyMjU2ODczMDgyNjEyNTA2ODIxODU2MTc5MTQ4MDkzOTg2NzA4OTIwODc4NjUxMjM1MzgyNjUzMjE4MDc0Njc0MyIsIjE5MjA5MjEyNjA0MTk0NzA1Mzk5MDA1Mjc1MDc0MDg2ODI3MTg2MDc2NzQ1NTE0MzgwMzAxMDM5NTU3Njk3MDg1NDkwMjI5ODUyNDM5Il0sWyIxIiwiMCJdXSwicGlfYyI6WyIxMDEzMjAyMzEyNDUwNjcyODI2MjU4MTI1MjU1ODAxOTc3MjU4MzkwNjk4NjkwNzExNzMwMDE4MTkyNDUzMTg2MDU3MDMyMzMzNzk0MyIsIjczNjIyMTI1MDIyMDg3OTU3MzUzNDcwMjE2MTM3MzU1MjMyNDM5MjM2NzUwNzM2NjgyMjU4MDM5MDE0MzE0NzA4OTE3Mzc4MTU3MzMiLCIxIl0sInByb3RvY29sIjoiZ3JvdGgxNiIsImN1cnZlIjoiYm4xMjgifSwicHViX3NpZ25hbHMiOlsiMSIsIjIxNTEzMTQwNTMwMjMzOTIxNTE1ODA5MjM1Mzg4NzgwMTM0NjgxMjQ1NjEyODU4NzQ0OTAwMjk3NzQwNDkwNDQ3NzM4NTczMzE0IiwiMSIsIjI3NzUyNzY2ODIzMzcxNDcxNDA4MjQ4MjI1NzA4NjgxMzEzNzY0ODY2MjMxNjU1MTg3MzY2MDcxODgxMDcwOTE4OTg0NDcxMDQyIiwiMjI5ODI1ODk3MDg5OTY4NTE2NzUxMTE5NDA0OTkyMzY5NTkxOTEzNzcyMDg5NDUyNTQ2ODMzNTg1NzA1NzY1NTIyMTA5ODkyNDk3MyIsIjEiLCIyMjk4MjU4OTcwODk5Njg1MTY3NTExMTk0MDQ5OTIzNjk1OTE5MTM3NzIwODk0NTI1NDY4MzM1ODU3MDU3NjU1MjIxMDk4OTI0OTczIiwiMTY4MTM4MTA3NSIsIjI2NzgzMTUyMTkyMjU1ODAyNzIwNjA4MjM5MDA0MzMyMTc5Njk0NCIsIjAiLCIyMDM3NjAzMzgzMjM3MTEwOTE3NzY4MzA0ODQ1NjAxNDUyNTkwNTExOTE3MzY3NDk4NTg0MzkxNTQ0NTYzNDcyNjE2NzQ1MDk4OTYzMCIsIjAiLCIxIiwiMTk5NjA0MjQiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiXSwidnAiOnsiQHR5cGUiOiJWZXJpZmlhYmxlUHJlc2VudGF0aW9uIiwiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiXSwidmVyaWZpYWJsZUNyZWRlbnRpYWwiOnsiQGNvbnRleHQiOlsiaHR0cHM6Ly93d3cudzMub3JnLzIwMTgvY3JlZGVudGlhbHMvdjEiLCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vaWRlbjMvY2xhaW0tc2NoZW1hLXZvY2FiL21haW4vc2NoZW1hcy9qc29uLWxkL2t5Yy12NC5qc29ubGQiXSwiQHR5cGUiOlsiVmVyaWZpYWJsZUNyZWRlbnRpYWwiLCJLWUNBZ2VDcmVkZW50aWFsIl0sImNyZWRlbnRpYWxTdWJqZWN0Ijp7IkB0eXBlIjoiS1lDQWdlQ3JlZGVudGlhbCIsImJpcnRoZGF5IjoxOTk2MDQyNH19fX1dfX0.eyJwcm9vZiI6eyJwaV9hIjpbIjkzOTkyOTEyMjUxMDI1NDc2MDExMTI4ODMwOTM1NzQ0MTU5MzUzMzU5ODIwODgyMTg2NDE5ODg5NTgwMzIzODA1MTIyNTczOTY0OTMiLCIxMDMxNDYxNzA0NjQ0ODIzNjE4MTkzNjYxODUwMTMzMDY0Njc2MjU3OTU1MTkxNTE1NTY5MTU4ODU5NTk4NjYzNzY4Mzc1OTE4NTczNCIsIjEiXSwicGlfYiI6W1siMTc3MDczODkwMDE3MTg2NDk4NTIyMjMyNjA1Mjk2Mzg2Mjg1OTc1NzIyOTU0MzU4MDY3Mjg0MTEyMTc0MTQwMDY4NDI1NTg3NDk1OTMiLCIyMTU2Nzc4MDgwMTMyNzU0NTc5ODk0NzkzMjIwODAzOTA3NjYyMTM0NDg3NzQ3NzU5NDQ1NzA2MDc5OTQwMzI1NjYyNzY5MTU1Njg0MSJdLFsiMjA3NzY4ODY1ODkwNzE2OTU3NDczMTUzODIyNjI5MjU0NzI3MzA2NTY3OTE5NDI5ODg0MjI2Mzk0NTAzMTEzODE4MjM3NTU1ODI0MCIsIjE0MzA5NTc3MDk4OTk3OTQ1Njc4OTM1MjgwMzgxMTE0NzI5MzY2NTU1MDIyODk5MTE2NTc5NjQ2NTI3NjEwMjYxOTIwMTg3NTEwNjUxIl0sWyIxIiwiMCJdXSwicGlfYyI6WyIyMTE4ODk1MDUwMjY2OTk0Njk0NjAzMzUzNTYyNTk1MjE5MjY1MTY2ODI2MjkyNDIyNzAyMDg2OTU3MDM0NjAyODE4OTc2MzM2MDk3NCIsIjgxODQ1NzY2ODU3MDk5MTY4NzA3ODkxNjgxOTI1MjIzMzg4NDQzNDMxNzk0NzgxMjY5NzI4MTE2NjQxMTY2NzIwOTY1MjAxNjU0NjkiLCIxIl0sInByb3RvY29sIjoiZ3JvdGgxNiIsImN1cnZlIjoiYm4xMjgifSwicHViX3NpZ25hbHMiOlsiMjE1MTMxNDA1MzAyMzM5MjE1MTU4MDkyMzUzODg3ODAxMzQ2ODEyNDU2MTI4NTg3NDQ5MDAyOTc3NDA0OTA0NDc3Mzg1NzMzMTQiLCI0MzA0NjAwNjM3MTg5NzI2OTU0Nzg4MTMzNDIxNjc0ODk0NzYxODQ0OTE2MDgyMTY2MjgyMzA4MDAyMDY1MDI4NTY4ODY0Mjg5Njc1IiwiNTIyOTY2ODY4NjU1NzYzNzAxNzc4MTE1NzM1NjMwNDc2OTY2MTcwOTIzODY3MDI3MDYxMzU2MDg4NzY5OTM1Mjk0NDk5NjU1MDI5NSJdfQ` - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV4Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld": loadSchema("kyc-v4.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) _, err = authInstance.FullVerify(context.Background(), token, request) require.NoError(t, err) + schemaLoader.assert(t) } func TestEmptyCredentialSubject(t *testing.T) { @@ -932,9 +773,24 @@ func TestEmptyCredentialSubject(t *testing.T) { token := `eyJhbGciOiJncm90aDE2IiwiY2lyY3VpdElkIjoiYXV0aFYyIiwiY3JpdCI6WyJjaXJjdWl0SWQiXSwidHlwIjoiYXBwbGljYXRpb24vaWRlbjMtemtwLWpzb24ifQ.eyJpZCI6Ijc0MWU2MTA4LTM4MzgtNDFiYS1hMGIwLTlhZmZkZjY1NTg2YSIsInR5cCI6ImFwcGxpY2F0aW9uL2lkZW4zY29tbS1wbGFpbi1qc29uIiwidHlwZSI6Imh0dHBzOi8vaWRlbjMtY29tbXVuaWNhdGlvbi5pby9hdXRob3JpemF0aW9uLzEuMC9yZXNwb25zZSIsInRoaWQiOiIxNjEwN2QwYi01ZDU3LTQ1OWEtYWJiMi00OWE2Mjg2YTA5NTMiLCJmcm9tIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycUd5VDhtTUdydlRqTVdDelRHOE1YVG9neGp6UFRVYjJMa2tMM0FKMTEiLCJ0byI6ImRpZDpwb2x5Z29uaWQ6cG9seWdvbjptdW1iYWk6MnFKNjg5a3BvSnhjU3pCNXNBRkp0UHNTQlNySEY1ZHE3MjJCSE1xVVJMIiwiYm9keSI6eyJkaWRfZG9jIjp7IkBjb250ZXh0IjpbImh0dHBzOi8vd3d3LnczLm9yZy9ucy9kaWQvdjEiXSwiaWQiOiJkaWQ6cG9seWdvbmlkOnBvbHlnb246bXVtYmFpOjJxR3lUOG1NR3J2VGpNV0N6VEc4TVhUb2d4anpQVFViMkxra0wzQUoxMSIsInNlcnZpY2UiOlt7ImlkIjoiZGlkOnBvbHlnb25pZDpwb2x5Z29uOm11bWJhaToycUd5VDhtTUdydlRqTVdDelRHOE1YVG9neGp6UFRVYjJMa2tMM0FKMTEjcHVzaCIsInR5cGUiOiJwdXNoLW5vdGlmaWNhdGlvbiIsInNlcnZpY2VFbmRwb2ludCI6Imh0dHBzOi8vcHVzaC1zdGFnaW5nLnBvbHlnb25pZC5jb20vYXBpL3YxIiwibWV0YWRhdGEiOnsiZGV2aWNlcyI6W3siY2lwaGVydGV4dCI6IkMxRU9BNGViOUh6RC9QREtPeHlaazZaYjBaUzlvSlR1RmgyTi8xaTJ3TWxrdFJ4bzhteGJmMnN2Nk14OFl1SGRLbVo4eVJWbE9CSmpqOGRDckxDRHplYjJPREs2ZDVsanN0S05GTUlhOFh6aW1DV2I5eXoyN0h6Tm1EbTJWdGtJQWxaSjB6cEJFdnZlSWNUVVVodmNXeFkzQnVRRnpYdmJHL2lIYnUxcWRkdUh3L3JVMmJoTE9jdDN1bnpXVnB3T1pVYXg5TExTWk9zSGVyR0hZM1JJWUp5ZCtDcVV3TU5DQWJHYlJFcjlUU1pGdU1HbzZ1NGVRSlBOOURGQ09NaXdCdS9UOW5vMTNCZ1NIcDhHSlV6eFc1YTg4Z0FXQUZjVE5hSDVkOUdoamlERXp4NDUyV291Wms0Zloxd1BVd3lPUHJsaCt2QjVDd05jejRpWXNZK0ZPZEFMdDdyRUZ1RWhLZXhCVlp5VmYxckFLUDhOdi83YWtHdCtaWlZJY3RsRHRTUGUwYXpseW9TYTFKVVo2a0JLclJWdmUvL1pWdVRSMm81VHRXN2I2SlJVZ2w2S2IrVEhiN3V1OWlRcDN5ODAvWTVtMXpiSzNyUnlLTjM0U0YwMmpkY2JkZWVoeWNRc1NTMmRscm1oODZ6MWRvUS9XMVlXQ0Zzam1PazNQdnZxVU8rSXRPSnhVYURNcWVlZXE2QldldUxxd01oZE5KRVRBN3BIRzhES1JFdDZZLzNXRlNaOFF0aWdVWU9XQUplVXNHRzh1SFRSeSt3aVVKV1NIcVFTSmZHdXFOakFLa05mVFVYeDNqWmhOYmEveEFtUXV0bkxQQjJpbXowNHNSRFhTUzNYMUFmSnVSdUp6Wk1lTUE3MXM2TEZaS01Iakw4cXBENzI0L21OcEVFPSIsImFsZyI6IlJTQS1PQUVQLTUxMiJ9XX19XX0sIm1lc3NhZ2UiOm51bGwsInNjb3BlIjpbeyJpZCI6MSwiY2lyY3VpdElkIjoiY3JlZGVudGlhbEF0b21pY1F1ZXJ5U2lnVjIiLCJwcm9vZiI6eyJwaV9hIjpbIjE4MjgxMDIzOTY3MTY3MTQ4Mjg0MDc3ODUyNzI1MjU0MzY3MjM3MTQ5Mzc4MDY0MjY1ODIyMDc2OTM3MDQ0NDc5NDE2OTM1NDk1MDE1IiwiMTY0NzkyMzExMjExNDA2NjU4MDc0MTMzOTI1NTIzNzEzMjAxNjcxNTcwOTc5MTIxNjU4NjE5MDk0MDYwNzkzMjYzOTUyOTM5OTUwODIiLCIxIl0sInBpX2IiOltbIjEwOTE5MzU4Njg1NTY1NzQzODkzMzg3Mjk1NjgwNzk0OTY2Njg0OTQ0NjQ1ODQ3OTMyNzI4MDEzMzI1OTgxOTY5MjY4ODk1MTkxMDI2IiwiMjEwMzk4NDgwMTE3Mzc1OTUxMDM0NjYxODQ4MTIyMzI5MDk1NDE4MTAwNDY5NzE4OTY1NjE3ODAwMzg3ODMzODk0NjA2MzkxNTQ5MTMiXSxbIjI1NDUyMzEzNzU3NDU3MDM4OTY0Mzg4NjU4ODEwNjYwMjYzMTg2NzM4NTc4MzQyNDIzNDg0MDc4OTYzMzg4MDE3MjI3MjA3NDIzNzgiLCIxNzE1NTc4OTMxNzg4MDI3MDc3NzUyMDM2OTc1MDM3NzAyODk1NDA1MTQ2OTY2Mzk1MTczMDQxMTkyMzE0NDIwODc4NDQ5MzgyNzYxMSJdLFsiMSIsIjAiXV0sInBpX2MiOlsiNDYxODI0NjU0NzkwMjkzMDE3MTYwMTM5MTUyOTAxNzk5OTMyNjcyOTkyMzUyNzA1MDE4NTAwNTE2OTI5NjUxOTI3NDQ4NTA2OTQ5OCIsIjgyMDg2Njc2OTM0Njg1OTQyMzczMTU2OTY3NjQ2Njg5NTI3MzE3MDk3MjA4Nzc5OTAxMjUyNTgzNDU2MDMwMzIyNjc0NjUzMTQ4MzkiLCIxIl0sInByb3RvY29sIjoiZ3JvdGgxNiIsImN1cnZlIjoiYm4xMjgifSwicHViX3NpZ25hbHMiOlsiMSIsIjIxNDA0MDQxODQxNjkwMTMwOTA4NTk1NTI1NjA1Njk1NjY0OTY4NTAwODc3NjE3MDU2MDY0MjY5MTkyODk1NTQxNTU3NzkzMjgyIiwiMTQxNzI3NzAwODg2MDIyNTU4MjU3MzM2MTEzNjUzOTg3MTg5MzUzNzEyNDQ1NzUyNTMwNTYzNjEzMDc4MjMzMDMwMjg0NDI5MDc5NTAiLCIxIiwiMjc3NTI3NjY4MjMzNzE0NzE0MDgyNDgyMjU3MDg2ODEzMTM3NjQ4NjYyMzE2NTUxODczNjYwNzE4ODEwNzA5MTg5ODQ0NzEwNDIiLCIxIiwiNjczMjk4MjYxNjY0NzgxMTc1NDExOTc5NjE4NjQ3NDI2MTQxNzgxOTM3MDI3NzE4NzI3OTkzMzQ2OTM2MDY0NTE0OTM5NzkzNjAzMiIsIjE2ODIzMzU0OTMiLCIyMTk1Nzg2MTcwNjQ1NDAwMTYyMzQxNjE2NDAzNzU3NTU4NjU0MTIiLCIwIiwiNDc5MjEzMDA3OTQ2MjY4MTE2NTQyODUxMTIwMTI1MzIzNTg1MDAxNTY0ODM1Mjg4MzI0MDU3NzMxNTAyNjQ3Nzc4MDQ5MzExMDY3NSIsIjAiLCIxIiwiNjIyMjQ4NzU0NTgyMTgxMjYxOTMwNTEzNjkwMTc5MDI1MTc3MDM5MDY4NDEwNTI4MTkxNTcxODk5NTY4MjQ5MTkzNzA0MTc1ODc2IiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIiwiMCIsIjAiLCIwIl19XX19.eyJwcm9vZiI6eyJwaV9hIjpbIjc3NjY1ODUzMDg2MjIxMTI5MDQ1MzQ0NjQ2MDY4NTg2NDk2MzUyNTA2MzY5NDQ5NTU0MjQzMTE0MDUzODc0NjkxMDk0MDIzMzM3NTkiLCI1OTc2MDc4NDg2NzExMTUzOTk2OTYzMDQ0NDU5NjY5MzcyNjgwMTgwMjQwNDk4MTgwOTI0ODE3MjE3MTM5NjE4MzMwMDQwMTc0MTIiLCIxIl0sInBpX2IiOltbIjEyMzg2MjU2MTc1Njk4NjIwMTY5ODAxMTMwNDEyNzEyNzgwOTYyNjIwNjY5NzIxNzc1NDcyODQ4OTY2NzEwNzI1MjQ3NjczNDk0NzExIiwiOTk3NTE0NzcyMDc3ODgzNjc1MTE4NDUzMzM0ODUzMDgyMTQ0OTk3MjM4NTUzOTE4NTk0MDUxNTg4Nzk1ODgyMjczMzg1ODQ4Nzk4MCJdLFsiMzI2Njg2MDAwNjYwNzg5ODg1MzQ4NjE3OTg1NTQ4OTA3NDc4Nzg5NjQ2NjQ1ODgyNTM1ODI2OTUxMjAxNTA5MjY3OTEwMzU5NjIwNiIsIjEwMjg0MTc1Nzg2ODM3MTg4MzEzMTQ3ODY5MzY2NTU1MDU1NTMzMDU5NjI4OTUwMDI0ODk5OTAwNzQwNDM4ODYwMTU1ODYxMTM4MjAiXSxbIjEiLCIwIl1dLCJwaV9jIjpbIjEyMDg2ODY2OTk3NjY3NDIwMDg1MDIxNTkwODY4NTA3NjYzNjk3OTQwMjA2MTk1NzQyOTIxNjM1MjI0MzAwODIyMjAzMjkxNTU1NjgyIiwiODM5ODExNDQ3NjE2OTc0NDYyODgzODA0NTE2NDk0NzkxNDA4MDUzOTQ2NjQwNTU5MDU0NzY4NTgyMzI3NzgxMzc3ODk0NDE2ODA1OCIsIjEiXSwicHJvdG9jb2wiOiJncm90aDE2IiwiY3VydmUiOiJibjEyOCJ9LCJwdWJfc2lnbmFscyI6WyIyMTQwNDA0MTg0MTY5MDEzMDkwODU5NTUyNTYwNTY5NTY2NDk2ODUwMDg3NzYxNzA1NjA2NDI2OTE5Mjg5NTU0MTU1Nzc5MzI4MiIsIjIwOTQ1MjY4MTg3NDg3NzkzMjI5NDU5NDkwMTk1MzIzMzk3NzY2ODIzNjQwNTU1ODU0NjMxNDI2NDE0MTgyOTU4NDk2Mjg3MTUwMDY4IiwiMTA1MjI5NTY0NzMwODM3MjU4OTA1Nzk2ODUxMjM2NzgyNTYxNzQ5MTMyOTY0MTI5MTIzMDE0MzU0NTIwNjAyOTQ2ODI1MTEzODU0NzMiXX0` - schemaLoader := &mockJSONLDSchemaLoader{schema: kycV101Schema} - authInstance, err := NewVerifier(verificationKeyloader, schemaLoader, stateResolvers) + schemaLoader := &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + } + authInstance, err := NewVerifier(verificationKeyloader, stateResolvers, + WithDocumentLoader(schemaLoader)) require.NoError(t, err) _, err = authInstance.FullVerify(context.Background(), token, request) require.NoError(t, err) + + schemaLoader.assert(t) +} + +func loadSchema(name string) string { + bs, err := os.ReadFile("testdata/" + name) + if err != nil { + panic(err) + } + return string(bs) } diff --git a/go.mod b/go.mod index 985da36..8692487 100644 --- a/go.mod +++ b/go.mod @@ -13,8 +13,7 @@ require ( github.com/iden3/go-jwz/v2 v2.0.0-20230519132540-75b6744028b1 github.com/iden3/go-rapidsnark/types v0.0.3 github.com/iden3/go-rapidsnark/verifier v0.0.5 - github.com/iden3/go-schema-processor v1.3.1 - github.com/iden3/go-schema-processor/v2 v2.0.0-20230615161820-08a6be6de17c + github.com/iden3/go-schema-processor/v2 v2.0.0-20230706160026-132b2d90334c github.com/iden3/iden3comm/v2 v2.0.0-20230615170418-d60ff7a4c7f3 github.com/ipfs/go-ipfs-api v0.6.0 github.com/piprate/json-gold v0.5.1-0.20230111113000-6ddbe6e6f19f @@ -69,8 +68,6 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect - github.com/qri-io/jsonpointer v0.1.1 // indirect - github.com/qri-io/jsonschema v0.2.1 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect diff --git a/go.sum b/go.sum index a101954..a5093ad 100644 --- a/go.sum +++ b/go.sum @@ -125,10 +125,8 @@ github.com/iden3/go-rapidsnark/verifier v0.0.5 h1:J7y0ovrEjDQoWtZmlrp4tgGng1A9fa github.com/iden3/go-rapidsnark/verifier v0.0.5/go.mod h1:KgL3Yr9NehlFDI4EIWVLE3UDUi8ulyjbp7HcXSBfiGI= github.com/iden3/go-rapidsnark/witness v0.0.6 h1:p+6QBymSV3XWm1kB2PL2vlXxKXJN8GyWuqNJv/0PGGU= github.com/iden3/go-rapidsnark/witness v0.0.6/go.mod h1:57IHQpnvx0CeS6cAT07oN/lqwT5LRc4zicYoZ1cnAPE= -github.com/iden3/go-schema-processor v1.3.1 h1:LJfFInfYGMOp0bTKKC17R8q4XI+VtqhFLPTEqnOIvlM= -github.com/iden3/go-schema-processor v1.3.1/go.mod h1:NwJ1nuGdRlCFaN1/V6mS0AOAdvpLcGf4KKq0mluLG7U= -github.com/iden3/go-schema-processor/v2 v2.0.0-20230615161820-08a6be6de17c h1:2EJ4pOnQvY3j0rxfmKFCBkirGzUGAvfbz/0xToZYh+E= -github.com/iden3/go-schema-processor/v2 v2.0.0-20230615161820-08a6be6de17c/go.mod h1:7dq+eNag32Ktvrlc/7Y590SN77Gphc7k3DxjDC0Wso8= +github.com/iden3/go-schema-processor/v2 v2.0.0-20230706160026-132b2d90334c h1:/1HxXIIBU9r4DyQoOuHrpsI3Lr9EHl832xa/nIvY5zo= +github.com/iden3/go-schema-processor/v2 v2.0.0-20230706160026-132b2d90334c/go.mod h1:fuC9+rNfhMtgK9HoFXFt1xvsd6mCdAm8psUJIz80o6o= github.com/iden3/iden3comm/v2 v2.0.0-20230615170418-d60ff7a4c7f3 h1:IV86LrOi8XtQWre60W0H9Z/Qu+z0JM5RYCt2MYE1dZM= github.com/iden3/iden3comm/v2 v2.0.0-20230615170418-d60ff7a4c7f3/go.mod h1:WS/rgjgZkXKR3pzjSmx8McR512Wr93kTsIV+zuR8sl0= github.com/iden3/wasmer-go v0.0.1 h1:TZKh8Se8B/73PvWrcu+FTU9L1k5XYAmtFbioj7l0Uog= @@ -222,15 +220,9 @@ github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/qri-io/jsonpointer v0.1.1 h1:prVZBZLL6TW5vsSB9fFHFAMBLI4b0ri5vribQlTJiBA= -github.com/qri-io/jsonpointer v0.1.1/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64= -github.com/qri-io/jsonschema v0.2.1 h1:NNFoKms+kut6ABPf6xiKNM5214jzxAhDBrPHCJ97Wg0= -github.com/qri-io/jsonschema v0.2.1/go.mod h1:g7DPkiOsK1xv6T/Ao5scXRkd+yTFygcANPBaaqW+VrI= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= -github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= @@ -239,7 +231,6 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= diff --git a/loaders/schema.go b/loaders/schema.go deleted file mode 100644 index 5c4c707..0000000 --- a/loaders/schema.go +++ /dev/null @@ -1,43 +0,0 @@ -package loaders - -import ( - "context" - "fmt" - "net/url" - - "github.com/iden3/go-schema-processor/v2/loaders" - "github.com/iden3/go-schema-processor/v2/processor" -) - -// SchemaLoader is an interface for schema loading -type SchemaLoader interface { - Load(ctx context.Context, URL string) (schemaBytes []byte, extension string, err error) -} - -// DefaultSchemaLoader is loader defined by auth lib, but can be replaced with any custom loader -type DefaultSchemaLoader struct { - IpfsURL string `json:"ipfs_url"` -} - -// Load loads schema from IPFS or by http link -// -//nolint:gocritic // URL is correct name for variable that describes URL. -func (d DefaultSchemaLoader) Load(ctx context.Context, URL string) (schemaBytes []byte, extension string, err error) { - var loader processor.SchemaLoader - schemaURL, err := url.Parse(URL) - if err != nil { - return nil, "", err - } - switch schemaURL.Scheme { - case "http", "https": - loader = &loaders.HTTP{URL: URL} - case "ipfs": - loader = loaders.IPFS{ - URL: d.IpfsURL, - CID: schemaURL.Host, - } - default: - return nil, "", fmt.Errorf("loader for %s is not supported", schemaURL.Scheme) - } - return loader.Load(ctx) -} diff --git a/pubsignals/atomicMtpV2.go b/pubsignals/atomicMtpV2.go index 301ea77..74dfc7f 100644 --- a/pubsignals/atomicMtpV2.go +++ b/pubsignals/atomicMtpV2.go @@ -8,9 +8,9 @@ import ( "time" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-auth/v2/loaders" core "github.com/iden3/go-iden3-core/v2" "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/piprate/json-gold/ld" "github.com/pkg/errors" ) @@ -23,7 +23,7 @@ type AtomicQueryMTPV2 struct { func (c *AtomicQueryMTPV2) VerifyQuery( ctx context.Context, query Query, - schemaLoader loaders.SchemaLoader, + schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, ) error { return query.Check(ctx, schemaLoader, &CircuitOutputs{ diff --git a/pubsignals/atomicSigV2.go b/pubsignals/atomicSigV2.go index 774cada..0a4a1b6 100644 --- a/pubsignals/atomicSigV2.go +++ b/pubsignals/atomicSigV2.go @@ -8,9 +8,9 @@ import ( "time" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-auth/v2/loaders" core "github.com/iden3/go-iden3-core/v2" "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/piprate/json-gold/ld" "github.com/pkg/errors" ) @@ -23,7 +23,7 @@ type AtomicQuerySigV2 struct { func (c *AtomicQuerySigV2) VerifyQuery( ctx context.Context, query Query, - schemaLoader loaders.SchemaLoader, + schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage, ) error { err := query.Check(ctx, schemaLoader, &CircuitOutputs{ diff --git a/pubsignals/authV2.go b/pubsignals/authV2.go index b915e32..c5b058f 100644 --- a/pubsignals/authV2.go +++ b/pubsignals/authV2.go @@ -8,9 +8,9 @@ import ( "time" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-auth/v2/loaders" core "github.com/iden3/go-iden3-core/v2" "github.com/iden3/go-iden3-core/v2/w3c" + "github.com/piprate/json-gold/ld" "github.com/pkg/errors" ) @@ -23,7 +23,7 @@ type AuthV2 struct { func (c *AuthV2) VerifyQuery( _ context.Context, _ Query, - _ loaders.SchemaLoader, + _ ld.DocumentLoader, _ json.RawMessage) error { return errors.New("authV2 circuit doesn't support queries") } diff --git a/pubsignals/circuitVerifier.go b/pubsignals/circuitVerifier.go index 95b529f..f90cca4 100644 --- a/pubsignals/circuitVerifier.go +++ b/pubsignals/circuitVerifier.go @@ -6,8 +6,8 @@ import ( "math/big" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-auth/v2/loaders" "github.com/iden3/go-iden3-auth/v2/state" + "github.com/piprate/json-gold/ld" ) // StateResolver is a state resolver interface @@ -18,7 +18,7 @@ type StateResolver interface { // Verifier is interface for verification of public signals of zkp type Verifier interface { - VerifyQuery(ctx context.Context, query Query, schemaLoader loaders.SchemaLoader, verifiablePresentation json.RawMessage) error + VerifyQuery(ctx context.Context, query Query, schemaLoader ld.DocumentLoader, verifiablePresentation json.RawMessage) error VerifyStates(ctx context.Context, resolvers map[string]StateResolver, opts ...VerifyOpt) error VerifyIDOwnership(userIdentifier string, challenge *big.Int) error diff --git a/pubsignals/query.go b/pubsignals/query.go index 7a14f7e..fff3a5e 100644 --- a/pubsignals/query.go +++ b/pubsignals/query.go @@ -9,9 +9,7 @@ import ( "strconv" "github.com/iden3/go-circuits/v2" - "github.com/iden3/go-iden3-auth/v2/loaders" core "github.com/iden3/go-iden3-core/v2" - jsonSuite "github.com/iden3/go-schema-processor/v2/json" "github.com/iden3/go-schema-processor/v2/merklize" "github.com/iden3/go-schema-processor/v2/utils" "github.com/piprate/json-gold/ld" @@ -80,9 +78,11 @@ type CircuitOutputs struct { } // Check checks if proof was created for this query. +// Would be good to use ctx for external http requests, but current interfaces +// doesn't allow to do it. Left it for future. func (q Query) Check( - ctx context.Context, - loader loaders.SchemaLoader, + _ context.Context, + loader ld.DocumentLoader, pubSig *CircuitOutputs, verifiablePresentation json.RawMessage, ) error { @@ -90,20 +90,22 @@ func (q Query) Check( return err } - schemaBytes, _, err := loader.Load(ctx, q.Context) + schemaDoc, err := loader.LoadDocument(q.Context) if err != nil { return fmt.Errorf("failed load schema by context: %w", err) } - if err := q.verifySchemaID(schemaBytes, pubSig); err != nil { + schemaBytes, err := json.Marshal(schemaDoc.Document) + if err != nil { + return fmt.Errorf("failed jsonify schema document: %w", err) + } + + if err := q.verifySchemaID(schemaBytes, pubSig, loader); err != nil { return err } - if err := q.verifyCredentialSubject( - pubSig, - verifiablePresentation, - schemaBytes, - ); err != nil { + if err := q.verifyCredentialSubject(pubSig, verifiablePresentation, + schemaBytes, loader); err != nil { return err } @@ -111,10 +113,12 @@ func (q Query) Check( return errors.New("check revocation is required") } - return q.verifyClaim(ctx, schemaBytes, pubSig) + return q.verifyClaim(schemaBytes, pubSig, loader) } -func (q Query) verifyClaim(_ context.Context, schemaBytes []byte, pubSig *CircuitOutputs) error { +func (q Query) verifyClaim(schemaBytes []byte, pubSig *CircuitOutputs, + schemaLoader ld.DocumentLoader) error { + if len(q.CredentialSubject) == 0 { return nil } @@ -125,7 +129,8 @@ func (q Query) verifyClaim(_ context.Context, schemaBytes []byte, pubSig *Circui } if pubSig.Merklized == 1 { - path, err := merklize.NewFieldPathFromContext(schemaBytes, q.Type, fieldName) + path, err := merklize.Options{DocumentLoader: schemaLoader}. + FieldPathFromContext(schemaBytes, q.Type, fieldName) if err != nil { return err } @@ -147,13 +152,7 @@ func (q Query) verifyClaim(_ context.Context, schemaBytes []byte, pubSig *Circui return errors.New("proof doesn't contains target query key") } } else { - slotIdx, err := jsonSuite.Parser{}.GetFieldSlotIndex(fieldName, schemaBytes) - if err != nil { - return err - } - if pubSig.SlotIndex != slotIdx { - return errors.New("different slot index for claim") - } + return errors.New("non-merklized credentials are not supported") } return nil @@ -172,10 +171,11 @@ func (q Query) verifyIssuer(pubSig *CircuitOutputs) error { return ErrUnavailableIssuer } -func (q Query) verifySchemaID(schemaBytes []byte, - pubSig *CircuitOutputs) error { +func (q Query) verifySchemaID(schemaBytes []byte, pubSig *CircuitOutputs, + schemaLoader ld.DocumentLoader) error { - schemaID, err := merklize.TypeIDFromContext(schemaBytes, q.Type) + schemaID, err := merklize.Options{DocumentLoader: schemaLoader}. + TypeIDFromContext(schemaBytes, q.Type) if err != nil { return err } @@ -190,6 +190,7 @@ func (q Query) verifyCredentialSubject( pubSig *CircuitOutputs, verifiablePresentation json.RawMessage, ctxBytes []byte, + schemaLoader ld.DocumentLoader, ) error { fieldName, predicate, err := extractQueryFields(q.CredentialSubject) if err != nil { @@ -198,10 +199,8 @@ func (q Query) verifyCredentialSubject( var fieldType string if fieldName != "" { - fieldType, err = merklize.TypeFromContext( - ctxBytes, - fmt.Sprintf("%s.%s", q.Type, fieldName), - ) + fieldType, err = merklize.Options{DocumentLoader: schemaLoader}. + TypeFromContext(ctxBytes, fmt.Sprintf("%s.%s", q.Type, fieldName)) if err != nil { return err } @@ -210,12 +209,8 @@ func (q Query) verifyCredentialSubject( // validate selectivity disclosure request if q.isSelectivityDisclosure(predicate) { ctx := context.Background() - return q.validateDisclosure( - ctx, - pubSig, - fieldName, - verifiablePresentation, - ) + return q.validateDisclosure(ctx, pubSig, fieldName, + verifiablePresentation, schemaLoader) } // validate empty credential subject request @@ -257,12 +252,10 @@ func (q Query) verifyCredentialSubject( return nil } -func (q Query) validateDisclosure( - ctx context.Context, - pubSig *CircuitOutputs, - key string, - verifiablePresentation json.RawMessage, -) error { +func (q Query) validateDisclosure(ctx context.Context, pubSig *CircuitOutputs, + key string, verifiablePresentation json.RawMessage, + schemaLoader ld.DocumentLoader) error { + if verifiablePresentation == nil { return errors.New("selective disclosure value is missed") } @@ -277,12 +270,16 @@ func (q Query) validateDisclosure( } } - mz, err := merklize.MerklizeJSONLD(ctx, bytes.NewBuffer(verifiablePresentation)) + mz, err := merklize.MerklizeJSONLD(ctx, + bytes.NewBuffer(verifiablePresentation), + merklize.WithDocumentLoader(schemaLoader)) if err != nil { return errors.Errorf("failed to merklize doc: %v", err) } - merklizedPath, err := merklize.NewPathFromDocument(verifiablePresentation, fmt.Sprintf("verifiableCredential.credentialSubject.%s", key)) + merklizedPath, err := merklize.Options{DocumentLoader: schemaLoader}. + NewPathFromDocument(verifiablePresentation, + fmt.Sprintf("verifiableCredential.credentialSubject.%s", key)) if err != nil { return errors.Errorf("failed build path to '%s' key: %v", key, err) } diff --git a/pubsignals/query_test.go b/pubsignals/query_test.go index 33551e3..a875a8a 100644 --- a/pubsignals/query_test.go +++ b/pubsignals/query_test.go @@ -6,121 +6,44 @@ import ( "errors" "fmt" "math/big" + "os" "testing" core "github.com/iden3/go-iden3-core/v2" + "github.com/iden3/go-schema-processor/v2/utils" + "github.com/piprate/json-gold/ld" "github.com/stretchr/testify/require" ) var ( - issuerDID = "did:polygonid:polygon:mumbai:2qHSHBGWGJ68AosMKcLCTp8FYdVrtYE6MtNHhq8xpK" - iid, _ = new(big.Int).SetString("22638457188543025296541325416907897762715008870723718557276875842936181250", 10) - issuerID, _ = core.IDFromInt(iid) - - schemaHashKYCEmployee, _ = big.NewInt(0).SetString("40507426258035268209384482717564233104", 10) - KYCEmployeeSchema = core.NewSchemaHashFromInt(schemaHashKYCEmployee) - - schemaHashKYCCountry, _ = big.NewInt(0).SetString("336615423900919464193075592850483704600", 10) - KYCCountrySchema = core.NewSchemaHashFromInt(schemaHashKYCCountry) - + issuerDID = "did:polygonid:polygon:mumbai:2qHSHBGWGJ68AosMKcLCTp8FYdVrtYE6MtNHhq8xpK" + iid, _ = new(big.Int).SetString("22638457188543025296541325416907897762715008870723718557276875842936181250", 10) + issuerID, _ = core.IDFromInt(iid) bigIntTrueHash, _ = big.NewInt(0).SetString("18586133768512220936620570745912940619677854269274689475585506675881198879027", 10) ) -type mockMemorySchemaLoader struct { +type mockJSONLDSchemaLoader struct { + schemas map[string]string + seen map[string]bool } -func (r *mockMemorySchemaLoader) Load(_ context.Context, _ string) (schema []byte, ext string, err error) { - return []byte(`{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "$metadata": { - "uris": { - "jsonLdContext": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", - "jsonSchema": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json/KYCCountryOfResidenceCredential-v2.json" - }, - "serialization": { - "valueDataSlotB": "countryCode" +func (r *mockJSONLDSchemaLoader) LoadDocument(u string) (*ld.RemoteDocument, error) { + if body, ok := r.schemas[u]; ok { + if r.seen == nil { + r.seen = make(map[string]bool) + } + r.seen[u] = true + var doc = ld.RemoteDocument{DocumentURL: u} + err := json.Unmarshal([]byte(body), &doc.Document) + return &doc, err } - }, - "@context": [ - { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "KYCAgeCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCAgeCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "birthday": { - "@id": "kyc-vocab:birthday", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCCountryOfResidenceCredential": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "countryCode": { - "@id": "kyc-vocab:countryCode", - "@type": "xsd:integer" - }, - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - } - } - }, - "KYCEmployee": { - "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCEmployee", - "@context": { - "@version": 1.1, - "@protected": true, - "id": "@id", - "type": "@type", - "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", - "xsd": "http://www.w3.org/2001/XMLSchema#", - "documentType": { - "@id": "kyc-vocab:documentType", - "@type": "xsd:integer" - }, - "ZKPexperiance": { - "@id": "kyc-vocab:hasZKPexperiance", - "@type": "xsd:boolean" - }, - "hireDate": { - "@id": "kyc-vocab:hireDate", - "@type": "xsd:dateTime" - }, - "position": { - "@id": "kyc-vocab:position", - "@type": "xsd:string" - }, - "salary": { - "@id": "kyc-vocab:salary", - "@type": "xsd:double" - } - } - } - } - ] + return nil, fmt.Errorf("schema not found: %v", u) } -`), "json-ld", nil + +func (r *mockJSONLDSchemaLoader) assert(t testing.TB) { + for url := range r.schemas { + require.True(t, r.seen[url], "schema not loaded: %v", url) + } } var vp = []byte(`{ @@ -168,6 +91,7 @@ func TestCheckRequest_Success(t *testing.T) { query Query pubSig *CircuitOutputs vp json.RawMessage + loader *mockJSONLDSchemaLoader }{ { name: "Check merkalized query", @@ -183,7 +107,7 @@ func TestCheckRequest_Success(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -193,6 +117,11 @@ func TestCheckRequest_Success(t *testing.T) { Merklized: 1, IsRevocationChecked: 1, }, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Selective disclosure", @@ -206,7 +135,7 @@ func TestCheckRequest_Success(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -217,6 +146,12 @@ func TestCheckRequest_Success(t *testing.T) { IsRevocationChecked: 1, }, vp: vp, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), + }, + }, }, { name: "Query with boolean type", @@ -227,12 +162,12 @@ func TestCheckRequest_Success(t *testing.T) { "$eq": true, }, }, - Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", Type: "KYCEmployee", }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCEmployeeSchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("1944808975288007371356450257872165609440470546066507760733183342797918372827", 10) return v @@ -242,6 +177,11 @@ func TestCheckRequest_Success(t *testing.T) { Merklized: 1, IsRevocationChecked: 1, }, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + }, }, { name: "Selective disclosure with xsd:string type", @@ -250,12 +190,12 @@ func TestCheckRequest_Success(t *testing.T) { CredentialSubject: map[string]interface{}{ "position": map[string]interface{}{}, }, - Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", Type: "KYCEmployee", }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCEmployeeSchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("15406634529806189041952040954758558497189093183268091368437514469450172572054", 10) return v @@ -269,6 +209,12 @@ func TestCheckRequest_Success(t *testing.T) { IsRevocationChecked: 1, }, vp: vpEmployee, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), + }, + }, }, { name: "EQ operator for xsd:string type", @@ -279,12 +225,12 @@ func TestCheckRequest_Success(t *testing.T) { "$eq": "Software Engineer", }, }, - Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", Type: "KYCEmployee", }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCEmployeeSchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("15406634529806189041952040954758558497189093183268091368437514469450172572054", 10) return v @@ -298,13 +244,19 @@ func TestCheckRequest_Success(t *testing.T) { IsRevocationChecked: 1, }, vp: vpEmployee, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), &mockMemorySchemaLoader{}, tt.pubSig, tt.vp) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp) require.NoError(t, err) + tt.loader.assert(t) }) } } @@ -316,6 +268,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { pubSig *CircuitOutputs vp json.RawMessage expErr error + loader *mockJSONLDSchemaLoader }{ { name: "Empty disclosure value for disclosure request", @@ -330,7 +283,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { vp: nil, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -341,6 +294,11 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("selective disclosure value is missed"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Not EQ operation for disclosure request", @@ -355,7 +313,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { vp: vp, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -366,6 +324,11 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("selective disclosure available only for equal operation"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Not array of values for disclosure request", @@ -380,7 +343,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { vp: vp, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -391,6 +354,11 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("selective disclosure not available for array of values"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Proof was generated for another disclosure value", @@ -405,7 +373,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { vp: vp, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -416,6 +384,12 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("different value between proof and disclosure value"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), + }, + }, }, { name: "Different key between proof and disclosure response", @@ -430,7 +404,7 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { vp: vp, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: func() *big.Int { v, _ := big.NewInt(0).SetString("17002437119434618783545694633038537380726339994244684348913844923422470806844", 10) return v @@ -441,13 +415,20 @@ func TestCheckRequest_SelectiveDisclosure_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("path '[https://www.w3.org/2018/credentials#verifiableCredential https://www.w3.org/2018/credentials#credentialSubject https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#documentType]' doesn't exist in document"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + "https://www.w3.org/2018/credentials/v1": loadSchema("credentials-v1.json-ld"), + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), &mockMemorySchemaLoader{}, tt.pubSig, tt.vp) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, tt.vp) require.EqualError(t, err, tt.expErr.Error()) + tt.loader.assert(t) }) } } @@ -458,6 +439,7 @@ func TestCheckRequest_Error(t *testing.T) { query Query pubSig *CircuitOutputs expErr error + loader *mockJSONLDSchemaLoader }{ { name: "Invalid issuer", @@ -468,6 +450,7 @@ func TestCheckRequest_Error(t *testing.T) { IssuerID: &issuerID, }, expErr: ErrUnavailableIssuer, + loader: &mockJSONLDSchemaLoader{}, }, { name: "Invalid Schema ID", @@ -478,9 +461,14 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), }, expErr: ErrSchemaID, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Multiply query", @@ -495,9 +483,14 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), }, expErr: errors.New("multiple requests not supported"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Failed params in request", @@ -511,9 +504,14 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), }, expErr: errors.New("failed cast type map[string]interface"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Multiple predicates in one request", @@ -530,9 +528,14 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), }, expErr: errors.New("multiple predicates for one field not supported"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Proof was generated for another query operator", @@ -548,10 +551,15 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), Operator: 3, }, expErr: ErrRequestOperator, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Proof was generated for another values", @@ -567,11 +575,16 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), Operator: 5, Value: []*big.Int{big.NewInt(40)}, }, expErr: ErrInvalidValues, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Proof was generated for another path", @@ -587,7 +600,7 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), ClaimPathKey: big.NewInt(0), Operator: 5, Value: []*big.Int{big.NewInt(20)}, @@ -595,9 +608,14 @@ func TestCheckRequest_Error(t *testing.T) { IsRevocationChecked: 1, }, expErr: errors.New("proof was generated for another path"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { - name: "Different slot index", + name: "non-merklized credentials are not supported", query: Query{ AllowedIssuers: []string{issuerDID}, Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", @@ -610,14 +628,19 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), Operator: 5, Value: []*big.Int{big.NewInt(20)}, Merklized: 0, SlotIndex: 0, IsRevocationChecked: 1, }, - expErr: errors.New("different slot index for claim"), + expErr: errors.New("non-merklized credentials are not supported"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Check revocation is required", @@ -634,7 +657,7 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCCountrySchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential")), Operator: 5, Value: []*big.Int{big.NewInt(20)}, Merklized: 0, @@ -642,12 +665,17 @@ func TestCheckRequest_Error(t *testing.T) { IsRevocationChecked: 0, }, expErr: errors.New("check revocation is required"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld": loadSchema("kyc-v3.json-ld"), + }, + }, }, { name: "Unsupported lt operator for xsd:boolean", query: Query{ AllowedIssuers: []string{issuerDID}, - Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", Type: "KYCEmployee", CredentialSubject: map[string]interface{}{ "ZKPexperiance": map[string]interface{}{ @@ -658,7 +686,7 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCEmployeeSchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee")), Operator: 2, Value: []*big.Int{big.NewInt(20)}, Merklized: 0, @@ -666,12 +694,17 @@ func TestCheckRequest_Error(t *testing.T) { IsRevocationChecked: 0, }, expErr: errors.New("invalid operation '$lt' for field type 'http://www.w3.org/2001/XMLSchema#boolean'"), + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + }, }, { name: "Negative value in request", query: Query{ AllowedIssuers: []string{issuerDID}, - Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld", + Context: "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld", Type: "KYCEmployee", CredentialSubject: map[string]interface{}{ "documentType": map[string]interface{}{ @@ -682,7 +715,7 @@ func TestCheckRequest_Error(t *testing.T) { }, pubSig: &CircuitOutputs{ IssuerID: &issuerID, - ClaimSchema: KYCEmployeeSchema, + ClaimSchema: utils.CreateSchemaHash([]byte("https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee")), Operator: 1, Value: []*big.Int{big.NewInt(-1)}, Merklized: 0, @@ -690,13 +723,19 @@ func TestCheckRequest_Error(t *testing.T) { IsRevocationChecked: 0, }, expErr: ErrNegativeValue, + loader: &mockJSONLDSchemaLoader{ + schemas: map[string]string{ + "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld": loadSchema("kyc-v101.json-ld"), + }, + }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.query.Check(context.Background(), &mockMemorySchemaLoader{}, tt.pubSig, nil) + err := tt.query.Check(context.Background(), tt.loader, tt.pubSig, nil) require.EqualError(t, err, tt.expErr.Error()) + tt.loader.assert(t) }) } } @@ -793,3 +832,11 @@ func TestVerifyQuery_Error(t *testing.T) { }) } } + +func loadSchema(name string) string { + bs, err := os.ReadFile("../testdata/" + name) + if err != nil { + panic(err) + } + return string(bs) +} diff --git a/testdata/credentials-v1.json-ld b/testdata/credentials-v1.json-ld new file mode 100644 index 0000000..0124a3c --- /dev/null +++ b/testdata/credentials-v1.json-ld @@ -0,0 +1,237 @@ +{ + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "VerifiableCredential": { + "@id": "https://www.w3.org/2018/credentials#VerifiableCredential", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "credentialSchema": { + "@id": "cred:credentialSchema", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + + "JsonSchemaValidator2018": "cred:JsonSchemaValidator2018" + } + }, + "credentialStatus": {"@id": "cred:credentialStatus", "@type": "@id"}, + "credentialSubject": {"@id": "cred:credentialSubject", "@type": "@id"}, + "evidence": {"@id": "cred:evidence", "@type": "@id"}, + "expirationDate": {"@id": "cred:expirationDate", "@type": "xsd:dateTime"}, + "holder": {"@id": "cred:holder", "@type": "@id"}, + "issued": {"@id": "cred:issued", "@type": "xsd:dateTime"}, + "issuer": {"@id": "cred:issuer", "@type": "@id"}, + "issuanceDate": {"@id": "cred:issuanceDate", "@type": "xsd:dateTime"}, + "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, + "refreshService": { + "@id": "cred:refreshService", + "@type": "@id", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + + "ManualRefreshService2018": "cred:ManualRefreshService2018" + } + }, + "termsOfUse": {"@id": "cred:termsOfUse", "@type": "@id"}, + "validFrom": {"@id": "cred:validFrom", "@type": "xsd:dateTime"}, + "validUntil": {"@id": "cred:validUntil", "@type": "xsd:dateTime"} + } + }, + + "VerifiablePresentation": { + "@id": "https://www.w3.org/2018/credentials#VerifiablePresentation", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "cred": "https://www.w3.org/2018/credentials#", + "sec": "https://w3id.org/security#", + + "holder": {"@id": "cred:holder", "@type": "@id"}, + "proof": {"@id": "sec:proof", "@type": "@id", "@container": "@graph"}, + "verifiableCredential": {"@id": "cred:verifiableCredential", "@type": "@id", "@container": "@graph"} + } + }, + + "EcdsaSecp256k1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256k1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "EcdsaSecp256r1Signature2019": { + "@id": "https://w3id.org/security#EcdsaSecp256r1Signature2019", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "Ed25519Signature2018": { + "@id": "https://w3id.org/security#Ed25519Signature2018", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "RsaSignature2018": { + "@id": "https://w3id.org/security#RsaSignature2018", + "@context": { + "@version": 1.1, + "@protected": true, + + "challenge": "sec:challenge", + "created": {"@id": "http://purl.org/dc/terms/created", "@type": "xsd:dateTime"}, + "domain": "sec:domain", + "expires": {"@id": "sec:expiration", "@type": "xsd:dateTime"}, + "jws": "sec:jws", + "nonce": "sec:nonce", + "proofPurpose": { + "@id": "sec:proofPurpose", + "@type": "@vocab", + "@context": { + "@version": 1.1, + "@protected": true, + + "id": "@id", + "type": "@type", + + "sec": "https://w3id.org/security#", + + "assertionMethod": {"@id": "sec:assertionMethod", "@type": "@id", "@container": "@set"}, + "authentication": {"@id": "sec:authenticationMethod", "@type": "@id", "@container": "@set"} + } + }, + "proofValue": "sec:proofValue", + "verificationMethod": {"@id": "sec:verificationMethod", "@type": "@id"} + } + }, + + "proof": {"@id": "https://w3id.org/security#proof", "@type": "@id", "@container": "@graph"} + } +} diff --git a/testdata/kyc-v101.json-ld b/testdata/kyc-v101.json-ld new file mode 100644 index 0000000..94812e1 --- /dev/null +++ b/testdata/kyc-v101.json-ld @@ -0,0 +1,79 @@ +{ + "@context": [ + { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "KYCAgeCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCAgeCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "birthday": { + "@id": "kyc-vocab:birthday", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + }, + "KYCCountryOfResidenceCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCCountryOfResidenceCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "countryCode": { + "@id": "kyc-vocab:countryCode", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + }, + "KYCEmployee": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v101.json-ld#KYCEmployee", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + }, + "ZKPexperiance": { + "@id": "kyc-vocab:hasZKPexperiance", + "@type": "xsd:boolean" + }, + "hireDate": { + "@id": "kyc-vocab:hireDate", + "@type": "xsd:dateTime" + }, + "position": { + "@id": "kyc-vocab:position", + "@type": "xsd:string" + }, + "salary": { + "@id": "kyc-vocab:salary", + "@type": "xsd:double" + } + } + } + } + ] +} diff --git a/testdata/kyc-v2.json-ld b/testdata/kyc-v2.json-ld new file mode 100644 index 0000000..0834274 --- /dev/null +++ b/testdata/kyc-v2.json-ld @@ -0,0 +1,48 @@ +{ + "@context": [ + { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "KYCAgeCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld#KYCAgeCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "serialization": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/serialization.md#", + "birthday": { + "@id": "kyc-vocab:birthday", + "@type": "serialization:IndexDataSlotA" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "serialization:IndexDataSlotB" + } + } + }, + "KYCCountryOfResidenceCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v2.json-ld#KYCCountryOfResidenceCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "serialization": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/serialization.md#", + "countryCode": { + "@id": "kyc-vocab:countryCode", + "@type": "serialization:IndexDataSlotA" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "serialization:IndexDataSlotB" + } + } + } + } + ] +} diff --git a/testdata/kyc-v3.json-ld b/testdata/kyc-v3.json-ld new file mode 100644 index 0000000..4c86336 --- /dev/null +++ b/testdata/kyc-v3.json-ld @@ -0,0 +1,48 @@ +{ + "@context": [ + { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "KYCAgeCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCAgeCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "birthday": { + "@id": "kyc-vocab:birthday", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + }, + "KYCCountryOfResidenceCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v3.json-ld#KYCCountryOfResidenceCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "countryCode": { + "@id": "kyc-vocab:countryCode", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + } + } + ] +} diff --git a/testdata/kyc-v4.json-ld b/testdata/kyc-v4.json-ld new file mode 100644 index 0000000..09f1938 --- /dev/null +++ b/testdata/kyc-v4.json-ld @@ -0,0 +1,48 @@ +{ + "@context": [ + { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "KYCAgeCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld#KYCAgeCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "birthday": { + "@id": "kyc-vocab:birthday", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + }, + "KYCCountryOfResidenceCredential": { + "@id": "https://raw.githubusercontent.com/iden3/claim-schema-vocab/main/schemas/json-ld/kyc-v4.jsonld#KYCCountryOfResidenceCredential", + "@context": { + "@version": 1.1, + "@protected": true, + "id": "@id", + "type": "@type", + "kyc-vocab": "https://github.com/iden3/claim-schema-vocab/blob/main/credentials/kyc.md#", + "xsd": "http://www.w3.org/2001/XMLSchema#", + "countryCode": { + "@id": "kyc-vocab:countryCode", + "@type": "xsd:integer" + }, + "documentType": { + "@id": "kyc-vocab:documentType", + "@type": "xsd:integer" + } + } + } + } + ] +}