Fixed all database CREATE queries, made all controllers and routes files, and many various fixes

This commit is contained in:
Gu://em_ 2025-05-04 19:31:03 +02:00
parent ff33af92b7
commit ca080b3e59
15 changed files with 159 additions and 86 deletions

View file

@ -2,12 +2,12 @@
const express = require("express");
const app = express();
const { loadConfig } = require("./src/utils/configManager");
const configManager = require("./src/utils/configManager");
const { connectDatabase, initDatabase } = require('./src/database/index');
// --- Load configuration ---
const config = loadConfig();
const config = configManager.loadConfig();
// --- Body parsing ---
app.use(express.json()); // Necessary to parse JSON bodies
@ -15,6 +15,7 @@ app.use(express.json()); // Necessary to parse JSON bodies
// Database connection
(async () => {
// --- Database connection ---
await connectDatabase();
await initDatabase();
@ -23,6 +24,7 @@ app.use(express.json()); // Necessary to parse JSON bodies
app.use("/", require("./src/routes/index"));
app.use("/mods", require("./src/routes/mods"));
app.use("/users", require("./src/routes/users"));
app.use("/list", require("./src/routes/list"));
app.use("/login", require("./src/routes/login"));
})();
@ -30,7 +32,7 @@ app.use(express.json()); // Necessary to parse JSON bodies
// --- Launch ---
const port = config.server.port;
const port = config.port;
app.listen(port, () => {
console.log("Server listening on port " + port + "...");
})

View file

@ -6,7 +6,7 @@ async function login(req, res) {
const token = await authService.login(req.body.username, req.body.password);
res.json({ token });
} catch (err) {
handleError(err, req, res, null);
handleError(err, res);
}
}

View file

@ -1,47 +1,68 @@
const handleError = require("../middleware/errors");
const mod_service = require("../services/modService")
const mod_service = require("../services/modService");
const { authorizeModModification, authenticateToken } = require("../middleware/auth");
async function getAllMods(req, res) {
async function listMods(req, res) {
try {
console.debug("Calling controller");
// Query
const query_result = await mod_service.getAllMods();
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't get mods: ");
handleError(error, req, res, null);
}
}
async function getModByName(req, res) {
try {
const query_result = await mod_service.getModByName(req.params.name);
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't get mod " + req.params.name + ": ");
handleError(error, req, res, null);
handleError(error, res);
}
}
async function createMod(req, res) {
try {
await mod_service.createMod(req.body);
res.sendStatus(200);
// Authenticate
await authenticateToken(req);
// Query
const mod_data = req.body;
const user = req.token_infos.username;
const query_result = await mod_service.createMod(mod_data, user);
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't create mod:", error.message);
handleError(error, req, res, null);
handleError(error, res);
}
}
async function modifyMod(req, res) {
try {
// Authorize
authorizeModModification(req);
// Query
const mod_data = req.body;
const query_result = await mod_service.modifyMod(mod_data);
res.json(query_result);
} catch (error) {
handleError(error, res);
}
}
async function getModByName(req, res) {
try {
// Query
const name = req.params.name
const query_result = await mod_service.getModByName(name);
res.json(query_result);
} catch (error) {
handleError(error, res);
}
}
async function deleteMod(req, res) {
try {
await mod_service.deleteMod(req.params.name);
return res.sendStatus(200);
// Authorize
authorizeModModification(req);
// Query
const name = req.params.name
const query_result = await mod_service.deleteMod(name);
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't delete mod " + req.params.name + ":", error.message);
handleError(error, req, res, null);
handleError(error, res);
}
}
module.exports = { getAllMods, getModByName, createMod, deleteMod };
module.exports = { listMods, getModByName, createMod, modifyMod, deleteMod };

View file

@ -1,47 +1,63 @@
const handleError = require("../middleware/errors");
const user_service = require("../services/userService")
const { authorizeUserModification } = require("../middleware/auth");
async function getAllUsers(req, res) {
async function listUsers(req, res) {
try {
console.debug("Calling controller");
// Query
const query_result = await user_service.getAllUsers();
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't get users: ");
handleError(error, req, res, null);
handleError(error, res);
}
}
async function getUserByName(req, res) {
try {
// Query
const query_result = await user_service.getUserByName(req.params.name);
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't get user " + req.params.name + ": ");
handleError(error, req, res, null);
handleError(error, res);
}
}
async function createUser(req, res) {
try {
await user_service.createUser(req.body);
res.sendStatus(200);
// Query
const query_result = await user_service.createUser(req.body);
res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't create user:", error.message);
handleError(error, req, res, null);
handleError(error, res);
}
}
async function modifyUser(req, res) {
try {
// Query
const diff_data = req.body;
const query_result = await user_service.modifyUser(diff_data);
res.json(query_result);
} catch (error) {
handleError(error, res);
}
}
async function deleteUser(req, res) {
try {
await user_service.deleteUser(req.params.name);
return res.sendStatus(200);
// Authenticate
await authorizeUserModification(req);
// Query
const user = req.params.name;
const token_user = req.token_infos
const query_result = await user_service.deleteUser(user, token_user);
return res.json(query_result);
} catch (error) {
console.error("ERROR: Couldn't delete user " + req.params.name + ":", error.message);
handleError(error, req, res, null);
handleError(error, res);
}
}
module.exports = { getAllUsers, getUserByName, createUser, deleteUser };
module.exports = { listUsers, getUserByName, createUser, modifyUser, deleteUser };

View file

@ -10,12 +10,12 @@ async function connectDatabase() {
const config = await getConfig();
// Choose database type
if (config.type === "mysql") {
db = new MySQLDatabase(config);
} else if (config.type === "sqlite") {
db = new SQLiteDatabase(config);
if (config.database.type === "mysql") {
db = new MySQLDatabase(config.database);
} else if (config.database.type === "sqlite") {
db = new SQLiteDatabase(config.database);
} else {
throw new Error("Invalid database type: ", config.type);
throw new Error("Invalid database type: ", config.database.type);
}
// Connect
@ -40,8 +40,8 @@ async function initDatabase() {
email TINYTEXT NOT NULL,
password TINYTEXT NOT NULL,
profile_picture LONGTEXT,
role TINYTEXT, NOT NULL,
settings LONGTEXT,
role TINYTEXT NOT NULL,
settings LONGTEXT
);`);
// --- Mods ---
@ -53,7 +53,7 @@ async function initDatabase() {
author TINYTEXT NOT NULL,
description TINYTEXT NOT NULL,
FOREIGN KEY author REFERENCES Users(username)
FOREIGN KEY (author) REFERENCES Users(username)
);`);
// Mods complementary infos
@ -66,7 +66,7 @@ async function initDatabase() {
creation_date TINYTEXT NOT NULL,
downloads_count INT NOT NULL,
FOREIGN KEY mod REFERENCES Users(username)
FOREIGN KEY (mod) REFERENCES Users(username)
);`);
// Mods tags
@ -74,7 +74,7 @@ async function initDatabase() {
mod TINYTEXT NOT NULL,
tag TINYTEXT NOT NULL,
FOREIGN KEY mod REFERENCES Mods(name)
FOREIGN KEY (mod) REFERENCES Mods(name)
);`);
// Mods versions
@ -89,7 +89,7 @@ async function initDatabase() {
environment TINYTEXT NOT NULL,
url TINYTEXT NOT NULL,
FOREGIN KEY mod REFERENCES Mods(name)
FOREIGN KEY (mod) REFERENCES Mods(name)
);`);
// User favorites (mods)
@ -97,8 +97,8 @@ async function initDatabase() {
username TINYTEXT NOT NULL,
mod TINYTEXT NOT NULL,
FOREIGN KEY username REFERENCES Users(username),
FOREGIN KEY mod REFERENCES Mods(name)
FOREIGN KEY (username) REFERENCES Users(username),
FOREIGN KEY (mod) REFERENCES Mods(name)
);`);
}

View file

@ -19,6 +19,8 @@ async function authenticateToken(req) {
} catch (err) {
throw new AppError(403, "Forbidden: Error verifying the authorization token");
}
return req.token_infos;
}

View file

@ -1,6 +1,6 @@
const AppError = require("../utils/appError");
const handleError = (err, req, res, next) => {
const handleError = (err, res) => {
// Send error infos
if (err instanceof AppError) {

View file

@ -1,8 +1,8 @@
const { getVersion } = require("../utils/configManager");
const configManager = require("../utils/configManager");
async function getVersion() {
const version = await getVersion();
const version = await configManager.getVersion();
const res = {
version: version
};

View file

@ -18,7 +18,7 @@ async function getModFullInfos(name) {
// Query
const base_infos = db.query(`SELECT * FROM Mods WHERE name = ?`, [name]);
const other_infos = db.query(`SELECT full_description, license, links, creation_date
const other_infos = db.query(`SELECT full_description, license, links, creation_date, downloads_count
FROM ModInfos WHERE name = ?`, [name]);
const tags = getModTags(name);
@ -28,7 +28,7 @@ async function getModFullInfos(name) {
return res;
}
async function getAllVersions(mod_name) {
async function listVersions(mod_name) {
return await db.query("SELECT * FROM ModVersions WHERE mod = ?", [mod_name]);
}
@ -162,7 +162,7 @@ async function updateModInfosAttribute(name, attribute, value) {
return;
}
async function ModExists(name) {
async function exists(name) {
return db.exists("Mods", "name", name);
}
@ -179,8 +179,8 @@ async function containsTag(name, tag) {
// --- Exports ---
module.exports = { getAllMods, getModByName, getFullModInfos,
getAllModVersions, getVersionByNumber, getVersion,
module.exports = { getAllMods, getModByName, getModFullInfos,
listVersions, getVersionByNumber, getVersion,
createMod, addVersion, addTags,
updateMod,
deleteMod, deleteVersion, deleteTags,

24
src/routes/list.js Normal file
View file

@ -0,0 +1,24 @@
const express = require("express");
const { listMods } = require("../controllers/mods");
// const { listModpacks } = require("../controllers/modpacks");
const { listUsers } = require("../controllers/users");
const router = express.Router();
// List mods
router.get("/mods", async (req,res) => {
listMods(req, res);
});
// List modpacks
// router.get("/modpacks", async (req,res) => {
// listModpacks(req, res);
// });
// List users
router.get("/users", async (req,res) => {
listUsers(req, res);
});
module.exports = router;

View file

@ -3,29 +3,23 @@ const controller = require("../controllers/mods");
const router = express.Router();
// List mods
router.get("/", async (req,res) => {
console.debug("Accessing mods list");
controller.getAllMods(req,res);
});
// Create a mod
router.post("/", async (req, res) => {
console.debug("Creating mod ", req.body.name);
controller.createMod(req, res);
});
// Modify mod
router.put("/:name", async (req,res) => {
controller.modifyMod(req,res);
});
// Get mod infos
router.get("/:name", async (req,res) => {
const name = req.params.name;
console.debug("Accessing mod " + name)
controller.getModByName(req, res);
});
// Delete mod
router.delete("/:name", async (req,res) => {
const name = req.params.name;
console.debug("Deleting mod " + name)
controller.deleteMod(req, res);
});

View file

@ -6,7 +6,7 @@ const router = express.Router();
// List users
router.get("/", async (req,res) => {
console.debug("Accessing users list");
controller.getAllUsers(req,res);
controller.listUsers(req,res);
});
// Create a user

View file

@ -50,6 +50,8 @@ async function createMod(mod_data, author) {
const { name, display_name, description, mod_infos } = mod_data;
mod_infos.full_description = await mdToHtml(mod_infos.full_description); // Convert
await sanitizeModData(mod_data); // Sanitize
//TODO
// mod_infos.creation_date = ...
// Write changes to database
model.createMod(name, display_name, author, description, mod_data);
@ -89,8 +91,8 @@ async function addTags(mod, tags) {
await model.addTags(mod, tags);
// Return
const { tags } = await model.getFullModInfos(mod);
return { "mod": mod, "tags": tags};
const { tags:res } = await model.getFullModInfos(mod);
return { "mod": mod, "tags": res};
}
@ -109,6 +111,9 @@ async function deleteMod(name) {
// Check existence
const mod = await model.getModByName(name);
if (!mod) {
throw new AppError(404, "No was found with this name", "Not found")
}
// Authorize
// TODO move outside of this function
@ -137,13 +142,20 @@ async function deleteVersion(version_infos) {
// Return
return res;
}
async function deleteTags(tags) {
async function deleteTags(mod, tags) {
// Check existence
// Validate (check existence)
//TODO
console.warn("Skipping validity checks for deleteTags");
// Wites changes to db
await model.deleteTags(mod, tags);
// Return
const { tags:res } = await model.getFullModInfos(mod);
return { "mod": mod, "tags": res};
}
module.exports = { getAllMods, getModByName, getFullModInfos,

View file

@ -27,16 +27,18 @@ async function createUser(user_data) {
return;
}
async function deleteUser(name) {
async function deleteUser(name, token_user) {
// Check existence
const exists = await model.exists(name);
if (!exists) {
throw new AppError(404, "Not found: Cannot find user with this name");
throw new AppError(404, "Cannot find user with this name", "Not found");
}
// Check authenticity
//TODO no auth provider
if (name != token_user) {
throw new AppError(401, "", "Unauthorized");
}
model.deleteUser(name);
return;

View file

@ -15,7 +15,7 @@ let config = {};
// --- Default config ---
const defaault_config = {
const default_config = {
"port": 8000,