Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion rust/src/oid4vci/credential.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ impl RawCredential {
W3cVcFormat::JwtVcJson => CredentialFormat::JwtVcJson,
W3cVcFormat::JwtVcJsonLd => CredentialFormat::JwtVcJsonLd,
},
payload: serde_json::to_vec(&credential.value).unwrap(),
payload: match credential.value {
serde_json::Value::String(s) => s.into_bytes(),
# SAFETY: value is `serde_json::Value`
value => serde_json::to_vec(&value).unwrap(),
},
}),
StandardFormat::MsoMdoc => match credential.value {
serde_json::Value::String(base64_mso_mdoc) => Ok(Self {
Expand Down
67 changes: 67 additions & 0 deletions rust/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,70 @@ pub async fn test_vc_playground_oid4vp() {
.await
.expect("Permission response submission failed");
}

#[cfg(test)]
mod tests {
use oid4vci::{
profile::{StandardFormat, W3cVcFormat},
Oid4vciCredential,
};

use crate::credential::{CredentialFormat, RawCredential};

#[test]
fn jwt_vc_json_payload_not_double_encoded() {
let jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIn0.\
signature";

let credential = Oid4vciCredential::new(serde_json::Value::String(jwt.to_owned()));
let format = StandardFormat::W3c(W3cVcFormat::JwtVcJson);

let raw = RawCredential::from_oid4vci(&format, credential).unwrap();

assert_eq!(raw.format, CredentialFormat::JwtVcJson);
assert_eq!(
raw.payload,
jwt.as_bytes(),
"payload should be the raw JWT bytes, not JSON-encoded with quotes"
);
}

#[test]
fn jwt_vc_json_ld_payload_not_double_encoded() {
let jwt = "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.\
eyJpc3MiOiJodHRwczovL2V4YW1wbGUuY29tIn0.\
signature";

let credential = Oid4vciCredential::new(serde_json::Value::String(jwt.to_owned()));
let format = StandardFormat::W3c(W3cVcFormat::JwtVcJsonLd);

let raw = RawCredential::from_oid4vci(&format, credential).unwrap();

assert_eq!(raw.format, CredentialFormat::JwtVcJsonLd);
assert_eq!(
raw.payload,
jwt.as_bytes(),
"payload should be the raw JWT bytes, not JSON-encoded with quotes"
);
}

#[test]
fn ldp_vc_payload_is_json_object() {
let vc = serde_json::json!({
"@context": ["https://www.w3.org/2018/credentials/v1"],
"type": ["VerifiableCredential"],
"issuer": "https://example.com",
"credentialSubject": {}
});

let credential = Oid4vciCredential::new(vc.clone());
let format = StandardFormat::W3c(W3cVcFormat::LdpVc);

let raw = RawCredential::from_oid4vci(&format, credential).unwrap();

assert_eq!(raw.format, CredentialFormat::LdpVc);
let roundtripped: serde_json::Value = serde_json::from_slice(&raw.payload).unwrap();
assert_eq!(roundtripped, vc);
}
}
Loading