Base backend code

This commit is contained in:
2026-05-12 19:29:45 -04:00
parent 8dd2d05643
commit f591bdffb5
13 changed files with 2636 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
node_modules
+65
View File
@@ -0,0 +1,65 @@
const Sequelize = require('sequelize');
const seqConn = new Sequelize({
dialect: 'sqlite',
storage: process.env.DB_STORAGE,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000,
},
logging: console.log,
});
////// Sessions, Users //////
// Sessions
const Session = seqConn.define('Session', {
sid: {
type: Sequelize.TEXT,
primaryKey: true
},
data: Sequelize.TEXT,
expires: Sequelize.DATE,
});
// User
const User = seqConn.define('User', {
username: {
type: Sequelize.TEXT,
unique: true,
allowNull: false,
},
password: {
type: Sequelize.TEXT,
allowNull: false
},
power: {
type: Sequelize.SMALLINT,
allowNull: false,
defaultValue: 0
}
});
// RegisteredDomain
const RegisteredDomain = seqConn.define('RegisteredDomain', {
domain: {
type: Sequelize.TEXT,
unique: true,
allowNull: false
},
owner: {
type: Sequelize.BIGINT.UNSIGNED,
allowNull: false
}
});
////// Exports //////
module.exports = {
db: seqConn,
models: {
Session,
User,
RegisteredDomain
}
}
+5
View File
@@ -0,0 +1,5 @@
# Server
SRV_PORT=5001
# Database
DB_STORAGE="data_devel.db"
+14
View File
@@ -0,0 +1,14 @@
const dotenv = require('dotenv');
const path = require('path');
function SetupEnvironment() {
const env = process.env.NODE_ENV || 'devel';
const envPath = path.resolve(process.cwd(), `${env}.env`);
dotenv.config({ path: envPath });
console.log(`Loaded environemnt: ${envPath}`);
}
module.exports = {
SetupEnvironment
}
+33
View File
@@ -0,0 +1,33 @@
function GenericErrorByCode(code) {
switch(code) {
case 403:
return new Error('Access Denied');
case 404:
return new Error('Not Found');
case 500:
return new Error('Internal Server Error');
}
}
function QuickError(res, code, mesg) {
res.status(code);
return new Error(mesg);
}
function FormatForAPI(message) {
return {
error: {
details: [
{
message: message
}
]
}
}
}
module.exports = {
GenericErrorByCode,
QuickError,
FormatForAPI
}
+55
View File
@@ -0,0 +1,55 @@
const metaInf = require('./meta.json');
const hbsHelpers = {
p1: (arg) => {return arg + 1},
m1: (arg) => {return arg - 1},
for: (from, to, block) => {
let incr = '';
for(let i = from; i < to; i++)
incr += block.fn(i);
return incr;
},
timeNowPassed: (cTime) => {
const utcNow = Date.now() + (new Date().getTimezoneOffset() * 60 * 1000);
return utcNow >= cTime;
},
replaceIfWithin: (array, searchString, replacement) => {
if (array.includes(searchString)) {
return replacement;
} else {
return searchString;
}
},
truncateStringElipsis: (inputString, maxLength) => {
const realStr = String(inputString);
if(realStr.length > maxLength)
return String(inputString).substring(0, maxLength - 3) + '...';
else
return realStr;
},
removeHTML: (inputString) => {
return String(inputString).replace(/<\/?[^>]+(>|$)/g, '');
},
formatDate: (inputDate) => {
return helpers.formatDate(inputDate);
},
lenEq: (array, comparitor) => {
return array.length === parseInt(comparitor);
},
lenNotEq: (array, comparitor) => {
return array.length !== parseInt(comparitor, 10);
},
optionSelected: (v1, v2) => {
return v1 === v2 ? 'selected' : '';
},
getCurrentYear: () => {
return new Date().getFullYear();
},
getMetaInfString: () => {
return `${metaInf.name} | ${metaInf.stage}.${metaInf.version}.${metaInf.branch}-${process.env.NODE_ENV}`;
}
}
module.exports = {
HBSHelpers: hbsHelpers
}
+103
View File
@@ -0,0 +1,103 @@
// Main App
const express = require('express');
const app = express();
const exphbs = require ('express-handlebars');
const { SetupEnvironment } = require('./environ');
const SetupRouter = require('./router');
// Database
const database = require('./database');
// Session
const session = require('express-session');
const SequelizeStore = require('connect-session-sequelize')(session.Store);
const cookieParser = require('cookie-parser');
// Error Handling
const { GenericErrorByCode, FormatForAPI } = require('./errors');
// Helpers
const { HBSHelpers } = require('./helpers');
// Security
const helmet = require('helmet');
// First things first, setup the environment
SetupEnvironment();
// Get what we need for starting the server
const serverPort = process.env.SRV_PORT;
// Database Setup
const db = database.db;
const sessionStore = new SequelizeStore({
db: db,
table: 'Session'
})
// Helmet setup
app.use(
helmet.contentSecurityPolicy({
directives: {
defaultSrc: ["'self'"],
scriptSrc: ["'self'"],
objectSrc: ["'none'"],
styleSrc: ["'self'", "'unsafe-inline'"],
imgSrc: ["'self'", 'data:', '*'],
mediaSrc: ["'self'", 'data:', '*'],
connectSrc: ["'self'", 'data:', '*']
}
})
);
// Handlebars Setup
const hbs = exphbs.create({
helpers: HBSHelpers,
defaultLayout: 'main',
extname: '.handlebars',
runtimeOptions: {
allowProtoPropertiesByDefault: true,
allowProtoMethodsByDefault: true,
},
});
app.engine('handlebars', hbs.engine);
app.set('view engine', 'handlebars');
// Cookie parsing
app.use(cookieParser(process.env.CKYKEY));
// Session
app.use(session({
name: 'session',
secret: process.env.SESSKEY,
resave: false,
saveUninitialized: false,
store: sessionStore,
cookie: {
httpOnly: true,
secure: process.env.NODE_ENV === 'prod',
sameSite: 'strict'
},
}));
// Setup Assets
app.use(express.static('assets'));
// Setup Router
SetupRouter(app);
db.sync().then(() => {
app.use((req, res, next) => {
next(GenericErrorByCode(404));
});
app.use((err, req, res, next) => {
res.status(err.status || 500);
res.json(FormatForAPI(err.message || 'Internal Server Error'));
});
app.listen(serverPort, () => {
console.log(`NDM running @ localhost:${serverPort}`);
});
});
+6
View File
@@ -0,0 +1,6 @@
{
"name": "NetDomainManager",
"stage": "alpha",
"version": "1.0.0.0",
"branch": "main"
}
+2282
View File
File diff suppressed because it is too large Load Diff
+31
View File
@@ -0,0 +1,31 @@
{
"name": "netdomainmanager",
"version": "1.0.0",
"description": "Registers and configures domains behind CoreDNS",
"repository": {
"type": "git",
"url": "https://git.modnark.xyz/Modnark/NetDomainManager.git"
},
"license": "MIT",
"author": "Modnark",
"type": "commonjs",
"main": "index.js",
"scripts": {
"dev": "NODE_ENV=devel nodemon index.js",
"prod": "NODE_ENV=prod node index.js",
"wdev": "set NODE_ENV=devel&& nodemon index.js",
"wprod": "set NODE_ENV=prod&& nodemon index.js"
},
"dependencies": {
"connect-session-sequelize": "^8.0.6",
"cookie-parser": "^1.4.7",
"dotenv": "^17.4.2",
"express": "^5.2.1",
"express-handlebars": "^9.0.1",
"express-session": "^1.19.0",
"helmet": "^8.1.0",
"nodemon": "^3.1.14",
"sequelize": "^6.37.8",
"sqlite3": "^6.0.1"
}
}
+5
View File
@@ -0,0 +1,5 @@
# Server
SRV_PORT=5000
# Database
DB_STORAGE="data_prod.db"
+36
View File
@@ -0,0 +1,36 @@
const fs = require('fs').promises;
const path = require('path');
async function SetupRouter(app, dir) {
try {
const files = await fs.readdir(dir, { withFileTypes: true });
await Promise.all(files.map(async (file) => {
if (file.name === "router.js") return;
const filePath = path.join(dir, file.name);
if (file.isDirectory()) {
await SetupRouter(app, filePath);
} else if (file.isFile()) {
const name = path.parse(filePath).name;
const module = require(filePath);
if (typeof module === 'function') {
console.log(`Found router: ${name}`);
app.use(module);
}
}
}));
} catch (err) {
console.error(err);
process.exit(-1);
}
}
module.exports = async function (app) {
console.log('Setting up routes...');
const cDir = path.join(__dirname, 'routes');
await SetupRouter(app, cDir);
console.log('Routes setup successfully!');
};
View File