import { Router } from 'express' import axios from 'axios' const router = Router() let cachedSid: string | null = null let sidExpiry = 0 async function getSid(): Promise { if (cachedSid && Date.now() < sidExpiry) return cachedSid const host = process.env.SYNOLOGY_HOST const res = await axios.get(`${host}/webapi/auth.cgi`, { params: { api: 'SYNO.API.Auth', version: 3, method: 'login', account: process.env.SYNOLOGY_USER, passwd: process.env.SYNOLOGY_PASSWORD, session: 'dashboard', format: 'sid', }, }) if (!res.data.success) throw new Error(`Synology login failed: ${JSON.stringify(res.data.error)}`) cachedSid = res.data.data.sid as string sidExpiry = Date.now() + 20 * 60 * 1000 return cachedSid } router.get('/storage', async (_req, res) => { try { const host = process.env.SYNOLOGY_HOST if (!host) { res.status(503).json({ error: 'SYNOLOGY_HOST not configured' }) return } const sid = await getSid() const storageRes = await axios.get(`${host}/webapi/entry.cgi`, { params: { api: 'SYNO.Storage.CGI.Storage', version: 1, method: 'load_info', _sid: sid, }, }) if (!storageRes.data.success) { cachedSid = null throw new Error(`Synology storage error: ${JSON.stringify(storageRes.data.error)}`) } const d = storageRes.data.data // eslint-disable-next-line @typescript-eslint/no-explicit-any const volumes: any[] = d?.volumes ?? d?.vol_info ?? d?.storage?.volumes ?? [] res.json({ volumes: volumes.map(v => ({ id: v.vol_path ?? v.volume_path ?? v.id, label: v.vol_path ?? v.display_name ?? v.id, // DSM 7: sizes live under v.size.{total,used} used: Number(v.size?.used ?? v.size_used ?? 0), total: Number(v.size?.total ?? v.size_total ?? 0), })), }) } catch (err: unknown) { if (err instanceof Error && err.message.includes('login failed')) cachedSid = null const msg = err instanceof Error ? err.message : 'Unknown error' res.status(500).json({ error: msg }) } }) router.get('/info', async (_req, res) => { try { const host = process.env.SYNOLOGY_HOST if (!host) { res.status(503).json({ error: 'SYNOLOGY_HOST not configured' }); return } const sid = await getSid() const r = await axios.get(`${host}/webapi/entry.cgi`, { params: { api: 'SYNO.DSM.Info', version: 2, method: 'getinfo', _sid: sid }, }) if (!r.data.success) throw new Error(`DSM info error: ${JSON.stringify(r.data.error)}`) const d = r.data.data ?? {} res.json({ model: d.model ?? '', dsmVersion: d.version ?? '', uptime: Number(d.uptime ?? 0), temperature: d.temperature != null ? Number(d.temperature) : null, }) } catch (err: unknown) { if (err instanceof Error && err.message.includes('login failed')) cachedSid = null const msg = err instanceof Error ? err.message : 'Unknown error' res.status(500).json({ error: msg }) } }) export default router