From c282c6b597cf9bc4de26efd7183f78cac8fcff50 Mon Sep 17 00:00:00 2001 From: leca Date: Wed, 19 Feb 2025 16:55:45 +0300 Subject: [PATCH] rework config system --- public/js/chat.js | 3 --- sample.env | 24 +++++++++++++++++------- src/config.js | 27 +++++++++++++++++++++++++++ src/controllers/api.js | 6 ++---- src/controllers/user.js | 9 ++++----- src/db.js | 13 ++++++------- src/index.js | 13 +++++++------ src/middlewares/auth.js | 7 +++---- src/middlewares/existance.js | 6 ++---- src/middlewares/requiredParameters.js | 6 ++---- src/routers/user.js | 24 +++++++++++++----------- views/header.pug | 3 ++- 12 files changed, 85 insertions(+), 56 deletions(-) create mode 100644 src/config.js diff --git a/public/js/chat.js b/public/js/chat.js index 71d128d..6b84f9a 100644 --- a/public/js/chat.js +++ b/public/js/chat.js @@ -44,9 +44,6 @@ $(document).ready(async () => { await onFetchMessageButtonClick(); - - - socket.onmessage = message => { try { message = JSON.parse(message.data) diff --git a/sample.env b/sample.env index a8cce34..85d7f73 100644 --- a/sample.env +++ b/sample.env @@ -1,12 +1,22 @@ -SECRET=GENERATE_A_STRONG_SECRET_HERE +#Databse DBUSER=mcserver -DBHOST=localhost +DBHOST=database DBNAME=mcserver -DBPORT=5432 +DBPORT=5433 DBPASS=GENERATE_A_STRONG_PASSWORD_HERE -PORT=3000 -REQUIRE_TOKEN=false + +#General +SECRET=GENERATE_A_STRONG_SECRET_HERE +APP_PORT=3000 + +#Token +REQUIRE_TOKEN=true DELETE_TOKEN_ON_USE=true -WS_CONNECTION_STRING=wss://auth.foxarmy.org -ENABLE_WORLDMAP=true + +#Chat +ENABLE_CHAT=false +WS_CONNECTION_STRING=ws://localhost:3000 + +#Map +ENABLE_WORLDMAP=false WORLDMAP_URL=http://localhost/map diff --git a/src/config.js b/src/config.js new file mode 100644 index 0000000..ea0af41 --- /dev/null +++ b/src/config.js @@ -0,0 +1,27 @@ +import dotenv from 'dotenv'; + +dotenv.config({ path: ".env" }); + +const getBoolean = value => { return value === 'true'? true : false } + +const config = { + dbuser: process.env.DBUSER, + dbhost: process.env.DBHOST, + dbname: process.env.DBNAME, + dbport: Number.parseInt(process.env.DBPORT), + dbpass: process.env.DBPASS, + + secret: process.env.SECRET, + app_port: Number.parseInt(process.env.APP_PORT), + + require_token: getBoolean(process.env.REQUIRE_TOKEN), + delete_token_on_use: getBoolean(process.env.DELETE_TOKEN_ON_USE), + + enable_chat: getBoolean(process.env.ENABLE_CHAT), + ws_connection_string: process.env.WS_CONNECTION_STRING, + + enable_worldmap: getBoolean(process.env.ENABLE_WORLDMAP), + worldmap_url: process.env.WORLDMAP_URL +} + +export default config; \ No newline at end of file diff --git a/src/controllers/api.js b/src/controllers/api.js index 60f0619..c37d574 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -1,7 +1,5 @@ import ApiService from "../services/api.js"; -import dotenv from 'dotenv'; - -dotenv.config({path: ".env"}); +import config from '../config.js'; class ApiController { async getChatMessages(req, res) { @@ -13,7 +11,7 @@ class ApiController { } async getWebsocketConnection(req, res) { - return res.status(200).send(process.env.WS_CONNECTION_STRING) + return res.status(200).send(config.ws_connection_string); } } diff --git a/src/controllers/user.js b/src/controllers/user.js index 08dc5b1..8c32f2b 100644 --- a/src/controllers/user.js +++ b/src/controllers/user.js @@ -1,14 +1,13 @@ import bcrypt from 'bcrypt'; import jwt from 'jsonwebtoken'; -import dotenv from 'dotenv'; import path from 'path'; import { Jimp } from 'jimp'; import fs from 'fs'; import UserService from "../services/user.js"; import utils from '../utils.js'; +import config from '../config.js'; -dotenv.config({path: ".env"}); class UserController { async register(req, res) { const { username, password } = req.body; @@ -27,11 +26,11 @@ class UserController { await UserService.register(username, hashedPassword); - if (process.env.REQUIRE_TOKEN == "true" && process.env.DELETE_TOKEN_ON_USE == "true") { + if (config.require_token && config.delete_token_on_use) { utils.removeFromFile('./inviteTokens.txt', req.body.inviteToken); } - const token = jwt.sign({ username }, process.env.SECRET, {expiresIn: "1y"}); + const token = jwt.sign({ username }, config.secret, {expiresIn: "1y"}); res.cookie("jwt", token); return res.status(200).send("Ok"); } @@ -44,7 +43,7 @@ class UserController { if (!bcrypt.compareSync(password, storedPassword)) { return res.status(403).send("Password is not correct"); } - const token = jwt.sign({ username }, process.env.SECRET, {expiresIn: "1y"}); + const token = jwt.sign({ username }, config.secret, {expiresIn: "1y"}); res.cookie("jwt", token); return res.status(200).send("Ok"); } diff --git a/src/db.js b/src/db.js index b55c0a5..049a705 100644 --- a/src/db.js +++ b/src/db.js @@ -1,19 +1,18 @@ import pg from 'pg'; import fs from 'fs'; -import dotenv from 'dotenv'; -dotenv.config({path: ".env"}); +import config from './config.js'; const { Pool } = pg; console.log("Connecting to PostgreSQL database"); const pool = new Pool({ - user: process.env.DBUSER, - host: process.env.DBHOST, - database: process.env.DBNAME, - password: process.env.DBPASS, - port: process.env.DBPORT + user: config.dbuser, + host: config.dbhost, + database: config.dbnape, + password: config.dbpass, + port: config.dbport }); pool.query(fs.readFileSync('./db_schema.psql').toString()); diff --git a/src/index.js b/src/index.js index 9fb23f4..308b495 100644 --- a/src/index.js +++ b/src/index.js @@ -1,5 +1,4 @@ import express from 'express'; -import dotenv from 'dotenv'; import session from 'express-session'; import cookieParser from 'cookie-parser'; import path from 'path'; @@ -7,13 +6,12 @@ import path from 'path'; import ApiRouter from './routers/api.js'; import UserRouter from './routers/user.js'; import startChat from './messages.js'; +import config from './config.js'; const app = express(); -dotenv.config({ path: ".env" }); - app.use(session({ - secret: process.env.SECRET, + secret: config.secret, resave: true, saveUninitialized: false, cookie: { maxAge: 1000 * 60 * 60 * 24 } @@ -28,9 +26,12 @@ app.set('view engine', 'pug'); app.use('/api', ApiRouter); app.use('/', UserRouter); -const server = app.listen(process.env.PORT, () => { +const server = app.listen(config.app_port, () => { console.log("App has been started!"); - startChat(); + + if(config.enable_chat) { + startChat(); + } }); export default server; diff --git a/src/middlewares/auth.js b/src/middlewares/auth.js index 8dbf8f8..bfe89fb 100644 --- a/src/middlewares/auth.js +++ b/src/middlewares/auth.js @@ -1,15 +1,14 @@ import fs from 'fs'; -import dotenv from 'dotenv'; import jwt from 'jsonwebtoken'; import UserService from '../services/user.js'; +import config from '../config.js'; -dotenv.config({path: ".env"}); const authenticate = async (req, res, next) => { try { const token = req.cookies["jwt"]; - if (!token || !jwt.verify(token, process.env.SECRET)) { + if (!token || !jwt.verify(token, config.secret)) { req.session.destroy(); res.clearCookie("jwt"); return res.redirect("/login"); @@ -24,7 +23,7 @@ const authenticate = async (req, res, next) => { }; const validateInviteToken = async (req, res, next) => { - if (process.env.REQUIRE_TOKEN != "true") return next(); + if (!config.require_token) return next(); const { inviteToken } = req.body; if (!inviteToken || inviteToken == "") return res.status(400).send("Token is not valid"); diff --git a/src/middlewares/existance.js b/src/middlewares/existance.js index dc387f0..635cbb6 100644 --- a/src/middlewares/existance.js +++ b/src/middlewares/existance.js @@ -1,9 +1,7 @@ -import dotenv from 'dotenv'; import jwt from 'jsonwebtoken'; import UserService from '../services/user.js'; - -dotenv.config({path: ".env"}); +import config from '../config.js'; const userDoesNotExist = async (req, res, next) => { @@ -20,7 +18,7 @@ const userExist = async (req, res, next) => { if (req.body.username) { username = req.body.username; } else if (req.cookies["jwt"]) { - if (!req.cookies["jwt"] || !jwt.verify(req.cookies["jwt"], process.env.SECRET)) { + if (!req.cookies["jwt"] || !jwt.verify(req.cookies["jwt"], config.secret)) { return res.status(403).send("Unauthorized"); } username = jwt.decode(req.cookies["jwt"]).username; diff --git a/src/middlewares/requiredParameters.js b/src/middlewares/requiredParameters.js index be6c659..20e0078 100644 --- a/src/middlewares/requiredParameters.js +++ b/src/middlewares/requiredParameters.js @@ -1,6 +1,4 @@ -import dotenv from 'dotenv'; - -dotenv.config({path: ".env"}); +import config from '../config.js'; const requireUsername = async (req, res, next) => { const { username } = req.body; @@ -19,7 +17,7 @@ const requirePassword = async (req, res, next) => { const requireInviteToken = async (req, res, next) => { const { inviteToken } = req.body; - if (!inviteToken && process.env.REQUIRE_TOKEN == "true") return res.status(400).send("Invite token is required"); + if (!inviteToken && config.require_token) return res.status(400).send("Invite token is required"); next(); }; diff --git a/src/routers/user.js b/src/routers/user.js index 03fbad0..fa9a812 100644 --- a/src/routers/user.js +++ b/src/routers/user.js @@ -1,25 +1,23 @@ import { Router } from 'express'; import jwt from 'jsonwebtoken'; -import dotenv from 'dotenv'; import auth from '../middlewares/auth.js'; import UserService from '../services/user.js'; - -dotenv.config({path: ".env"}); +import config from '../config.js'; const UserRouter = new Router(); UserRouter.get('/register', async (req, res) => { - if (req.cookies["jwt"] && jwt.verify(req.cookies["jwt"], process.env.SECRET)) + if (req.cookies["jwt"] && jwt.verify(req.cookies["jwt"], config.secret)) return res.redirect("/index"); return res.render("register.pug", { - require_token: process.env.REQUIRE_TOKEN == "true"? true : false + require_token: config.require_token? true : false }); }); UserRouter.get(['/', '/login'], async (req, res) => { - if(req.cookies["jwt"] && jwt.verify(req.cookies["jwt"], process.env.SECRET)) { + if(req.cookies["jwt"] && jwt.verify(req.cookies["jwt"], config.secret)) { return res.redirect("/index"); } @@ -32,7 +30,8 @@ UserRouter.get(['/index', '/skin'], auth.authenticate, async (req, res) => { return res.render('skin.pug', { username: username, can_have_cloak: await UserService.canHaveCloak(username), - enable_worldmap: process.env.ENABLE_WORLDMAP + enable_chat: config.enable_chat, + enable_worldmap: config.enable_worldmap }); }); @@ -41,7 +40,8 @@ UserRouter.get('/changepassword', auth.authenticate, async (req, res) => { return res.render('changepassword.pug', { can_have_cloak: await UserService.canHaveCloak(username), - enable_worldmap: process.env.ENABLE_WORLDMAP + enable_chat: config.enable_chat, + enable_worldmap: config.enable_worldmap }); }); @@ -50,7 +50,8 @@ UserRouter.get('/chat', auth.authenticate, async (req, res) => { return res.render('chat.pug', { can_have_cloak: await UserService.canHaveCloak(username), - enable_worldmap: process.env.ENABLE_WORLDMAP + enable_chat: config.enable_chat, + enable_worldmap: config.enable_worldmap }); }); @@ -59,8 +60,9 @@ UserRouter.get('/worldmap', auth.authenticate, async (req, res) => { return res.render('worldmap.pug', { can_have_cloak: await UserService.canHaveCloak(username), - enable_worldmap: process.env.ENABLE_WORLDMAP, - worldmap_url: process.env.WORLDMAP_URL + enable_worldmap: config.enable_worldmap, + enable_chat: config.enable_chat, + worldmap_url: config.worldmap_url }); }); diff --git a/views/header.pug b/views/header.pug index 531d477..29bc7df 100644 --- a/views/header.pug +++ b/views/header.pug @@ -6,7 +6,8 @@ div(class="action-tabs") else button(class="actionTabButton" id="skinsTabButton" onclick="goToPage('/index')") Скин button(class="actionTabButton" id="passwordChangeTabButton" onclick="goToPage('/changepassword')") Сменить пароль - button(class="actionTabButton" id="chatTabButton" onclick="goToPage('/chat')") Чат + if (enable_chat) + button(class="actionTabButton" id="chatTabButton" onclick="goToPage('/chat')") Чат if (enable_worldmap) button(class="actionTabButton" id="chatTabButton" onclick="goToPage('/worldmap')") Карта мира button(class="actionTabButton logoutTabButton" id="logoutTabButton" onclick="window.location.href='/api/logout'") Выйти