fix: pass jellyfin/jellyseerr secrets via get_machine_config and add placeholder for set fields

This commit is contained in:
2026-05-07 23:39:59 +02:00
parent 7e80733837
commit befddf93ce
2 changed files with 67 additions and 19 deletions
@@ -130,7 +130,13 @@ def _resolve_machine(service: str, request: Request | None = None) -> dict[str,
def get_jellyfin_client(request: Request = None) -> JellyfinClient: def get_jellyfin_client(request: Request = None) -> JellyfinClient:
"""Return a Jellyfin client for the selected machine.""" """Return a Jellyfin client for the selected machine."""
machine = get_settings_store().get_machine_config(_request_machine_id(request)) or _resolve_machine("jellyfin", request) store = get_settings_store()
machine_id = _request_machine_id(request)
machine = store.get_machine_config(machine_id) if machine_id else None
if machine is None:
resolved = _resolve_machine("jellyfin", request)
if resolved:
machine = store.get_machine_config(resolved["id"])
if machine and machine.get("jellyfin_url") and machine.get("jellyfin_api_key"): if machine and machine.get("jellyfin_url") and machine.get("jellyfin_api_key"):
cache_key = (machine["id"], machine["jellyfin_url"], machine.get("jellyfin_api_key") or "") cache_key = (machine["id"], machine["jellyfin_url"], machine.get("jellyfin_api_key") or "")
return _jellyfin_client_for(cache_key) return _jellyfin_client_for(cache_key)
@@ -140,7 +146,13 @@ def get_jellyfin_client(request: Request = None) -> JellyfinClient:
def get_jellyseerr_client(request: Request = None) -> JellyseerrClient | None: def get_jellyseerr_client(request: Request = None) -> JellyseerrClient | None:
"""Return a cached Jellyseerr client when configured, otherwise None.""" """Return a cached Jellyseerr client when configured, otherwise None."""
machine = get_settings_store().get_machine_config(_request_machine_id(request)) or _resolve_machine("jellyseerr", request) store = get_settings_store()
machine_id = _request_machine_id(request)
machine = store.get_machine_config(machine_id) if machine_id else None
if machine is None:
resolved = _resolve_machine("jellyseerr", request)
if resolved:
machine = store.get_machine_config(resolved["id"])
if machine and machine.get("jellyseerr_url") and machine.get("jellyseerr_api_key"): if machine and machine.get("jellyseerr_url") and machine.get("jellyseerr_api_key"):
return JellyseerrClient(machine["jellyseerr_url"], machine.get("jellyseerr_api_key") or "") return JellyseerrClient(machine["jellyseerr_url"], machine.get("jellyseerr_api_key") or "")
@@ -217,7 +229,13 @@ def get_settings_store() -> SettingsStore:
def get_user_id(request: Request = None) -> str: def get_user_id(request: Request = None) -> str:
"""Return the configured Jellyfin user ID or discover the first available one.""" """Return the configured Jellyfin user ID or discover the first available one."""
machine = get_settings_store().get_machine_config(_request_machine_id(request)) or _resolve_machine("jellyfin", request) store = get_settings_store()
machine_id = _request_machine_id(request)
machine = store.get_machine_config(machine_id) if machine_id else None
if machine is None:
resolved = _resolve_machine("jellyfin", request)
if resolved:
machine = store.get_machine_config(resolved["id"])
if machine and machine.get("jellyfin_user_id"): if machine and machine.get("jellyfin_user_id"):
return str(machine["jellyfin_user_id"]) return str(machine["jellyfin_user_id"])
client = get_jellyfin_client(request) client = get_jellyfin_client(request)
+46 -16
View File
@@ -78,6 +78,7 @@ function MachineEditor({
hint, hint,
machine, machine,
sshKeys, sshKeys,
editingMachine,
onChange, onChange,
onValidateSSH, onValidateSSH,
isValidatingSSH, isValidatingSSH,
@@ -89,6 +90,7 @@ function MachineEditor({
hint?: string; hint?: string;
machine: MonitoringMachineInput; machine: MonitoringMachineInput;
sshKeys: SSHKey[]; sshKeys: SSHKey[];
editingMachine?: MonitoringMachine | null;
onChange: ( onChange: (
draft: draft:
| MonitoringMachineInput | MonitoringMachineInput
@@ -107,6 +109,8 @@ function MachineEditor({
const enabledServices = draft.services.length; const enabledServices = draft.services.length;
const hasJellyfin = draft.services.includes("jellyfin"); const hasJellyfin = draft.services.includes("jellyfin");
const hasJellyseerr = draft.services.includes("jellyseerr"); const hasJellyseerr = draft.services.includes("jellyseerr");
const placeholderIfSet = (isSet: boolean | undefined) =>
isSet ? "Set, not shown" : undefined;
return ( return (
<Card variant="outlined"> <Card variant="outlined">
<CardContent sx={{ p: 1.5 }}> <CardContent sx={{ p: 1.5 }}>
@@ -322,6 +326,7 @@ function MachineEditor({
size="small" size="small"
label="Password" label="Password"
type="password" type="password"
placeholder={placeholderIfSet(editingMachine?.password_set)}
value={draft.password} value={draft.password}
onChange={(e) => onChange={(e) =>
setDraft((current) => ({ setDraft((current) => ({
@@ -419,6 +424,7 @@ function MachineEditor({
size="small" size="small"
label="Jellyfin API key" label="Jellyfin API key"
type="password" type="password"
placeholder={placeholderIfSet(editingMachine?.jellyfin_api_key_set)}
value={draft.jellyfin_api_key} value={draft.jellyfin_api_key}
onChange={(e) => onChange={(e) =>
setDraft((current) => ({ setDraft((current) => ({
@@ -470,6 +476,7 @@ function MachineEditor({
size="small" size="small"
label="Jellyseerr API key" label="Jellyseerr API key"
type="password" type="password"
placeholder={placeholderIfSet(editingMachine?.jellyseerr_api_key_set)}
value={draft.jellyseerr_api_key} value={draft.jellyseerr_api_key}
onChange={(e) => onChange={(e) =>
setDraft((current) => ({ setDraft((current) => ({
@@ -832,18 +839,34 @@ function SSHKeyManager({ sshKeys }: { sshKeys: SSHKey[] }) {
</Typography> </Typography>
</Box> </Box>
<Stack direction="row" spacing={1}> <Stack direction="row" spacing={1}>
<Button <Button
size="small" variant="outlined"
onClick={() => onClick={() =>
setDraft({ openEditMachine({
id: key.id, id: selectedMachine.id,
name: key.name, name: selectedMachine.name,
private_key: "", mode: selectedMachine.mode,
passphrase: "", enabled: selectedMachine.enabled,
public_key: key.public_key, services: selectedMachine.services,
fingerprint: key.fingerprint, host: selectedMachine.host,
notes: key.notes, port: selectedMachine.port,
}) username: selectedMachine.username,
key_directory: "",
key_name: "",
path_prefix: "",
ssh_key_id: selectedMachine.ssh_key_id,
ssh_private_key: "",
ssh_private_key_passphrase: "",
password: "",
media_root: selectedMachine.media_root,
jellyfin_url: selectedMachine.jellyfin_url,
jellyfin_user_id:
selectedMachine.jellyfin_user_id,
jellyfin_api_key: "",
jellyseerr_url: selectedMachine.jellyseerr_url,
jellyseerr_api_key: "",
notes: selectedMachine.notes,
}, selectedMachine)
} }
> >
Edit Edit
@@ -1005,6 +1028,7 @@ export function Settings() {
const [machineDraft, setMachineDraft] = useState<MonitoringMachineInput>( const [machineDraft, setMachineDraft] = useState<MonitoringMachineInput>(
emptyMachine(), emptyMachine(),
); );
const [editingMachine, setEditingMachine] = useState<MonitoringMachine | null>(null);
const [selectedMachineId, setSelectedMachineId] = useState(""); const [selectedMachineId, setSelectedMachineId] = useState("");
const orderedMachines = useMemo(() => machines ?? [], [machines]); const orderedMachines = useMemo(() => machines ?? [], [machines]);
const selectedMachine = useMemo( const selectedMachine = useMemo(
@@ -1028,21 +1052,25 @@ export function Settings() {
const beginLocal = () => { const beginLocal = () => {
clearSSHValidation(); clearSSHValidation();
setMachineDraft(emptyMachine("local")); setMachineDraft(emptyMachine("local"));
setEditingMachine(null);
setMachineDialogOpen(true); setMachineDialogOpen(true);
}; };
const beginRemote = () => { const beginRemote = () => {
clearSSHValidation(); clearSSHValidation();
setMachineDraft(emptyMachine("ssh")); setMachineDraft(emptyMachine("ssh"));
setEditingMachine(null);
setMachineDialogOpen(true); setMachineDialogOpen(true);
}; };
const openEditMachine = (machine: MonitoringMachineInput) => { const openEditMachine = (input: MonitoringMachineInput, original?: MonitoringMachine | null) => {
clearSSHValidation(); clearSSHValidation();
setMachineDraft(machine); setMachineDraft(input);
setEditingMachine(original ?? null);
setMachineDialogOpen(true); setMachineDialogOpen(true);
}; };
const closeMachineDialog = () => { const closeMachineDialog = () => {
clearSSHValidation(); clearSSHValidation();
setMachineDialogOpen(false); setMachineDialogOpen(false);
setEditingMachine(null);
}; };
const updateMachineDraft = ( const updateMachineDraft = (
draft: draft:
@@ -1056,6 +1084,7 @@ export function Settings() {
clearSSHValidation(); clearSSHValidation();
await saveMachine.mutateAsync(draft); await saveMachine.mutateAsync(draft);
setMachineDialogOpen(false); setMachineDialogOpen(false);
setEditingMachine(null);
setMachineDraft(emptyMachine(draft.mode)); setMachineDraft(emptyMachine(draft.mode));
}; };
const validateMachineSSH = async () => { const validateMachineSSH = async () => {
@@ -1250,7 +1279,7 @@ export function Settings() {
jellyseerr_url: machine.jellyseerr_url, jellyseerr_url: machine.jellyseerr_url,
jellyseerr_api_key: "", jellyseerr_api_key: "",
notes: machine.notes, notes: machine.notes,
}); }, machine);
}} }}
/> />
</Box> </Box>
@@ -1376,7 +1405,7 @@ export function Settings() {
jellyseerr_url: selectedMachine.jellyseerr_url, jellyseerr_url: selectedMachine.jellyseerr_url,
jellyseerr_api_key: "", jellyseerr_api_key: "",
notes: selectedMachine.notes, notes: selectedMachine.notes,
}) }, selectedMachine)
} }
> >
Edit Edit
@@ -1425,6 +1454,7 @@ export function Settings() {
} }
machine={machineDraft} machine={machineDraft}
sshKeys={sshKeys} sshKeys={sshKeys}
editingMachine={editingMachine}
onChange={updateMachineDraft} onChange={updateMachineDraft}
onValidateSSH={validateMachineSSH} onValidateSSH={validateMachineSSH}
isValidatingSSH={testMachineSSH.isPending} isValidatingSSH={testMachineSSH.isPending}