diff --git a/package.json b/package.json index 1facd76..b761ae0 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "license": "ISC", "packageManager": "pnpm@10.5.2", "dependencies": { - "ajv": "^8.17.1", "bcrypt": "^5.1.1", "better-sqlite3": "^11.9.1", "dompurify": "^3.2.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d1d6f0f..1859315 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,9 +8,6 @@ importers: .: dependencies: - ajv: - specifier: ^8.17.1 - version: 8.17.1 bcrypt: specifier: ^5.1.1 version: 5.1.1 @@ -95,9 +92,6 @@ packages: resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==} engines: {node: '>= 14'} - ajv@8.17.1: - resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} - ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -302,12 +296,6 @@ packages: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} - fast-deep-equal@3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - - fast-uri@3.0.6: - resolution: {integrity: sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==} - file-uri-to-path@1.0.0: resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} @@ -470,9 +458,6 @@ packages: canvas: optional: true - json-schema-traverse@1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - jsonwebtoken@9.0.2: resolution: {integrity: sha512-PRp66vJ865SSqOlgqS8hujT5U4AOgMfhrwYIuIhfKaoSCZcirrmASQr8CX7cUg+RMih+hgznrjp99o+W4pJLHQ==} engines: {node: '>=12', npm: '>=6'} @@ -700,10 +685,6 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} - require-from-string@2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} deprecated: Rimraf versions prior to v4 are no longer supported @@ -993,13 +974,6 @@ snapshots: agent-base@7.1.3: {} - ajv@8.17.1: - dependencies: - fast-deep-equal: 3.1.3 - fast-uri: 3.0.6 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - ansi-regex@5.0.1: {} anymatch@3.1.3: @@ -1223,10 +1197,6 @@ snapshots: transitivePeerDependencies: - supports-color - fast-deep-equal@3.1.3: {} - - fast-uri@3.0.6: {} - file-uri-to-path@1.0.0: {} fill-range@7.1.1: @@ -1417,8 +1387,6 @@ snapshots: - supports-color - utf-8-validate - json-schema-traverse@1.0.0: {} - jsonwebtoken@9.0.2: dependencies: jws: 3.2.2 @@ -1646,8 +1614,6 @@ snapshots: dependencies: picomatch: 2.3.1 - require-from-string@2.0.2: {} - rimraf@3.0.2: dependencies: glob: 7.2.3 diff --git a/src/controllers/index.js b/src/controllers/index.js index 3580e6b..725d1f5 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -1,14 +1,12 @@ -const index_service = require("../services/indexService"); const handleError = require("../middleware/errors"); - -async function getVersion(req, res) { +async function helloWorld(req, res) { try { - const query_result = await index_service.getVersion(); - res.json(query_result); + const query_result = "Unknown development version"; + res.send(query_result); } catch (error) { - handleError(error, res); + handleError(error); } } -module.exports = { getVersion }; \ No newline at end of file +module.exports = { helloWorld }; diff --git a/src/database/index.js b/src/database/index.js index 0e7bed9..116b623 100644 --- a/src/database/index.js +++ b/src/database/index.js @@ -1,6 +1,6 @@ +const { getConfig } = require("../utils/configManager"); const MySQLDatabase = require("./mysql"); const SQLiteDatabase = require("./sqlite"); -const { getConfig } = require("../utils/configManager"); let db; @@ -11,11 +11,11 @@ async function connectDatabase() { // Choose database type if (config.type === "mysql") { - db = new MySQLDatabase(config); + db = new MySQLDatabase(config); } else if (config.type === "sqlite") { - db = new SQLiteDatabase(config); + db = new SQLiteDatabase(config); } else { - throw new Error("Invalid database type: ", config.type); + throw new Error("Invalid database type: ", config.type); } // Connect @@ -31,80 +31,45 @@ async function initDatabase() { throw new Error("Database is not connected"); } - // --- Users --- + // Create mods table + db.exec("CREATE TABLE IF NOT EXISTS mods ( \ + Username tinytext PRIMARY KEY, \ + DisplayName tinytext, \ + Author tinytext,\ + Versions longtext,\ + OtherInfos longtext \ + );"); + + // Insert example mod + // if (!(await db.exists("mods", "Name", "example"))) { + // console.debug("Creating default mod"); + // db.exec(`INSERT INTO mods (Name, DisplayName, Author, Versions, OtherInfos) \ + // VALUES ('example', 'Example mod', '${config.users.admin.username}', '', '');`); + // } - // Uers table - db.exec("CREATE TABLE IF NOT EXISTS Users ( \ - username TINYTEXT PRIMARY KEY, \ - display_name TINYTEXT, \ - email TINYTEXT,\ - password TINYTEXT,\ - profile_picture LONGTEXT,\ - settings LONGTEXT, \ - );"); - - // --- Mods --- - - // Mods table - db.exec(`CREATE TABLE IF NOT EXISTS Mods ( - name TINYTEXT PRIMARY KEY, - display_name TINYTEXT NOT NULL, - author TINYTEXT NOT NULL, - description TINYTEXT NOT NULL, - - FOREIGN KEY author REFERENCES Users(username) - );`); - - // Mods complementary infos - db.exec(`CREATE TABLE IF NOT EXISTS ModInfos ( - mod TINYTEXT PRIMARY KEY, - full_description TEXT NOT NULL, - license TINYTEXT, - custom_license TEXT, - links TEXT, - creation_date TINYTEXT NOT NULL, - downloads_count INT NOT NULL, - - FOREIGN KEY mod REFERENCES Users(username) - );`); - - // Mods tags - db.exec(`CREATE TABLE IF NOT EXISTS ModTags ( - mod TINYTEXT NOT NULL, - tag TINYTEXT NOT NULL, - - FOREIGN KEY mod REFERENCES Mods(name) - );`); - - // Mods versions - db.exec(`CREATE TABLE IF NOT EXISTS ModVersions ( - mod TINYTEXT NOT NULL, - version_number TINYTEXT NOT NULL, - channel TINYTEXT NOT NULL, - changelog TEXT NOT NULL, - release_date TINYTEXT NOT NULL, - game_version TINYTEXT NOT NULL, - platform TINYTEXT NOT NULL, - environment TINYTEXT NOT NULL, - url TINYTEXT NOT NULL, - - FOREGIN KEY mod REFERENCES Mods(name) - );`); - - // User favorites (mods) - db.exec(`CREATE TABLE IF NOT EXISTS UserFavoriteMods ( - username TINYTEXT NOT NULL, - mod TINYTEXT NOT NULL, - - FOREIGN KEY username REFERENCES Users(username), - FOREGIN KEY mod REFERENCES Mods(name) - );`); + db.exec("DROP TABLE users"); + // Create users table + db.exec("CREATE TABLE IF NOT EXISTS users ( \ + Username tinytext PRIMARY KEY, \ + DisplayName tinytext, \ + Email tinytext,\ + Password tinytext,\ + ProfilePicture longtext,\ + Preferences longtext, \ + Favorites longtext \ + );"); + // Insert default admin account + // if (!(await db.exists("users", "Username", config.users.admin.username))) { + // console.debug("Creating default admin user"); + // db.exec(`INSERT INTO users (Username, DisplayName, Email, Password, ProfilePicture, Preferences, Favorites) \ + // VALUES ('${config.users.admin.username}', 'Admin', '', '${config.users.admin.password}', '', '', '' );`); + // } } function getDatabase() { - return db; + return db; } diff --git a/src/middleware/auth.js b/src/middleware/auth.js index 8506166..7e5d098 100644 --- a/src/middleware/auth.js +++ b/src/middleware/auth.js @@ -1,83 +1,23 @@ -const { getModByName } = require("../services/modService"); -const { getModpackByName } = require("../services/modpackService"); -const { getUserByName } = require("../services/userService"); -const { verifyToken } = require("../utils/crypto"); +const authService = require("../services/authService"); const AppError = require("../utils/appError"); -async function authenticateToken(req) { +function authenticateToken(req, res, next) { - const token = req.header("Authorization"); + const auth_header = req.headers["authorization"]; + const token = auth_header && auth_header.split(' ')[1]; - if (!token) { - throw new AppError(401, "Missing authorization header", "Unauthorized"); + if (token == null) { + throw new AppError(401, "Unauthorized: missing or bad authorization header"); } try { - req.token_infos = await verifyToken(token); - console.debug("Authorizing token from", req.token_infos); + req.user = authService.verifyToken(token); + next(); } catch (err) { throw new AppError(403, "Forbidden: Error verifying the authorization token"); } } -async function authorizeModModification(req) { - - // Auth token - await authenticateToken(req); - // Get mod infos - if (!req.params || req.params.id) { - throw new AppError(400, "No mod name was scpecified", "Bad request"); - } - const mod_name = req.params.id; - const mod = getModByName(mod_name); - if (!mod) { - throw new AppError(404, "No mod was found with this name", "Not found"); - } - // Authorize - if ( mod.author != req.token_infos.username) { - throw new AppError(401, "Mod author differs from current user", "Unauthorized"); - } -} - -async function authorizeModpackModification(req) { - - // Auth token - await authenticateToken(req); - // Get mod infos - if (!req.params || req.params.id) { - throw new AppError(400, "No mod name was scpecified", "Bad request"); - } - const modpack_name = req.params.id; - const modpack = getModpackByName(modpack_name); - if (!modpack) { - throw new AppError(404, "No mod was found with this name", "Not found"); - } - // Authorize - if ( modpack.author != req.token_infos.username) { - throw new AppError(401, "Mod author differs from current user", "Unauthorized"); - } -} - -async function authorizeUserModification(req) { - - // Auth token - await authenticateToken(req); - // Get mod infos - if (!req.params || req.params.id) { - throw new AppError(400, "No mod name was scpecified", "Bad request"); - } - const user_name = req.params.id; - const user = getUserByName(user_name); - if (!user) { - throw new AppError(404, "No mod was found with this name", "Not found"); - } - // Authorize - if ( user.username != req.token_infos.username) { - throw new AppError(401, "Mod author differs from current user", "Unauthorized"); - } -} - - -module.exports = { authenticateToken, authorizeModModification, authorizeModpackModification, authorizeUserModification }; \ No newline at end of file +module.exports = { authenticateToken } \ No newline at end of file diff --git a/src/models/index.js b/src/models/index.js deleted file mode 100644 index b5f3bfb..0000000 --- a/src/models/index.js +++ /dev/null @@ -1,12 +0,0 @@ -const { getVersion } = require("../utils/configManager"); - -async function getVersion() { - - const version = await getVersion(); - const res = { - version: version - }; - return res; -} - -module.exports = { getVersion } \ No newline at end of file diff --git a/src/models/mod.js b/src/models/mod.js index 11f30e9..f64cc2d 100644 --- a/src/models/mod.js +++ b/src/models/mod.js @@ -3,16 +3,27 @@ const AppError = require('../utils/appError'); const db = getDatabase(); async function getAllMods() { - return db.query("SELECT name FROM Mods"); + return db.query("SELECT * FROM mods"); } async function getModByName(name) { - return await db.query("SELECT name, display_name, author FROM Mods WHERE name = ?;", [name]); + try { + console.debug("Searching for", name); + const res = await db.query("SELECT * FROM mods WHERE Name = ?;", [name]); + if (res && res.length > 0) { + return res[0]; + } else { + return null; + } + } catch (err) { + console.error("Error in getModByName:", err); + throw err; + } } async function exists(name) { - return db.exists("Mods", "name", name); + return db.exists("mods", "Name", name); } async function createMod(mod_data) { @@ -20,8 +31,8 @@ async function createMod(mod_data) { const { name, displayName, author, versions, otherInfos } = mod_data; const { description, links, tags, screenshots, license, changelogs, counts } = otherInfos; - await db.prepare("INSERT INTO mods (name, display_name, author) \ - VALUES (?, ?, ?, ?)", [name, displayName, author]); + await db.prepare("INSERT INTO mods (Name, DisplayName, Author, Versions) \ + VALUES (?, ?, ?, ?)", [name, displayName, author, versions]); // db.prepare("INSERT INTO modsDescription (Name, Description, Links, Tags, Screenshots, License, Changelogs, Counts) \ // VALUES (?, ?, ?, ?, ?, ?, ?, ?)", [name, description, links, tags, screenshots, license, changelogs, counts]); return; @@ -29,7 +40,7 @@ async function createMod(mod_data) { async function deleteMod(name) { console.log("WARNING: using a WIP function : deleteMod (models/mods.js)"); - db.prepare("DELETE FROM Mods WHERE name = ?", [name]); + db.prepare("DELETE FROM mods WHERE Name = ?", [name]); // db.prepare("DELETE FROM modsDescription WHERE Name = ?", [name]); return; } diff --git a/src/models/user.js b/src/models/user.js index 9be6cb9..3f80528 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -7,29 +7,52 @@ async function getAllUsers() { } async function getUserByName(name) { - return await db.query("SELECT * FROM Users WHERE username = ?;", [name]); + try { + console.debug("Searching for", name); + const res = await db.query("SELECT * FROM users WHERE Username = ?;", [name]); + if (res && res.length > 0) { + return res[0]; + } else { + return null; + } + } catch (err) { + console.error("Error in getUserByName:", err); + throw err; + } + } async function getUserByEmail(email) { - return await db.query("SELECT * FROM Users WHERE email = ?;", [email]); + try { + console.debug("Searching for", email); + const res = await db.query("SELECT * FROM users WHERE Email = ?;", [email]); + if (res && res.length > 0) { + return res[0]; + } else { + return null; + } + } catch (err) { + console.error("Error in getUserByName:", err); + throw err; + } + } async function exists(name) { - return db.exists("Users", "username", name); + return db.exists("users", "Username", name); } async function createUser(user_data) { const { name, email, password, displayName, profilePicture, favorites, preferences } = user_data; - //TODO breakdown to handle partial updates - await db.prepare("INSERT INTO Users (username, email, password, display_name, profile_picture, favorites, preferences) \ + await db.prepare("INSERT INTO users (Username, Email, Password, DisplayName, ProfilePicture, Favorites, Preferences) \ VALUES (?, ?, ?, ?)", [name, email, password, displayName, profilePicture, favorites, preferences]); return; } async function deleteUser(name) { - await db.prepare("DELETE FROM Users WHERE username = ?", [name]); + db.prepare("DELETE FROM users WHERE Username = ?", [name]); return; } @@ -45,4 +68,4 @@ async function updateUser(user_data) { -module.exports = { getAllUsers, getUserByName, getUserByEmail, createUser, deleteUser, exists } \ No newline at end of file +module.exports = { getAllUsers, getUserByName, createUser, deleteUser, exists } \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js index 36880b8..d219546 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -3,8 +3,12 @@ const controller = require("../controllers/index"); const router = express.Router(); +router.get('/', (res, req) => { + console.debug("Triggered hello world"); + controller.helloWorld(res, req); +}); -router.get('/version', async (res, req) => { +router.get('/version', (res, req) => { controller.getVersion(res, req); }); diff --git a/src/schemas/auth.js b/src/schemas/auth.js deleted file mode 100644 index e57a75c..0000000 --- a/src/schemas/auth.js +++ /dev/null @@ -1,21 +0,0 @@ -const Ajv = require("ajv"); -const ajv = new Ajv(); - -// --- Schemas --- - -const AuthUserSchema = { - type: 'object', - properties: { - email: { type: 'string', format: 'email' }, - password: { type: 'string', minLength: 3, maxLength: 30 }, - }, - required: ['email', 'password'], - additionalProperties: false -}; - -const validateAuthUserData = ajv.compile(AuthUserSchema); - - -// --- Exports --- - -module.exports = { validateAuthUserData, validateAuthNodeData }; \ No newline at end of file diff --git a/src/schemas/mod.js b/src/schemas/mod.js deleted file mode 100644 index 6d7dc9d..0000000 --- a/src/schemas/mod.js +++ /dev/null @@ -1,21 +0,0 @@ -const Ajv = require("ajv"); -const ajv = new Ajv(); - -// --- Schemas --- -//TODO - -const newModSchema = { - type: 'object', - properties: { - name: { type: 'string'}, - }, - required: ['name'], - additionalProperties: false -}; - -const validateNewModData = ajv.compile(newModSchema); - - -// --- Exports --- - -module.exports = { validateNewModData }; \ No newline at end of file diff --git a/src/schemas/modpack.js b/src/schemas/modpack.js deleted file mode 100644 index df4a49a..0000000 --- a/src/schemas/modpack.js +++ /dev/null @@ -1,21 +0,0 @@ -const Ajv = require("ajv"); -const ajv = new Ajv(); - -// --- Schemas --- -//TODO - -const newModpackSchema = { - type: 'object', - properties: { - name: { type: 'string'}, - }, - required: ['name'], - additionalProperties: false -}; - -const validateNewModpackData = ajv.compile(newModpackSchema); - - -// --- Exports --- - -module.exports = { validateNewModpackData }; \ No newline at end of file diff --git a/src/schemas/user.js b/src/schemas/user.js deleted file mode 100644 index 0c009a1..0000000 --- a/src/schemas/user.js +++ /dev/null @@ -1,23 +0,0 @@ -const Ajv = require("ajv"); -const ajv = new Ajv(); - -// --- Schemas --- -//TODO - -const newUserSchema = { - type: 'object', - properties: { - email: { type: 'string', format: 'email' }, - name: { type: 'string' }, - password: { type: 'string', minLength: 3, maxLength: 30 }, - }, - required: ['name', 'email', 'password'], - additionalProperties: false -}; - -const validateNewUserData = ajv.compile(newUserSchema); - - -// --- Exports --- - -module.exports = { validateNewUserData }; \ No newline at end of file diff --git a/src/services/authService.js b/src/services/authService.js index bbf25cc..dc5bb90 100644 --- a/src/services/authService.js +++ b/src/services/authService.js @@ -3,7 +3,7 @@ const jwt = require("jsonwebtoken"); const userModel = require("../models/user"); const AppError = require("../utils/appError"); const configManager = require("../utils/configManager"); -const validate = require("../utils/validate_legacy"); +const validate = require("../utils/validate"); const JWT_Secret = configManager.getJWTSecret(); @@ -45,10 +45,22 @@ async function login(identifier, password) { return jwt.sign({ username: user[0].username, role: user[0].role }, await JWT_Secret); } +function verifyToken(token) { + return new Promise( (resolve, reject) => { + jwt.verify( token, JWT_Secret, (err, user) => { + if (err) { + reject(err); + } else { + resolve(user); + } + }); + }); +} + // function authorizeRole(user, roles) { // if (!user || !roles.includes(user.role)) { // throw new AppError(401, "Unauthorized: You don't have the necessary permissions to access this resource"); // } // } -module.exports = { login }; \ No newline at end of file +module.exports = { login, verifyToken }; \ No newline at end of file diff --git a/src/services/indexService.js b/src/services/indexService.js deleted file mode 100644 index d2fc506..0000000 --- a/src/services/indexService.js +++ /dev/null @@ -1,7 +0,0 @@ -const model = require("../models/index"); - -async function getVersion() { - return model.getVersion(); -} - -module.exports = { getVersion } diff --git a/src/services/modService.js b/src/services/modService.js index 739b217..b1611d5 100644 --- a/src/services/modService.js +++ b/src/services/modService.js @@ -1,6 +1,6 @@ const model = require("../models/mod"); const AppError = require("../utils/appError"); -const { validateModData } = require("../utils/validate_legacy"); +const { validateModData } = require("../utils/validate"); const { mdToHtml } = require("../utils/convert"); const { sanitizeModData } = require("../utils/sanitize"); diff --git a/src/services/userService.js b/src/services/userService.js index 1eb2ca5..a8eea3c 100644 --- a/src/services/userService.js +++ b/src/services/userService.js @@ -1,6 +1,6 @@ const model = require("../models/user"); const AppError = require("../utils/appError"); -const { validateUserData } = require("../utils/validate_legacy"); +const { validateUserData } = require("../utils/validate"); const { sanitizeUserData } = require("../utils/sanitize"); async function getAllUsers() { diff --git a/src/utils/crypto.js b/src/utils/crypto.js deleted file mode 100644 index be1ffc5..0000000 --- a/src/utils/crypto.js +++ /dev/null @@ -1,61 +0,0 @@ -// --- Imports --- -const jwt = require("jsonwebtoken"); -const bcrypt = require("bcrypt"); -const { getConfig, getJWTSecret } = require("./configManager"); - - -// --- Config --- - -// Declarations -let JWT_Secret; -let token_expiry; -// Constant values -const saltRounds = 12; -// Load -(async () => { - const config = await getConfig(); - JWT_Secret = await getJWTSecret(); - token_expiry = config.auth.tokenExpiry; - signature_algorithm = config.auth.signatureAlgorithm; -})(); - - -// --- Functions --- - -async function hashPassword(passwd) { - const hash = bcrypt.hashSync(passwd, saltRounds); - return hash; -} - - -async function passwordsMatch(password, hashed_password) { - return await bcrypt.compare(password, hashed_password); -} - - -async function signToken(payload, options = null) { - if (options == null) { - return jwt.sign(payload, JWT_Secret, { expiresIn: token_expiry, }); - } - else { - return jwt.sign(payload, JWT_Secret, options); - } - -} - - -function verifyToken(token) { - return new Promise( async (resolve, reject) => { - await jwt.verify( token, JWT_Secret, (err, user) => { - if (err) { - reject(err); - } else { - resolve(user); - } - }); - }); -} - - -// --- Exports --- -module.exports = { passwordsMatch, hashPassword, verifyToken, signToken }; \ No newline at end of file diff --git a/src/utils/validate.js b/src/utils/validate.js index b7c3519..63c605b 100644 --- a/src/utils/validate.js +++ b/src/utils/validate.js @@ -1,32 +1,82 @@ -// --- Imports --- +const mod_model = require("../models/mod"); +const user_model = require("../models/user"); const AppError = require("./appError"); +async function validateModData(mod_data) { + //TODO WIP + // Check fields existence + const not_null = mod_data && + Object.keys(mod_data).length == 5 && + mod_data.name && + mod_data.displayName && + mod_data.author && + mod_data.versions != null; + + // mod_data.otherInfos != null && + // Object.keys(mod_data.otherInfos).length == 0 && + // mod_data.otherInfos.description != null && + // mod_data.otherInfos.links != null && + // mod_data.otherInfos.tags != null && + // mod_data.otherInfos.screenshots != null && + // mod_data.otherInfos.license != null && + // mod_data.otherInfos.changelogs != null; -// --- Functions --- + if (!not_null) { + console.debug("Item is missing expected fields:", mod_data); + throw new AppError(400, "Bad request", "Missing expected fields"); + } -async function validateNewModData(mod_data) { - - throw new AppError(501, "Not implemented"); - //TODO - // try { - // node_schemas.validateNewModData(node_data); - // } catch (err) { - // throw new AppError(400, "Missing or invalid fields", "Bad request", err); - // } + // Check fields format (check if sanitized) + const is_valid_name = /^[a-zA-Z0-9_]+$/.test(mod_data.name); + const is_valid_displayName = true; + // const is_valid_displayName = /^[a-zA-Z0-9_]+$/.test(mod_data.name); // Temporary + // const + + const is_valid = is_valid_name && is_valid_displayName; + if (!is_valid) { + console.debug("Fields are not following the expected formats"); + throw new AppError(400, "Bad request", "The provided fields don't match the expected format"); + } + // Check if mod already exists + const exists = await mod_model.exists(mod_data.name); + if (exists) { + console.debug("Error: Item already exists"); + throw new AppError(403, "Forbidden", "Content with this name already exists"); + } } -async function validateNewUserData(user_data) { - +async function validateUserData(user_data) { throw new AppError(501, "Not implemented"); + //TODO - // try { - // node_schemas.validateNewUserData(node_data); - // } catch (err) { - // throw new AppError(400, "Missing or invalid fields", "Bad request", err); - // } + // Check fields existence + // ... + + if (!not_null) { + console.debug("Missing expected fields:", mod_data); + throw new AppError(400, "Bad request: Missing expected fields"); + } + + // Check fields format (check if sanitized) + const is_valid_username = /^[a-zA-Z0-9_]+$/.test(user_data.username); + // const is_valid_email = ... + // ... + + const is_valid = is_valid_username && is_valid_email; + if (!is_valid) { + console.debug("Fields are not following the expected formats"); + throw new AppError(400, "Bad request: The provided fields don't match the expected format"); + } + + // Check if user already exists + const exists = await user_model.exists(user_data.username); + if (exists) { + console.debug("Error: User already exists"); + throw new AppError(403, "Forbidden: User with this name already exists"); + } } async function validateCretendials(identifier, password) { @@ -34,9 +84,6 @@ async function validateCretendials(identifier, password) { throw new AppError(501, "Not implemented"); } - -// --- Utils --- - async function isEmail(text) { const email_regex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/; return email_regex.test(text); @@ -48,4 +95,4 @@ async function isID(text) { } -module.exports = { validateNewModData, validateNewUserData, isEmail, isID }; \ No newline at end of file +module.exports = { validateModData, validateUserData, isEmail, isID }; \ No newline at end of file diff --git a/src/utils/validate_legacy.js b/src/utils/validate_legacy.js deleted file mode 100644 index 63c605b..0000000 --- a/src/utils/validate_legacy.js +++ /dev/null @@ -1,98 +0,0 @@ -const mod_model = require("../models/mod"); -const user_model = require("../models/user"); -const AppError = require("./appError"); - -async function validateModData(mod_data) { - //TODO WIP - // Check fields existence - const not_null = mod_data && - Object.keys(mod_data).length == 5 && - mod_data.name && - mod_data.displayName && - mod_data.author && - mod_data.versions != null; - - // mod_data.otherInfos != null && - // Object.keys(mod_data.otherInfos).length == 0 && - // mod_data.otherInfos.description != null && - // mod_data.otherInfos.links != null && - // mod_data.otherInfos.tags != null && - // mod_data.otherInfos.screenshots != null && - // mod_data.otherInfos.license != null && - // mod_data.otherInfos.changelogs != null; - - if (!not_null) { - console.debug("Item is missing expected fields:", mod_data); - throw new AppError(400, "Bad request", "Missing expected fields"); - } - - // Check fields format (check if sanitized) - const is_valid_name = /^[a-zA-Z0-9_]+$/.test(mod_data.name); - const is_valid_displayName = true; - // const is_valid_displayName = /^[a-zA-Z0-9_]+$/.test(mod_data.name); // Temporary - // const - - const is_valid = is_valid_name && is_valid_displayName; - if (!is_valid) { - console.debug("Fields are not following the expected formats"); - throw new AppError(400, "Bad request", "The provided fields don't match the expected format"); - } - - // Check if mod already exists - const exists = await mod_model.exists(mod_data.name); - if (exists) { - console.debug("Error: Item already exists"); - throw new AppError(403, "Forbidden", "Content with this name already exists"); - } -} - - -async function validateUserData(user_data) { - throw new AppError(501, "Not implemented"); - - //TODO - - // Check fields existence - // ... - - if (!not_null) { - console.debug("Missing expected fields:", mod_data); - throw new AppError(400, "Bad request: Missing expected fields"); - } - - // Check fields format (check if sanitized) - const is_valid_username = /^[a-zA-Z0-9_]+$/.test(user_data.username); - // const is_valid_email = ... - // ... - - const is_valid = is_valid_username && is_valid_email; - if (!is_valid) { - console.debug("Fields are not following the expected formats"); - throw new AppError(400, "Bad request: The provided fields don't match the expected format"); - } - - // Check if user already exists - const exists = await user_model.exists(user_data.username); - if (exists) { - console.debug("Error: User already exists"); - throw new AppError(403, "Forbidden: User with this name already exists"); - } -} - -async function validateCretendials(identifier, password) { - - throw new AppError(501, "Not implemented"); -} - -async function isEmail(text) { - const email_regex = /^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$/; - return email_regex.test(text); -} - -async function isID(text) { - const id_regex = /[a-zA-Z0-9_]+/; - return id_regex.test(text); -} - - -module.exports = { validateModData, validateUserData, isEmail, isID }; \ No newline at end of file