sdl/sdl-mgr/app/modules/web/index.js

208 lines
5.4 KiB
JavaScript

import serveIndex from 'serve-index';
import open from 'open';
const module = 'web'; // Module Name
import { load_config, log } from '../nwa-lib/index.js';
const config = load_config();
log(`${module}: Loaded module: ${module}`);
import fs from 'fs';
import path from 'path';
import { parse } from 'csv-parse';
import express from 'express';
const app = express();
// Serve config as JSON
app.get('/api/config', (req, res) => {
res.json(config);
let webreqmeta = {
method: req.method,
url: req.originalUrl,
ip: req.ip,
userAgent: req.get('User-Agent')
};
log(module + ': WEBAPI: ' + JSON.stringify(webreqmeta))
});
// Serve sidepanel nav as JSON
app.get('/api/nav/sidepanel', (req, res) => {
const sideMenuPath = path.join(
config.dirs.html,
'conf',
'nav-sidepanel.json'
);
try {
const sideMenuData = JSON.parse(
fs.readFileSync(sideMenuPath, 'utf8')
);
res.json(sideMenuData);
log(module + ': INFO: GET /api/nav/sidepanel');
} catch (err) {
log(`ERROR: GET /api/nav/sidepanel failed: ${err}`);
res.status(500).json({ error: 'Failed to load nav-sidepanel.json' });
}
});
// Serve nav as JSON
app.get('/api/nav', (req, res) => {
const menuPath = (path.join(config.dirs.html, 'conf', 'nav.json'));
try {
const menuData = JSON.parse(fs.readFileSync(menuPath, 'utf8'));
res.json(menuData);
log(module + ': INFO: GET /api/nav');
} catch (err) {
log(`ERROR: GET /api/nav failed: ${err}`);
res.status(500).json({ error: 'Failed to load nav.json' });
}
});
// API
app.get ('/api', (req, res) => {
res.json(gen_api_usage(req));
let webreqmeta = {
method: req.method,
url: req.originalUrl,
ip: req.ip,
userAgent: req.get('User-Agent')
};
log(module + ': WEBAPI: ' + JSON.stringify(webreqmeta))
});
// Distribution
app.use(
'/dist',
logStaticRequests('dist'),
express.static(config.dirs.dist),
serveIndex(config.dirs.dist, {
icons: true,
view: 'details'
})
);
// /img
app.use('/img', logStaticRequests('img'), express.static(path.join(config.dirs.html, 'img')));
// /css
app.use('/css', logStaticRequests('css'), express.static(path.join(config.dirs.html, 'css')));
// /js
app.use('/js', logStaticRequests('js'), express.static(path.join(config.dirs.html, 'js')));
// md
app.use('/md', logStaticRequests('md'), express.static(path.join(config.dirs.html, 'md')));
// Web Libs
for (let wl in config.modules.web.weblibs) {
log(`${module}: Serving WebLib: /${wl} at ${path.join(config.dirs.app, 'node_modules', config.modules.web.weblibs[wl])}`)
app.use('/' + wl, logStaticRequests(wl), express.static(path.join(config.dirs.app, 'node_modules', config.modules.web.weblibs[wl])));
}
// Top Level Website
app.use('/', logStaticRequests('html'), express.static(path.join(config.dirs.html)));
// Catch-all for 404 Not Found
app.use((req, res, next) => {
const webreqmeta = {
method: req.method,
url: req.originalUrl,
ip: req.ip,
userAgent: req.get('User-Agent')
};
log(`404 NOT FOUND: ${JSON.stringify(webreqmeta)}`);
if (req.originalUrl.startsWith('/api/')) {
res.status(404).json({ error: 'Not Found', path: req.originalUrl });
} else {
res.status(404).sendFile(path.join(config.dirs.html, '404.html'));
}
});
// Starting Web Server
const bindAddrs =
Array.isArray(config.modules[module].bind_ip_addrs) &&
config.modules[module].bind_ip_addrs.length > 0
? config.modules[module].bind_ip_addrs
: ['0.0.0.0'];
for (const ip_addr of bindAddrs) {
if (ip_addr === '0.0.0.0') {
const server = app.listen(config.modules[module].port, '0.0.0.0', () => {
for (const ip of config.host.ips) {
log(`INFO: WebUI running at http://${ip}:${config.modules[module].port}`, true);
if (config.modules[module].open_browser && ip === '127.0.0.1') {
open(`http://127.0.0.1:${config.modules[module].port}`);
}
}
});
server.on('error', (err) => {
log(`ERROR: WebUI failed to start on 0.0.0.0:${config.modules[module].port}: ${err}`, true);
});
} else {
const server = app.listen(config.modules[module].port, ip_addr, () => {
log(`INFO: WebUI running at http://${ip_addr}:${config.modules[module].port}`, true);
if (config.modules[module].open_browser) {
open(`http://${ip_addr}:${config.modules[module].port}`);
}
});
server.on('error', (err) => {
log(`ERROR: WebUI failed to start on ${ip_addr}:${config.modules[module].port}: ${err}`, true);
});
}
}
// ----------- Libraries -------------
function logStaticRequests(subdir) {
const func = 'logStaticRequests';
return (req, res, next) => {
const webreqmeta = {
method: req.method,
url: req.originalUrl,
ip: req.ip,
userAgent: req.get('User-Agent'),
type: subdir
};
log(`${module}: ${func}: Web Req: ${JSON.stringify(webreqmeta)}`);
next();
};
}
// API Usage
function gen_api_usage(req) {
// let base_url = "http://localhost:" + config.web.port;
const base_url = `${req.protocol}://${req.headers.host}`;
let usage = {};
usage['API'] = {}
usage['API']['DESC'] = "API"
usage['API']['URL'] = base_url + '/api';
usage['API']['CONFIG'] = {}
usage['API']['CONFIG']['DESC'] = "API Config JSON"
usage['API']['CONFIG']['URL'] = base_url + '/api/config';
return usage;
}