hydrationhub/src/index.ts

107 lines
3.2 KiB
TypeScript

// MARK: Imports
import path from 'node:path';
import fs from 'node:fs';
import ChildProcess from 'child_process';
import __path from './handlers/path.js';
import log from './handlers/log.js';
//import db from './handlers/db.js';
import config from './handlers/config.js';
// Express & more
import express from 'express';
import helmet from 'helmet';
import fileUpload from 'express-fileupload';
import bodyParser from 'body-parser';
import { Eta, Options } from 'eta';
import routes from './routes/index.js';
// MARK: Express
const app = express();
// Versioning
try {
const rawPkg = fs.readFileSync('package.json', 'utf8');
const pkgJson = JSON.parse(rawPkg);
app.locals.version = pkgJson.version;
} catch (error) {
log.core.error('Failed to get version from package.json.');
app.locals.version = '0.0.0';
}
try {
app.locals.versionRevLong = ChildProcess.execSync('git rev-parse HEAD').toString().trim();
app.locals.versionRev = app.locals.versionRevLong.substring(0, 7);
} catch (error) {
log.core.error('Failed to get git revision hash.');
app.locals.versionRev = '0';
app.locals.versionRevLong = '0';
}
try {
app.locals.versionRevLatest = ChildProcess.execSync('git ls-remote --refs -q').toString().trim().split('\t')[0];
} catch (error) {
log.core.error('Failed to get latest git revision hash.');
app.locals.versionRevLatest = '0';
}
app.locals.versionUpdateAvailable = false;
if (app.locals.versionRevLong === app.locals.versionRevLatest) {
log.core.info(`Running Latest Version (${app.locals.versionRevLong}; ${app.locals.version})`);
} else {
log.core.info(`Running Version: ${app.locals.versionRevLong}; ${app.locals.version} (Latest: ${app.locals.versionRevLatest})`);
app.locals.versionUpdateAvailable = true;
}
// ETA Init
const eta = new Eta({ views: path.join(__path, 'views') });
app.engine('eta', buildEtaEngine());
app.set('view engine', 'eta');
// MARK: Express Middleware & Config
app.set('x-powered-by', false); // helmet does this too. But not in devmode
if (!config.global.devmode) {
app.use(
helmet({
strictTransportSecurity: config.global.http_enable_hsts,
contentSecurityPolicy: {
useDefaults: false,
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'", config.global.http_domain],
objectSrc: ["'none'"],
upgradeInsecureRequests: config.global.devmode ? null : []
}
}
})
); // Add headers
}
app.use(fileUpload({ useTempFiles: false, debug: config.global.devmode_fileupload }));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(routes);
// TODO: Remove hardcoded http
app.listen(config.global.http_port, config.global.http_listen_address, () => {
log.web.info(`Listening at http://${config.global.http_listen_address}:${config.global.http_port}`);
});
log.core.trace('Running from path: ' + __path);
config.global.devmode && log.core.error('DEVMODE ACTIVE! Do NOT use this in prod!');
// MARK: Helper Functions
function buildEtaEngine() {
return (path: string, opts: Options, callback: CallableFunction) => {
try {
const fileContent = eta.readFile(path);
const renderedTemplate = eta.renderString(fileContent, opts);
callback(null, renderedTemplate);
} catch (error) {
callback(error);
}
};
}