From 0766487309721c16fa829b63af8fa7d44af73d3d Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Thu, 14 May 2020 21:02:38 +0200 Subject: [PATCH] - Fixed SQL injection ""issue"" And various code cleaning things for spell route --- client/src/assets/images/cog-1.svg | 34 ++++++- database/spellsaurus_db_create.sql | 2 +- database/spellsaurus_db_data.sql | 2 + index.js | 6 -- package-lock.json | 31 ++---- package.json | 34 +++++++ routes/spells.js | 157 +++++++++++++++++------------ 7 files changed, 171 insertions(+), 95 deletions(-) create mode 100644 package.json diff --git a/client/src/assets/images/cog-1.svg b/client/src/assets/images/cog-1.svg index 3992225..2b37d4a 100644 --- a/client/src/assets/images/cog-1.svg +++ b/client/src/assets/images/cog-1.svg @@ -1 +1,33 @@ -Created by Johannes Sfrom the Noun Project \ No newline at end of file + + + + + diff --git a/database/spellsaurus_db_create.sql b/database/spellsaurus_db_create.sql index 5c247df..8e5cc12 100644 --- a/database/spellsaurus_db_create.sql +++ b/database/spellsaurus_db_create.sql @@ -1,5 +1,5 @@ DROP DATABASE IF EXISTS spellsaurus; -CREATE DATABASE spellsaurus; +CREATE DATABASE spellsaurus CHARACTER SET utf8 COLLATE utf8_bin; USE spellsaurus; /* ==== PRIMARY TABLES ==== */ diff --git a/database/spellsaurus_db_data.sql b/database/spellsaurus_db_data.sql index f84f060..e326da9 100644 --- a/database/spellsaurus_db_data.sql +++ b/database/spellsaurus_db_data.sql @@ -1,3 +1,5 @@ +SET NAMES utf8; + -- META SCHOOLS INSERT INTO `meta_school` VALUES (1, 'Magies blanches', 'Magies disciplinant les arts de soins et de lumières.'), diff --git a/index.js b/index.js index 2ff401a..93543ab 100644 --- a/index.js +++ b/index.js @@ -23,9 +23,3 @@ const server = app.listen( port, () => {console.log(`App listening on port ${por // Routing app.use('/api/spells', routes.spells) - -// On process kill with SIGINT -process.on('SIGINT', () => { - db.end() - server.close() -}) diff --git a/package-lock.json b/package-lock.json index c548a9d..d94ee6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,8 @@ { - "requires": true, + "name": "auracle-api", + "version": "1.0.0", "lockfileVersion": 1, + "requires": true, "dependencies": { "accepts": { "version": "1.3.7", @@ -235,16 +237,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.43.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.43.0.tgz", - "integrity": "sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==" + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==" }, "mime-types": { - "version": "2.1.26", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.26.tgz", - "integrity": "sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==", + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", "requires": { - "mime-db": "1.43.0" + "mime-db": "1.44.0" } }, "ms": { @@ -268,19 +270,6 @@ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, - "node": { - "version": "13.10.1", - "resolved": "https://registry.npmjs.org/node/-/node-13.10.1.tgz", - "integrity": "sha512-xVeLmv6T+Cf1iPGDRhi4JOxGeV7jSYjacAWXDuHcZpc38qHfGaTdb6EpPYM9pKFvTThaYbb6/sq8JLv7DS+MHA==", - "requires": { - "node-bin-setup": "^1.0.0" - } - }, - "node-bin-setup": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/node-bin-setup/-/node-bin-setup-1.0.6.tgz", - "integrity": "sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q==" - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", diff --git a/package.json b/package.json new file mode 100644 index 0000000..ea794e1 --- /dev/null +++ b/package.json @@ -0,0 +1,34 @@ +{ + "name": "auracle-api", + "version": "1.0.0", + "description": "API for Auracle database", + "main": "index.js", + "scripts": { + "test": "start" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/AlexisNP/spellsaurus.git" + }, + "keywords": [ + "api", + "rpg", + "spells", + "magic", + "database", + "ttrpg", + "dices", + "worldbuilding" + ], + "author": "AlexisNP", + "license": "ISC", + "bugs": { + "url": "https://github.com/AlexisNP/spellsaurus/issues" + }, + "homepage": "https://github.com/AlexisNP/spellsaurus#readme", + "dependencies": { + "cors": "^2.8.5", + "express": "^4.17.1", + "mysql": "^2.18.1" + } +} diff --git a/routes/spells.js b/routes/spells.js index c74775c..e210f38 100644 --- a/routes/spells.js +++ b/routes/spells.js @@ -6,23 +6,64 @@ let router = express.Router() const connection = require('../database/connection') const db = connection.db -const getSpells = (params) => { +// Builds the associated infos for a given spell object +const buildSpell = async (spell) => { + + // Fetches the spell's schools + let fetchSpellSchoolData = new Promise((resolve, reject) => { + let query = + "SELECT school.id, school.name " + + "FROM spells_schools AS sc " + + "INNER JOIN school AS school ON sc.id_school = school.id " + + "WHERE sc.id_spell = " + spell.id + + db.query(query, (err, result) => { + if (err) return reject + resolve(result) + }) + }) + + // Fetches the spell's variables + let fetchSpellVariablesData = new Promise((resolve, reject) => { + let query = + "SELECT variable.id, variable.description " + + "FROM spells_variables AS sv " + + "INNER JOIN variable AS variable ON sv.id_variable = variable.id " + + "WHERE sv.id_spell = " + spell.id + + db.query(query, (err, result) => { + if (err) console.log(err) + resolve(result) + }) + }) + + // Fetches the spell's ingredients + let fetchSpellIngredientsData = new Promise((resolve, reject) => { + let query = + "SELECT ingredient.id, ingredient.name " + + "FROM spells_ingredients AS si " + + "INNER JOIN ingredient AS ingredient ON si.id_ingredient = ingredient.id " + + "WHERE si.id_spell = " + spell.id + + db.query(query, (err, result) => { + if (err) console.log(err) + resolve(result) + }) + }) + + // Builds the spell and returns it + spell.schools = await fetchSpellSchoolData + spell.variables = await fetchSpellVariablesData + spell.ingredients = await fetchSpellIngredientsData + return spell +} + +const getSpells = () => { let fetchSpellsData = new Promise((resolve, reject) => { let query = "SELECT DISTINCT * " + - "FROM spell " + - "WHERE 1 = 1 " - - // Checks if the params object has items - if (!(Object.keys(params).length === 0 && params.constructor === Object)) { - if (params.id) { - query += "AND id = " + params.id + " " - } - if (params.name) { - query += "AND name = " + params.name + " " - } - } + "FROM spell " db.query(query, async (err, result) => { if (err) { return reject } @@ -30,68 +71,35 @@ const getSpells = (params) => { // Loops over the results to fetch the associated tables for (let i = 0; i < result.length; i++) { - - let currentSpell_ID = result[i].id - - // Fetches the spell's schools - let fetchSpellSchoolData = new Promise((resolve, reject) => { - let query = - "SELECT school.name " + - "FROM spells_schools AS sc " + - "INNER JOIN school AS school ON sc.id_school = school.id " + - "WHERE sc.id_spell = " + currentSpell_ID - - db.query(query, (err, result) => { - if (err) return reject - resolve(result) - }) - }) - - // Fetches the spell's variables - let fetchSpellVariablesData = new Promise((resolve, reject) => { - let query = - "SELECT variable.description " + - "FROM spells_variables AS sv " + - "INNER JOIN variable AS variable ON sv.id_variable = variable.id " + - "WHERE sv.id_spell = " + currentSpell_ID - - db.query(query, (err, result) => { - if (err) console.log(err) - resolve(result) - }) - }) - - // Fetches the spell's ingredients - let fetchSpellIngredientsData = new Promise((resolve, reject) => { - let query = - "SELECT ingredient.name " + - "FROM spells_ingredients AS si " + - "INNER JOIN ingredient AS ingredient ON si.id_ingredient = ingredient.id " + - "WHERE si.id_spell = " + currentSpell_ID - - db.query(query, (err, result) => { - if (err) console.log(err) - resolve(result) - }) - }) - - result[i].schools = await fetchSpellSchoolData - result[i].variables = await fetchSpellVariablesData - result[i].ingredients = await fetchSpellIngredientsData - + result[i] = await buildSpell(result[i]) } resolve(result) }) }) - return fetchSpellsData } -router -.get('/', async (req, res, next) => { +const getSpell = (id) => { + let fetchSpellData = new Promise((resolve, reject) => { + + let query = + "SELECT FROM spell where id = " + id + + db.query(query, async (err, result) => { + if (err) { return reject } + resolve(result); + }) + }) + return fetchSpellData +} + +// ROUTES +// ALL SPELLS METHODS +// Router +router.get('/', async (req, res, next) => { getSpells(req.query) .then(v => { - res.setHeader('Content-Type', 'application/json') + res.setHeader('Content-Type', 'application/json;charset=utf-8') res.end(JSON.stringify(v)) }) .catch(err => { @@ -100,5 +108,22 @@ router }) }) +// ONE SPELL METHODS +// Regex for param validation +const regex = RegExp(/^[1-9]\d*$/); + +// Param validation +router.param('id', (req, res, next, id) => { + if (regex.test(id)) { + next() + } else { + res.status(403).send('The id parameter should be an integer.') + } +}) + +// Router +router.get('/:id/', async (req, res, next) => { + console.log("id") +}) module.exports = router \ No newline at end of file