Skip to content

Keep asset:// as the only user-visible and persisted asset reference in editor flows#34

Closed
Copilot wants to merge 10 commits intomainfrom
copilot/fix-blob-url-exposure
Closed

Keep asset:// as the only user-visible and persisted asset reference in editor flows#34
Copilot wants to merge 10 commits intomainfrom
copilot/fix-blob-url-exposure

Conversation

Copy link
Copy Markdown

Copilot AI commented Mar 24, 2026

  • Review current branch state and inspect the remaining asset:// failures in edit mode
  • Locate the TinyMCE/text iDevice paths that still parse asset:// before runtime resolution
  • Update TinyMCE content loading so setContent() input is converted to runtime URLs before the browser parses it, while getContent() still returns canonical asset://
  • Avoid unnecessary DOM parsing in the text iDevice legacy wrapper cleanup when content is not actually wrapped, so raw asset:// HTML is not eagerly loaded there
  • Add regression tests for TinyMCE BeforeSetContent asset resolution and text iDevice wrapper handling with asset:// content
  • Run targeted frontend tests for TinyMCE and text iDevice
  • Run make fix, make bundle, and make test-frontend
  • Run code review and CodeQL checks, then summarize the security impact
Original prompt

This section details on the original issue you should resolve

<issue_title>Do not expose blob: URLs to users; keep asset:// as the only user-visible and persisted asset reference exelearning#1598</issue_title>
<issue_description>### Summary

Users should never see or copy blob: URLs inside eXeLearning editors or HTML source views.

blob: URLs are browser-temporary runtime URLs. They are not stable project references, they are not portable, and users can mistakenly copy them into their content thinking they are the real asset path.

The editor should expose only asset://... references to users and internally translate them to temporary blob: URLs only when needed for rendering or preview.

Problem

At the moment, users can end up seeing blob: URLs such as:

blob:https://static.exelearning.dev/62e7c455-f41c-45a5-a42a-9a8864d22cac

This is misleading because:

  • blob: URLs are temporary and browser/session-specific.
  • They are not suitable for persistence in project content.
  • Some users copy them manually into HTML.
  • This can produce broken references, confusion, and hard-to-understand editing errors.

From a user perspective, the only meaningful reference should be something stable and project-aware, for example:

asset://8f3e9c2a-1b4d-4f7e-9a3c-2d1e5f7a9b3c.jpg

or, in a friendlier future form:

asset://images/photo.jpg

with the application internally resolving that to the current asset UUID and to a runtime blob: URL when rendering.

Current architecture context

The current codebase already seems aligned with this direction:

  • The architecture documentation describes assets as using asset://... URLs as the content-addressable reference format.
  • AssetManager also documents that assets are referenced with asset:// URLs in HTML.
  • The same file clearly distinguishes those stored references from display-time blob URLs created with URL.createObjectURL(...).

That means this issue is less about changing the storage model and more about enforcing a stricter boundary between:

  • canonical persisted referencesasset://...
  • temporary runtime rendering URLsblob:...

Proposal

Phase 1: low-risk fix

Ensure that users never see blob: URLs in editable content.

Concretely:

  1. Do not write blob: URLs into the persisted HTML/Yjs content

    • Before save / serialization, rewrite any known local blob reference back to its corresponding asset://... URL.
    • If a blob URL cannot be mapped to a known asset, show a validation warning and prevent saving that broken reference.
  2. Do not show blob: URLs in source/code editing dialogs

    • If the user opens HTML/source mode, the content shown should contain only asset://... references.
  3. Do not insert blob: URLs when using media/file pickers

    • Insert asset://... directly into the editor model.
    • Convert to blob: only in the rendering layer.
  4. Add a defensive cleanup step on paste/import/save

    • Detect blob: references in HTML.
    • If they match a locally known asset, replace them automatically with asset://....
    • If not, notify the user that temporary browser URLs are not valid project references.

Phase 2: optional usability improvement

Introduce a friendlier alias format for display, while keeping the UUID-based model internally:

asset://folder/image.jpg

Possible behavior:

  • UI/source editor displays asset://folder/image.jpg
  • internally the model still resolves that to the canonical asset UUID
  • export/runtime resolution continues using the current asset metadata

This would be more understandable for non-technical users than a raw UUID.


Suggested implementation approach

A simple implementation path could be:

A. Enforce canonicalization in one place

Create a single utility responsible for normalizing asset references in HTML:

  • input: raw HTML from editor/source/import/paste
  • output: normalized HTML with only asset://... references

This utility could:

  • replace known blob: URLs using the existing reverse blob cache / asset metadata
  • preserve valid asset://... references
  • ignore http:, https:, data:, anchors, etc.
  • optionally report unknown blob: references

This avoids scattering the logic across multiple editors.

B. Apply normalization at the boundary points

Use that normalization in these moments:

  • after inserting media from the file manager
  • before writing HTML into Yjs / project state
  • before opening source editor views
  • during import/paste sanitization

C. Keep runtime translation separate

Rendering layers can still resolve asset://... to blob: internally for preview, iframe rendering, or local display.

That preserves the current runtime behavior while making the persisted/user-facing format predictable.

Why this is a good fit for the current design

This proposal works well with the current architecture because the project alre...


📱 Kick off Copilot coding agent tasks wherever you are with GitHub Mobile, available on iOS and Android.

Copilot AI changed the title [WIP] Fix exposure of blob URLs to users Keep asset:// as the only user-visible and persisted asset reference in editor flows Mar 24, 2026
Copilot AI requested a review from erseco March 24, 2026 18:03
@erseco erseco closed this Apr 4, 2026
@github-actions
Copy link
Copy Markdown

github-actions bot commented Apr 4, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-04-04 17:48 UTC

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Do not expose blob: URLs to users; keep asset:// as the only user-visible and persisted asset reference #1598

2 participants