From 56e2a9750643bcc468b37076b6d0e076bbdbcee7 Mon Sep 17 00:00:00 2001 From: ZGaetano Date: Sat, 18 Apr 2026 13:42:08 -0400 Subject: [PATCH] =?UTF-8?q?feat:=20AMPP=20folder=20sync=20integration=20?= =?UTF-8?q?=E2=80=94=20pre-create=20folder=20hierarchy=20on=20upload,=20ex?= =?UTF-8?q?pose=20lookup=20endpoint=20for=20Script=20Task:=20settings.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- services/mam-api/src/routes/settings.js | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 services/mam-api/src/routes/settings.js diff --git a/services/mam-api/src/routes/settings.js b/services/mam-api/src/routes/settings.js new file mode 100644 index 0000000..09b2253 --- /dev/null +++ b/services/mam-api/src/routes/settings.js @@ -0,0 +1,87 @@ +import express from 'express'; +import pool from '../db/pool.js'; +import { requireAuth } from '../middleware/auth.js'; +import { getAmppConfig } from '../ampp/client.js'; + +const router = express.Router(); +router.use(requireAuth); + +// GET /api/v1/settings/ampp — Return current AMPP config (token value masked) +router.get('/ampp', async (req, res, next) => { + try { + const result = await pool.query( + "SELECT key, value FROM settings WHERE key IN ('ampp_base_url', 'ampp_token')" + ); + const out = {}; + for (const row of result.rows) { + if (row.key === 'ampp_token') { + out.ampp_token_exists = true; // Never return the raw token + } else { + out[row.key] = row.value; + } + } + res.json(out); + } catch (err) { + next(err); + } +}); + +// PUT /api/v1/settings/ampp — Save AMPP credentials +router.put('/ampp', async (req, res, next) => { + try { + const { ampp_base_url, ampp_token } = req.body; + if (!ampp_base_url) { + return res.status(400).json({ error: 'ampp_base_url is required' }); + } + + const baseUrl = ampp_base_url.trim().replace(/\/$/, ''); + + await pool.query( + `INSERT INTO settings (key, value, updated_at) + VALUES ('ampp_base_url', $1, NOW()) + ON CONFLICT (key) DO UPDATE SET value = $1, updated_at = NOW()`, + [baseUrl] + ); + + if (ampp_token) { + await pool.query( + `INSERT INTO settings (key, value, updated_at) + VALUES ('ampp_token', $1, NOW()) + ON CONFLICT (key) DO UPDATE SET value = $1, updated_at = NOW()`, + [ampp_token.trim()] + ); + } + + res.json({ message: 'AMPP settings saved' }); + } catch (err) { + next(err); + } +}); + +// POST /api/v1/settings/ampp/test — Verify AMPP connectivity +router.post('/ampp/test', async (req, res, next) => { + try { + const config = await getAmppConfig(); + if (!config) { + return res.status(400).json({ error: 'AMPP credentials not configured' }); + } + + const testUrl = `${config.ampp_base_url}/api/v1/store/folder/folders?limit=1`; + const testRes = await fetch(testUrl, { + headers: { + Authorization: `Bearer ${config.ampp_token}`, + 'Content-Type': 'application/json', + }, + }); + + if (!testRes.ok) { + return res.status(400).json({ error: `AMPP returned HTTP ${testRes.status}` }); + } + + res.json({ message: 'AMPP connection successful' }); + } catch (err) { + res.status(400).json({ error: `Connection failed: ${err.message}` }); + } +}); + +export default router;