Add the profile page, and publish it as an embeddable panel

Developed in a separate session; committed here alongside the calendar work
that shares this repository's migration journal.

A person can now see their own Plex link, their Watch Now slots and their watch
history at /profile. The same panel is published in two further forms so that
accounts.sticknife.com on charon can carry it as one section of a wider
sticknife profile, next to the other services' sections.

  - watch_history (0024) records what has been played, keyed on the Plex
    history id so a re-sync cannot duplicate a row. Partial unique index,
    because that id is null for anything entered by hand.
  - plex_accounts.is_server_owner (0025) marks the one account whose viewing
    the server files under local account 1 rather than under its plex.tv id.
  - The embed carries its own layout, origin allowlist and a frame-height
    reporter, so the host page can size it without guessing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
odin
2026-08-17 15:42:17 +02:00
parent 3ccae54259
commit 1dfa2c0a04
30 changed files with 8119 additions and 233 deletions
+20
View File
@@ -32,6 +32,26 @@ AMPELOS_AGENT_TIMEOUT_SECONDS=30
# both repositories' environments, in neither's history.
AMPELOS_AGENT_TOKEN=
# --- the sticknife-wide profile -------------------------------------------
# accounts.sticknife.com shows an Ampelos section in its own profile page, by
# framing /embed/profile and/or reading /api/profile. See PROFILE-INTEGRATION.md.
#
# Which origins may frame /embed/* and call /api/profile from a browser.
# Comma-separated ORIGINS, scheme included -- a bare hostname is silently
# ignored by the CSP parser and never matches a CORS Origin header. Everything
# outside /embed is frame-ancestors 'none' regardless of what is set here.
AMPELOS_EMBED_ANCESTORS=https://accounts.sticknife.com
#
# Optional, and OFF unless set. Lets charon render the panel SERVER-side, where
# there is no browser to carry a session cookie: it presents this as a bearer
# token and names the user with ?email= or ?userId=.
#
# That is a full read of anybody's profile, watch history included. It is
# deliberately NOT AMPELOS_AGENT_TOKEN -- that one is deployed to every
# satellite host, and a leaked herald script should not also hand over
# everyone's viewing. Leave it unset if charon only ever iframes the panel.
AMPELOS_PROFILE_API_TOKEN=
# --- external services ----------------------------------------------------
MOVIEDB_API=
PLEX_URL=