Files
memos-chrome-extension/CLAUDE.md
Paul Spenke 84b3dd69f1 Fix security bugs and migrate image uploads to /api/v1/attachments
* Replace /api/v1/resources with /api/v1/attachments for image uploads
* Upload attachments as JSON with base64-encoded content field
* After memo creation, link each attachment via PATCH /api/v1/attachments/{id}
* Rewrite markdown image URLs to use /file/attachments/{id} pattern
* Fix XSS: sanitize marked.parse output with a DOM-based allowlist sanitizer
* Fix SSRF: validate img.src scheme (http/https only) before fetching
* Fix stack overflow: use chunked base64 encoding for large images
* Update CLAUDE.md to document new attachment flow
2026-03-18 17:55:04 +01:00

3.0 KiB

CLAUDE.md

Project Overview

Memos Clipper is a Chrome Extension (Manifest V3) that clips web pages or text selections and saves them to a Memos instance in Markdown format.

Architecture

Three-part Chrome extension:

  • src/content.js — Content script injected into pages; extracts HTML and converts it to Markdown
  • src/popup.html / src/popup.js — Main popup UI: editor, preview, image gallery, send button
  • src/settings.html / src/settings.js — Options page: Memos URL, API token, defaults
  • src/background.js — Service worker (minimal; onInstalled listener only)

Tech Stack

  • Runtime: Chrome MV3 (Manifest V3)
  • Language: Vanilla JavaScript (ES6+), no frontend framework
  • Styling: Tailwind CSS v4 + PostCSS + Autoprefixer; CSS variables for theming; dark mode via prefers-color-scheme
  • Markdown: Custom HTML→Markdown converter in content.js; marked.min.js for preview rendering
  • Build: Vite v8 with vite-plugin-static-copy

Build & Development

npm install          # Install dependencies
npm run dev          # Dev server with hot reload
npm run build        # Production build → dist/
npm run preview      # Preview built output

Load the extension in Chrome: Extensions → Load unpacked → select dist/

Key Implementation Details

API Integration

  • Memos API v1: /api/v1/memos, /api/v1/attachments
  • Requires Memos v0.22+
  • Bearer token auth via chrome.storage.sync
  • Attachment flow: upload via POST /api/v1/attachments (JSON + base64 content), create memo, then link each attachment to the memo via PATCH /api/v1/attachments/{id} with { memo: "memos/{id}" }

Content Extraction

  • Removes boilerplate: nav, ads, sidebars, cookie banners (45+ selectors)
  • Supports full-page and selection-only modes
  • Converts: headings, lists, tables, code blocks, links, images, blockquotes

Image Handling

  • Filters images smaller than 32px (icons/tracking pixels)
  • Deduplicates images
  • Supports data URIs
  • Uploads images as attachments (POST /api/v1/attachments) with base64-encoded content
  • After memo creation, links each attachment to the memo via PATCH /api/v1/attachments/{id}
  • Attachment file URL pattern: {memosUrl}/file/attachments/{id}

Storage

  • chrome.storage.sync for cross-device settings (URL, token, defaults)

Project Structure

src/
├── manifest.json       # MV3 config (permissions, entry points)
├── popup.html/.js/.css # Main extension popup
├── settings.html/.js/.css # Options page
├── content.js          # Page content extractor
├── background.js       # Service worker
├── marked.min.js       # Bundled Markdown renderer
└── icons/              # 16, 32, 48, 128px PNG icons
dist/                   # Build output (gitignored)
vite.config.js
package.json

Permissions

  • activeTab, scripting, storage
  • Host permissions: <all_urls> (needed for cross-origin image fetching and API calls)