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