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:
@@ -0,0 +1,25 @@
|
||||
/**
|
||||
* The origins allowed to embed Ampelos or read its profile API from a browser.
|
||||
*
|
||||
* AMPELOS_EMBED_ANCESTORS is the single source of truth for both, and it is
|
||||
* read in two places on purpose: next.config.ts needs it at build time to write
|
||||
* the CSP `frame-ancestors` header, and route handlers need it at request time
|
||||
* to answer CORS. Keeping one env var and two readers is better than a shared
|
||||
* module, because next.config.ts cannot use the "@/" path alias.
|
||||
*
|
||||
* Origins, not hostnames -- scheme included. Both the CSP parser and the CORS
|
||||
* Origin header deal in origins, and a bare hostname is silently ignored by the
|
||||
* first and never matches the second.
|
||||
*/
|
||||
const DEFAULT_ORIGINS = "https://accounts.sticknife.com";
|
||||
|
||||
export function embedOrigins(): string[] {
|
||||
return (process.env.AMPELOS_EMBED_ANCESTORS ?? DEFAULT_ORIGINS)
|
||||
.split(",")
|
||||
.map((origin) => origin.trim())
|
||||
.filter(Boolean);
|
||||
}
|
||||
|
||||
export function isAllowedOrigin(origin: string | null): origin is string {
|
||||
return Boolean(origin) && embedOrigins().includes(origin!);
|
||||
}
|
||||
Reference in New Issue
Block a user