diff --git a/server/index.ts b/server/index.ts index 11bcf8a..8f8418c 100644 --- a/server/index.ts +++ b/server/index.ts @@ -7,7 +7,7 @@ import { readSettings, writeSettings } from './settings.js' import { registerDriver, getDriver, getAvailableClients, listClients, addClient, removeClient, getClient, - sanitizeClient, dispatchDownload, dispatchList + sanitizeClient, dispatchDownload, dispatchList, updateClient } from './torrent-clients/index.js' import qbittorrentDriver from './torrent-clients/qbittorrent.js' import transmissionDriver from './torrent-clients/transmission.js' @@ -71,11 +71,31 @@ app.delete('/api/torrent-clients/:uuid', requireAuth, (req, res) => { if (!ok) { res.status(404).json({ error: 'Client introuvable' }); return } res.json({ ok: true }) }) +app.put('/api/torrent-clients/:uuid', requireAuth, (req, res) => { + const { name, type, config } = req.body + if (!name || !type || !config) { res.status(400).json({ error: 'name, type et config requis' }); return } + if (!getDriver(type)) { res.status(400).json({ error: `Type inconnu : ${type}` }); return } + const updated = updateClient(String(req.params.uuid), name, type, config) + if (!updated) { res.status(404).json({ error: 'Client introuvable' }); return } + res.json(sanitizeClient(updated)) +}) app.post('/api/torrent-clients/test-config', requireAuth, async (req, res) => { - const { type, config } = req.body + const { type, config, uuid } = req.body if (!type || !config) { res.status(400).json({ error: 'type et config requis' }); return } const driver = getDriver(type) if (!driver) { res.status(400).json({ error: `Type inconnu : ${type}` }); return } + + if (uuid) { + const oldClient = getClient(uuid) + if (oldClient) { + for (const field of driver.definition.fields) { + if (field.type === 'password' && config[field.key] === '••••••••') { + config[field.key] = oldClient.config[field.key] + } + } + } + } + res.json(await driver.test(config)) }) app.post('/api/torrent-clients/:uuid/test', requireAuth, async (req, res) => { diff --git a/server/torrent-clients/index.ts b/server/torrent-clients/index.ts index bd0baa3..146c56d 100644 --- a/server/torrent-clients/index.ts +++ b/server/torrent-clients/index.ts @@ -103,6 +103,30 @@ export function addClient(name: string, type: string, config: Record): SavedClient | null { + const clients = loadClients() + const index = clients.findIndex(c => c.uuid === uuid) + if (index === -1) return null + + const oldClient = clients[index] + const definition = getDriver(type)?.definition + + // Conserver les mots de passe si "••••••••" est envoyé + if (definition) { + for (const field of definition.fields) { + if (field.type === 'password' && config[field.key] === '••••••••') { + config[field.key] = oldClient.config[field.key] + } + } + } + + const client: SavedClient = { uuid, name, type, config } + clients[index] = client + saveClients(clients) + logger.info('torrent-clients', `Client mis à jour : "${name}" (${type})`) + return client +} + export function removeClient(uuid: string): boolean { const clients = loadClients() const target = clients.find(c => c.uuid === uuid) diff --git a/src/views/settings/DownloadClientView.vue b/src/views/settings/DownloadClientView.vue index cf32815..e905d33 100644 --- a/src/views/settings/DownloadClientView.vue +++ b/src/views/settings/DownloadClientView.vue @@ -34,6 +34,7 @@
+
@@ -49,7 +50,7 @@
-

Ajouter un client

+

{{ modal.uuid ? 'Modifier un client' : 'Ajouter un client' }}

@@ -116,6 +117,7 @@ const healthStatus = ref>({}) const modal = ref({ open : false, + uuid : null as string | null, name : '', type : '', config : {} as Record, @@ -171,7 +173,20 @@ async function deleteClient(uuid: string) { } function openAddModal() { - modal.value = { open: true, name: '', type: '', config: {}, testing: false, saving: false, tested: false } + modal.value = { open: true, uuid: null, name: '', type: '', config: {}, testing: false, saving: false, tested: false } +} + +function editClient(client: any) { + modal.value = { + open : true, + uuid : client.uuid, + name : client.name, + type : client.type, + config : JSON.parse(JSON.stringify(client.config)), + testing: false, + saving : false, + tested : true, + } } function closeModal() { modal.value.open = false } @@ -193,7 +208,7 @@ async function testNewClient() { try { const res = await fetch('/api/torrent-clients/test-config', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', - body: JSON.stringify({ type: modal.value.type, config: modal.value.config }), + body: JSON.stringify({ type: modal.value.type, config: modal.value.config, uuid: modal.value.uuid }), }) const { ok, message } = await res.json() modal.value.tested = ok @@ -209,8 +224,12 @@ async function saveClient() { if (!modal.value.tested) return modal.value.saving = true try { - const res = await fetch('/api/torrent-clients', { - method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'include', + const isEdit = !!modal.value.uuid + const method = isEdit ? 'PUT' : 'POST' + const url = isEdit ? `/api/torrent-clients/${modal.value.uuid}` : '/api/torrent-clients' + + const res = await fetch(url, { + method, headers: { 'Content-Type': 'application/json' }, credentials: 'include', body: JSON.stringify({ name : modal.value.name || clientLabel(modal.value.type), type : modal.value.type, @@ -219,10 +238,15 @@ async function saveClient() { }) if (res.ok) { const client = await res.json() - clients.value.push(client) + if (isEdit) { + const index = clients.value.findIndex(c => c.uuid === client.uuid) + if (index !== -1) clients.value[index] = client + } else { + clients.value.push(client) + } refreshHealth(client.uuid) closeModal() - toast('Client enregistré ✓', 'success') + toast(isEdit ? 'Client modifié ✓' : 'Client enregistré ✓', 'success') } else { const { error } = await res.json() toast(error ?? "Erreur lors de l'enregistrement", 'error')