- Moved api files to a relevant subfolder
This commit is contained in:
176
api/database/auracle_db_create.sql
Normal file
176
api/database/auracle_db_create.sql
Normal file
@@ -0,0 +1,176 @@
|
||||
DROP DATABASE IF EXISTS auracle;
|
||||
CREATE DATABASE auracle CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
|
||||
USE auracle;
|
||||
|
||||
/* =========== PRIMARY TABLES =========== */
|
||||
|
||||
/* PERMISSIONS */
|
||||
CREATE TABLE IF NOT EXISTS `role` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY(`id`)
|
||||
);
|
||||
|
||||
/* USERS */
|
||||
CREATE TABLE IF NOT EXISTS `user` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`uuid` VARCHAR(36) NOT NULL,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT "Disciple",
|
||||
`mail` VARCHAR(255) NOT NULL,
|
||||
`avatar` VARCHAR(255),
|
||||
`gender` VARCHAR(255),
|
||||
`password` VARCHAR(255) NOT NULL,
|
||||
`role_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
||||
`verified` BOOLEAN DEFAULT false,
|
||||
`banned` BOOLEAN DEFAULT false,
|
||||
PRIMARY KEY(`id`),
|
||||
FOREIGN KEY(`role_id`) REFERENCES role(`id`)
|
||||
);
|
||||
|
||||
/* SPELLS */
|
||||
CREATE TABLE IF NOT EXISTS `spell` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom du sort",
|
||||
`description` VARCHAR(1000) NOT NULL DEFAULT "Description du sort",
|
||||
`level` INT UNSIGNED DEFAULT 0,
|
||||
`charge` INT UNSIGNED DEFAULT 0,
|
||||
`cost` VARCHAR(255) DEFAULT "0",
|
||||
`is_ritual` BOOLEAN DEFAULT false,
|
||||
`published` BOOLEAN DEFAULT true,
|
||||
`public` BOOLEAN DEFAULT true,
|
||||
`author_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
FOREIGN KEY(`author_id`) REFERENCES user(`id`)
|
||||
);
|
||||
|
||||
/* META SCHOOLS */
|
||||
CREATE TABLE IF NOT EXISTS `meta_school` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école mère",
|
||||
`description` VARCHAR(255) DEFAULT "Description de l'école mère",
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
/* SCHOOLS */
|
||||
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",
|
||||
`meta_school_id` INT UNSIGNED NOT NULL,
|
||||
PRIMARY KEY (`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 encore chaude.",
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
/* COMMON VARIABLES */
|
||||
CREATE TABLE IF NOT EXISTS `variable` (
|
||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
||||
`description` VARCHAR(255) NOT NULL DEFAULT "Nombre de créatures affectées",
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
|
||||
/* ==== ASSOCIATION TABLES ==== */
|
||||
|
||||
/* SPELLS' SCHOOLS */
|
||||
/* One spell can have multiple (up to 3) schools */
|
||||
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 `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 `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`)
|
||||
);
|
||||
|
||||
/* Ajout d'une nouvelle ligne avant l'insert de description */
|
||||
DELIMITER $$
|
||||
CREATE TRIGGER `multiLine` BEFORE INSERT ON `spell` FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.description = replace(NEW.description, '<l>', '\n');
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
/* =========== PRIMARY INSERTS =========== */
|
||||
SET NAMES utf8;
|
||||
USE auracle;
|
||||
|
||||
-- PERMISSIONS
|
||||
INSERT INTO `role` (name, description) VALUES
|
||||
("Visiteur", "Utilisateur normal, peut consulter les sorts."),
|
||||
("Scribe", "Gardiens des écrits, les scribes sont capables de modifier et d'ajouter des sortilèges."),
|
||||
("Arcanologue", "Maîtres de l'arcane, ils ont le pouvoir et la responsabilité de juger les sortilèges récents et de les supprimer, ou valider."),
|
||||
("Augure", "Régents des grimoires, ils ont droit d'accès à l'intégralité des informations connues, et pouvoir absolu sur le savoir arcanique.");
|
||||
|
||||
-- META SCHOOLS
|
||||
INSERT INTO `meta_school` (name, description) VALUES
|
||||
('Magies blanches', 'Magies disciplinant les arts de soins et de lumières.'),
|
||||
('Magies noires', 'Magies disciplinant l\'art de la mort et des secrets.'),
|
||||
('Magies élémentaires', 'Magies disciplinant les éléments basiques tels que l\'eau, la foudre et le feu, pour n\'en citer que les plus populaires.'),
|
||||
('Magies spirituelles', 'Magies disciplinant l\'esprit, tant pour le défendre que l\'attaquer.'),
|
||||
('Magies spatio-temporelles', 'Magies régissant le temps et l\'espace.'),
|
||||
('Magies affiliées', 'Magies rattachées à une forme d\'énergie magique particulière.'),
|
||||
('Magies autres', 'Magies trop spécifiques et ne rentrant dans aucune autre grande école.');
|
||||
|
||||
-- SCHOOLS
|
||||
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),
|
||||
('Tenebromancie', 'Discipline arcanique de la lumière.', 2),
|
||||
('Necromancie', 'Discipline arcanique de la mort.', 2),
|
||||
('Morbomancie', 'Discipline arcanique des maladies et malédictions.', 2),
|
||||
('Pyromancie', 'Discipline arcanique du feu.', 3),
|
||||
('Hydromancie', 'Discipline arcanique de l\'eau.', 3),
|
||||
('Electromancie', 'Discipline arcanique de la foudre.', 3),
|
||||
('Terramancie', 'Discipline arcanique de la terre.', 3),
|
||||
('Sidéromancie', 'Discipline arcanique des métaux rares et précieux.', 3),
|
||||
('Caelomancie', 'Discipline arcanique de l\'air.', 3),
|
||||
('Légimancie', 'Discipline arcanique de la lecture et du contrôle spirituel.', 4),
|
||||
('Illusiomancie', 'Discipline arcanique des illusions.', 4),
|
||||
('Cruciomancie', 'Discipline arcanique de la destruction spirituelle.', 4),
|
||||
('Chronomancie', 'Discipline arcanique du temps.', 5),
|
||||
('Spatiomancie', 'Discipline arcanique de l\'espace.', 5),
|
||||
('Kénomancie', 'Discipline arcanique du néant.', 6),
|
||||
('Lutomancie', 'Discipline arcanique des abysses.', 6),
|
||||
('Échomancie', 'Discipline arcanique de la résolution animique.', 6),
|
||||
('Protomancie', 'Discipline arcanique de la magie pure.', 7),
|
||||
('Rebumancie', 'Discipline arcanique de la lumière.', 7),
|
||||
('Vocamancie', 'Discipline arcanique de la lumière.', 7),
|
||||
('Somamancie', 'Discipline arcanique de la maîtrise corporelle.', 7),
|
||||
('Antimancie', 'Discipline arcanique de l\'annulation arcanique.', 7);
|
||||
|
||||
-- INGREDIENTS
|
||||
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
|
||||
('Nombre de personnes soignées');
|
||||
37
api/database/auracle_db_schools.sql
Normal file
37
api/database/auracle_db_schools.sql
Normal file
@@ -0,0 +1,37 @@
|
||||
USE auracle;
|
||||
|
||||
/* Insertions de masses */
|
||||
DELIMITER $$
|
||||
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 spell_school (spell_id, school_id) VALUES (@i, id_school);
|
||||
SET @i = @i + 1;
|
||||
END WHILE;
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
||||
CALL insertIntoSchoolRange(1, 25, 1);
|
||||
CALL insertIntoSchoolRange(26, 50, 2);
|
||||
CALL insertIntoSchoolRange(51, 70, 3);
|
||||
CALL insertIntoSchoolRange(71, 95, 4);
|
||||
CALL insertIntoSchoolRange(96, 111, 5);
|
||||
CALL insertIntoSchoolRange(112, 115, 6);
|
||||
CALL insertIntoSchoolRange(116, 141, 7);
|
||||
CALL insertIntoSchoolRange(142, 167, 8);
|
||||
CALL insertIntoSchoolRange(168, 193, 9);
|
||||
CALL insertIntoSchoolRange(194, 217, 10);
|
||||
CALL insertIntoSchoolRange(218, 220, 11);
|
||||
CALL insertIntoSchoolRange(221, 242, 12);
|
||||
CALL insertIntoSchoolRange(243, 257, 13);
|
||||
CALL insertIntoSchoolRange(258, 272, 14);
|
||||
CALL insertIntoSchoolRange(273, 283, 15);
|
||||
CALL insertIntoSchoolRange(284, 301, 16);
|
||||
CALL insertIntoSchoolRange(302, 322, 17);
|
||||
CALL insertIntoSchoolRange(323, 339, 19);
|
||||
CALL insertIntoSchoolRange(340, 341, 20);
|
||||
CALL insertIntoSchoolRange(342, 356, 21);
|
||||
CALL insertIntoSchoolRange(357, 387, 22);
|
||||
CALL insertIntoSchoolRange(388, 396, 24);
|
||||
CALL insertIntoSchoolRange(397, 403, 25);
|
||||
18
api/database/bookshelf.js
Normal file
18
api/database/bookshelf.js
Normal file
@@ -0,0 +1,18 @@
|
||||
// MODULES
|
||||
const fs = require('fs')
|
||||
const mysql = require('mysql')
|
||||
|
||||
// Setting up the database connection
|
||||
const knex = require('knex')({
|
||||
client: "mysql",
|
||||
connection: {
|
||||
host : process.env.DB_HOST,
|
||||
user : process.env.DB_USER,
|
||||
password : process.env.DB_PASSWORD,
|
||||
database : "auracle",
|
||||
charset : "utf8"
|
||||
},
|
||||
})
|
||||
const bookshelf = require('bookshelf')(knex)
|
||||
|
||||
module.exports = { bookshelf }
|
||||
48
api/functions.js
Normal file
48
api/functions.js
Normal file
@@ -0,0 +1,48 @@
|
||||
// Error handling
|
||||
const { HttpError } = require('./validations/Errors')
|
||||
|
||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
||||
const regexXSS = RegExp(/<[^>]*script/)
|
||||
|
||||
// Check if int for param validation
|
||||
const paramIntCheck = (req, res, next, input) => {
|
||||
try {
|
||||
if (regexInt.test(input)) {
|
||||
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
|
||||
})
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Check if script injection attempt
|
||||
const isXSSAttempt = (string) => {
|
||||
if (regexXSS.test(string)) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// Check if object is null
|
||||
const isEmptyObject = (obj) => {
|
||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
paramIntCheck,
|
||||
isXSSAttempt,
|
||||
isEmptyObject
|
||||
}
|
||||
60
api/index.js
Normal file
60
api/index.js
Normal file
@@ -0,0 +1,60 @@
|
||||
'use strict';
|
||||
|
||||
// MODULES
|
||||
const express = require('express')
|
||||
const bodyParser = require('body-parser')
|
||||
const helmet = require('helmet')
|
||||
const morgan = require('morgan')
|
||||
const cors = require('cors') // module to format the json response
|
||||
const dotenv = require('dotenv').config()
|
||||
|
||||
// Creates instances of database connections
|
||||
const connection = require('./database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// CONSTANTS
|
||||
const port = 2814
|
||||
|
||||
// Import routes
|
||||
const routes = require('./routes')
|
||||
|
||||
// Builds app w/ express
|
||||
let app = express()
|
||||
app.use(bodyParser.json({ limit: '10kb' }))
|
||||
app.use(cors())
|
||||
app.use(morgan('tiny'))
|
||||
app.use(helmet())
|
||||
|
||||
// Serves
|
||||
const server = app.listen( port, () => {console.log(`App listening on port ${port}`)})
|
||||
|
||||
// Get credentials
|
||||
// app.get('/api/login', (req, res, next) => {
|
||||
// if (req.headers.auracle_key !== process.env.API_KEY_PUBLIC) {
|
||||
// return res.status(401).send('Credentials error !')
|
||||
// } else {
|
||||
// return res.status(200).send(JSON.stringify(
|
||||
// {
|
||||
// "secret_key": process.env.API_KEY_PRIVATE,
|
||||
// })
|
||||
// )
|
||||
// }
|
||||
// })
|
||||
|
||||
// Auth guard
|
||||
const authguard = (req, res, next) => {
|
||||
if (req.headers.auracle_key !== process.env.API_KEY_PUBLIC) {
|
||||
return res.status(401).send('The API key is either missing or incorrect.')
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
}
|
||||
|
||||
// Routing
|
||||
app.use('/api/spells', authguard,routes.spells)
|
||||
app.use('/api/schools', authguard, routes.schools)
|
||||
app.use('/api/meta_schools', authguard, routes.meta_schools)
|
||||
app.use('/api/variables', authguard, routes.variables)
|
||||
app.use('/api/ingredients', authguard, routes.ingredients)
|
||||
app.use('/api/users', authguard, routes.users)
|
||||
|
||||
13
api/models/ingredient-model.js
Normal file
13
api/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
api/models/meta-school-model.js
Normal file
13
api/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
api/models/school-model.js
Normal file
17
api/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
api/models/spell-model.js
Normal file
21
api/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)
|
||||
9
api/models/user-model.js
Normal file
9
api/models/user-model.js
Normal file
@@ -0,0 +1,9 @@
|
||||
'use strict'
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
|
||||
let User = bookshelf.Model.extend({
|
||||
tableName: 'user',
|
||||
hidden: ['id', 'password']
|
||||
})
|
||||
|
||||
module.exports = bookshelf.model('User', User)
|
||||
13
api/models/variable-model.js
Normal file
13
api/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)
|
||||
2433
api/package-lock.json
generated
Normal file
2433
api/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
44
api/package.json
Normal file
44
api/package.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"name": "auracle-api",
|
||||
"version": "1.0.0",
|
||||
"description": "API for Auracle database",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"api": "node index.js",
|
||||
"client": "cd client && npm run serve"
|
||||
},
|
||||
"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": {
|
||||
"bcrypt": "^4.0.1",
|
||||
"bookshelf": "^1.1.1",
|
||||
"cors": "^2.8.5",
|
||||
"dotenv": "^8.2.0",
|
||||
"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",
|
||||
"uuid": "^8.2.0"
|
||||
}
|
||||
}
|
||||
171
api/repositories/ingredient-repository.js
Normal file
171
api/repositories/ingredient-repository.js
Normal file
@@ -0,0 +1,171 @@
|
||||
'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 isXSSAttempt = require('../functions').isXSSAttempt
|
||||
const isEmptyObject = require('../functions').isEmptyObject
|
||||
|
||||
// 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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getSpellsFromOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']})
|
||||
.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 (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 (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 (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 (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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = IngredientRepository
|
||||
53
api/repositories/meta-school-repository.js
Normal file
53
api/repositories/meta-school-repository.js
Normal file
@@ -0,0 +1,53 @@
|
||||
'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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MetaSchoolRepository
|
||||
172
api/repositories/school-repository.js
Normal file
172
api/repositories/school-repository.js
Normal file
@@ -0,0 +1,172 @@
|
||||
'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 isXSSAttempt = require('../functions').isXSSAttempt
|
||||
const isEmptyObject = require('../functions').isEmptyObject
|
||||
|
||||
// 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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getSpellsFromOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']})
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
reject(new HttpError(500, "Couldn't get spells from 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 (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 (isXSSAttempt(s.name) || 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 (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 (isXSSAttempt(s.name) || 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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SchoolRepository
|
||||
280
api/repositories/spell-repository.js
Normal file
280
api/repositories/spell-repository.js
Normal file
@@ -0,0 +1,280 @@
|
||||
'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 isXSSAttempt = require('../functions').isXSSAttempt
|
||||
const isEmptyObject = require('../functions').isEmptyObject
|
||||
|
||||
// Error handling
|
||||
const { HttpError } = require('../validations/Errors')
|
||||
|
||||
class SpellRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll(name, description, level, charge, cost, ritual) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = model.forge()
|
||||
|
||||
if (name) { query.where('name', 'like', `%${name}%`) }
|
||||
if (description) { query.where('description', 'like', `%${description}%`) }
|
||||
if (level) { query.where({ 'level' : level }) }
|
||||
if (charge) { query.where({ 'charge' : charge }) }
|
||||
if (cost) { query.where({ 'cost' : cost }) }
|
||||
if (ritual) { query.where({ 'is_ritual' : ritual }) }
|
||||
|
||||
query.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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getAllPublic(name, description, level, charge, cost, ritual) {
|
||||
return new Promise((resolve, reject) => {
|
||||
|
||||
let query = model.forge()
|
||||
.where({ 'public' : 1 })
|
||||
|
||||
if (name) { query.where('name', 'like', `%${name}%`) }
|
||||
if (description) { query.where('description', 'like', `%${description}%`) }
|
||||
if (level) { query.where({ 'level' : level }) }
|
||||
if (charge) { query.where({ 'charge' : charge }) }
|
||||
if (cost) { query.where({ 'cost' : cost }) }
|
||||
if (ritual) { query.where({ 'is_ritual' : ritual }) }
|
||||
|
||||
query.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 public spells"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getPage(page) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'public' : 1 })
|
||||
.fetchPage({
|
||||
pageSize: 20,
|
||||
page: page,
|
||||
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 public 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 (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 (isXSSAttempt(s.name) || isXSSAttempt(s.description) || 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 (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 (isXSSAttempt(s.name) || isXSSAttempt(s.description) || 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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SpellRepository
|
||||
180
api/repositories/user-repository.js
Normal file
180
api/repositories/user-repository.js
Normal file
@@ -0,0 +1,180 @@
|
||||
'use strict'
|
||||
// Bookshelf
|
||||
const bookshelf = require('../database/bookshelf').bookshelf
|
||||
const model = require('../models/user-model')
|
||||
|
||||
// Hashing and passwords
|
||||
const bcrypt = require('bcrypt')
|
||||
const { v4: uuidv4 } = require('uuid')
|
||||
|
||||
// Model validation
|
||||
const Validator = require('jsonschema').Validator
|
||||
const v = new Validator()
|
||||
const UserValidation = require("../validations/UserValidation")
|
||||
v.addSchema(UserValidation, "/UserValidation")
|
||||
|
||||
// Validations
|
||||
const isXSSAttempt = require('../functions').isXSSAttempt
|
||||
const isEmptyObject = require('../functions').isEmptyObject
|
||||
|
||||
class UserRepository {
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
getAll() {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.fetchAll()
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true }))
|
||||
})
|
||||
.catch(() => {
|
||||
reject({
|
||||
"message": "Database error, couldn't get all users.",
|
||||
"code": 500
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOneByUUID(uuid, full) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'uuid' : uuid })
|
||||
.fetch()
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true, visibility: !full }))
|
||||
})
|
||||
.catch(err => {
|
||||
reject({
|
||||
"message": "User with this UUID was not found.",
|
||||
"code": 404
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getOneByEmail(mail, full) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'mail': mail })
|
||||
.fetch()
|
||||
.then(v => {
|
||||
resolve(v.toJSON({ omitPivot: true, visibility: !full }))
|
||||
})
|
||||
.catch(() => {
|
||||
reject({
|
||||
"message": "User with this email was not found.",
|
||||
"code": 404
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
addOne(u) {
|
||||
return new Promise(async (resolve, reject) => {
|
||||
// Checks if body exists and if the model fits, and throws errors if it doesn't
|
||||
if (isEmptyObject(u)) {
|
||||
reject({
|
||||
"message": "Request body cannot be empty.",
|
||||
"code": 403
|
||||
})
|
||||
} else if (!v.validate(u, UserValidation).valid) {
|
||||
reject({
|
||||
"message": "Schema is not valid - " + v.validate(u, UserValidation).errors,
|
||||
"code": 403
|
||||
})
|
||||
} else if (isXSSAttempt(u.name) || isXSSAttempt(u.password) || isXSSAttempt(u.mail)) {
|
||||
reject({
|
||||
"message": "Injection attempt detected, aborting the request.",
|
||||
"code": 403
|
||||
})
|
||||
} else {
|
||||
let hash = await bcrypt.hash(u.password, 10)
|
||||
let uuid = uuidv4()
|
||||
|
||||
this.checkIfEmailAvailable(u.mail)
|
||||
.then(() => {
|
||||
bookshelf.transaction(t => {
|
||||
return model.forge({
|
||||
'uuid': uuid,
|
||||
'name': u.name,
|
||||
'mail': u.mail,
|
||||
'password': hash,
|
||||
})
|
||||
.save(null, {
|
||||
transacting: t
|
||||
})
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
})
|
||||
.then(() => {
|
||||
return this.getOneByUUID(uuid, false)
|
||||
})
|
||||
.then(newUser => {
|
||||
resolve({
|
||||
"message": "Account successfully created !",
|
||||
"user": newUser,
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
resolve({
|
||||
"message": "An error has occured while creating your account.",
|
||||
"code": 500,
|
||||
})
|
||||
})
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Log user with an email address and a password
|
||||
logUser(mail, password) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getOneByEmail(mail, true)
|
||||
.then(async fetchedUser => {
|
||||
|
||||
let match = await bcrypt.compare(password, fetchedUser.password)
|
||||
delete fetchedUser.id
|
||||
delete fetchedUser.password
|
||||
|
||||
if (match) {
|
||||
resolve({
|
||||
"message": "User successfully logged in !",
|
||||
"user": fetchedUser,
|
||||
})
|
||||
} else {
|
||||
reject({
|
||||
"message": "Les informations de connexion sont erronées.",
|
||||
})
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
reject(err)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// Check if one user already has that email
|
||||
checkIfEmailAvailable(mail) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.getOneByEmail(mail, false)
|
||||
.then(() => {
|
||||
reject({
|
||||
"message": "L'email est déjà utilisé par un autre utilisateur.",
|
||||
"code": 403
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
resolve(true)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserRepository
|
||||
168
api/repositories/variable-repository.js
Normal file
168
api/repositories/variable-repository.js
Normal file
@@ -0,0 +1,168 @@
|
||||
'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 isXSSAttempt = require('../functions').isXSSAttempt
|
||||
const isEmptyObject = require('../functions').isEmptyObject
|
||||
|
||||
// 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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
getSpellsFromOne(id) {
|
||||
return new Promise((resolve, reject) => {
|
||||
model.forge()
|
||||
.where({ 'id' : id })
|
||||
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']})
|
||||
.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 (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 (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 (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 (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"))
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = VariableRepository
|
||||
15
api/routes/index.js
Normal file
15
api/routes/index.js
Normal file
@@ -0,0 +1,15 @@
|
||||
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,
|
||||
meta_schools,
|
||||
ingredients,
|
||||
variables,
|
||||
users,
|
||||
}
|
||||
168
api/routes/ingredients.js
Normal file
168
api/routes/ingredients.js
Normal file
@@ -0,0 +1,168 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const functions = require('../functions')
|
||||
|
||||
// Repository
|
||||
const IngredientRepository = require('../repositories/ingredient-repository');
|
||||
const Ingredients = new IngredientRepository();
|
||||
|
||||
// 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
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET SPELLS FROM ONE ------------------
|
||||
const getSpellsFromOne = (id) => {
|
||||
return Ingredients.getSpellsFromOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/spells', async (req, res) => {
|
||||
getSpellsFromOne(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 validations
|
||||
router.param('id', functions.paramIntCheck)
|
||||
|
||||
module.exports = router
|
||||
68
api/routes/meta_schools.js
Normal file
68
api/routes/meta_schools.js
Normal file
@@ -0,0 +1,68 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const functions = require('../functions')
|
||||
|
||||
// Repository
|
||||
const MetaSchoolRepository = require('../repositories/meta-school-repository');
|
||||
const MetaSchools = new MetaSchoolRepository();
|
||||
|
||||
// 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 validations
|
||||
router.param('id', functions.paramIntCheck)
|
||||
|
||||
module.exports = router
|
||||
167
api/routes/schools.js
Normal file
167
api/routes/schools.js
Normal file
@@ -0,0 +1,167 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const functions = require('../functions')
|
||||
|
||||
// Repository
|
||||
const SchoolRepository = require('../repositories/school-repository');
|
||||
const Schools = new SchoolRepository();
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getSchools = () => {
|
||||
return Schools.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/', async (req, res) => {
|
||||
getSchools()
|
||||
.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 getSchool = (id) => {
|
||||
return Schools.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/', async (req, res) => {
|
||||
getSchool(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
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET SPELLS FROM ONE ------------------
|
||||
const getSpellsFromOne = (id) => {
|
||||
return Schools.getSpellsFromOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/spells', async (req, res) => {
|
||||
getSpellsFromOne(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 addSchool = (s) => {
|
||||
return Schools.addOne(s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/', async (req, res) => {
|
||||
addSchool(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 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 validations
|
||||
router.param('id', functions.paramIntCheck)
|
||||
|
||||
module.exports = router
|
||||
191
api/routes/spells.js
Normal file
191
api/routes/spells.js
Normal file
@@ -0,0 +1,191 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const functions = require('../functions')
|
||||
|
||||
// Repository
|
||||
const SpellReposity = require('../repositories/spell-repository');
|
||||
const Spells = new SpellReposity();
|
||||
|
||||
// ROUTES
|
||||
// GET ALL PUBLIC ------------------
|
||||
const getPublicSpells = (name, description, level, charge, cost, ritual) => {
|
||||
return Spells.getAllPublic(name, description, level, charge, cost, ritual)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('//:name?/:description?/:level?/:charge?/:cost?/:ritual?/', async (req, res) => {
|
||||
getPublicSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual)
|
||||
.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 ALL ------------------
|
||||
const getSpells = (name, description, level, charge, cost, ritual) => {
|
||||
return Spells.getAll(name, description, level, charge, cost, ritual)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/private/:name?/:description?/:level?/:charge?/:cost?/:ritual?/', async (req, res) => {
|
||||
getSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual)
|
||||
.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 SOME ------------------
|
||||
const getSomeSpells = (page) => {
|
||||
return Spells.getPage(page)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/page/:page', async (req, res) => {
|
||||
getSomeSpells(req.params.page)
|
||||
.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 getSpell = (id) => {
|
||||
return Spells.getOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/', async (req, res) => {
|
||||
getSpell(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 addSpell = (s) => {
|
||||
return Spells.addOne(s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/', async (req, res) => {
|
||||
addSpell(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 updateSpell = (id, s) => {
|
||||
return Spells.updateOne(id, s)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.put('/:id/', async (req, res) => {
|
||||
updateSpell(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 deleteSpell = (id) => {
|
||||
return Spells.deleteOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.delete('/:id/', async (req, res) => {
|
||||
deleteSpell(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 validations
|
||||
router.param('id', functions.paramIntCheck)
|
||||
router.param('page', functions.paramIntCheck)
|
||||
|
||||
module.exports = router
|
||||
113
api/routes/users.js
Normal file
113
api/routes/users.js
Normal file
@@ -0,0 +1,113 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const db = connection.db
|
||||
|
||||
// Repository
|
||||
const UserRepository = require('../repositories/user-repository');
|
||||
const Users = new UserRepository();
|
||||
|
||||
// ROUTES
|
||||
// GET ALL ------------------
|
||||
const getUsers = () => {
|
||||
return Users.getAll()
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/', async (req, res) => {
|
||||
getUsers()
|
||||
.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 FORM UUID ------------------
|
||||
const getUserByUUID = (uuid) => {
|
||||
return Users.getOneByUUID(uuid)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:uuid/', async (req, res) => {
|
||||
getUserByUUID(req.params.uuid)
|
||||
.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
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// LOG A USER ------------------
|
||||
const logUser = (mail, password) => {
|
||||
return Users.logUser(mail, password)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/login', async (req, res) => {
|
||||
logUser(req.body.mail, req.body.password)
|
||||
.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 addUser = (u) => {
|
||||
return Users.addOne(u)
|
||||
.catch(err => {
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.post('/', async (req, res) => {
|
||||
addUser(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
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
module.exports = router
|
||||
168
api/routes/variables.js
Normal file
168
api/routes/variables.js
Normal file
@@ -0,0 +1,168 @@
|
||||
'use strict'
|
||||
|
||||
// Router
|
||||
const express = require('express')
|
||||
let router = express.Router()
|
||||
|
||||
// Connection
|
||||
const connection = require('../database/bookshelf')
|
||||
const functions = require('../functions')
|
||||
|
||||
// Repository
|
||||
const VariableRepository = require('../repositories/variable-repository');
|
||||
const Variables = new VariableRepository();
|
||||
|
||||
// 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
|
||||
})
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// GET SPELLS FROM ONE ------------------
|
||||
const getSpellsFromOne = (id) => {
|
||||
return Variables.getSpellsFromOne(id)
|
||||
.catch(err => {
|
||||
console.log(err)
|
||||
throw err
|
||||
})
|
||||
}
|
||||
router.get('/:id/spells', async (req, res) => {
|
||||
getSpellsFromOne(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 validations
|
||||
router.param('id', functions.paramIntCheck)
|
||||
|
||||
module.exports = router
|
||||
13
api/validations/Errors.js
Normal file
13
api/validations/Errors.js
Normal file
@@ -0,0 +1,13 @@
|
||||
// Http error w/ http code
|
||||
class HttpError extends Error {
|
||||
constructor(code, message) {
|
||||
super(message)
|
||||
this.name = "HttpError"
|
||||
this.code = code
|
||||
Error.captureStackTrace(this, this.constructor);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
HttpError
|
||||
}
|
||||
11
api/validations/IngredientValidation.js
Normal file
11
api/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
api/validations/MetaSchoolValidation.js
Normal file
12
api/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
|
||||
12
api/validations/SchoolValidation.js
Normal file
12
api/validations/SchoolValidation.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const School = {
|
||||
"id": "/SchoolValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"meta_school_id": { "type": "number" },
|
||||
},
|
||||
"required": ["name", "description", "meta_school_id"]
|
||||
}
|
||||
|
||||
module.exports = School
|
||||
39
api/validations/SpellValidation.js
Normal file
39
api/validations/SpellValidation.js
Normal file
@@ -0,0 +1,39 @@
|
||||
const Spell = {
|
||||
"id": "/SpellValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"description": { "type": "string" },
|
||||
"level": { "type": "number" },
|
||||
"charge": { "type": "number" },
|
||||
"cost": { "type": "string" },
|
||||
"is_ritual": { "type": "boolean" },
|
||||
"schools": {
|
||||
"type": { "type": "array" },
|
||||
"items": {
|
||||
"properties": {
|
||||
"id": { "type": "number" },
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"type": { "type": "array" },
|
||||
"items": {
|
||||
"properties": {
|
||||
"id": { "type": "number" },
|
||||
}
|
||||
}
|
||||
},
|
||||
"ingredients": {
|
||||
"type": { "type": "array" },
|
||||
"items": {
|
||||
"properties": {
|
||||
"id": { "type": "number" },
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["name", "description"]
|
||||
}
|
||||
|
||||
module.exports = Spell
|
||||
12
api/validations/UserValidation.js
Normal file
12
api/validations/UserValidation.js
Normal file
@@ -0,0 +1,12 @@
|
||||
const User = {
|
||||
"id": "/UserValidation",
|
||||
"type": Object,
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"mail": { "type": "string" },
|
||||
"password": { "type": "string" },
|
||||
},
|
||||
"required": ["name", "password", "mail"]
|
||||
}
|
||||
|
||||
module.exports = User
|
||||
10
api/validations/VariableValidation.js
Normal file
10
api/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