import type { PluginManifest } from '@@/plugins/manifest'; /** * Fofos — the fofos website's admin, inside Officer. * * ── What it replaces ── * * A server-rendered admin on its own subdomain with its own argon2 passwords, its own session cookie * and its own `/admin/setup` bootstrap. Every part of that duplicated something Officer already does, * and none of it could be shared: giving somebody access to the machine still meant giving them * access to the admin, separately, by hand. That is the whole reason this is a plugin. * * ── It holds no content ── * * fofos owns its own database and its own media store, and this reads and writes them over HTTP. The * only thing in Officer's database is the connection — a URL and a token. * * That is a deliberate property rather than a convenience. **Deleting this plugin cannot lose a * photograph or a line of the client's copy**, with the "delete its data" checkbox ticked or not, * because none of it was ever here. The alternative — a `db/schema.ts` carrying fofos's own tables — * would have put every one of them under an installer that is allowed to drop them. * * ── The permission is grantable; the credential is not ── * * Reading and editing the site is exactly what a member might be brought in to do. The TOKEN is a * different matter: it is unrestricted write authority over everything the public sees, so `/_config` * is `ownerOnly` — the split that field exists for, and the same shape proxy-manager and Jellyfin use * for the same reason. * * ── No `screens` ── * * One screen at the mount prefix, labelled `label`. The nine sections are `?section=` on that one * screen rather than nine routes: they are panels of one workspace, and `screens` is for a plugin * contributing genuinely separate destinations. */ export const manifest: PluginManifest = { publisher: 'officerdev', version: '2026.08.29.08', platform: '>=1.0.0', label: 'Fofos', summary: "The fofos website's content — pages, galleries, drops and collabs", /** one website's admin, and useless without that website. */ tags: ['Personal'], icon: 'PenLine', color: '#c2410c', // Nothing to declare. It talks HTTP to fofos and stores one row; there is no host binary anywhere // on the path, and fofos itself is a separate deployment rather than something this installs. permissions: [ { key: 'fofos-admin', label: 'Fofos', description: 'Edit the fofos website — pages, galleries, drops, collabs and the messages people send', // Where the fofos URL and token are set, and the probe that checks them. Prefix-matched, so // `/_config/test` is covered too — deliberately, because that request carries the token in its // BODY. A member who could call it would have an oracle pointed at a credential that can // rewrite the whole public site. ownerOnly: ['/_config'], }, ], };