Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: support StatusList2021Entry credentials, fetch logo from .well-known/openid-credential-issuer #414

Merged
merged 132 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
132 commits
Select commit Hold shift + click to select a range
b1858c1
WIP
nanderstabel Jun 26, 2024
a87866c
Add Thuiswinkel verification checkmark
maiertech Jun 27, 2024
768fc78
fix: fix logo_url binding, renameto thuiswinkel_validation
nanderstabel Jun 27, 2024
a781199
Rename `thuiswinkel_waarborg_verification` to `thuiswinkel_verificati…
maiertech Jun 27, 2024
987f861
feat: add `issuance_date` to `ValidationResult`
nanderstabel Jun 28, 2024
dca2caa
Change label for domain verification
maiertech Jun 28, 2024
2ff57af
fix: fix `issuance_date`
nanderstabel Jun 28, 2024
1c50934
Add issuance date and change logo position
maiertech Jun 28, 2024
72ebdfb
chore(deps-dev): bump prettier-plugin-tailwindcss from 0.6.1 to 0.6.5…
dependabot[bot] Jul 2, 2024
d69775c
chore(deps-dev): bump @ianvs/prettier-plugin-sort-imports (#260)
dependabot[bot] Jul 2, 2024
cebee1e
chore(deps-dev): bump prettier-plugin-svelte from 3.2.3 to 3.2.5 (#262)
dependabot[bot] Jul 2, 2024
ad9da84
chore(deps-dev): bump prettier from 3.3.0 to 3.3.2 (#261)
dependabot[bot] Jul 2, 2024
9413454
Make `imageId` reactive
maiertech Jul 2, 2024
b792b33
Merge branch 'dev' into feat/linked-vp
maiertech Jul 3, 2024
b0d8ff7
fix: fix lint errors
nanderstabel Jul 9, 2024
7b50623
Merge branch 'dev' into feat/linked-vp
nanderstabel Jul 9, 2024
f608fc5
add: backend actions-reducers for editable trust list
Oran-Dan Aug 21, 2024
86b2b35
cargo fmt
Oran-Dan Aug 21, 2024
3c200a3
add: testing
Oran-Dan Aug 21, 2024
02bbbf3
feat: trusted domains list (first version) (#352)
Oran-Dan Aug 30, 2024
bad8844
Merge branch 'dev' into feat/linked-vp
nanderstabel Sep 5, 2024
61fb522
feat: add `validate_linked_verifiable_presentations`
nanderstabel Sep 11, 2024
e102098
refactor: apply clippy suggestions
nanderstabel Sep 11, 2024
ca6792f
feat: use `ServiceEndpoint::from`
nanderstabel Sep 18, 2024
2835141
Merge branch 'dev' into feat/linked-vp
nanderstabel Sep 18, 2024
6a0776f
refactor: remove unused variables
nanderstabel Sep 18, 2024
d830179
Merge branch 'dev' into feat/editable_trust_list
daniel-mader Sep 18, 2024
ab4d19b
Merge branch 'dev' into feat/linked-vp
nanderstabel Sep 19, 2024
74f96bd
refactor: replace icon imports
nanderstabel Sep 20, 2024
f8826f3
Merge branch 'dev' into feat/editable_trust_list
nanderstabel Sep 24, 2024
878d1ad
Merge branch 'dev' into feat/linked-vp
nanderstabel Sep 24, 2024
384ef4c
Merge branch 'feat/linked-vp' into feat/editable_trust_list
nanderstabel Sep 24, 2024
09eed4f
Merge branch 'dev' into feat/linked-vp
nanderstabel Oct 2, 2024
221239f
feat: add alignment & criteria display
Oran-Dan Oct 15, 2024
4ab246c
chore: pnpm format
Oran-Dan Oct 15, 2024
2f3d987
chore: eslint failed
Oran-Dan Oct 15, 2024
85fa7b8
feat: filter linked VPs based on trust list
nanderstabel Oct 16, 2024
3ab3107
feat: display trusted domains as trusted issuers
nanderstabel Oct 16, 2024
9dd3964
Merge branch 'dev' into feat/editable_trust_list
nanderstabel Oct 16, 2024
1e24136
Merge branch 'feat/editable_trust_list' into feat/sd-jwt
nanderstabel Oct 16, 2024
2a4f6d1
chore: try to fix git workflow build fail
Oran-Dan Oct 16, 2024
e0e3155
chore: try to fix git workflow build fail
Oran-Dan Oct 16, 2024
a0d21aa
chore: add comment to ubuntu version fix
Oran-Dan Oct 16, 2024
91f883d
chore: update serde_json dependency, make error messages static for c…
Oran-Dan Oct 16, 2024
8edbf35
chore: cargo fmt
Oran-Dan Oct 16, 2024
eae6b02
chore: cargo clippy
Oran-Dan Oct 16, 2024
a550a26
chore: fix tests
Oran-Dan Oct 16, 2024
8b406ba
chore: cargo fmt
Oran-Dan Oct 16, 2024
b07b910
feat: add achievementType to badge overview display
Oran-Dan Oct 17, 2024
cf6e2c6
Merge remote-tracking branch 'origin/feat/display_alignment_obv3' int…
daniel-mader Oct 18, 2024
7abc2db
ci: release version 0.6.13
daniel-mader Oct 18, 2024
e716e1f
fix: disable prerender trust-list
daniel-mader Oct 18, 2024
25f7a96
WIP
nanderstabel Oct 18, 2024
2ff3161
WIP
nanderstabel Oct 21, 2024
c0525d9
Merge branch 'feat/sd-jwt' into ci/release-0.6.14
nanderstabel Oct 22, 2024
38bff4d
WIP
nanderstabel Oct 21, 2024
6a42c6c
Merge branch 'feat/sd-jwt' into ci/release-0.6.14
nanderstabel Oct 22, 2024
4be740e
ci: release version 0.6.14
daniel-mader Oct 22, 2024
99db57a
chore: rename variable
Oran-Dan Oct 28, 2024
68f541b
chore: fix log message
Oran-Dan Oct 28, 2024
3bb663e
chore: fix trusted domain validation
Oran-Dan Oct 28, 2024
431a63a
feat: add default trust lists to all profiles at creation
Oran-Dan Oct 28, 2024
7c83590
feat: add did:web url validation against trust_list, format
Oran-Dan Oct 28, 2024
820ac3a
chore: cargo clippy:
Oran-Dan Oct 28, 2024
8a6f6cf
feat: add fetching logo from well known endpoint
Oran-Dan Oct 29, 2024
282c370
chore: fix fallback icon, add comments
Oran-Dan Oct 29, 2024
b85f236
chore: add credenco to trusted issuers
Oran-Dan Oct 29, 2024
a7df268
Merge remote-tracking branch 'origin/feat/fetch_logo_from_well_known_…
daniel-mader Oct 30, 2024
4dca2a5
ci: release version 0.6.15
daniel-mader Oct 30, 2024
4b9f9d8
fix: set SD-JWT format check back to `VcSdJwt` (#394)
nanderstabel Oct 31, 2024
2bfd1b6
feat: display `alignment` & `criteria` for Open Badges 3.0 (#386)
Oran-Dan Oct 31, 2024
fafc458
fix: use hash-based image identifier to prevent caching, use colored …
daniel-mader Oct 31, 2024
4cedef0
ci: release version 0.7.0
daniel-mader Oct 31, 2024
41bd603
fix: trusted issuer domain url validation (#397)
Oran-Dan Oct 31, 2024
5da831a
Make it more clear how scrolling is done
maiertech Nov 1, 2024
38f4a5f
Define prop `class` for `TopNavBar` to make it more explicit
maiertech Nov 1, 2024
3ed4daf
Remove unneded class
maiertech Nov 1, 2024
54ecdb4
Fix `/me/settings`
maiertech Nov 1, 2024
5d7f33e
Fix `/me/settings/app`
maiertech Nov 1, 2024
0a6c7f0
Fix `/me/settings/about`
maiertech Nov 1, 2024
3253489
Fix `/me/settings/app/did`
maiertech Nov 1, 2024
6ddba7f
Fix `/me/settings/app/keys`
maiertech Nov 1, 2024
4736701
Fix `/me/settings/app/language`
maiertech Nov 1, 2024
bb9be8b
Fix `/me/settings/app/theme`
maiertech Nov 1, 2024
65b8eb4
Fix `/me/settings/app/trust-list`
maiertech Nov 1, 2024
0b7e4db
Fix `/me/settings/profile`
maiertech Nov 1, 2024
8a7dab8
Fix `/prompt/accept-connection`
maiertech Nov 1, 2024
0f0ae8b
Fix `/prompt/credential-offer`
maiertech Nov 1, 2024
7e419fb
Fix `/prompt/share-credentials`
maiertech Nov 1, 2024
1c60836
fix: adjust UniMe text color in dark mode
daniel-mader Nov 3, 2024
8d33c9d
feat: add terms & conditions
daniel-mader Nov 3, 2024
d4b889d
fix: checkbox tick color in dark mode
daniel-mader Nov 3, 2024
247852f
feat: update app icon
daniel-mader Nov 3, 2024
004f0da
Merge remote-tracking branch 'origin/maiertech/issue393' into ci/rele…
daniel-mader Nov 3, 2024
abc01d9
ci: release version 0.7.1
daniel-mader Nov 3, 2024
0be997e
feat: update app icon
daniel-mader Nov 3, 2024
6d8a859
feat: fix app icon
daniel-mader Nov 3, 2024
9d718d8
fix: higher resolution app icon
daniel-mader Nov 4, 2024
b4a5732
Merge branch 'feat/content-update' into ci/release-0.7
daniel-mader Nov 4, 2024
5ec97af
refactor: remove `Beta` from `productName`
daniel-mader Nov 4, 2024
47bc8af
ci: release version 0.7.2
daniel-mader Nov 4, 2024
0ea2076
refactor: update camera usage description
daniel-mader Nov 5, 2024
bc7d89f
Merge branch 'feat/content-update' into ci/release-0.7
daniel-mader Nov 5, 2024
4f1b570
refactor: update camera usage description
daniel-mader Nov 5, 2024
b4f4fff
Merge branch 'feat/content-update' into ci/release-0.7
daniel-mader Nov 5, 2024
9b79e4a
Fix layout issues by creating a new stacking context (#410)
maiertech Nov 5, 2024
82ec418
ci: release version 0.7.3
daniel-mader Nov 5, 2024
b7663ad
fix: support StatusList2021Entry, add logo fetching from well-known/o…
Oran-Dan Nov 22, 2024
cb26bdd
chore: refactor fn get_logo_uri
Oran-Dan Nov 22, 2024
a8034de
chore: add domain to default trust list
Oran-Dan Dec 5, 2024
fcaf20f
chore: cargo clippy
Oran-Dan Dec 5, 2024
fc6f362
chore: merge dev unime/ folder into branch
Oran-Dan Dec 5, 2024
cafd0c8
chore: checkout dev identity-wallet/src/state/trustlist/
Oran-Dan Dec 5, 2024
fdd6044
chore: checkout dev into identity-wallet/ files
Oran-Dan Dec 6, 2024
04e2533
chore: checkout dev files and merge dev
Oran-Dan Dec 6, 2024
5208fc0
chore: remove outdated files
Oran-Dan Dec 6, 2024
960cb3c
chore: remove outdated unime/ files
Oran-Dan Dec 6, 2024
7e59e2f
chore: fix tests
Oran-Dan Dec 6, 2024
f1f68b9
Merge branch 'dev' into fix/status_list_2021_entry_and_logo_fetching
Oran-Dan Dec 6, 2024
0b040ff
chore: remove outdated domain
Oran-Dan Dec 6, 2024
ff6fe1d
chore: add TODO in comment
Oran-Dan Dec 6, 2024
f2d8e0f
chore: fix PascalCasing
Oran-Dan Dec 6, 2024
102300a
chore: clarify log message
Oran-Dan Dec 6, 2024
851aeab
chore: add spec in comment to alternative property name
Oran-Dan Dec 6, 2024
c9d7d9b
chore: remove workaround which should be fixed in frontend, add comments
Oran-Dan Dec 6, 2024
6e0e063
Merge branch 'dev' into fix/status_list_2021_entry_and_logo_fetching
Oran-Dan Dec 6, 2024
2ac4224
chore: fix comments
Oran-Dan Dec 6, 2024
8c0141c
chore: fix default trust list entries check in linked vp flow
Oran-Dan Dec 6, 2024
6786422
chore: fix PR comments
Oran-Dan Dec 7, 2024
7ddf99a
chore
Oran-Dan Dec 9, 2024
335a30d
Merge branch 'dev' into fix/status_list_2021_entry_and_logo_fetching
Oran-Dan Dec 9, 2024
dd5962f
chore: update tests to include logo fetching through wiremock
Oran-Dan Dec 9, 2024
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
8 changes: 7 additions & 1 deletion identity-wallet/resources/default_trust_list.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
{
"id": "b01f4a74-3005-4749-a030-c5444bc4dab5",
"display_name": "Impierce Demos",
"entries": ["https://ngdil.com", "https://selv.iota.org", "https://thuiswinkel-agent.dev.impierce.com"]
"entries": [
"https://ngdil.com",
"https://selv.iota.org",
"https://thuiswinkel-agent.dev.impierce.com",
"https://mijnkvk.acc.credenco.com",
"https://agent.wallet.bd.demo.sphereon.com"
]
}
19 changes: 14 additions & 5 deletions identity-wallet/src/state/did/validate_domain_linkage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ pub async fn validate_domain_linkage(url: url::Url, did: &str) -> ValidationResu
Err(e) => {
return ValidationResult {
status: ValidationStatus::Unknown,
message: Some(e.to_string()),
message: Some(format!("Error while fetching configuration: {}", e)),
..Default::default()
};
}
Expand Down Expand Up @@ -142,10 +142,15 @@ async fn fetch_configuration(mut url: url::Url) -> Result<DomainLinkageConfigura
info!("Fetching DID configuration from: {}", url);

// 2. Fetch the resource
let response = reqwest::get(url).await.map_err(|e| e.to_string())?;
let response = reqwest::get(url.clone())
.await
.map_err(|_| format!("failed to get response from resource url: {}", url))?;

// 3. Parse to JSON value (mutable)
let mut json = response.json::<serde_json::Value>().await.map_err(|e| e.to_string())?;
let mut json = response
.json::<serde_json::Value>()
.await
.map_err(|_| "failed to parse response into JSON value".to_string())?;

// 4. Remove all non-string values from `linked_dids` (JSON-LD)
if let serde_json::Value::Object(ref mut root) = json {
Expand All @@ -156,7 +161,8 @@ async fn fetch_configuration(mut url: url::Url) -> Result<DomainLinkageConfigura
}

// 5. Deserialize to `DomainLinkageConfiguration`
let config = DomainLinkageConfiguration::from_json_value(json).map_err(|e| e.to_string())?;
let config = DomainLinkageConfiguration::from_json_value(json)
.map_err(|_| "failed to deserialize DomainLinkageConfiguration from JSON".to_string())?;
Ok(config)
}

Expand Down Expand Up @@ -240,7 +246,10 @@ mod tests {
result,
ValidationResult {
status: ValidationStatus::Unknown,
message: Some("failed to decode JSON".to_string()),
message: Some(
"Error while fetching configuration: failed to deserialize DomainLinkageConfiguration from JSON"
.to_string()
),
..Default::default()
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ use futures::{
};
use identity_iota::{
core::{OneOrMany, ToJson},
credential::{DecodedJwtPresentation, FailFast, Jwt, JwtCredentialValidator, JwtPresentationValidator, Subject},
credential::{
DecodedJwtCredential, DecodedJwtPresentation, FailFast, Jwt, JwtCredentialValidationOptions,
JwtCredentialValidator, JwtPresentationValidator, StatusCheck, Subject,
},
document::{CoreDocument, Service},
verification::jws::Decoder,
};
use identity_jose::jwt::JwtClaims;
use log::{info, warn};
use oid4vc::oid4vci::credential_issuer::credential_issuer_metadata::CredentialIssuerMetadata;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use ts_rs::TS;
Expand Down Expand Up @@ -189,15 +193,26 @@ async fn get_validated_linked_credential_data(
info!("Issuer linked domains: {issuer_linked_domains:#?}");

// Only linked verifiable credentials with at least one successful domain linkage validation are considered
let validated_linked_domains = get_validated_linked_domains(&issuer_linked_domains, &issuer_did).await;
let mut validated_linked_domains = get_validated_linked_domains(&issuer_linked_domains, &issuer_did).await;

// TODO: This is a fallback to get the url from a did:web to validate domain linkage. This is useful for companies who haven't implemented domain linkage yet.
if validated_linked_domains.is_empty() {
if let Some(did_web_url) = extract_url_from_did_web(&issuer_did) {
validated_linked_domains.insert(0, did_web_url);
}
}

if !validated_linked_domains.is_empty() {
let validator = JwtCredentialValidator::with_signature_verifier(Verifier);

// `SkipUnsupported` allows for custom credential types, such as the StatusList2021Entry (https://www.w3.org/TR/2023/WD-vc-status-list-20230427/#statuslist2021entry)
let options = JwtCredentialValidationOptions::new().status_check(StatusCheck::SkipUnsupported);

// Decode the linked verifiable credential and validate it
if let Ok(linked_verifiable_credential) = validator.validate::<_, Value>(
&linked_verifiable_credential,
&issuer_document,
&Default::default(),
&options,
FailFast::FirstError,
) {
info!("Validated linked verifiable credential: {linked_verifiable_credential:#?}");
Expand All @@ -208,19 +223,23 @@ async fn get_validated_linked_credential_data(
OneOrMany::Many(subjects) => subjects.first(),
};

OptionFuture::from(credential_subject.map(|credential_subject| async {
if let Some(credential_subject) = credential_subject {
let name = get_name(credential_subject);
let logo_uri = get_logo_uri(credential_subject).await;
let logo_uri = get_logo_uri(credential_subject, &linked_verifiable_credential, &validated_linked_domains).await;
let issuance_date = linked_verifiable_credential.credential.issuance_date.to_rfc3339();

LinkedVerifiableCredentialData {
info!("LinkedVerifiableCredentialData: name: {name:?}, logo_uri: {logo_uri:?}, issuance_date: {issuance_date}");
Some(LinkedVerifiableCredentialData {
name,
logo_uri,
issuance_date,
issuer_linked_domains: validated_linked_domains,
}
}))
.await
})
}
else {
warn!("Failed to get credential_subject from linked_verifiable_credential: {linked_verifiable_credential:#?}");
None
}
} else {
warn!("Failed to validate linked verifiable credential: {linked_verifiable_credential:#?}");
// TODO: Should we add more fine-grained error handling? `None` here means that the linked verifiable credential is invalid.
Expand Down Expand Up @@ -319,30 +338,117 @@ fn get_name(credential_subject: &Subject) -> Option<String> {
.properties
.get("name")
.or_else(|| credential_subject.properties.get("naam")) // TODO: "naam" is expected to be used in Dutch credentials
.or_else(|| credential_subject.properties.get("legal_person_name")) // This is another valid property name according to the following spec:
// EWC RFC005: Issue Legal Person Identification Data (LPID) - v1.0
// https://github.com/EWC-consortium/eudi-wallet-rfcs/blob/49faa8b0ba5e5e79836e247fd07cc0447c1ae98b/ewc-rfc005-issue-legal-person-identification-data.md#51031-lpid-attributes-specification
.and_then(Value::as_str)
.map(ToString::to_string)
}

async fn get_logo_uri(credential_subject: &Subject) -> Option<String> {
OptionFuture::from(
credential_subject
.properties
.get("image")
.and_then(Value::as_str)
.map(|image| async {
let _ = download_asset(
image
.parse()
.inspect_err(|err| warn!("Failed to parse logo URI: {:#?}", err))
.ok()?,
&hash(image),
)
.await;
Some(image.to_string())
}),
)
.await
.flatten()
/// First, try to get the logo URI from the credential subject.
/// If this doesn't succeed, iterate through the validated linked domains and try to fetch it from the well-known/openid-credential-issuer endpoint.
/// In this endpoint, first we look inside the Display field, at the root.
/// If we can't find a logo there, we look inside the Credential Configurations Supported field at the root.
/// We try to match keys inside the Credential Configurations Supported object against the credential `type` array of the linked verifiable credential, in reverse order.
/// At first success the loop breaks and we download the image.
/// Otherwise, we use a fallback icon.
async fn get_logo_uri(
credential_subject: &Subject,
linked_verifiable_credential: &DecodedJwtCredential<Value>,
validated_linked_domains: &[Url],
) -> Option<String> {
let mut logo_uri = credential_subject
.properties
.get("image")
.and_then(Value::as_str)
.map(ToString::to_string);

// Check if logo URI was retrieved, if not then attempt to retrieve from a well-known endpoint
if logo_uri.is_none() {
for domain in validated_linked_domains.iter() {
let well_known_endpoint = format!("{}.well-known/openid-credential-issuer", domain);
info!("Trying to fetch image from {well_known_endpoint} endpoint");
if let Ok(response) = reqwest::Client::new().get(&well_known_endpoint).send().await {
if let Ok(metadata) = response.json::<CredentialIssuerMetadata>().await {
logo_uri = metadata.display.as_deref().and_then(extract_logo_uri_from_display);

if logo_uri.is_some() {
break;
}
}
}
// TODO: Due to mixing 2 specs here, the oid4vci and linked verifiable presentation spec, we lose the Credential Issuer Identifier (CII) during the linked vp flow.
// The CII tells us where exactly we can add "/.well-known/openid-credential-issuer" to fetch the Credential Issuer Metadata, in which we might find the logo.
// For now we assume it's the same domain as the linked domain.
// But this is no guarantee and the code below is one such workaround.
let well_known_endpoint = format!("{}oid4vci/.well-known/openid-credential-issuer", domain);
info!("Trying to fetch image from {well_known_endpoint} endpoint");
if let Ok(response) = reqwest::Client::new().get(&well_known_endpoint).send().await {
if let Ok(metadata) = response.json::<CredentialIssuerMetadata>().await {
logo_uri = linked_verifiable_credential.credential.types.iter().find_map(|type_| {
info!("Trying to fetch from Credential Configuration Supported: {}", type_);
metadata
.credential_configurations_supported
.get(type_)
.map(|credential_configuration| credential_configuration.display.as_ref())
.and_then(extract_logo_uri_from_display)
});

if logo_uri.is_some() {
break;
}
}
}
}
}

if let Some(ref logo_uri_str) = logo_uri {
info!("Logo URI: {:?}", logo_uri_str);

// Parse the logo URI
match logo_uri_str.parse() {
Ok(parsed_url) => {
// Download the asset if parsing succeeded
if download_asset(parsed_url, &hash(logo_uri_str)).await.is_err() {
warn!("Failed to download logo URI");
return None;
}
logo_uri
}
Err(parse_err) => {
// Log parse error if the URI is invalid
warn!("Failed to parse logo URI: {:#?}, {}", logo_uri_str, parse_err);
None
}
}
} else {
warn!("Failed to extract logo URI from well-known endpoints nor credential subject");
None
}
}

fn extract_logo_uri_from_display(display: &[Value]) -> Option<String> {
display
.first()
.and_then(|display| display.get("logo"))
.and_then(|logo| logo.get("uri").or(logo.get("url")))
.and_then(|url| url.as_str())
.map(ToString::to_string)
}

fn extract_url_from_did_web(did_web: &str) -> Option<Url> {
if let Some(did) = did_web.strip_prefix("did:web:") {
let url_str = if let Some(index_colon) = did.find(':') {
&did[..index_colon]
} else {
did
};

if let Ok(url) = Url::parse(&format!("https://{}", url_str)) {
return Some(url);
}
}
None
}

#[cfg(test)]
Expand Down Expand Up @@ -574,13 +680,25 @@ mod tests {

Jwt::from(message)
}

async fn add_logo_endpoint(&self) {
Mock::given(method("GET"))
.and(path("logo.png"))
.respond_with(ResponseTemplate::new(200).set_body_raw(
include_bytes!("../../../resources/images/impierce_white.png"),
"image/png",
))
.mount(&self.mock_server)
.await;
}
}

#[tokio::test]
async fn validate_linked_verifiable_presentations_successfully_validates_multiple_presentations() {
let mut holder = TestEntity::new().await;

let mut issuer_a = TestEntity::new().await;
issuer_a.add_logo_endpoint().await;

// Add the `/did_configuration.json` and `/did.json` endpoints to the issuer A mock server.
issuer_a
Expand All @@ -589,18 +707,21 @@ mod tests {
issuer_a.add_well_known_did_json().await;

let mut issuer_b = TestEntity::new().await;
issuer_b.add_logo_endpoint().await;

// Add the `/did_configuration.json` and `/did.json` endpoints to the issuer B mock server.
issuer_b
.add_well_known_did_configuration_json("linked-domain", &[issuer_b.domain.clone().into()])
.await;
issuer_b.add_well_known_did_json().await;

let logo_uri_a: String = format!("{}logo.png", issuer_a.domain.clone());

let verifiable_credential_jwt = issuer_a
.issue_credential(
holder.did_document.id().to_string().as_str(),
"Webshop",
"https://webshop.com/logo.jpg".parse().unwrap(),
logo_uri_a.parse().unwrap(),
)
.await;

Expand All @@ -618,11 +739,13 @@ mod tests {
)
.await;

let logo_uri_b: String = format!("{}logo.png", issuer_b.domain.clone());

let verifiable_credential_jwt_2 = issuer_b
.issue_credential(
holder.did_document.id().to_string().as_str(),
"Webshop",
"https://webshop.com/logo.jpg".parse().unwrap(),
logo_uri_b.parse().unwrap(),
)
.await;

Expand All @@ -647,13 +770,13 @@ mod tests {
vec![
vec![LinkedVerifiableCredentialData {
name: Some("Webshop".to_string()),
logo_uri: Some("https://webshop.com/logo.jpg".to_string()),
logo_uri: Some(logo_uri_a),
issuer_linked_domains: vec![issuer_a.domain.clone()],
..Default::default()
}],
vec![LinkedVerifiableCredentialData {
name: Some("Webshop".to_string()),
logo_uri: Some("https://webshop.com/logo.jpg".to_string()),
logo_uri: Some(logo_uri_b),
issuer_linked_domains: vec![issuer_b.domain.clone()],
..Default::default()
}]
Expand Down Expand Up @@ -757,14 +880,17 @@ mod tests {
.add_well_known_did_configuration_json("linked-domain", &[issuer.domain.clone().into()])
.await;
issuer.add_well_known_did_json().await;
issuer.add_logo_endpoint().await;

let mut holder = TestEntity::new().await;

let issuer_logo = format!("{}logo.png", issuer.domain.clone());

let verifiable_credential_jwt = issuer
.issue_credential(
holder.did_document.id().to_string().as_str(),
"Webshop",
"https://webshop.com/logo.jpg".parse().unwrap(),
issuer_logo.parse().unwrap(),
)
.await;

Expand Down Expand Up @@ -795,7 +921,7 @@ mod tests {
validated_linked_presentation_data,
Some(vec![LinkedVerifiableCredentialData {
name: Some("Webshop".to_string()),
logo_uri: Some("https://webshop.com/logo.jpg".to_string()),
logo_uri: Some(issuer_logo),
issuer_linked_domains: vec![issuer.domain.clone()],
..Default::default()
}])
Expand Down
Loading
Loading