Skip to content

fix: restore ingredient thumbnails with c2pa-web - #389

Merged
MassivaM merged 8 commits into
contentauth:mainfrom
timmurphydev:fix/restore-ingredient-thumbnails
Jun 23, 2026
Merged

fix: restore ingredient thumbnails with c2pa-web#389
MassivaM merged 8 commits into
contentauth:mainfrom
timmurphydev:fix/restore-ingredient-thumbnails

Conversation

@timmurphydev

Copy link
Copy Markdown
Contributor

Overview

Restores ingredient thumbnail rendering. The c2pa-web SDK exposes raw resource bytes via reader.resourceToBytes() and we need to fetch and assign thumbnails explicitly.

  • Add resolveThumbnails helper that walks the manifest store and fetches embedded thumbnail bytes, keyed by absolute JUMBF identifier.
  • For ingredients with a manifest and claim thumbnail, we use its c2pa.thumbnail.claim assertion.
  • Otherwise we fall back to the c2pa.thumbnail.ingredient assertion on the containing manifest, if present.

@andyparsons
andyparsons requested review from andyparsons May 6, 2026 23:48
@timmurphydev

Copy link
Copy Markdown
Contributor Author

This update prioritizes the signed ingredient's own c2pa.thumbnail.claim, if present,
over the c2pa.thumbnail.ingredient assertion that the consuming manifest's signer
references via ingredient.thumbnail. When a signed ingredient already provides
its own claim thumbnail, a consuming signer's separate ingredient assertion
thumbnail could be an intentional override pointing at a misleading image. The
claim thumbnail more faithfully represents the ingredient.

When no claim thumbnail is available for an ingredient, we fall back to
c2pa.thumbnail.ingredient only if the containing manifest is trusted. If it is
untrusted, we suppress the thumbnail so an untrusted signer can't force a false
thumbnail to display for an ingredient that has no claim thumbnail of its own. A
signed ingredient's own claim thumbnail is still shown when present (untrusted
state is flagged in the UI).

It solves this kind of issue:

Before:
Screenshot 2026-05-07 at 9 33 40 AM

After:
Screenshot 2026-05-07 at 9 34 07 AM

@timmurphydev
timmurphydev marked this pull request as draft May 7, 2026 14:02
@timmurphydev
timmurphydev marked this pull request as ready for review May 7, 2026 14:48
@timmurphydev

Copy link
Copy Markdown
Contributor Author

@andyparsons I synced this with main after #388 merged, and just updated c2pa-web to 0.9.0.

Comment thread package.json Outdated
@mauricefisher64

Copy link
Copy Markdown

Not a JS expert but looks good to me.

Comment thread src/lib/resolveThumbnails.ts Outdated
@@ -0,0 +1,66 @@
// Copyright 2021-2024 Adobe, Copyright 2025 The C2PA Contributors

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a new file this can be Copyright 2026 The C2PA contributors

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MassivaM Can this be // Copyright 2021-2024 Adobe, Copyright 2026 The C2PA Contributors instead? There is an eslint header rule that enforces this format.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes I forgot we had that linter , we'll want to change this eventually but yes that's okay for now!

Comment thread src/lib/asset.ts Outdated
// untrusted, we suppress the thumbnail so an untrusted signer can't force a false
// thumbnail to display for an ingredient that has no claim thumbnail of its own. A
// signed ingredient's own claim thumbnail is still shown when present (untrusted
// state is flagged in the UI).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/**
 * The code prioritizes the signed ingredient's own c2pa.thumbnail.claim, if present,
 * over the c2pa.thumbnail.ingredient assertion that the consuming manifest's signer
 * references via ingredient.thumbnail. When a signed ingredient already provides
 * its own claim thumbnail, a consuming signer's separate ingredient assertion
 * thumbnail could be an intentional override pointing at a misleading image. The
 * claim thumbnail more faithfully represents the ingredient.
 *
 * When no claim thumbnail is available for an ingredient, we fall back to
 * c2pa.thumbnail.ingredient only if the containing manifest is trusted. If it is
 * untrusted, we suppress the thumbnail so an untrusted signer can't force a false
 * thumbnail to display for an ingredient that has no claim thumbnail of its own. A
 * signed ingredient's own claim thumbnail is still shown when present (untrusted
 * state is flagged in the UI)
 */

Can we use a multiline comment here to make it more readable

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MassivaM I just fixed this. Thanks!

Comment thread src/lib/asset.ts
@MassivaM

Copy link
Copy Markdown
Contributor

@timmurphydev feel free to merge this when you're ready

@timmurphydev

Copy link
Copy Markdown
Contributor Author

Thanks @MassivaM! I don't think I have permission to merge, though.

@MassivaM

Copy link
Copy Markdown
Contributor

I'll merge for you right now @timmurphydev , can you double check that all is good once it's deployed ? I'll ping here once it's done

@MassivaM
MassivaM merged commit a09c33d into contentauth:main Jun 23, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants