Merge pull request 'fix(settings): rewrite route to match single-row column schema (was double-encoded base64 + wrong key/value schema)' (#32) from feat/ui-theme-settings-champion into master
Some checks failed
Build & Publish Docker Image / build-and-push (push) Has been cancelled

Reviewed-on: #32
This commit was merged in pull request #32.
This commit is contained in:
2026-03-09 22:34:54 -05:00

View File

@@ -1 +1,64 @@
Y29uc3QgZXhwcmVzcyA9IHJlcXVpcmUoJ2V4cHJlc3MnKTsKY29uc3Qgcm91dGVyID0gZXhwcmVzcy5Sb3V0ZXIoKTsKY29uc3QgeyBnZXREYXRhYmFzZSB9ID0gcmVxdWlyZSgnLi4vZGIvaW5pdCcpOwoKLy8gR0VUIGFsbCBzZXR0aW5ncwpyb3V0ZXIuZ2V0KCcvJywgKHJlcSwgcmVzKSA9PiB7CiAgdHJ5IHsKICAgIGNvbnN0IGRiID0gZ2V0RGF0YWJhc2UoKTsKICAgIGNvbnN0IHJvd3MgPSBkYi5wcmVwYXJlKCdTRUxFQ1Qga2V5LCB2YWx1ZSBGUk9NIHNldHRpbmdzJykuYWxsKCk7CiAgICBjb25zdCBzZXR0aW5ncyA9IHt9OwogICAgcm93cy5mb3JFYWNoKHIgPT4geyBzZXR0aW5nc1tyLmtleV0gPSByLnZhbHVlOyB9KTsKICAgIHJlcy5qc29uKHNldHRpbmdzKTsKICB9IGNhdGNoIChlcnJvcikgewogICAgcmVzLnN0YXR1cyg1MDApLmpzb24oeyBlcnJvcjogZXJyb3IubWVzc2FnZSB9KTsKICB9Cn0pOwoKLy8gUFVUIHVwZGF0ZSBzZXR0aW5ncwpyb3V0ZXIucHV0KCcvJywgKHJlcSwgcmVzKSA9PiB7CiAgdHJ5IHsKICAgIGNvbnN0IGRiID0gZ2V0RGF0YWJhc2UoKTsKICAgIGNvbnN0IHVwc2VydCA9IGRiLnByZXBhcmUoJ0lOU0VSVCBJTlRPIHNldHRpbmdzIChrZXksIHZhbHVlKSBWQUxVRVMgKD8sID8pIE9OIENPTUZMSUNIVCBLRVBVUERBVEU9ZXhjbHVkZWQudmFsdWUnKTsKICAgIGNvbnN0IHVwZGF0ZU1hbnkgPSBkYi50cmFuc2FjdGlvbigoZW50cmllcykgPT4gewogICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhlbnRyaWVzKSkgewogICAgICAgIHVwc2VydC5ydW4oa2V5LCB2YWx1ZSA9PSBudWxsID8gJycgOiBTdHJpbmcodmFsdWUpKTsKICAgICAgfQogICAgfSk7CiAgICB1cGRhdGVNYW55KHJlcS5ib2R5KTsKICAgIHJlcy5qc29uKHsgbWVzc2FnZTogJ1NldHRpbmdzIHNhdmVkJyB9KTsKICB9IGNhdGNoIChlcnJvcikgewogICAgcmVzLnN0YXR1cyg1MDApLmpzb24oeyBlcnJvcjogZXJyb3IubWVzc2FnZSB9KTsKICB9Cn0pOwoKbW9kdWxlLmV4cG9ydHMgPSByb3V0ZXI7Cg==
const express = require('express');
const router = express.Router();
const { getDatabase } = require('../db/init');
// Allowed columns — whitelist prevents arbitrary SQL column injection
const ALLOWED_KEYS = [
'kennel_name',
'kennel_tagline',
'kennel_address',
'kennel_phone',
'kennel_email',
'kennel_website',
'kennel_akc_id',
'kennel_breed',
'owner_name',
];
// GET /api/settings
router.get('/', (req, res) => {
try {
const db = getDatabase();
// Always returns exactly one row (seeded in init.js)
const row = db.prepare(`SELECT ${ALLOWED_KEYS.join(', ')} FROM settings LIMIT 1`).get();
res.json(row || {});
} catch (error) {
console.error('Error fetching settings:', error);
res.status(500).json({ error: error.message });
}
});
// PUT /api/settings
router.put('/', (req, res) => {
try {
const db = getDatabase();
const updates = req.body || {};
// Build SET clause only for allowed keys that were sent
const fields = Object.keys(updates).filter(k => ALLOWED_KEYS.includes(k));
if (fields.length === 0) {
return res.status(400).json({ error: 'No valid settings fields provided' });
}
const setClause = fields.map(f => `${f} = ?`).join(', ');
const values = fields.map(f => updates[f] == null ? null : String(updates[f]));
// Ensure a row exists, then update it
const existing = db.prepare('SELECT id FROM settings LIMIT 1').get();
if (!existing) {
db.prepare(`INSERT INTO settings (kennel_name) VALUES ('BREEDR')`).run();
}
db.prepare(`UPDATE settings SET ${setClause}, updated_at = datetime('now') WHERE id = (SELECT id FROM settings LIMIT 1)`)
.run(...values);
const row = db.prepare(`SELECT ${ALLOWED_KEYS.join(', ')} FROM settings LIMIT 1`).get();
res.json(row || {});
} catch (error) {
console.error('Error saving settings:', error);
res.status(500).json({ error: error.message });
}
});
module.exports = router;