diff --git a/Cargo.toml b/Cargo.toml index 2ca2e2460..ff6ec5181 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi" -version = "0.9.0" +version = "0.10.0" authors = ["Spruce Systems, Inc."] edition = "2021" license = "Apache-2.0" @@ -37,9 +37,9 @@ ssi-json-ld = { path = "./crates/json-ld", version = "0.3", default-features = f ssi-security = { path = "./crates/security", version = "0.1", default-features = false } ssi-caips = { path = "./crates/caips", version = "0.2.1", default-features = false } ssi-ucan = { path = "./crates/ucan", version = "0.2.1", default-features = false } -ssi-zcap-ld = { path = "./crates/zcap-ld", version = "0.2.1", default-features = false } +ssi-zcap-ld = { path = "./crates/zcap-ld", version = "0.3.0", default-features = false } ssi-ssh = { path = "./crates/ssh", version = "0.2.1", default-features = false } -ssi-status = { path = "./crates/status", version = "0.2", default-features = false } +ssi-status = { path = "./crates/status", version = "0.3.0", default-features = false } ssi-bbs = { path = "./crates/bbs", version = "0.1.1", default-features = false } # Verifiable Claims @@ -48,13 +48,13 @@ ssi-jws = { path = "./crates/claims/crates/jws", version = "0.3", default-featur ssi-jwt = { path = "./crates/claims/crates/jwt", version = "0.3", default-features = false } ssi-sd-jwt = { path = "./crates/claims/crates/sd-jwt", version = "0.3", default-features = false } ssi-cose = { path = "./crates/claims/crates/cose", version = "0.1", default-features = false } -ssi-vc = { path = "./crates/claims/crates/vc", version = "0.3.1", default-features = false } -ssi-vc-jose-cose = { path = "./crates/claims/crates/vc-jose-cose", version = "0.1.1", default-features = false } +ssi-vc = { path = "./crates/claims/crates/vc", version = "0.4.0", default-features = false } +ssi-vc-jose-cose = { path = "./crates/claims/crates/vc-jose-cose", version = "0.2.0", default-features = false } ssi-data-integrity-core = { path = "./crates/claims/crates/data-integrity/core", version = "0.2", default-features = false } ssi-di-sd-primitives = { path = "./crates/claims/crates/data-integrity/sd-primitives", version = "0.2", default-features = false } ssi-data-integrity-suites = { path = "./crates/claims/crates/data-integrity/suites", version = "0.1.1", default-features = false } ssi-data-integrity = { path = "./crates/claims/crates/data-integrity", version = "0.1.1", default-features = false } -ssi-claims = { path = "./crates/claims", version = "0.1.1", default-features = false } +ssi-claims = { path = "./crates/claims", version = "0.2.0", default-features = false } # DID methods ssi-dids-core = { path = "./crates/dids/core", version = "0.1.1", default-features = false } diff --git a/crates/claims/Cargo.toml b/crates/claims/Cargo.toml index 1f48e17f5..05e8f06db 100644 --- a/crates/claims/Cargo.toml +++ b/crates/claims/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi-claims" -version = "0.1.1" +version = "0.2.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "Apache-2.0" diff --git a/crates/claims/crates/vc-jose-cose/Cargo.toml b/crates/claims/crates/vc-jose-cose/Cargo.toml index d033f22be..0badec7bf 100644 --- a/crates/claims/crates/vc-jose-cose/Cargo.toml +++ b/crates/claims/crates/vc-jose-cose/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi-vc-jose-cose" -version = "0.1.1" +version = "0.2.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "Apache-2.0" diff --git a/crates/claims/crates/vc/Cargo.toml b/crates/claims/crates/vc/Cargo.toml index 0ed899af0..83cdfd630 100644 --- a/crates/claims/crates/vc/Cargo.toml +++ b/crates/claims/crates/vc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi-vc" -version = "0.3.1" +version = "0.4.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "Apache-2.0" diff --git a/crates/claims/crates/vc/src/v1/revocation/v2020.rs b/crates/claims/crates/vc/src/v1/revocation/v2020.rs index 23aaa3f19..e14f35db5 100644 --- a/crates/claims/crates/vc/src/v1/revocation/v2020.rs +++ b/crates/claims/crates/vc/src/v1/revocation/v2020.rs @@ -169,7 +169,7 @@ impl CredentialStatus for RevocationList2020Status { ))); } - let revocation_list = match revocation_list_credential.credential_subjects.as_slice() { + let revocation_list = match revocation_list_credential.credential_subjects.as_ref() { [RevocationList2020Subject::RevocationList2020(l)] => l, [] => return Ok(StatusCheck::Invalid(Reason::MissingCredentialSubject)), _ => return Ok(StatusCheck::Invalid(Reason::TooManyCredentialSubjects)), diff --git a/crates/claims/crates/vc/src/v1/revocation/v2021.rs b/crates/claims/crates/vc/src/v1/revocation/v2021.rs index 927034e87..2cc51f110 100644 --- a/crates/claims/crates/vc/src/v1/revocation/v2021.rs +++ b/crates/claims/crates/vc/src/v1/revocation/v2021.rs @@ -192,7 +192,7 @@ impl CredentialStatus for StatusList2021Entry { ))); } - let revocation_list = match status_list_credential.credential_subjects.as_slice() { + let revocation_list = match status_list_credential.credential_subjects.as_ref() { [StatusList2021Subject::StatusList2021(l)] => l, [] => return Ok(StatusCheck::Invalid(Reason::MissingCredentialSubject)), _ => return Ok(StatusCheck::Invalid(Reason::TooManyCredentialSubjects)), diff --git a/crates/claims/crates/vc/src/v1/syntax/credential.rs b/crates/claims/crates/vc/src/v1/syntax/credential.rs index 9dcb6e5ac..d1dfd3259 100644 --- a/crates/claims/crates/vc/src/v1/syntax/credential.rs +++ b/crates/claims/crates/vc/src/v1/syntax/credential.rs @@ -10,9 +10,9 @@ use xsd_types::DateTime; use crate::{ syntax::{ - not_null, value_or_array, IdOr, IdentifiedObject, IdentifiedTypedObject, - MaybeIdentifiedTypedObject, RequiredContextList, RequiredType, RequiredTypeSet, - TypeSerializationPolicy, Types, + non_empty_value_or_array, not_null, value_or_array, IdOr, IdentifiedObject, + IdentifiedTypedObject, MaybeIdentifiedTypedObject, NonEmptyVec, RequiredContextList, + RequiredType, RequiredTypeSet, TypeSerializationPolicy, Types, }, Identified, MaybeIdentified, Typed, }; @@ -79,12 +79,8 @@ pub struct SpecializedJsonCredential< /// Credential subjects. #[serde(rename = "credentialSubject")] - #[serde( - with = "value_or_array", - default, - skip_serializing_if = "Vec::is_empty" - )] - pub credential_subjects: Vec, + #[serde(with = "non_empty_value_or_array")] + pub credential_subjects: NonEmptyVec, /// Issuer. pub issuer: Issuer, @@ -180,7 +176,7 @@ where id: Option, issuer: Issuer, issuance_date: xsd_types::DateTime, - credential_subjects: Vec, + credential_subjects: NonEmptyVec, ) -> Self { Self { context: Context::default(), diff --git a/crates/dids/methods/ethr/src/lib.rs b/crates/dids/methods/ethr/src/lib.rs index 3f6c30a1f..22d3aa9cb 100644 --- a/crates/dids/methods/ethr/src/lib.rs +++ b/crates/dids/methods/ethr/src/lib.rs @@ -380,7 +380,10 @@ mod tests { signing::AlterSignature, AnyInputSuiteOptions, AnySuite, CryptographicSuite, ProofOptions, }, - vc::v1::{JsonCredential, JsonPresentation}, + vc::{ + syntax::NonEmptyVec, + v1::{JsonCredential, JsonPresentation}, + }, VerificationParameters, }; use ssi_dids_core::{did, DIDResolver}; @@ -492,9 +495,9 @@ mod tests { None, did.clone().into_uri().into(), "2021-02-18T20:23:13Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })], + })), ); let verification_method = if eip712 { diff --git a/crates/dids/methods/key/src/lib.rs b/crates/dids/methods/key/src/lib.rs index 70911e6a4..e18f41562 100644 --- a/crates/dids/methods/key/src/lib.rs +++ b/crates/dids/methods/key/src/lib.rs @@ -364,7 +364,7 @@ mod tests { use resolution::Parameters; use ssi_claims::{ data_integrity::{AnyInputSuiteOptions, AnySuite}, - vc::v1::JsonCredential, + vc::{syntax::NonEmptyVec, v1::JsonCredential}, VerificationParameters, }; use ssi_data_integrity::{CryptographicSuite, ProofOptions as SuiteOptions}; @@ -576,9 +576,9 @@ mod tests { Some(uri!("http://example.org/credentials/3731").to_owned()), did.clone().into_uri().into(), "2020-08-19T21:41:50Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:d23dd687a7dc6787646f2eb98d0" - })], + })), ); let verification_method = DIDKey @@ -630,9 +630,9 @@ mod tests { None, did.clone().into_uri().into(), "2021-02-18T20:17:46Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:d23dd687a7dc6787646f2eb98d0" - })], + })), ); let verification_method = DIDKey @@ -684,9 +684,9 @@ mod tests { None, did.clone().into_uri().into(), "2021-02-18T20:17:46Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:d23dd687a7dc6787646f2eb98d0" - })], + })), ); let verification_method = DIDKey diff --git a/crates/dids/methods/pkh/src/lib.rs b/crates/dids/methods/pkh/src/lib.rs index 7a071ae52..c98edf75a 100644 --- a/crates/dids/methods/pkh/src/lib.rs +++ b/crates/dids/methods/pkh/src/lib.rs @@ -957,7 +957,10 @@ mod tests { data_integrity::{ signing::AlterSignature, AnyInputSuiteOptions, CryptographicSuite, ProofOptions, }, - vc::v1::{JsonCredential, JsonPresentation}, + vc::{ + syntax::NonEmptyVec, + v1::{JsonCredential, JsonPresentation}, + }, VerificationParameters, }; use ssi_verification_methods_core::{ProofPurpose, SingleSecretSigner}; @@ -974,9 +977,9 @@ mod tests { None, did.clone().into_uri().into(), "2021-03-18T16:38:25Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })], + })), ); let issuance_date = cred.issuance_date.clone().unwrap(); @@ -1090,7 +1093,10 @@ mod tests { data_integrity::{ signing::AlterSignature, AnyInputSuiteOptions, CryptographicSuite, ProofOptions, }, - vc::v1::{JsonCredential, JsonPresentation}, + vc::{ + syntax::NonEmptyVec, + v1::{JsonCredential, JsonPresentation}, + }, VerificationParameters, }; use ssi_verification_methods_core::{ProofPurpose, SingleSecretSigner}; @@ -1105,9 +1111,9 @@ mod tests { None, did.clone().into_uri().into(), "2021-03-18T16:38:25Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })], + })), ); let issuance_date = cred.issuance_date.clone().unwrap(); let created_date = diff --git a/crates/dids/methods/tz/tests/did.rs b/crates/dids/methods/tz/tests/did.rs index 904a79676..0687a88b3 100644 --- a/crates/dids/methods/tz/tests/did.rs +++ b/crates/dids/methods/tz/tests/did.rs @@ -7,7 +7,10 @@ use ssi_claims::{ signing::AlterSignature, AnyInputSuiteOptions, AnySuite, CryptographicSuite, DataIntegrity, ProofOptions as SuiteOptions, }, - vc::v1::{JsonCredential, JsonPresentation}, + vc::{ + syntax::NonEmptyVec, + v1::{JsonCredential, JsonPresentation}, + }, VerificationParameters, }; use ssi_dids_core::{did, resolution::Options, DIDResolver, VerificationMethodDIDResolver}; @@ -223,9 +226,9 @@ async fn credential_prove_verify_did_tz1() { None, did.clone().into_uri().into(), "2021-01-27T16:39:07Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })] + })) ), vec![ssi_claims::data_integrity::Proof::new( ssi_claims::data_integrity::suites::Ed25519BLAKE2BDigestSize20Base58CheckEncodedSignature2021, @@ -327,9 +330,9 @@ async fn credential_prove_verify_did_tz2() { None, did.clone().into_uri().into(), "2021-02-18T20:23:13Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })], + })), ); let didtz = VerificationMethodDIDResolver::new(DIDTZ); @@ -425,9 +428,9 @@ async fn credential_prove_verify_did_tz3() { None, did.clone().into_uri().into(), "2021-03-04T14:18:21Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:example:foo" - })], + })), ); let didtz = VerificationMethodDIDResolver::new(DIDTZ); diff --git a/crates/dids/methods/web/src/lib.rs b/crates/dids/methods/web/src/lib.rs index 19528df90..48afe4f3e 100644 --- a/crates/dids/methods/web/src/lib.rs +++ b/crates/dids/methods/web/src/lib.rs @@ -138,7 +138,7 @@ impl DIDMethodResolver for DIDWeb { mod tests { use ssi_claims::{ data_integrity::{AnySuite, CryptographicSuite, ProofOptions}, - vc::v1::JsonCredential, + vc::{syntax::NonEmptyVec, v1::JsonCredential}, VerificationParameters, }; use ssi_dids_core::{did, DIDResolver, Document, VerificationMethodDIDResolver}; @@ -254,9 +254,9 @@ mod tests { None, did!("did:web:localhost").to_owned().into_uri().into(), "2021-01-26T16:57:27Z".parse().unwrap(), - vec![json_syntax::json!({ + NonEmptyVec::new(json_syntax::json!({ "id": "did:web:localhost" - })], + })), ); let key: JWK = include_str!("../../../../../tests/ed25519-2020-10-18.json") diff --git a/crates/status/Cargo.toml b/crates/status/Cargo.toml index 755df54ab..e43078e91 100644 --- a/crates/status/Cargo.toml +++ b/crates/status/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi-status" -version = "0.2.1" +version = "0.3.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "Apache-2.0" diff --git a/crates/zcap-ld/Cargo.toml b/crates/zcap-ld/Cargo.toml index cf4050994..e174038dd 100644 --- a/crates/zcap-ld/Cargo.toml +++ b/crates/zcap-ld/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ssi-zcap-ld" -version = "0.2.1" +version = "0.3.0" edition = "2021" authors = ["Spruce Systems, Inc."] license = "Apache-2.0" diff --git a/examples/issue-revocation-list.rs b/examples/issue-revocation-list.rs index 5aaa32c8e..f403e641c 100644 --- a/examples/issue-revocation-list.rs +++ b/examples/issue-revocation-list.rs @@ -10,7 +10,7 @@ use ssi::{ jwk::JWK, verification_methods::SingleSecretSigner, }; -use ssi_claims::VerificationParameters; +use ssi_claims::{vc::syntax::NonEmptyVec, VerificationParameters}; use ssi_dids::DIDResolver; use static_iref::{iri, uri}; @@ -30,7 +30,7 @@ async fn main() { Some(uri!("https://example.test/revocationList.json").to_owned()), uri!("did:example:foo").to_owned().into(), xsd_types::DateTime::now_ms(), - vec![RevocationList2020Subject::RevocationList2020(rl)], + NonEmptyVec::new(RevocationList2020Subject::RevocationList2020(rl)), ); let verification_method = iri!("did:example:foo#key1").into(); diff --git a/examples/issue-status-list.rs b/examples/issue-status-list.rs index b70f499ec..38c396bd8 100644 --- a/examples/issue-status-list.rs +++ b/examples/issue-status-list.rs @@ -8,7 +8,7 @@ use ssi::{ jwk::JWK, verification_methods::SingleSecretSigner, }; -use ssi_claims::VerificationParameters; +use ssi_claims::{vc::syntax::NonEmptyVec, VerificationParameters}; use ssi_dids::DIDResolver; use static_iref::{iri, uri}; @@ -28,7 +28,7 @@ async fn main() { Some(uri!("https://example.com/credentials/status/3").to_owned()), uri!("did:example:12345").to_owned().into(), xsd_types::DateTime::now_ms(), - vec![StatusList2021Subject::StatusList2021(rl)], + NonEmptyVec::new(StatusList2021Subject::StatusList2021(rl)), ); let verification_method = iri!("did:example:12345#key1").into(); diff --git a/tests/send.rs b/tests/send.rs index 5e8c28097..2e1588342 100644 --- a/tests/send.rs +++ b/tests/send.rs @@ -17,6 +17,7 @@ use ssi::{ verification_methods::SingleSecretSigner, JWK, }; +use ssi_claims::vc::syntax::NonEmptyVec; use static_iref::uri; use std::future::Future; @@ -30,7 +31,10 @@ fn data_integrity_sign_is_send() { Some(uri!("https://example.org/#CredentialId").to_owned()), // id uri!("https://example.org/#Issuer").to_owned().into(), // issuer xsd_types::DateTime::now(), // issuance date - vec![], + NonEmptyVec::new(Claims { + name: "name".into(), + email: "email@example.com".into(), + }), ); let key = JWK::generate_p256(); // requires the `p256` feature.