Base backend code
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
+65
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
+14
@@ -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
|
||||||
|
}
|
||||||
@@ -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
@@ -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
|
||||||
|
}
|
||||||
@@ -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}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"name": "NetDomainManager",
|
||||||
|
"stage": "alpha",
|
||||||
|
"version": "1.0.0.0",
|
||||||
|
"branch": "main"
|
||||||
|
}
|
||||||
Generated
+2282
File diff suppressed because it is too large
Load Diff
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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!');
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user