Skip to content

Allow generation of bundles meant for web publishing #13

@eljojo

Description

@eljojo

Part of #9. Also addresses #12.

Summary

The full web-hosted recovery story: publish recover.html on GitHub Pages, generate deployable bundles with a single CLI command, and auto-load the manifest when hosted alongside.

Requires word list support to be landed first (see protocol v2 + word lists issue) — without word lists, web-hosted recovery would require friends to drag-drop files, which defeats the purpose of hosting.


Part A: Web-publishable bundles

Files:

  • internal/cmd/bundle.go (or new internal/cmd/publish.go) — New --web flag or subcommand
  • internal/bundle/web.go — Web bundle generation logic

What rememory bundle --web produces:

web-bundle/
  index.html          # recover.html (generic, no pre-filled share)
  MANIFEST.age        # The encrypted archive

That's it. Two files. Upload them anywhere.

Behavior:

  • recover.html is generic — no share pre-filled, no contact list embedded
  • MANIFEST.age sits alongside it
  • The recover.html detects it's being served over HTTP and auto-loads ./MANIFEST.age (see Part C)
  • Friends visit the URL, type their 24 words, and recover

What friends receive (instead of a ZIP):

  • A URL (e.g., https://mysecrets.example.com/)
  • Their 24 recovery words (on a printed card, in person, or by other secure means)
  • Instructions: "Go to this URL, type your words, and follow the steps"

CLI output:

Web bundle created in web-bundle/

Deploy this folder to any static host (GitHub Pages, Cloudflare Pages, Netlify, etc.)
Then give each friend the URL and their recovery words.

Tests:

  • Integration test: generate web bundle, verify contents
  • E2E: serve the web bundle locally, recover using word input

Part B: Load manifest from relative URL (#12)

Files:

  • internal/html/assets/src/app.ts — Auto-fetch manifest logic

Behavior:

  • On load, detect protocol: http: / https: vs file:
  • If HTTP(S): try fetch('./MANIFEST.age'). If found, auto-load it. Show "Loaded from server" label.
  • If file://: skip auto-fetch (same-origin restrictions make it impossible anyway). Keep current drag-drop behavior.
  • If fetch fails (404, network error): silently fall back to manual upload. No error shown — the user might be using a generic recover.html with a separate MANIFEST.age.

Security consideration:

  • The manifest is already encrypted with age. Loading it over HTTP doesn't compromise security — without the shares, it's opaque ciphertext.
  • No other network requests. This is the only fetch recover.html ever makes.

Tests:

  • Playwright E2E: serve recover.html + MANIFEST.age together, verify auto-load
  • Playwright E2E: serve recover.html alone, verify graceful fallback

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions