Skip to content

LOOPIN-76 — Add Chat Image Attachments and Harden Media Lifecycle #166

Description

@shaig-mahmudov

Type: Backend / Chat / Media / Security
Priority: High

Description

Add image attachment support to Group Chat and complete the production hardening of the media upload lifecycle.

The existing chat implementation supports text messages only. The media module also validates declared file size and storage metadata, but it does not yet verify that uploaded content is a valid image, clean abandoned uploads or provide a finalized media delivery strategy.

Extend chat messages with secure media attachments and add the remaining validation, cleanup and delivery mechanisms required for reliable frontend integration.

Scope

  • Add a CHAT_IMAGE or generic CHAT_ATTACHMENT media purpose.

  • Define supported chat attachment types and size limits.

  • Add a GroupMessageAttachment entity or equivalent attachment model.

  • Associate chat attachments with:

    • A Group Message.
    • A Media Asset.
    • The sending user where required for auditing.
  • Support:

    • Text-only messages.
    • Image-only messages.
    • Text and image messages.
  • Update REST chat message creation requests to accept media attachment IDs.

  • Update WebSocket/STOMP message payloads to support attachment IDs.

  • Validate chat attachments:

    • Sender owns the media asset.
    • Sender is an active member of the Group.
    • Media purpose is valid for chat.
    • Media status is UPLOADED.
    • Media has not already been attached incompatibly.
  • Mark chat media as ATTACHED when the message is persisted.

  • Include attachment metadata in:

    • REST message responses.
    • Chat history responses.
    • WebSocket message events.
  • Ensure message persistence and media attachment happen consistently.

  • Define attachment cleanup behavior when:

    • A message is deleted.
    • A Group is archived or deleted.
    • Chat history is removed.
  • Add real image content validation instead of trusting only the declared MIME type.

  • Validate image signatures or decode uploaded images using an appropriate image validation mechanism.

  • Reject invalid, malformed or unsupported image content.

  • Add maximum image dimension and total pixel limits.

  • Protect against decompression bombs and excessively large decoded images.

  • Define whether image metadata such as EXIF should be removed or preserved.

  • Add scheduled cleanup for expired PENDING_UPLOAD media records.

  • Delete abandoned storage objects that were uploaded but never completed.

  • Reconcile media records whose storage objects are missing.

  • Finalize frontend media delivery through one documented strategy:

    • Public CDN URL.
    • Controlled media endpoint.
    • Presigned download URL.
  • Prevent internal bucket names and object keys from being exposed unnecessarily.

  • Define URL expiration and refresh behavior when presigned download URLs are used.

  • Add retry or reconciliation behavior for storage deletion and database update failures.

  • Add rate limiting for media upload requests where appropriate.

  • Add unit, integration and WebSocket tests for chat attachment flows.

  • Add MinIO/Testcontainers coverage for validation, cleanup and attachment lifecycle.

  • Update OpenAPI documentation, WebSocket documentation and Bruno collections.

Acceptance Criteria

  • Group Chat supports text-only, image-only and combined text-image messages.
  • Users cannot attach media they do not own.
  • Users cannot send attachments to Groups they are not authorized to access.
  • Chat rejects media with an invalid purpose or lifecycle status.
  • Uploaded chat media becomes ATTACHED only after the message is persisted successfully.
  • Failed message creation does not leave media incorrectly attached.
  • REST chat history and WebSocket events return consistent attachment information.
  • Invalid files with forged image MIME types are rejected.
  • Oversized images, unsupported formats and unsafe image dimensions are rejected.
  • Expired pending uploads are cleaned automatically.
  • Uploaded but uncompleted orphan objects are removed.
  • Missing storage objects can be detected and reconciled.
  • Chat attachment deletion and Group cleanup behavior are documented and tested.
  • Frontend clients receive a documented and usable image delivery URL.
  • Storage credentials, private object keys and internal bucket details are not exposed.
  • Media lifecycle cleanup failures are observable and retryable.
  • MinIO integration tests validate upload, completion, attachment, delivery and cleanup flows.
  • OpenAPI, Bruno and WebSocket documentation describe the complete chat attachment workflow.

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Status
Backlog

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions