Merge branch 'dev-bookshelf' into dev
This commit is contained in:
@@ -29,15 +29,16 @@ CREATE TABLE IF NOT EXISTS `school` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école",
|
||||
`description` VARCHAR(255) DEFAULT "Description de l'école",
|
||||
`id_meta_school` INT UNSIGNED NOT NULL,
|
||||
`meta_school_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY(`id_meta_school`) REFERENCES meta_school(`id`)
|
||||
FOREIGN KEY(`meta_school_id`) REFERENCES meta_school(`id`)
|
||||
);
|
||||
|
||||
/* COMMON INGREDIENTS */
|
||||
CREATE TABLE IF NOT EXISTS `ingredient` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT "Langue de salamandre",
|
||||
`description` VARCHAR(255) NOT NULL DEFAULT "Une langue de salamandre de feu qui bouge encore un peu.",
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
@@ -63,30 +64,30 @@ CREATE TABLE IF NOT EXISTS `user` (
|
||||
|
||||
/* SPELLS' SCHOOLS */
|
||||
/* One spell can have multiple (up to 3) schools */
|
||||
CREATE TABLE IF NOT EXISTS `spells_schools` (
|
||||
`id_spell` INT UNSIGNED NOT NULL,
|
||||
`id_school` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id_spell`, `id_school`),
|
||||
FOREIGN KEY(`id_spell`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`id_school`) REFERENCES school(`id`)
|
||||
CREATE TABLE IF NOT EXISTS `spell_school` (
|
||||
`spell_id` INT UNSIGNED NOT NULL,
|
||||
`school_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`spell_id`, `school_id`),
|
||||
FOREIGN KEY(`spell_id`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`school_id`) REFERENCES school(`id`)
|
||||
);
|
||||
|
||||
/* SPELLS' VARIABLES */
|
||||
/* One spell can have multiple (up to 2) variables of cost */
|
||||
CREATE TABLE IF NOT EXISTS `spells_variables` (
|
||||
`id_spell` INT UNSIGNED NOT NULL,
|
||||
`id_variable` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id_spell`, `id_variable`),
|
||||
FOREIGN KEY(`id_spell`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`id_variable`) REFERENCES variable(`id`)
|
||||
CREATE TABLE IF NOT EXISTS `spell_variable` (
|
||||
`spell_id` INT UNSIGNED NOT NULL,
|
||||
`variable_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`spell_id`, `variable_id`),
|
||||
FOREIGN KEY(`spell_id`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`variable_id`) REFERENCES variable(`id`)
|
||||
);
|
||||
|
||||
/* SPELLS' VARIABLES */
|
||||
/* One spell can have multiple ingredients */
|
||||
CREATE TABLE IF NOT EXISTS `spells_ingredients` (
|
||||
`id_spell` INT UNSIGNED NOT NULL,
|
||||
`id_ingredient` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`id_spell`, `id_ingredient`),
|
||||
FOREIGN KEY(`id_spell`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`id_ingredient`) REFERENCES ingredient(`id`)
|
||||
CREATE TABLE IF NOT EXISTS `spell_ingredient` (
|
||||
`spell_id` INT UNSIGNED NOT NULL,
|
||||
`ingredient_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`spell_id`, `ingredient_id`),
|
||||
FOREIGN KEY(`spell_id`) REFERENCES spell(`id`),
|
||||
FOREIGN KEY(`ingredient_id`) REFERENCES ingredient(`id`)
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ INSERT INTO `meta_school` (name, description) VALUES
|
||||
('Magies autres', 'Magies trop spécifiques et ne rentrant dans aucune autre grande école.');
|
||||
|
||||
-- SCHOOLS
|
||||
INSERT INTO `school` (name, description, id_meta_school) VALUES
|
||||
INSERT INTO `school` (name, description, meta_school_id) VALUES
|
||||
('Lumomancie', 'Discipline arcanique de la lumière.', 1),
|
||||
('Vitamancie', 'Discipline arcanique de la guérison et de l\'énergie vitale.', 1),
|
||||
('Obstrumancie', 'Discipline arcanique de la protection et des sceaux.', 1),
|
||||
@@ -207,9 +207,9 @@ INSERT INTO `user` (name, mail, password) VALUES
|
||||
('Kevin', '35.alexis.mail@gmail.com', 'sept777');
|
||||
|
||||
-- INGREDIENTS
|
||||
INSERT INTO `ingredient` (name) VALUES
|
||||
('Volonté'),
|
||||
('Geste');
|
||||
INSERT INTO `ingredient` (name, description) VALUES
|
||||
('Volonté', 'La force de volonté du lanceur, concentrée sur un objectif'),
|
||||
('Geste', 'Un geste précis facilitant la canalisation magique');
|
||||
|
||||
-- VARIABLES
|
||||
INSERT INTO `variable` (description) VALUES
|
||||
@@ -223,11 +223,11 @@ SCHEMA
|
||||
*/
|
||||
|
||||
DELIMITER $$
|
||||
CREATE PROCEDURE insertIntoSchoolRange(IN delimiter_start INT, IN delimiter_end INT, IN school_id INT)
|
||||
CREATE PROCEDURE insertIntoSchoolRange(IN delimiter_start INT, IN delimiter_end INT, IN id_school INT)
|
||||
BEGIN
|
||||
SET @i = delimiter_start;
|
||||
WHILE @i <= delimiter_end DO
|
||||
INSERT INTO spells_schools (id_spell, id_school) VALUES (@i, school_id);
|
||||
INSERT INTO spell_school (spell_id, school_id) VALUES (@i, id_school);
|
||||
SET @i = @i + 1;
|
||||
END WHILE;
|
||||
END$$
|
||||
|
||||
23
database/bookshelf.js
Normal file
23
database/bookshelf.js
Normal file
@@ -0,0 +1,23 @@
|
||||
// MODULES
|
||||
const fs = require('fs')
|
||||
const mysql = require('mysql')
|
||||
|
||||
// Fetches and parses credentials file
|
||||
let credentials_data = fs.readFileSync('./database/credentials.json')
|
||||
let credentials = JSON.parse(credentials_data)
|
||||
|
||||
// Setting up the database connection
|
||||
const knex = require('knex')({
|
||||
client: credentials.client,
|
||||
connection: {
|
||||
host : credentials.host,
|
||||
user : credentials.user,
|
||||
password : credentials.password,
|
||||
database : credentials.database,
|
||||
charset : credentials.charset
|
||||
},
|
||||
debug: true
|
||||
})
|
||||
const bookshelf = require('bookshelf')(knex)
|
||||
|
||||
module.exports = { bookshelf }
|
||||
@@ -1,22 +0,0 @@
|
||||
// MODULES
|
||||
const fs = require('fs')
|
||||
const mysql = require('mysql')
|
||||
|
||||
// Fetches and parses credentials file
|
||||
let credentials_data = fs.readFileSync('./database/credentials.json')
|
||||
let credentials = JSON.parse(credentials_data)
|
||||
|
||||
const db = mysql.createConnection({
|
||||
host: credentials.host,
|
||||
user: credentials.user,
|
||||
password: credentials.password,
|
||||
database: credentials.database,
|
||||
})
|
||||
|
||||
db.on('error', err => {
|
||||
if (err.errno == 'ECONNRESET') {
|
||||
console.log("The connection was reset during your request. Please try again later.");
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = { db }
|
||||
7
index.js
7
index.js
@@ -8,7 +8,7 @@ const morgan = require('morgan')
|
||||
const cors = require('cors') // module to format the json response
|
||||
|
||||
// Creates instances of database connections
|
||||
const connection = require('./database/connection')
|
||||
const connection = require('./database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// CONSTANTS
|
||||
@@ -30,4 +30,7 @@ const server = app.listen( port, () => {console.log(`App listening on port ${por
|
||||
// Routing
|
||||
app.use('/api/spells', routes.spells)
|
||||
app.use('/api/schools', routes.schools)
|
||||
app.use('/api/users', routes.users)
|
||||
app.use('/api/meta_schools', routes.meta_schools)
|
||||
app.use('/api/variables', routes.variables)
|
||||
app.use('/api/ingredients', routes.ingredients)
|
||||
app.use('/api/users', routes.users)
|
||||
|
||||
13
models/ingredient-model.js
Normal file
13
models/ingredient-model.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
require('./spell-model')
|
||||
|
||||
let Ingredient = bookshelf.Model.extend({
|
||||
tableName: 'ingredient',
|
||||
spells() {
|
||||
return this.belongsToMany( 'Spell', 'spell_ingredient')
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('Ingredient', Ingredient)
|
||||
13
models/meta-school-model.js
Normal file
13
models/meta-school-model.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
require('./school-model')
|
||||
|
||||
let MetaSchool = bookshelf.Model.extend({
|
||||
tableName: 'meta_school',
|
||||
schools() {
|
||||
return this.hasMany( 'School' )
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('MetaSchool', MetaSchool)
|
||||
17
models/school-model.js
Normal file
17
models/school-model.js
Normal file
@@ -0,0 +1,17 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
require('./spell-model')
|
||||
require('./meta-school-model')
|
||||
|
||||
let School = bookshelf.Model.extend({
|
||||
tableName: 'school',
|
||||
spells() {
|
||||
return this.belongsToMany( 'Spell', 'spell_school')
|
||||
},
|
||||
meta_schools() {
|
||||
return this.belongsTo( 'MetaSchool', 'meta_school_id')
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('School', School)
|
||||
21
models/spell-model.js
Normal file
21
models/spell-model.js
Normal file
@@ -0,0 +1,21 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
require('./school-model')
|
||||
require('./variable-model')
|
||||
require('./ingredient-model')
|
||||
|
||||
let Spell = bookshelf.Model.extend({
|
||||
tableName: 'spell',
|
||||
schools() {
|
||||
return this.belongsToMany( 'School', 'spell_school' )
|
||||
},
|
||||
variables() {
|
||||
return this.belongsToMany( 'Variable', 'spell_variable' )
|
||||
},
|
||||
ingredients() {
|
||||
return this.belongsToMany( 'Ingredient', 'spell_ingredient' )
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('Spell', Spell)
|
||||
8
models/user-model.js
Normal file
8
models/user-model.js
Normal file
@@ -0,0 +1,8 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
let User = bookshelf.Model.extend({
|
||||
tableName: 'user',
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('User', User)
|
||||
13
models/variable-model.js
Normal file
13
models/variable-model.js
Normal file
@@ -0,0 +1,13 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
require('./spell-model')
|
||||
|
||||
let Variable = bookshelf.Model.extend({
|
||||
tableName: 'variable',
|
||||
spells() {
|
||||
return this.belongsToMany( 'Spell', 'spell_variable')
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('Variable', Variable)
|
||||
1292
package-lock.json
generated
1292
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -28,11 +28,13 @@
|
||||
"homepage": "https://github.com/AlexisNP/spellsaurus#readme",
|
||||
"dependencies": {
|
||||
"bcrypt": "^4.0.1",
|
||||
"bookshelf": "^1.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.1",
|
||||
"helmet": "^3.22.0",
|
||||
"jsonschema": "^1.2.6",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"knex": "^0.21.1",
|
||||
"morgan": "^1.10.0",
|
||||
"mysql": "^2.18.1"
|
||||
}
|
||||
|
||||
173
repositories/ingredient-repository.js
Normal file
173
repositories/ingredient-repository.js
Normal file
@@ -0,0 +1,173 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/ingredient-model')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const IngredientValidation = require("../validations/IngredientValidation")
|
||||
v.addSchema(IngredientValidation, "/IngredientValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class IngredientRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll({ withRelated: ['spells'] })
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get ingredients"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['spells']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get ingredient"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addOne(igr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(igr)) {
|
||||
reject(new HttpError(403, "Error: Ingredient cannot be nothing !"))
|
||||
} else if (!v.validate(igr, IngredientValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(igr, IngredientValidation).errors))
|
||||
} else if (this.isXSSAttempt(igr.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
bookshelf.transaction(t => {
|
||||
return model.forge({
|
||||
'name': igr.name,
|
||||
'description': igr.description,
|
||||
}).save(null, {
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['spells'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Insert Ingredient error"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateOne(id, igr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(igr)) {
|
||||
reject(new HttpError(403, "Error: Ingredient cannot be nothing !"))
|
||||
} else if (!v.validate(igr, IngredientValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(igr, IngredientValidation).errors))
|
||||
} else if (this.isXSSAttempt(igr.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
model.forge({id: id})
|
||||
.fetch({require: true, withRelated: ['spells']})
|
||||
.then(v => {
|
||||
bookshelf.transaction(t => {
|
||||
return v.save({
|
||||
'name': igr.name,
|
||||
'description': igr.description,
|
||||
}, {
|
||||
method: 'update',
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['spells'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Update Ingredient error"))
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get ingredient"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deleteOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({require: true, withRelated: ['spells']})
|
||||
.then(v => {
|
||||
v.spells().detach()
|
||||
v.destroy()
|
||||
})
|
||||
.then(() => {
|
||||
resolve({
|
||||
'message': 'Ingredient with ID ' + id + ' successfully deleted !'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get ingredient"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IngredientRepository
|
||||
72
repositories/meta-school-repository.js
Normal file
72
repositories/meta-school-repository.js
Normal file
@@ -0,0 +1,72 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/meta-school-model')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const MetaSchoolValidation = require("../validations/MetaSchoolValidation")
|
||||
v.addSchema(MetaSchoolValidation, "/MetaSchoolValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class MetaSchoolRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll({ withRelated: ['schools'] })
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get meta schools"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['schools']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get meta school"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = MetaSchoolRepository
|
||||
174
repositories/school-repository.js
Normal file
174
repositories/school-repository.js
Normal file
@@ -0,0 +1,174 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/school-model')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const SchoolValidation = require("../validations/SchoolValidation")
|
||||
v.addSchema(SchoolValidation, "/SchoolValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class SchoolRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll({ withRelated: ['meta_schools'] })
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get schools"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['meta_schools']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get school"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addOne(s) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: School cannot be nothing !"))
|
||||
} else if (!v.validate(s, SchoolValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors))
|
||||
} else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
bookshelf.transaction(t => {
|
||||
return model.forge({
|
||||
'name': s.name,
|
||||
'description': s.description,
|
||||
'meta_school_id': s.meta_school_id,
|
||||
}).save(null, {
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['meta_schools'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Insert School error"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateOne(id, s) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: School cannot be nothing !"))
|
||||
} else if (!v.validate(s, SchoolValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors))
|
||||
} else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
model.forge({id: id})
|
||||
.fetch({require: true, withRelated: ['meta_schools']})
|
||||
.then(v => {
|
||||
bookshelf.transaction(t => {
|
||||
return v.save({
|
||||
'name': s.name,
|
||||
'description': s.description,
|
||||
'meta_school_id': s.meta_school_id
|
||||
}, {
|
||||
method: 'update',
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['meta_schools'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Update School error"))
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get school"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deleteOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({require: true, withRelated: ['spells', 'meta_schools']})
|
||||
.then(v => {
|
||||
v.spells().detach()
|
||||
v.destroy()
|
||||
})
|
||||
.then(() => {
|
||||
resolve({
|
||||
'message': 'School with ID ' + id + ' successfully deleted !'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get school"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SchoolRepository
|
||||
245
repositories/spell-repository.js
Normal file
245
repositories/spell-repository.js
Normal file
@@ -0,0 +1,245 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/spell-model')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const SpellValidation = require("../validations/SpellValidation")
|
||||
v.addSchema(SpellValidation, "/SpellValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class SpellRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients'] })
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get spells"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get spell"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addOne(s) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
||||
} else if (!v.validate(s, SpellValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors))
|
||||
} else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description) || this.isXSSAttempt(s.cost)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
bookshelf.transaction(t => {
|
||||
return model.forge({
|
||||
'name': s.name,
|
||||
'description': s.description,
|
||||
'level': s.level,
|
||||
'charge' : s.charge,
|
||||
'cost' : s.cost,
|
||||
'is_ritual' : s.is_ritual
|
||||
}).save(null, {
|
||||
transacting: t
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.schools()
|
||||
.attach(s.schools, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.variables()
|
||||
.attach(s.variables, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.ingredients()
|
||||
.attach(s.ingredients, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['schools.meta_schools', 'variables', 'ingredients'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Insert Spell error"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateOne(id, s) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
||||
} else if (!v.validate(s, SpellValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors))
|
||||
} else if (this.isXSSAttempt(s.name) || this.isXSSAttempt(s.description) || this.isXSSAttempt(s.cost)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
model.forge({id: id})
|
||||
.fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
||||
.then(v => {
|
||||
bookshelf.transaction(t => {
|
||||
return v.save({
|
||||
'name': s.name,
|
||||
'description': s.description,
|
||||
'level': s.level,
|
||||
'charge' : s.charge,
|
||||
'cost' : s.cost,
|
||||
'is_ritual' : s.is_ritual
|
||||
}, {
|
||||
method: 'update',
|
||||
transacting: t
|
||||
})
|
||||
// Detaches AND attaches pivot tables, dw about it
|
||||
.tap(spell => {
|
||||
if (s.schools) {
|
||||
let schools = spell.related('school');
|
||||
return spell.schools().detach(schools, { transacting: t});
|
||||
}
|
||||
return
|
||||
})
|
||||
.tap(spell => {
|
||||
if (s.variables) {
|
||||
let variables = spell.related('variable');
|
||||
return spell.variables().detach(variables, { transacting: t});
|
||||
}
|
||||
return
|
||||
})
|
||||
.tap(spell => {
|
||||
if (s.ingredients) {
|
||||
let ingredients = spell.related('ingredient');
|
||||
return spell.ingredients().detach(ingredients, { transacting: t});
|
||||
}
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.schools()
|
||||
.attach(s.schools, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.variables()
|
||||
.attach(s.variables, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.tap(spell => {
|
||||
return spell
|
||||
.ingredients()
|
||||
.attach(s.ingredients, {
|
||||
transacting: t
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['schools.meta_schools', 'variables', 'ingredients'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Update Spell error"))
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get spell"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deleteOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
||||
.then(v => {
|
||||
v.schools().detach()
|
||||
v.variables().detach()
|
||||
v.ingredients().detach()
|
||||
v.destroy()
|
||||
})
|
||||
.then(() => {
|
||||
resolve({
|
||||
'message': 'Spell with ID ' + id + ' successfully deleted !'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get spell"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SpellRepository
|
||||
74
repositories/user-repository.js
Normal file
74
repositories/user-repository.js
Normal file
@@ -0,0 +1,74 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/user-model')
|
||||
|
||||
// Hashing and passwords
|
||||
const bcrypt = require('bcrypt')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const UserValidation = require("../validations/UserValidation")
|
||||
v.addSchema(UserValidation, "/UserValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class UserRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._model.forge()
|
||||
.fetchAll()
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get users"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this._model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch()
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get user"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserRepository
|
||||
170
repositories/variable-repository.js
Normal file
170
repositories/variable-repository.js
Normal file
@@ -0,0 +1,170 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/variable-model')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const VariableValidation = require("../validations/VariableValidation")
|
||||
v.addSchema(VariableValidation, "/VariableValidation")
|
||||
|
||||
// Validations
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
class VariableRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll({ withRelated: ['spells'] })
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get variables"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
getOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['spells']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get variable"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addOne(vr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(vr)) {
|
||||
reject(new HttpError(403, "Error: Variable cannot be nothing !"))
|
||||
} else if (!v.validate(vr, VariableValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(vr, VariableValidation).errors))
|
||||
} else if (this.isXSSAttempt(vr.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
bookshelf.transaction(t => {
|
||||
return model.forge({
|
||||
'description': vr.description,
|
||||
}).save(null, {
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['spells'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Insert Variable error"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
updateOne(id, vr) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (this.isEmptyObject(vr)) {
|
||||
reject(new HttpError(403, "Error: Variable cannot be nothing !"))
|
||||
} else if (!v.validate(vr, VariableValidation).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(vr, VariableValidation).errors))
|
||||
} else if (this.isXSSAttempt(vr.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
model.forge({id: id})
|
||||
.fetch({require: true, withRelated: ['spells']})
|
||||
.then(v => {
|
||||
bookshelf.transaction(t => {
|
||||
return v.save({
|
||||
'description': vr.description,
|
||||
}, {
|
||||
method: 'update',
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(v => {
|
||||
return v.load(['spells'])
|
||||
})
|
||||
.then(v => {
|
||||
resolve(this.getOne(v.id))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Update Variable error"))
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get variable"))
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
deleteOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({require: true, withRelated: ['spells']})
|
||||
.then(v => {
|
||||
v.spells().detach()
|
||||
v.destroy()
|
||||
})
|
||||
.then(() => {
|
||||
resolve({
|
||||
'message': 'Variable with ID ' + id + ' successfully deleted !'
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(404, "Couldn't get variable"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VariableRepository
|
||||
@@ -1,9 +1,15 @@
|
||||
const users = require('./users')
|
||||
const spells = require('./spells')
|
||||
const schools = require('./schools')
|
||||
const meta_schools = require('./meta_schools')
|
||||
const variables = require('./variables')
|
||||
const ingredients = require('./ingredients')
|
||||
const users = require('./users')
|
||||
|
||||
module.exports = {
|
||||
spells,
|
||||
schools,
|
||||
users
|
||||
meta_schools,
|
||||
ingredients,
|
||||
variables,
|
||||
users,
|
||||
}
|
||||
165
routes/ingredients.js
Normal file
165
routes/ingredients.js
Normal file
@@ -0,0 +1,165 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Repository
|
||||
const IngredientRepository = require('../repositories/ingredient-repository');
|
||||
const Ingredients = new IngredientRepository();
|
||||
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getIngredients = () => {
|
||||
return Ingredients.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/', async (req, res) => {
|
||||
getIngredients()
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET ONE ------------------
|
||||
const getIngredient = (id) => {
|
||||
return Ingredients.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/', async (req, res) => {
|
||||
getIngredient(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// CREATE ONE ------------------
|
||||
const addIngredient = (igr) => {
|
||||
return Ingredients.addOne(igr)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/', async (req, res) => {
|
||||
addIngredient(req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// UPDATE ONE ------------------
|
||||
const updateIngredient = (id, igr) => {
|
||||
return Ingredients.updateOne(id, igr)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.put('/:id/', async (req, res) => {
|
||||
updateIngredient(req.params.id, req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// DELETE ONE ------------------
|
||||
const deleteIngredient = (id) => {
|
||||
return Ingredients.deleteOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.delete('/:id/', async (req, res) => {
|
||||
deleteIngredient(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
// Param validation for ID
|
||||
// (check if id is int) (could be refactored)
|
||||
router.param('id', (req, res, next, id) => {
|
||||
try {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new Error;
|
||||
}
|
||||
} catch (err) {
|
||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
91
routes/meta_schools.js
Normal file
91
routes/meta_schools.js
Normal file
@@ -0,0 +1,91 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Repository
|
||||
const MetaSchoolRepository = require('../repositories/meta-school-repository');
|
||||
const MetaSchools = new MetaSchoolRepository();
|
||||
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getMetaSchools = () => {
|
||||
return MetaSchools.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/', async (req, res) => {
|
||||
getMetaSchools()
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET ONE ------------------
|
||||
const getMetaSchool = (id) => {
|
||||
return MetaSchools.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/', async (req, res) => {
|
||||
getMetaSchool(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// Param validation for ID
|
||||
// (check if id is int) (could be refactored)
|
||||
router.param('id', (req, res, next, id) => {
|
||||
try {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new Error;
|
||||
}
|
||||
} catch (err) {
|
||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
@@ -5,49 +5,24 @@ const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/connection')
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Validations
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
// Repository
|
||||
const SchoolRepository = require('../repositories/school-repository');
|
||||
const Schools = new SchoolRepository();
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const School = require("../models/School")
|
||||
v.addSchema(School, "/SchoolModel")
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../models/Errors')
|
||||
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getSchools = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT DISTINCT * FROM school"
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else if (result.length == 0) {
|
||||
reject(new HttpError(404, 'No schools were found'))
|
||||
}
|
||||
|
||||
// Loops over the results to fetch the associated tables
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
try {
|
||||
result[i] = await buildSchool(result[i])
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
return Schools.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -70,23 +45,9 @@ router.get('/', async (req, res) => {
|
||||
|
||||
// GET ONE ------------------
|
||||
const getSchool = (id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT * FROM school WHERE id = " + db.escape(id)
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
}
|
||||
try {
|
||||
result = buildSchool(result[0])
|
||||
resolve(result)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
return Schools.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -109,41 +70,9 @@ router.get('/:id/', async (req, res) => {
|
||||
|
||||
// CREATE ONE ------------------
|
||||
const addSchool = (s) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: School cannot be nothing !"))
|
||||
} else if (!v.validate(s, School).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, School).errors))
|
||||
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
let query = `INSERT INTO school (name, description, id_meta_school) VALUES (${db.escape(s.name)}, ${db.escape(s.description)}, ${db.escape(s.id_meta_school)})`
|
||||
|
||||
db.query(query, (err, result) => {
|
||||
if (err) {
|
||||
if (err.errno == 1452) {
|
||||
reject(new HttpError(404, "Error: No meta school matching this ID"))
|
||||
} else {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
}
|
||||
} else {
|
||||
console.log(`Inserted "${s.name}" with ID ${result.insertId}, affecting ${result.affectedRows} row(s)`)
|
||||
|
||||
const new_school_id = result.insertId
|
||||
|
||||
getSchool(new_school_id)
|
||||
.then(v => {
|
||||
resolve(v)
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
return Schools.addOne(s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -163,17 +92,66 @@ router.post('/', async (req, res) => {
|
||||
})
|
||||
})
|
||||
|
||||
// Param validation for single school
|
||||
// UPDATE ONE ------------------
|
||||
const updateSchool = (id, s) => {
|
||||
return Schools.updateOne(id, s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.put('/:id/', async (req, res) => {
|
||||
updateSchool(req.params.id, req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// DELETE ONE ------------------
|
||||
const deleteSchool = (id) => {
|
||||
return Schools.deleteOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.delete('/:id/', async (req, res) => {
|
||||
deleteSchool(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
// Param validation for ID
|
||||
// (check if id is int) (could be refactored)
|
||||
router.param('id', (req, res, next, id) => {
|
||||
const regex = RegExp(/^[1-9]\d*$/);
|
||||
try {
|
||||
if (regex.test(id)) {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new HttpError(403, 'Provided ID must be an integer')
|
||||
throw new Error;
|
||||
}
|
||||
} catch (err) {
|
||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
@@ -183,59 +161,4 @@ router.param('id', (req, res, next, id) => {
|
||||
}
|
||||
})
|
||||
|
||||
// SHARED FUNCTIONS ------------------
|
||||
|
||||
// Builds the associated infos for a given school object
|
||||
const buildSchool = async (school) => {
|
||||
|
||||
// Fetches the school's parent school
|
||||
let fetchMetaSchoolData = (s) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (s == null) { reject(new HttpError(404, "Error: No school matching this ID"))}
|
||||
|
||||
let query =
|
||||
"SELECT ms.id, ms.name " +
|
||||
"FROM meta_school AS ms " +
|
||||
"WHERE ms.id = " + s.id_meta_school
|
||||
|
||||
|
||||
db.query(query, (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else {
|
||||
delete s.id_meta_school
|
||||
s.meta_school = result
|
||||
resolve(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let s = fetchMetaSchoolData(school)
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
const isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
const isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = router
|
||||
565
routes/spells.js
565
routes/spells.js
@@ -5,48 +5,24 @@ const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/connection')
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Validations
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
// Repository
|
||||
const SpellReposity = require('../repositories/spell-repository');
|
||||
const Spells = new SpellReposity();
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const Spell = require("../models/Spell")
|
||||
v.addSchema(Spell, "/SpellModel")
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../models/Errors')
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getSpells = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT DISTINCT * FROM spell"
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else if (result.length == 0) {
|
||||
reject(new HttpError(404, 'No spells were found'))
|
||||
}
|
||||
|
||||
// Loops over the results to fetch the associated tables
|
||||
for (let i = 0; i < result.length; i++) {
|
||||
try {
|
||||
result[i] = await buildSpell(result[i])
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
}
|
||||
resolve(result)
|
||||
})
|
||||
})
|
||||
return Spells.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -69,23 +45,9 @@ router.get('/', async (req, res) => {
|
||||
|
||||
// GET ONE ------------------
|
||||
const getSpell = (id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT * FROM spell WHERE id = " + db.escape(id)
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
}
|
||||
try {
|
||||
result = buildSpell(result[0])
|
||||
resolve(result)
|
||||
} catch (err) {
|
||||
reject(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
return Spells.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -108,136 +70,9 @@ router.get('/:id/', async (req, res) => {
|
||||
|
||||
// CREATE ONE ------------------
|
||||
const addSpell = (s) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
||||
} else if (!v.validate(s, Spell).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, Spell).errors))
|
||||
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
let query =
|
||||
'INSERT INTO spell (name, description'
|
||||
|
||||
if (s.level !== null) { query += ', level' }
|
||||
if (s.charge !== null) { query += ', charge' }
|
||||
if (s.cost !== null) { query += ', cost' }
|
||||
if (s.is_ritual !== null) { query += ', is_ritual' }
|
||||
|
||||
query += `) VALUES (${db.escape(s.name)}, ${db.escape(s.description)}`
|
||||
|
||||
if (s.level !== null) { query += `, ${s.level}` }
|
||||
if (s.charge !== null) { query += `, ${s.charge}` }
|
||||
if (s.cost !== null) { query += `, ${db.escape(s.cost)}` }
|
||||
if (s.is_ritual !== null) { query += `, ${s.is_ritual}` }
|
||||
|
||||
query += ')'
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
}
|
||||
console.log(`Inserted "${s.name}" with ID ${result.insertId}, affecting ${result.affectedRows} row(s)`)
|
||||
|
||||
const new_spell_id = result.insertId
|
||||
|
||||
let addSchoolsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.schools !== null) {
|
||||
if (s.schools.length > 0) {
|
||||
for (let i = 0; i < s.schools.length; i++) {
|
||||
if (!regexInt.test(s.schools[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - School ID should be an integer !'))
|
||||
}
|
||||
|
||||
let insert_schools_query = `INSERT INTO spells_schools (id_spell, id_school) VALUES (${new_spell_id}, ${s.schools[i].id})`
|
||||
|
||||
db.query(insert_schools_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No schools matching this ID'))
|
||||
} else {
|
||||
console.log(`Associated school ID ${s.schools[i].id} to spell ID ${new_spell_id}, affecting ${result.affectedRows} row(s)`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let addVariablesData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.variables !== null) {
|
||||
if (s.variables.length > 0) {
|
||||
for (let i = 0; i < s.variables.length; i++) {
|
||||
if (!regexInt.test(s.variables[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - Variable ID should be an integer !'))
|
||||
}
|
||||
|
||||
let insert_variables_query = `INSERT INTO spells_variables (id_spell, id_variable) VALUES (${new_spell_id}, ${s.variables[i].id})`
|
||||
db.query(insert_variables_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No variables matching this ID'))
|
||||
} else {
|
||||
console.log(`Associated variable ID ${s.variables[i].id} to spell ID ${new_spell_id}, affecting ${result.affectedRows} row(s)`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let addIngredientsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.ingredients !== null) {
|
||||
if (s.ingredients.length > 0) {
|
||||
for (let i = 0; i < s.ingredients.length; i++) {
|
||||
if (!regexInt.test(s.ingredients[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - Ingredient ID should be an integer !'))
|
||||
}
|
||||
|
||||
let insert_ingredients_query = `INSERT INTO spells_ingredients (id_spell, id_ingredient) VALUES (${new_spell_id}, ${s.ingredients[i].id})`
|
||||
db.query(insert_ingredients_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No ingredients matching this ID'))
|
||||
} else {
|
||||
console.log(`Associated ingredient ID ${s.ingredients[i].id} to spell ID ${new_spell_id}, affecting ${result.affectedRows} row(s)`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Promise.all([addSchoolsData(), addVariablesData(), addIngredientsData()])
|
||||
.then(() => {
|
||||
resolve(getSpell(new_spell_id))
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
}).catch(err => {
|
||||
return Spells.addOne(s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -259,186 +94,15 @@ router.post('/', async (req, res) => {
|
||||
|
||||
|
||||
// UPDATE ONE ------------------
|
||||
const updateSpell = (s, id) => {
|
||||
return new Promise( async (resolve, reject) => {
|
||||
|
||||
// Check if spell exists
|
||||
let old_spell = await getSpell(id)
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (isEmptyObject(s)) {
|
||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
||||
} else if (!v.validate(s, Spell).valid) {
|
||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, Spell).errors))
|
||||
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) {
|
||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
||||
} else {
|
||||
|
||||
let updateSchoolsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.schools !== null) {
|
||||
if (s.schools.length > 0) {
|
||||
let delete_schools_query =
|
||||
`DELETE FROM spells_schools WHERE id_spell = ${old_spell.id}`
|
||||
|
||||
db.query(delete_schools_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error - Spell school deletion failed.'))
|
||||
}
|
||||
})
|
||||
|
||||
for (let i = 0; i < s.schools.length; i++) {
|
||||
if (!regexInt.test(s.schools[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - School ID should be an integer !'))
|
||||
} else {}
|
||||
|
||||
let update_schools_query = `INSERT INTO spells_schools (id_spell, id_school) VALUES (${old_spell.id}, ${s.schools[i].id})`
|
||||
db.query(update_schools_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No schools matching this ID'))
|
||||
} else {
|
||||
console.log(`Updated association school ID ${s.schools[i].id} to spell ID ${old_spell.id}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let updateVariablesData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.variables !== null) {
|
||||
if (s.variables.length > 0) {
|
||||
let delete_variables_query =
|
||||
`DELETE FROM spells_variables WHERE id_spell = ${old_spell.id}`
|
||||
|
||||
db.query(delete_variables_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error - Spell variable deletion failed.'))
|
||||
}
|
||||
})
|
||||
|
||||
for (let i = 0; i < s.variables.length; i++) {
|
||||
if (!regexInt.test(s.variables[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - Variable ID should be an integer !'))
|
||||
}
|
||||
|
||||
let update_variables_query = `INSERT INTO spells_variables (id_spell, id_variable) VALUES (${old_spell.id}, ${s.variables[i].id})`
|
||||
db.query(update_variables_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No variables matching this ID'))
|
||||
} else {
|
||||
console.log(`Updated variable ID "${s.variables[i].id}" to spell ID ${old_spell.id}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let updateIngredientsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (s.ingredients !== null) {
|
||||
if (s.ingredients.length > 0) {
|
||||
let delete_ingredients_query =
|
||||
`DELETE FROM spells_ingredients WHERE id_spell = ${old_spell.id}`
|
||||
|
||||
db.query(delete_ingredients_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error - Spell ingredients deletion failed.'))
|
||||
}
|
||||
console.log(result)
|
||||
})
|
||||
|
||||
// Loops over ingredients query
|
||||
for (let i = 0; i < s.ingredients.length; i++) {
|
||||
if (!regexInt.test(s.ingredients[i].id)) {
|
||||
reject(new HttpError(403, 'Query error - Ingredient ID should be an integer !'))
|
||||
}
|
||||
|
||||
let update_ingredients_query = `INSERT INTO spells_ingredients (id_spell, id_ingredient) VALUES (${old_spell.id}, ${s.ingredients[i].id})`
|
||||
db.query(update_ingredients_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(404, 'Database error - No ingredients matching this ID'))
|
||||
} else {
|
||||
console.log(`Updated ingredient ID "${s.ingredients[i].id}" to spell ID ${old_spell.id}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
let updateSpellData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let update_spell_query =
|
||||
'UPDATE spell SET '
|
||||
|
||||
if (s.name !== null) { update_spell_query += `name = "${s.name}" ` }
|
||||
if (s.description !== null) { update_spell_query += `, description = "${s.description}" ` }
|
||||
if (s.level !== null) { update_spell_query += `, level = ${s.level} ` }
|
||||
if (s.charge !== null) { update_spell_query += `, charge = ${s.charge} ` }
|
||||
if (s.cost !== null) { update_spell_query += `, cost = "${s.cost}" ` }
|
||||
if (s.is_ritual !== null) { update_spell_query += `, is_ritual = ${s.is_ritual} ` }
|
||||
|
||||
update_spell_query += ` WHERE id = ${db.escape(id)}`
|
||||
|
||||
db.query(update_spell_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error - Spell update failed'))
|
||||
} else {
|
||||
console.log(`Updated "${s.name}" on ID ${old_spell.id}, affecting ${result.affectedRows} row(s)`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const sub_promises = [
|
||||
updateSchoolsData(),
|
||||
updateVariablesData(),
|
||||
updateIngredientsData()
|
||||
]
|
||||
|
||||
Promise.all(sub_promises)
|
||||
.then(() => {
|
||||
updateSpellData()
|
||||
})
|
||||
.then(() => {
|
||||
resolve(getSpell(old_spell.id))
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
const updateSpell = (id, s) => {
|
||||
return Spells.updateOne(id, s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.put('/:id/', async (req, res) => {
|
||||
updateSpell(req.body, req.params.id)
|
||||
updateSpell(req.params.id, req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
@@ -456,92 +120,9 @@ router.put('/:id/', async (req, res) => {
|
||||
|
||||
// DELETE ONE ------------------
|
||||
const deleteSpell = (id) => {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
|
||||
// Check if spell exists
|
||||
let old_spell = await getSpell(id)
|
||||
.catch(() => {
|
||||
reject((new HttpError(404, 'No spell matching this ID')))
|
||||
})
|
||||
|
||||
let deleteSchoolsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let delete_schools_query = `DELETE FROM spells_schools WHERE id_spell = ${db.escape(id)}`
|
||||
db.query(delete_schools_query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Spell schools deletion failed'))
|
||||
} else {
|
||||
console.log(`Deleted schools associated to spell ID ${db.escape(id)}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let deleteVariablesData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let delete_variables_query = `DELETE FROM spells_variables WHERE id_spell = ${db.escape(id)}`
|
||||
db.query(delete_variables_query, async (err, result) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, 'Spell variables deletion failed'))
|
||||
} else {
|
||||
console.log(`Deleted variables associated to spell ID ${db.escape(id)}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let deleteIngredientsData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let delete_ingredients_query = `DELETE FROM spells_ingredients WHERE id_spell = ${db.escape(id)}`
|
||||
db.query(delete_ingredients_query, async (err, result) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, 'Spell ingredients deletion failed'))
|
||||
} else {
|
||||
console.log(`Deleted ingredients associated to spell ID ${db.escape(id)}`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let deleteSpellData = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let delete_spell_query = `DELETE FROM spell WHERE id = ${db.escape(id)}`
|
||||
db.query(delete_spell_query, async (err, result) => {
|
||||
if (err) {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, 'Spell deletion failed'))
|
||||
} else {
|
||||
console.log(`Deleted spell ID ${db.escape(id)}, affecting ${result.affectedRows} rows`)
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const promises = [
|
||||
deleteSchoolsData(),
|
||||
deleteVariablesData(),
|
||||
deleteIngredientsData()
|
||||
]
|
||||
|
||||
Promise.all(promises)
|
||||
.then(() => {
|
||||
deleteSpellData()
|
||||
let response = {
|
||||
message: `Spell ID ${id} was successfully deleted.`
|
||||
}
|
||||
resolve(response)
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
return Spells.deleteOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -562,16 +143,17 @@ router.delete('/:id/', async (req, res) => {
|
||||
})
|
||||
|
||||
|
||||
// Param validation for single spell
|
||||
// Param validation for ID
|
||||
// (check if id is int) (could be refactored)
|
||||
router.param('id', (req, res, next, id) => {
|
||||
try {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
throw new Error;
|
||||
}
|
||||
} catch (err) {
|
||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
@@ -581,107 +163,4 @@ router.param('id', (req, res, next, id) => {
|
||||
}
|
||||
})
|
||||
|
||||
// SHARED FUNCTIONS ------------------
|
||||
|
||||
// Builds the associated infos for a given spell object
|
||||
const buildSpell = async (spell) => {
|
||||
|
||||
// Fetches the spell's schools
|
||||
let fetchSpellSchoolData = (s) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (s == null) { reject(new HttpError(404, "Error: No spell matching this ID"))}
|
||||
|
||||
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 = " + s.id
|
||||
|
||||
db.query(query, (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else {
|
||||
s.schools = result
|
||||
resolve(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Fetches the spell's variables
|
||||
let fetchSpellVariablesData = (s) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (s == null) { reject(new HttpError(404, "Error: No spell matching this ID"))}
|
||||
|
||||
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 = " + s.id
|
||||
|
||||
db.query(query, (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else {
|
||||
s.variables = result
|
||||
resolve(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Fetches the spell's ingredients
|
||||
let fetchSpellIngredientsData = (s) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
if (s == null) { reject(new HttpError(404, "Error: No spell matching this ID"))}
|
||||
|
||||
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 = " + s.id
|
||||
|
||||
db.query(query, (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else {
|
||||
s.ingredients = result
|
||||
resolve(s)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Builds the spell and returns it
|
||||
let s = await fetchSpellSchoolData(spell)
|
||||
.then(s => { return fetchSpellVariablesData(s) })
|
||||
.then(s => { return fetchSpellIngredientsData(s) })
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
const isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
const isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = router
|
||||
|
||||
@@ -1,45 +1,28 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/connection')
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Hashing and passwords
|
||||
const bcrypt = require('bcrypt')
|
||||
// Repository
|
||||
const UserRepository = require('../repositories/user-repository');
|
||||
const Users = new UserRepository();
|
||||
|
||||
// Validations
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const User = require("../models/User")
|
||||
v.addSchema(User, "/UserModel")
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../models/Errors')
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getUsers = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT DISTINCT * FROM user"
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else if (result.length == 0) {
|
||||
reject(new HttpError(404, 'No users were found'))
|
||||
} else {
|
||||
resolve(result)
|
||||
}
|
||||
})
|
||||
})
|
||||
return Users.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -62,21 +45,9 @@ router.get('/', async (req, res) => {
|
||||
|
||||
// GET ONE ------------------
|
||||
const getUser = (id) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = "SELECT * FROM user WHERE id = " + db.escape(id)
|
||||
|
||||
db.query(query, async (err, result) => {
|
||||
if (err) {
|
||||
reject(new HttpError(500, 'Database error'))
|
||||
} else if (result.length == 0) {
|
||||
reject(new HttpError(404, 'No User matching this ID'))
|
||||
} else {
|
||||
resolve(result)
|
||||
}
|
||||
})
|
||||
})
|
||||
return Users.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
@@ -211,33 +182,11 @@ router.param('id', (req, res, next, id) => {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
new Error
|
||||
}
|
||||
} catch (err) {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
})
|
||||
)
|
||||
throw new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
}
|
||||
})
|
||||
|
||||
// Check if object is null
|
||||
const isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
const isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = router
|
||||
165
routes/variables.js
Normal file
165
routes/variables.js
Normal file
@@ -0,0 +1,165 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Repository
|
||||
const VariableRepository = require('../repositories/variable-repository');
|
||||
const Variables = new VariableRepository();
|
||||
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getvariables = () => {
|
||||
return Variables.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/', async (req, res) => {
|
||||
getvariables()
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET ONE ------------------
|
||||
const getVariable = (id) => {
|
||||
return Variables.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/', async (req, res) => {
|
||||
getVariable(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.end(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// CREATE ONE ------------------
|
||||
const addVariable = (vr) => {
|
||||
return Variables.addOne(vr)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/', async (req, res) => {
|
||||
addVariable(req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// UPDATE ONE ------------------
|
||||
const updateVariable = (id, vr) => {
|
||||
return Variables.updateOne(id, vr)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.put('/:id/', async (req, res) => {
|
||||
updateVariable(req.params.id, req.body)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// DELETE ONE ------------------
|
||||
const deleteVariable = (id) => {
|
||||
return Variables.deleteOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.delete('/:id/', async (req, res) => {
|
||||
deleteVariable(req.params.id)
|
||||
.then(v => {
|
||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
||||
res.send(JSON.stringify(v))
|
||||
})
|
||||
.catch(err => {
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
// Param validation for ID
|
||||
// (check if id is int) (could be refactored)
|
||||
router.param('id', (req, res, next, id) => {
|
||||
try {
|
||||
if (regexInt.test(id)) {
|
||||
next()
|
||||
} else {
|
||||
throw new Error;
|
||||
}
|
||||
} catch (err) {
|
||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
||||
res.status(err.code).send(JSON.stringify(
|
||||
{
|
||||
"error": err.message,
|
||||
"code": err.code
|
||||
})
|
||||
)
|
||||
}
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
11
validations/IngredientValidation.js
Normal file
11
validations/IngredientValidation.js
Normal file
@@ -0,0 +1,11 @@
|
||||
const Ingredient = {
|
||||
"id": "/IngredientValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" }
|
||||
},
|
||||
"required": ["name", "description"]
|
||||
}
|
||||
|
||||
module.exports = Ingredient
|
||||
12
validations/MetaSchoolValidation.js
Normal file
12
validations/MetaSchoolValidation.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const MetaSchool = {
|
||||
"id": "/MetaSchoolValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"schools": { "type": "array" }
|
||||
},
|
||||
"required": ["name", "description"]
|
||||
}
|
||||
|
||||
module.exports = MetaSchool
|
||||
@@ -1,12 +1,12 @@
|
||||
const School = {
|
||||
"id": "/SchoolModel",
|
||||
"id": "/SchoolValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"id_meta_school": { "type": "number" },
|
||||
"meta_school_id": { "type": "number" },
|
||||
},
|
||||
"required": ["name", "description", "id_meta_school"]
|
||||
"required": ["name", "description", "meta_school_id"]
|
||||
}
|
||||
|
||||
module.exports = School
|
||||
@@ -1,5 +1,5 @@
|
||||
const Spell = {
|
||||
"id": "/SpellModel",
|
||||
"id": "/SpellValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
@@ -1,5 +1,5 @@
|
||||
const User = {
|
||||
"id": "/UserModel",
|
||||
"id": "/UserValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
10
validations/VariableValidation.js
Normal file
10
validations/VariableValidation.js
Normal file
@@ -0,0 +1,10 @@
|
||||
const Variable = {
|
||||
"id": "/VariableValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"description": { "type": "string" },
|
||||
},
|
||||
"required": ["description"]
|
||||
}
|
||||
|
||||
module.exports = Variable
|
||||
Reference in New Issue
Block a user