Skip to content

fix(contacts): show photos that have no TYPE parameter#5565

Open
MiMoHo wants to merge 2 commits into
nextcloud:mainfrom
MiMoHo:fix/photo-without-type-parameter
Open

fix(contacts): show photos that have no TYPE parameter#5565
MiMoHo wants to merge 2 commits into
nextcloud:mainfrom
MiMoHo:fix/photo-without-type-parameter

Conversation

@MiMoHo

@MiMoHo MiMoHo commented Jul 12, 2026

Copy link
Copy Markdown

Summary

Contact photos stored without an explicit TYPE parameter, e.g.

PHOTO;ENCODING=b:
iVBORw0KGgoAAAANSUhEUgAA...

were not displayed: getPhotoUrl() called photoType.toLowerCase() on the missing parameter and threw

TypeError: Cannot read properties of undefined (reading 'toLowerCase')

so the app fell back to initials, while other CardDAV clients (eM Client, iOS Contacts) display these photos fine. The TYPE parameter is optional per RFC 2426/6350.

Changes

  • When the TYPE parameter is missing, detect the image type from the magic bytes of the base64 data (png, jpeg, gif, webp, bmp, svg). SVG detected this way still goes through the existing sanitizeSVG path.
  • Unknown signatures fall back to jpeg: browsers content-sniff raster images in an img element, so a wrong subtype still renders — before this change the app just threw.
  • Drive-by: the error logs in getPhotoUrl() referenced this.contact, which does not exist on the Contact class and always logged undefined; they now log this.

Checklist

  • Jest tests added: photo with explicit TYPE, binary photo without TYPE (png + jpeg magic bytes), vCard 4.0 data-URI photo
  • Full Jest suite passes, npm run lint clean for the touched files, production build succeeds

Resolve #5401

🤖 Generated with Claude Code

The TYPE parameter of PHOTO is optional, but getPhotoUrl() called
toLowerCase() on it unconditionally. Contacts stored e.g. as
'PHOTO;ENCODING=b:…' (without TYPE) threw a TypeError and showed
initials instead of the photo, while other CardDAV clients displayed
them fine.

Detect the image type from the magic bytes of the base64 data when
the TYPE parameter is missing. Unknown signatures fall back to jpeg,
which browsers happily content-sniff in an img element anyway.

Also log the contact itself in getPhotoUrl() error messages instead
of the undefined this.contact.

Resolves nextcloud#5401

Assisted-by: Claude:claude-fable-5
Signed-off-by: MiMoHo <37556964+MiMoHo@users.noreply.github.com>
@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 75.00000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/models/contact.js 75.00% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

Comment thread src/models/contact.js Outdated
const signature = Object.keys(signatures).find((signature) => photoB64Data.startsWith(signature))
// browsers detect raster images in an img element from the content,
// so a wrong subtype still renders fine
return signature ? signatures[signature] : 'jpeg'

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.

@SebastianKrupinski: I don't know if we should do such a fallback here. I think adding a warning or something like this would make more sense?

@DerDreschner

Copy link
Copy Markdown
Contributor

Hey @MiMoHo, thank you very much for your first PR here! Looks pretty good and useful to me. But additional colleagues will have a look into it as well.

@hamza221 hamza221 added bug Something isn't working 3. to review Waiting for reviews labels Jul 16, 2026
Address review feedback on nextcloud#5565: instead of silently assuming JPEG
for a PHOTO whose magic bytes match no known signature, log a warning
so the guess is visible in the console. The fallback itself stays, as
browsers content-sniff raster images in an img element regardless of
the declared subtype.

Add a test for the unknown-signature path, closing the coverage gap
codecov reported on the fallback branch.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: MiMoHo <37556964+MiMoHo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Contact photos with PHOTO;ENCODING=b: are not displayed in Contacts app (Nextcloud 34)

3 participants