a new section above Administration. it embeds THE PLATFORM'S OWN file browser rather than drawing a file list — upload, delete, rename, move, thumbnails, the context menu and every task hanging off it already exist and are maintained in one place. a plugin's own would be a second to keep in step, arriving without any of that. `basePath` IS A JAIL, not a starting folder: `useFileBrowserApp` resets currentPath whenever it leaves, so pointing it at `<root>/media/originals` means the breadcrumb stops there and `derived/` is not reachable by navigating. that is what was asked for — people work in originals, derived is made for them. IT IS A GUARDRAIL AND NOT A PERMISSION BOUNDARY, and the panel says so in its own docstring because the difference will matter to whoever reads this next. the file-browser API is unchanged and still addresses the whole home: anyone with file access reaches derived/ through the Files screen. this prevents an accident, not a determined person. confining it properly means scoping that API per user, which is a platform change and a much larger one. the panel also says, once, that derived/ exists and is made from these — otherwise somebody who knows about it would think it had been lost. `rootRelative` is new on the settings API because only the SERVER knows what home is. the file browser addresses everything relative to a root, and a browser deriving that prefix from the absolute path would be guessing. null when the root sits outside home — a legitimate setting the browser cannot address, which the panel explains rather than rendering an empty folder. NOTHING HERE IS FOFOS-SPECIFIC, which matters now that this plugin is the template for other site admins: the root is a setting, media/originals is the layout this plugin creates, and both are read from the API. another site's plugin changes the label. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
2.9 KiB
TypeScript
65 lines
2.9 KiB
TypeScript
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.19',
|
|
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'],
|
|
},
|
|
],
|
|
};
|