routes/admin.js - git - Webernet Explorer _X
git 🏠 Home 👤 Sign up Self hosted git, retro shell
★ otgit, code hosting from the year 2000 ★
📄 octuna / routes / admin.js
88 lines · 3.3 KB · Raw
1const auth = require('../lib/auth');
2const config = require('../lib/config');
3const render = require('../lib/render');
4const respond = require('../lib/respond');
5 
6function requireAdmin(req, res) {
7 const session = auth.requireAuth(req, res);
8 if (!session) return null;
9 if (session.username !== config.get('admin.user')) {
10 respond.forbidden(res);
11 return null;
12 }
13 return session;
14}
15 
16function buildSettingsForm() {
17 const schema = config.schema();
18 const sections = {};
19 for (const [key, def] of Object.entries(schema)) {
20 if (def.secret) continue;
21 const section = key.split('.')[0];
22 if (!sections[section]) sections[section] = [];
23 sections[section].push({ key, def, value: config.get(key) });
24 }
25 
26 const out = ['<form id="adminSettingsForm">'];
27 for (const [section, fields] of Object.entries(sections)) {
28 out.push(`<div class="panel"><div class="head">${render.escape(section)}</div><div class="body admin-section">`);
29 for (const { key, def, value } of fields) {
30 const fid = 'f_' + key.replace(/\./g, '_');
31 const restartNote = config.requiresRestart(key)
32 ? ' <em class="restart-note">(requires restart)</em>' : '';
33 out.push(`<div class="setting-row">`);
34 out.push(`<label for="${fid}">${render.escape(key)}${restartNote}</label>`);
35 if (def.type === 'boolean') {
36 out.push(`<select id="${fid}" data-key="${key}" data-type="boolean">
37 <option value="true"${value === true ? ' selected' : ''}>true</option>
38 <option value="false"${value === false ? ' selected' : ''}>false</option>
39 </select>`);
40 } else if (def.type === 'enum') {
41 out.push(`<select id="${fid}" data-key="${key}" data-type="enum">`);
42 for (const opt of def.values) {
43 out.push(`<option value="${render.escape(opt)}"${value === opt ? ' selected' : ''}>${render.escape(opt)}</option>`);
44 }
45 out.push('</select>');
46 } else if (def.type === 'number') {
47 out.push(`<input type="number" id="${fid}" data-key="${key}" data-type="number" value="${value}" step="1">`);
48 } else {
49 out.push(`<input type="text" id="${fid}" data-key="${key}" data-type="string" value="${render.escape(String(value || ''))}">`);
50 }
51 out.push('</div>');
52 }
53 out.push('</div></div>');
54 }
55 out.push('<div style="padding:10px"><button type="submit">Save settings</button> <span class="form-msg" id="adminMsg"></span></div>');
56 out.push('</form>');
57 return out.join('\n');
58}
59 
60function settingsPage(req, res) {
61 const session = requireAdmin(req, res);
62 if (!session) return;
63 const content = render.fill(render.loadView('admin-settings.html'), {
64 SETTINGS_FORM: buildSettingsForm()
65 });
66 res.end(render.page({ title: 'Admin settings', content, session, addressUrl: req.url }));
67}
68 
69function saveSettings(req, res) {
70 const session = requireAdmin(req, res);
71 if (!session) return;
72 respond.readJson(req, (err, body) => {
73 if (err) return respond.badRequest(res, err.message);
74 try {
75 config.setMany(body);
76 respond.json(res, 200, { ok: true });
77 } catch (e) {
78 respond.badRequest(res, e.message);
79 }
80 });
81}
82 
83module.exports = function register(router) {
84 router.get('/admin', (_req, res) => respond.redirect(res, '/admin/settings'));
85 router.get('/admin/settings', settingsPage);
86 router.post('/admin/settings/save', saveSettings);
87};
88 
Done 🔒 Internet