wire the trigger: connecting an admin server provisions everyone
the decision and the execution existed; nothing called them. connecting a server would have given a working media connection and zero accounts. the trigger is registering an ADMIN server, not installing the plugin. at install there is no credential, so there is nothing to provision with — and this is also the right moment for a re-run, since a revoked token or a moved server both come back through the same door. the sidecar now holds the pushed account list in memory. each users:list REPLACES what was held rather than merging: it is the platform's current truth, not a cache. persisting it would create a second copy of the platform's users that could disagree with it, and the recovery from disagreement is re-reading the platform anyway. `hasProvisionableUsers()` distinguishes never-told from told-there-is-nobody. an empty list means a server with only an owner; no list at all means the push has not arrived or the plugin is not entitled. provisioning nothing is right for the first and a silent failure for the second. awaited, so the response says what happened instead of the owner finding it in a log later. and it never throws: registering the server already succeeded by then, and losing it to a provisioning error would leave them with no media access AND no accounts, which is worse than the accounts alone. mapping rows are written one at a time as each result is known, not batched at the end. a create that succeeds upstream but whose row fails to write leaves an orphan account officer will try to create again — the narrower that window, the better. found while wiring: the first edit landed the block in editServer as well as addServer, where `auth` does not exist. caught by tsgo, removed.
This commit is contained in:
@@ -4,6 +4,7 @@ import { handleConfigRoute, noteProbe } from './config';
|
||||
import { handleBytesRoute, handleOfficerRoute } from './routes';
|
||||
import { getConfig, probe } from './upstream';
|
||||
import { API_URL } from '@@/officer-url.mjs';
|
||||
import { setProvisionableUsers } from './user-list';
|
||||
|
||||
// The officer-jellyfin sidecar. Owns the whole Jellyfin contract for Officer: the instance URL, the access
|
||||
// token, the Jellyfin user it belongs to and the DeviceId its sessions are keyed by. The platform API is a
|
||||
@@ -137,6 +138,12 @@ function handleCommand(cmd: SidecarCommand, reply: ReplyFn) {
|
||||
case 'ping':
|
||||
reply({ type: 'pong', id: cmd.id });
|
||||
break;
|
||||
// The platform's account list, pushed because this plugin's manifest declares `userProvisioning`.
|
||||
// Arrives on registration and again on every account create or delete. No reply — it is a statement,
|
||||
// not a question.
|
||||
case 'users:list':
|
||||
setProvisionableUsers(cmd.users);
|
||||
break;
|
||||
default:
|
||||
reply({
|
||||
type: 'error',
|
||||
|
||||
Reference in New Issue
Block a user