Added authGuard function and its implementations

Also refactored small code mistakes.
This commit is contained in:
Alexis
2021-01-19 18:52:52 +01:00
parent 410a58fc09
commit e8ca2416b7
31 changed files with 4062 additions and 3947 deletions

View File

@@ -163,19 +163,24 @@ INSERT INTO `permission` (slug) VALUES
("MODIFY_SPELLS"), ("MODIFY_SPELLS"),
("DELETE_SPELLS"), ("DELETE_SPELLS"),
("WARN_USERS"), ("WARN_USERS"),
("BAN_USERS"); ("BAN_USERS"),
("SECRET_SPELLS"),
("SECRET_USERS");
INSERT INTO `role_permission` (role_id, permission_id) VALUES INSERT INTO `role_permission` (role_id, permission_id) VALUES
(2, 1), (2, 1),
(3, 1), (3, 1),
(3, 2), (3, 2),
(3, 3), (3, 3),
(3, 7),
(4, 1), (4, 1),
(4, 2), (4, 2),
(4, 3), (4, 3),
(4, 4), (4, 4),
(4, 5), (4, 5),
(4, 6); (4, 6),
(4, 7),
(4, 8);
-- USERS -- USERS
INSERT INTO `user` (uuid, name, mail, avatar, gender, register_date, password, role_id, verified, banned) VALUES INSERT INTO `user` (uuid, name, mail, avatar, gender, register_date, password, role_id, verified, banned) VALUES

View File

@@ -5,11 +5,11 @@ const fs = require('fs');
const knex = require('knex')({ const knex = require('knex')({
client: "mysql", client: "mysql",
connection: { connection: {
host : process.env.DB_HOST, host: process.env.DB_HOST,
user : process.env.DB_USER, user: process.env.DB_USER,
password : process.env.DB_PASSWORD, password: process.env.DB_PASSWORD,
database : process.env.DB_DATABASE, database: process.env.DB_DATABASE,
charset : "utf8" charset: "utf8"
}, },
}); });
const bookshelf = require('bookshelf')(knex); const bookshelf = require('bookshelf')(knex);

View File

@@ -11,9 +11,9 @@ const paramIntCheck = (req, res, next, input) => {
} }
} catch (err) { } catch (err) {
res.status(err.code).send(JSON.stringify({ res.status(err.code).send(JSON.stringify({
"message": "Le paramètre doit être un entier non-nul.", "message": "Le paramètre doit être un entier non-nul.",
"code": 403, "code": 403,
}) })
) )
} }
} }

View File

@@ -19,10 +19,10 @@ const routes = require('./routes');
let app = express(); let app = express();
app.use(bodyParser.json({ limit: '10kb' })); app.use(bodyParser.json({ limit: '10kb' }));
app.use(cors({ app.use(cors({
origin: [ origin: [
"http://localhost:8080", "http://localhost:8080",
], ],
credentials: true, credentials: true,
})); }));
app.use(morgan('dev')); app.use(morgan('dev'));
app.use(helmet()); app.use(helmet());
@@ -31,7 +31,7 @@ app.use(helmet());
app.listen(port, () => console.log(`App listening on port ${port}`)); app.listen(port, () => console.log(`App listening on port ${port}`));
// Entry route // Entry route
app.use('/api/v1/', routes.auth ); app.use('/api/v1/', routes.auth);
// Routing // Routing
app.use('/api/v1/spells', routes.spells); app.use('/api/v1/spells', routes.spells);

View File

@@ -5,10 +5,10 @@ require('./user-model');
let APIToken = bookshelf.Model.extend({ let APIToken = bookshelf.Model.extend({
tableName: 'api_token', tableName: 'api_token',
hidden: [ 'id' ], hidden: ['id'],
user() { user() {
return this.hasOne( 'User', 'user_uuid' ); return this.belongsTo('User', 'user_uuid', 'uuid');
} }
}) })
module.exports = bookshelf.model( 'APIToken', APIToken ); module.exports = bookshelf.model('APIToken', APIToken);

View File

@@ -6,7 +6,7 @@ require('./spell-model')
let Ingredient = bookshelf.Model.extend({ let Ingredient = bookshelf.Model.extend({
tableName: 'ingredient', tableName: 'ingredient',
spells() { spells() {
return this.belongsToMany( 'Spell', 'spell_ingredient') return this.belongsToMany('Spell', 'spell_ingredient')
} }
}) })

View File

@@ -6,7 +6,7 @@ require('./school-model')
let MetaSchool = bookshelf.Model.extend({ let MetaSchool = bookshelf.Model.extend({
tableName: 'meta_school', tableName: 'meta_school',
schools() { schools() {
return this.hasMany( 'School' ) return this.hasMany('School')
} }
}) })

View File

@@ -4,10 +4,10 @@ require('./role-model')
let Permission = bookshelf.Model.extend({ let Permission = bookshelf.Model.extend({
tableName: 'permission', tableName: 'permission',
hidden: [ 'id' ], hidden: ['id'],
role() { role() {
return this.belongsToMany( 'Role', 'role_permission' ) return this.belongsToMany('Role', 'role_permission')
} }
}) })
module.exports = bookshelf.model( 'Permission', Permission ); module.exports = bookshelf.model('Permission', Permission);

View File

@@ -5,8 +5,8 @@ require('./permission-model')
let Role = bookshelf.Model.extend({ let Role = bookshelf.Model.extend({
tableName: 'role', tableName: 'role',
permissions() { permissions() {
return this.belongsToMany( 'Permission', 'role_permission' ); return this.belongsToMany('Permission', 'role_permission');
} }
}) })
module.exports = bookshelf.model( 'Role', Role ); module.exports = bookshelf.model('Role', Role);

View File

@@ -7,10 +7,10 @@ require('./meta-school-model')
let School = bookshelf.Model.extend({ let School = bookshelf.Model.extend({
tableName: 'school', tableName: 'school',
spells() { spells() {
return this.belongsToMany( 'Spell', 'spell_school' ) return this.belongsToMany('Spell', 'spell_school')
}, },
meta_schools() { meta_schools() {
return this.belongsTo( 'MetaSchool', 'meta_school_id' ) return this.belongsTo('MetaSchool', 'meta_school_id')
} }
}) })

View File

@@ -6,13 +6,13 @@ require('./spell-model');
let User = bookshelf.Model.extend({ let User = bookshelf.Model.extend({
tableName: 'user', tableName: 'user',
hidden: [ 'password', 'role_id' ], hidden: ['password', 'role_id'],
role() { role() {
return this.belongsTo( 'Role' ); return this.belongsTo('Role');
}, },
spells() { spells() {
return this.hasMany( 'Spell', 'author_id' ); return this.hasMany('Spell', 'author_id');
} }
}) })
module.exports = bookshelf.model( 'User', User ) module.exports = bookshelf.model('User', User)

View File

@@ -6,7 +6,7 @@ require('./spell-model')
let Variable = bookshelf.Model.extend({ let Variable = bookshelf.Model.extend({
tableName: 'variable', tableName: 'variable',
spells() { spells() {
return this.belongsToMany( 'Spell', 'spell_variable') return this.belongsToMany('Spell', 'spell_variable')
} }
}) })

4750
api/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,44 @@
{ {
"name": "auracle-api", "name": "auracle-api",
"version": "1.0.0", "version": "1.0.0",
"description": "API for Auracle database", "description": "API for Auracle database",
"main": "index.js", "main": "index.js",
"scripts": { "scripts": {
"start": "node index.js" "start": "node index.js"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/AlexisNP/spellsaurus.git" "url": "git+https://github.com/AlexisNP/spellsaurus.git"
}, },
"keywords": [ "keywords": [
"api", "api",
"rpg", "rpg",
"spells", "spells",
"magic", "magic",
"database", "database",
"ttrpg", "ttrpg",
"dices", "dices",
"worldbuilding" "worldbuilding"
], ],
"author": "AlexisNP", "author": "AlexisNP",
"license": "ISC", "license": "ISC",
"bugs": { "bugs": {
"url": "https://github.com/AlexisNP/spellsaurus/issues" "url": "https://github.com/AlexisNP/spellsaurus/issues"
}, },
"homepage": "https://github.com/AlexisNP/spellsaurus#readme", "homepage": "https://github.com/AlexisNP/spellsaurus#readme",
"dependencies": { "dependencies": {
"bcrypt": "^5.0.0", "bcrypt": "^5.0.0",
"bookshelf": "^1.1.1", "bookshelf": "^1.1.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"dotenv": "^8.2.0", "dotenv": "^8.2.0",
"express": "^4.17.1", "express": "^4.17.1",
"handlebars": "^4.7.6", "handlebars": "^4.7.6",
"helmet": "^3.22.0", "helmet": "^3.22.0",
"jsonschema": "^1.2.6", "jsonschema": "^1.2.6",
"knex": "^0.21.1", "knex": "^0.21.1",
"morgan": "^1.10.0", "morgan": "^1.10.0",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"nodemailer": "^6.4.17", "nodemailer": "^6.4.17",
"uuid": "^8.2.0" "uuid": "^8.2.0"
} }
} }

View File

@@ -5,9 +5,9 @@ const model = require('../models/ingredient-model')
// Model validation // Model validation
const Validator = require('jsonschema').Validator const Validator = require('jsonschema').Validator
const v = new Validator() const validator = new Validator()
const IngredientValidation = require("../validations/IngredientValidation") const IngredientValidation = require("../validations/IngredientValidation")
v.addSchema(IngredientValidation, "/IngredientValidation") validator.addSchema(IngredientValidation, "/IngredientValidation")
// Validations // Validations
const isXSSAttempt = require('../functions').isXSSAttempt const isXSSAttempt = require('../functions').isXSSAttempt
@@ -21,54 +21,54 @@ class IngredientRepository {
getAll() { getAll() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.fetchAll({ withRelated: ['spells'] }) .fetchAll({ withRelated: ['spells'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Il n'existe aucun ingrédient disponible.", "message": "Il n'existe aucun ingrédient disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getOne(id) { getOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['spells']}) .fetch({ withRelated: ['spells'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "L'ingrédient en question n'a pas pu être trouvé.", "message": "L'ingrédient en question n'a pas pu être trouvé.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getSpellsFromOne(id) { getSpellsFromOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']}) .fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Les sortilèges liés à cet ingrédient n'ont pas pu être récupérés.", "message": "Les sortilèges liés à cet ingrédient n'ont pas pu être récupérés.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
@@ -80,9 +80,9 @@ class IngredientRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(igr, IngredientValidation).valid) { } else if (!validator.validate(igr, IngredientValidation).valid) {
reject({ reject({
"message": `Le modèle d'ingrédient n'est pas respecté : ${v.validate(s, IngredientValidation).errors}`, "message": `Le modèle d'ingrédient n'est pas respecté : ${validator.validate(s, IngredientValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(igr.description)) { } else if (isXSSAttempt(igr.description)) {
@@ -98,62 +98,10 @@ class IngredientRepository {
}).save(null, { }).save(null, {
transacting: t 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({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
});
})
}
})
}
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({
"message": "Le corps de la requête ne peut pas être vide.",
"code": 403,
});
} else if (!v.validate(igr, IngredientValidation).valid) {
reject({
"message": `Le modèle d'ingrédient n'est pas respecté : ${v.validate(s, IngredientValidation).errors}`,
"code": 403,
});
} else if (isXSSAttempt(igr.description)) {
reject({
"message": "Tentative d'injection XSS détectée, requête refusée.",
"code": 403,
});
} else {
new model({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 => { .catch(err => {
console.log(err)
throw err throw err
}) })
}) })
.then(v => { .then(v => {
return v.load(['spells']) return v.load(['spells'])
}) })
@@ -167,6 +115,83 @@ class IngredientRepository {
"code": 500, "code": 500,
}); });
}) })
}
})
}
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({
"message": "Le corps de la requête ne peut pas être vide.",
"code": 403,
});
} else if (!validator.validate(igr, IngredientValidation).valid) {
reject({
"message": `Le modèle d'ingrédient n'est pas respecté : ${validator.validate(s, IngredientValidation).errors}`,
"code": 403,
});
} else if (isXSSAttempt(igr.description)) {
reject({
"message": "Tentative d'injection XSS détectée, requête refusée.",
"code": 403,
});
} else {
new model({ 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({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
});
})
})
.catch(err => {
console.log(err)
reject({
"message": "L'ingrédient en question n'a pas été trouvé.",
"code": 404,
});
})
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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 => { .catch(err => {
console.log(err) console.log(err)
@@ -175,31 +200,6 @@ class IngredientRepository {
"code": 404, "code": 404,
}); });
}) })
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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({
"message": "L'ingrédient en question n'a pas été trouvé.",
"code": 404,
});
})
}) })
} }
} }

View File

@@ -5,9 +5,9 @@ const model = require('../models/meta-school-model')
// Model validation // Model validation
const Validator = require('jsonschema').Validator const Validator = require('jsonschema').Validator
const v = new Validator() const validator = new Validator()
const MetaSchoolValidation = require("../validations/MetaSchoolValidation") const MetaSchoolValidation = require("../validations/MetaSchoolValidation")
v.addSchema(MetaSchoolValidation, "/MetaSchoolValidation") validator.addSchema(MetaSchoolValidation, "/MetaSchoolValidation")
// Validations // Validations
const regexXSS = RegExp(/<[^>]*script/) const regexXSS = RegExp(/<[^>]*script/)
@@ -20,35 +20,35 @@ class MetaSchoolRepository {
getAll() { getAll() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.fetchAll({ withRelated: ['schools'] }) .fetchAll({ withRelated: ['schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Il n'existe aucune grande école disponible.", "message": "Il n'existe aucune grande école disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getOne(id) { getOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['schools']}) .fetch({ withRelated: ['schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "La grande école en question n'a pas pu être trouvée.", "message": "La grande école en question n'a pas pu être trouvée.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
} }

View File

@@ -5,9 +5,9 @@ const model = require('../models/school-model')
// Model validation // Model validation
const Validator = require('jsonschema').Validator const Validator = require('jsonschema').Validator
const v = new Validator() const validator = new Validator()
const SchoolValidation = require("../validations/SchoolValidation") const SchoolValidation = require("../validations/SchoolValidation")
v.addSchema(SchoolValidation, "/SchoolValidation") validator.addSchema(SchoolValidation, "/SchoolValidation")
// Validations // Validations
const isXSSAttempt = require('../functions').isXSSAttempt const isXSSAttempt = require('../functions').isXSSAttempt
@@ -21,53 +21,53 @@ class SchoolRepository {
getAll() { getAll() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.fetchAll({ withRelated: ['meta_schools'] }) .fetchAll({ withRelated: ['meta_schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Il n'existe aucune école disponible.", "message": "Il n'existe aucune école disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getOne(id) { getOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['meta_schools']}) .fetch({ withRelated: ['meta_schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "L'école en question n'a pas pu être trouvée.", "message": "L'école en question n'a pas pu être trouvée.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getSpellsFromOne(id) { getSpellsFromOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']}) .fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Les sortilèges de cette école n'ont pas pu être récupérés.", "message": "Les sortilèges de cette école n'ont pas pu être récupérés.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
@@ -79,9 +79,9 @@ class SchoolRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(s, SchoolValidation).valid) { } else if (!validator.validate(s, SchoolValidation).valid) {
reject({ reject({
"message": `Le modèle d'école n'est pas respecté : ${v.validate(s, SchoolValidation).errors}`, "message": `Le modèle d'école n'est pas respecté : ${validator.validate(s, SchoolValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) { } else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
@@ -97,24 +97,24 @@ class SchoolRepository {
'meta_school_id': s.meta_school_id, 'meta_school_id': s.meta_school_id,
}).save(null, { }).save(null, {
transacting: t transacting: t
})
.catch(err => {
throw err
})
})
.then(v => {
return v.load(['meta_schools']);
})
.then(v => {
resolve(this.getOne(v.id));
}) })
.catch(err => { .catch(err => {
throw err console.log(err)
reject({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
})
}) })
})
.then(v => {
return v.load(['meta_schools']);
})
.then(v => {
resolve(this.getOne(v.id));
})
.catch(err => {
console.log(err)
reject({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
})
})
} }
}) })
} }
@@ -127,9 +127,9 @@ class SchoolRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(s, SchoolValidation).valid) { } else if (!validator.validate(s, SchoolValidation).valid) {
reject({ reject({
"message": `Le modèle d'école n'est pas respecté : ${v.validate(s, SchoolValidation).errors}`, "message": `Le modèle d'école n'est pas respecté : ${validator.validate(s, SchoolValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) { } else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
@@ -138,35 +138,60 @@ class SchoolRepository {
"code": 403, "code": 403,
}); });
} else { } else {
new model({id: id}) new model({ id: id })
.fetch({require: true, withRelated: ['meta_schools']}) .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 => { .then(v => {
return v.load(['meta_schools']) bookshelf.transaction(t => {
}) return v.save({
.then(v => { 'name': s.name,
resolve(this.getOne(v.id)) '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({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
})
})
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err);
reject({ reject({
"message": "Une erreur d'insertion s'est produite.", "message": "L'école en question n'a pas été trouvée.",
"code": 500, "code": 404,
}) });
})
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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 => { .catch(err => {
@@ -176,31 +201,6 @@ class SchoolRepository {
"code": 404, "code": 404,
}); });
}) })
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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({
"message": "L'école en question n'a pas été trouvée.",
"code": 404,
});
})
}) })
} }
} }

View File

@@ -5,9 +5,9 @@ const model = require('../models/spell-model')
// Model validation // Model validation
const Validator = require('jsonschema').Validator const Validator = require('jsonschema').Validator
const v = new Validator() const validator = new Validator()
const SpellValidation = require("../validations/SpellValidation") const SpellValidation = require("../validations/SpellValidation")
v.addSchema(SpellValidation, "/SpellValidation") validator.addSchema(SpellValidation, "/SpellValidation")
// Validations // Validations
const isXSSAttempt = require('../functions').isXSSAttempt const isXSSAttempt = require('../functions').isXSSAttempt
@@ -25,88 +25,88 @@ class SpellRepository {
if (name) { query.where('name', 'like', `%${name}%`) } if (name) { query.where('name', 'like', `%${name}%`) }
if (description) { query.where('description', 'like', `%${description}%`) } if (description) { query.where('description', 'like', `%${description}%`) }
if (level) { query.where({ 'level' : level }) } if (level) { query.where({ 'level': level }) }
if (charge) { query.where({ 'charge' : charge }) } if (charge) { query.where({ 'charge': charge }) }
if (cost) { query.where({ 'cost' : cost }) } if (cost) { query.where({ 'cost': cost }) }
if (ritual) { query.where({ 'is_ritual' : ritual }) } if (ritual) { query.where({ 'is_ritual': ritual }) }
query.fetchAll({ withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ] }) query.fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Il n'existe aucun sortilège disponible.", "message": "Il n'existe aucun sortilège disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getAllPublic(name, description, level, charge, cost, ritual) { getAllPublic(name, description, level, charge, cost, ritual) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let query = new model().where({ 'public' : 1 }) let query = new model().where({ 'public': 1 })
if (name) { query.where('name', 'like', `%${name}%`) } if (name) { query.where('name', 'like', `%${name}%`) }
if (description) { query.where('description', 'like', `%${description}%`) } if (description) { query.where('description', 'like', `%${description}%`) }
if (level) { query.where({ 'level' : level }) } if (level) { query.where({ 'level': level }) }
if (charge) { query.where({ 'charge' : charge }) } if (charge) { query.where({ 'charge': charge }) }
if (cost) { query.where({ 'cost' : cost }) } if (cost) { query.where({ 'cost': cost }) }
if (ritual) { query.where({ 'is_ritual' : ritual }) } if (ritual) { query.where({ 'is_ritual': ritual }) }
query.fetchAll({ withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ] }) query.fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })); resolve(v.toJSON({ omitPivot: true }));
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Il n'existe aucun sortilège disponible.", "message": "Il n'existe aucun sortilège disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getPage(page) { getPage(page) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'public' : 1 }) .where({ 'public': 1 })
.fetchPage({ .fetchPage({
pageSize: 20, pageSize: 20,
page: page, page: page,
withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ], withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'],
}) })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "La page de sortilèges n'a pas pu être chargée", "message": "La page de sortilèges n'a pas pu être chargée",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getOne(id) { getOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ]}) .fetch({ withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Le sortilège en question n'a pas été trouvé.", "message": "Le sortilège en question n'a pas été trouvé.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
@@ -118,10 +118,10 @@ class SpellRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(s, SpellValidation).valid) { } else if (!validator.validate(s, SpellValidation).valid) {
reject({ reject({
"message": `Le modèle de sortilège n'est pas respecté : ${v.validate(s, SpellValidation).errors}`, "message": `Le modèle de sortilège n'est pas respecté : ${validator.validate(s, SpellValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) { } else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) {
reject({ reject({
@@ -134,54 +134,54 @@ class SpellRepository {
'name': s.name, 'name': s.name,
'description': s.description, 'description': s.description,
'level': s.level, 'level': s.level,
'charge' : s.charge, 'charge': s.charge,
'cost' : s.cost, 'cost': s.cost,
'is_ritual' : s.is_ritual 'is_ritual': s.is_ritual
}).save(null, { }).save(null, {
transacting: t transacting: t
}) })
.tap(spell => { .tap(spell => {
return spell return spell
.schools() .schools()
.attach(s.schools, { .attach(s.schools, {
transacting: t 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);
reject({
"message": "Un attributs du sortilège a provoqué une erreur d'insertion.",
"code": 500,
});
})
})
.then(v => {
return v.load(['schools.meta_schools', 'variables', 'ingredients', 'author'])
}) })
.tap(spell => { .then(v => {
return spell resolve(this.getOne(v.id))
.variables()
.attach(s.variables, {
transacting: t
});
})
.tap(spell => {
return spell
.ingredients()
.attach(s.ingredients, {
transacting: t
});
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Un attributs du sortilège a provoqué une erreur d'insertion.", "message": "Le sortilège n'a pas pu être ajouté.",
"code": 500, "code": 500,
}); });
}) })
})
.then(v => {
return v.load([ 'schools.meta_schools', 'variables', 'ingredients', 'author' ])
})
.then(v => {
resolve(this.getOne(v.id))
})
.catch(err => {
console.log(err);
reject({
"message": "Le sortilège n'a pas pu être ajouté.",
"code": 500,
});
})
} }
}) })
} }
@@ -194,9 +194,9 @@ class SpellRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(s, SpellValidation).valid) { } else if (!validator.validate(s, SpellValidation).valid) {
reject({ reject({
"message": `Le modèle de sortilège n'est pas respecté : ${v.validate(s, SpellValidation).errors}`, "message": `Le modèle de sortilège n'est pas respecté : ${validator.validate(s, SpellValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) { } else if (isXSSAttempt(s.name) || isXSSAttempt(s.description) || isXSSAttempt(s.cost)) {
@@ -205,82 +205,110 @@ class SpellRepository {
"code": 403, "code": 403,
}); });
} else { } else {
new model({id: id}) new model({ id: id })
.fetch({require: true, withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ]}) .fetch({ require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
.then(v => { .then(v => {
bookshelf.transaction(t => { bookshelf.transaction(t => {
return v.save({ return v.save({
'name': s.name, 'name': s.name,
'description': s.description, 'description': s.description,
'level': s.level, 'level': s.level,
'charge' : s.charge, 'charge': s.charge,
'cost' : s.cost, 'cost': s.cost,
'is_ritual' : s.is_ritual 'is_ritual': s.is_ritual
}, { }, {
method: 'update', 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});
}
})
.tap(spell => {
if (s.variables) {
let variables = spell.related('variable');
return spell.variables().detach(variables, { transacting: t});
}
})
.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 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);
reject({
"message": "Un attributs du sortilège a provoqué une erreur d'insertion.",
"code": 500,
}) })
// 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 });
}
})
.tap(spell => {
if (s.variables) {
let variables = spell.related('variable');
return spell.variables().detach(variables, { transacting: t });
}
})
.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);
reject({
"message": "Un attributs du sortilège a provoqué une erreur d'insertion.",
"code": 500,
})
})
}) })
}) .then(v => {
.then(v => { return v.load(['schools.meta_schools', 'variables', 'ingredients', 'author']);
return v.load([ 'schools.meta_schools', 'variables', 'ingredients', 'author' ]); })
}) .then(v => {
.then(v => { resolve(this.getOne(v.id));
resolve(this.getOne(v.id)); })
.catch(err => {
console.log(err);
reject({
"message": "Une erreur de chargement est survenue.",
"code": 500,
});
})
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
reject({ reject({
"message": "Une erreur de chargement est survenue.", "message": "Le sortilège en question n'a pas été trouvé.",
"code": 500, "code": 404,
}); });
}) })
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.where({ 'id': id })
.fetch({ require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
.then(v => {
v.schools().detach();
v.variables().detach();
v.ingredients().detach();
v.destroy();
})
.then(() => {
resolve({
"message": `Le sortilège #${id} a été supprimé avec succès.`,
"code": 200,
});
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
@@ -289,34 +317,6 @@ class SpellRepository {
"code": 404, "code": 404,
}); });
}) })
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.where({ 'id' : id })
.fetch({require: true, withRelated: [ 'schools.meta_schools', 'variables', 'ingredients', 'author' ]})
.then(v => {
v.schools().detach();
v.variables().detach();
v.ingredients().detach();
v.destroy();
})
.then(() => {
resolve({
"message": `Le sortilège #${id} a été supprimé avec succès.`,
"code": 200,
});
})
.catch(err => {
console.log(err);
reject({
"message": "Le sortilège en question n'a pas été trouvé.",
"code": 404,
});
})
}) })
} }
} }

View File

@@ -13,9 +13,9 @@ const mails = require('../smtp/mails');
// Model validation // Model validation
const Validator = require('jsonschema').Validator; const Validator = require('jsonschema').Validator;
const v = new Validator(); const validator = new Validator();
const UserValidation = require("../validations/UserValidation"); const UserValidation = require("../validations/UserValidation");
v.addSchema(UserValidation, "/UserValidation"); validator.addSchema(UserValidation, "/UserValidation");
// Validations // Validations
const isXSSAttempt = require('../functions').isXSSAttempt; const isXSSAttempt = require('../functions').isXSSAttempt;
@@ -35,17 +35,17 @@ class UserRepository {
getAll() { getAll() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.fetchAll({ withRelated: [ 'role.permissions' ] }) .fetchAll({ withRelated: ['role.permissions'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })); resolve(v.toJSON({ omitPivot: true }));
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Erreur de base de données, les utilisateurs n'ont pas pu être récupérés.", "message": "Erreur de base de données, les utilisateurs n'ont pas pu être récupérés.",
"code": 500, "code": 500,
}); });
}) })
}) })
} }
@@ -70,17 +70,17 @@ class UserRepository {
} }
new model() new model()
.where({ 'uuid' : uuid }) .where({ 'uuid': uuid })
.fetch({ withRelated: [ 'role.permissions' ] }) .fetch({ withRelated: ['role.permissions'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true, visibility: !full })); resolve(v.toJSON({ omitPivot: true, visibility: !full }));
}) })
.catch(() => { .catch(() => {
reject({ reject({
"message": "L'utilisateur avec cet UUID n'a pas été trouvé.", "message": "L'utilisateur avec cet UUID n'a pas été trouvé.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
@@ -105,17 +105,17 @@ class UserRepository {
} }
new model() new model()
.where({ 'mail': mail }) .where({ 'mail': mail })
.fetch({ withRelated: [ 'role' ] }) .fetch({ withRelated: ['role'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true, visibility: !full })); resolve(v.toJSON({ omitPivot: true, visibility: !full }));
}) })
.catch(() => { .catch(() => {
reject({ reject({
"message": "L'utilisateur avec cet email n'a pas été trouvé.", "message": "L'utilisateur avec cet email n'a pas été trouvé.",
"code": 404, "code": 404,
});
}); });
});
}) })
} }
@@ -137,17 +137,17 @@ class UserRepository {
} }
new model() new model()
.where({ 'uuid': uuid }) .where({ 'uuid': uuid })
.fetch({ withRelated: [ 'role', 'spells.schools.meta_schools', 'spells.variables', 'spells.ingredients' ] }) .fetch({ withRelated: ['role', 'spells.schools.meta_schools', 'spells.variables', 'spells.ingredients'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })); resolve(v.toJSON({ omitPivot: true }));
}) })
.catch(() => { .catch(() => {
reject({ reject({
"message": "Les sorts liés à cet utilisateur n'ont pas été trouvés.", "message": "Les sorts liés à cet utilisateur n'ont pas été trouvés.",
"code": 404, "code": 404,
});
}); });
});
}) })
} }
@@ -165,12 +165,12 @@ class UserRepository {
// Checks if body exists and if the model fits, and throws errors if it doesn't // Checks if body exists and if the model fits, and throws errors if it doesn't
if (isEmptyObject(u)) { if (isEmptyObject(u)) {
reject({ reject({
"message": "Le corps de requête ne peut être vide.", "message": "Le corps de requête ne peut être vide.",
"code": 403, "code": 403,
}) })
} else if (!v.validate(u, UserValidation).valid) { } else if (!validator.validate(u, UserValidation).valid) {
reject({ reject({
"message": "Structure de la requête invalide - " + v.validate(u, UserValidation).errors, "message": "Structure de la requête invalide - " + validator.validate(u, UserValidation).errors,
"code": 403, "code": 403,
}) })
} else if (isXSSAttempt(u.name) || isXSSAttempt(u.password) || isXSSAttempt(u.mail)) { } else if (isXSSAttempt(u.name) || isXSSAttempt(u.password) || isXSSAttempt(u.mail)) {
@@ -185,58 +185,58 @@ class UserRepository {
let verification_token = uuidv4(); let verification_token = uuidv4();
this.checkIfEmailAvailable(u.mail) this.checkIfEmailAvailable(u.mail)
.then(() => {
bookshelf.transaction(t => {
return new model({
'uuid': uuid,
'name': u.name,
'mail': u.mail,
'password': hash,
'verification_token': verification_token,
})
.save(null, {
transacting: t
})
.catch(err => {
console.log(err);
reject({
"message": "Un attribut de l'utilisateur a provoqué une erreur d'insertion.",
"code": 500,
});
})
})
.then(() => { .then(() => {
return this.getOneByUUID(uuid, false) bookshelf.transaction(t => {
}) return new model({
.then(newUser => { 'uuid': uuid,
'name': u.name,
'mail': u.mail,
'password': hash,
'verification_token': verification_token,
})
.save(null, {
transacting: t
})
.catch(err => {
console.log(err);
reject({
"message": "Un attribut de l'utilisateur a provoqué une erreur d'insertion.",
"code": 500,
});
})
})
.then(() => {
return this.getOneByUUID(uuid, false)
})
.then(newUser => {
// Send a mail to the new user's email with a link to verification url // Send a mail to the new user's email with a link to verification url
mails.sendRegistrationMail({ mails.sendRegistrationMail({
user: { user: {
name: newUser.name, name: newUser.name,
mail: newUser.mail, mail: newUser.mail,
token: verification_token, token: verification_token,
} }
}); });
// Then resolves the api call // Then resolves the api call
resolve({ resolve({
"message": `Compte utilisateur #${newUser.id} créé avec succès.`, "message": `Compte utilisateur #${newUser.id} créé avec succès.`,
"code": 201, "code": 201,
"user": newUser, "user": newUser,
}); });
})
.catch(err => {
console.log(err);
resolve({
"message": "Une erreur s'est produite en créant votre compte. Veuillez réessayer ultérieurement ou contactez l'administrateur.",
"code": 500,
})
})
}) })
.catch(err => { .catch(err => {
console.log(err); reject(err)
resolve({
"message": "Une erreur s'est produite en créant votre compte. Veuillez réessayer ultérieurement ou contactez l'administrateur.",
"code": 500,
})
}) })
})
.catch(err => {
reject(err)
})
} }
}) })
} }
@@ -252,31 +252,31 @@ class UserRepository {
verifyUser(token) { verifyUser(token) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'verification_token' : token }) .where({ 'verification_token': token })
.fetch() .fetch()
.then(v => { .then(v => {
bookshelf.transaction(t => { bookshelf.transaction(t => {
return v.save({ return v.save({
'verification_token': null, 'verification_token': null,
'verified': 1, 'verified': 1,
}, { }, {
method: 'update', method: 'update',
transacting: t transacting: t
})
})
.then(() => {
resolve({
"message": "Insérez ici une future redirection vers le client.",
"code": 202,
})
})
})
.catch(() => {
reject({
"message": "Le lien de vérification ne semble pas correct.",
"code": 404,
}) })
}) })
.then(() => {
resolve({
"message": "Insérez ici une future redirection vers le client.",
"code": 202,
})
})
})
.catch(() => {
reject({
"message": "Le lien de vérification ne semble pas correct.",
"code": 404,
})
})
}); });
} }
@@ -292,44 +292,44 @@ class UserRepository {
logUser(mail, password) { logUser(mail, password) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.getOneByEmail(mail, true) this.getOneByEmail(mail, true)
.then(async fetchedUser => { .then(async fetchedUser => {
let match = await bcrypt.compare(password, fetchedUser.password); let match = await bcrypt.compare(password, fetchedUser.password);
// Makes sure no hash gets out // Makes sure no hash gets out
delete fetchedUser.password; delete fetchedUser.password;
// If you found a user... // If you found a user...
if (match) { if (match) {
// If they're banned... // If they're banned...
if (fetchedUser.banned) { if (fetchedUser.banned) {
reject({ reject({
"message": `L'utilisateur #${fetchedUser.name} a été banni, la connexion est impossible.`, "message": `L'utilisateur #${fetchedUser.name} a été banni, la connexion est impossible.`,
"code": 403, "code": 403,
}); });
// If they're not verified... // If they're not verified...
} else if (!fetchedUser.verified) { } else if (!fetchedUser.verified) {
reject({ reject({
"message": `L'utilisateur #${fetchedUser.name} n'as pas été vérifié, le compte doit être activé avant la connexion.`, "message": `L'utilisateur #${fetchedUser.name} n'as pas été vérifié, le compte doit être activé avant la connexion.`,
"code": 401, "code": 401,
}); });
} else {
resolve({
"message": `L'utilisateur #${fetchedUser.name} s'est connecté.`,
"code": 200,
"user": fetchedUser,
});
}
} else { } else {
resolve({ reject({
"message": `L'utilisateur #${fetchedUser.name} s'est connecté.`, "message": "Les informations de connexions sont erronées.",
"code": 200, "code": 400,
"user": fetchedUser,
}); });
} }
} else { })
reject({ .catch(err => {
"message": "Les informations de connexions sont erronées.", reject(err);
"code": 400, })
});
}
})
.catch(err => {
reject(err);
})
}) })
} }
@@ -346,54 +346,139 @@ class UserRepository {
genAPIToken(mail, password) { genAPIToken(mail, password) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.logUser(mail, password) this.logUser(mail, password)
.then(v => { .then(v => {
let user = v.user; let user = v.user;
let new_token = uuidv4(); let new_token = uuidv4();
bookshelf.transaction(t => { bookshelf.transaction(t => {
return new token_model({ return new token_model({
'value': new_token, 'value': new_token,
'user_uuid': user.uuid, 'user_uuid': user.uuid,
}) })
.save(null, { .save(null, {
transacting: t transacting: t
}) })
.catch(err => { .catch(err => {
// If the account already has an API key linked... // If the account already has an API key linked...
if (err.errno == 1062) { if (err.errno == 1062) {
this.fetchAPIKey(user.uuid) this.fetchAPIKey(user.uuid)
.then(old_api_key => { .then(old_api_key => {
reject({ reject({
"message": "Votre compte a déjà généré une clé d'API.", "message": "Votre compte a déjà généré une clé d'API.",
"code": 409, "code": 409,
"API_key": old_api_key.value, "API_key": old_api_key.value,
}); });
});
// Default errors
} else {
throw err
}
}); });
// Default errors
} else {
throw err
}
});
})
.then(api_key => {
resolve({
"message": "La clé d'API a été généré.",
"code": 201,
"API_key": api_key,
}) })
.then(api_key => {
resolve({
"message": "La clé d'API a été généré.",
"code": 201,
"API_key": api_key,
})
})
.catch(err => {
console.log(err);
reject({
"message": "La génération de jeton d'API n'a pas pu être conclue.",
"code": 500,
});
})
}) })
.catch(err => { .catch(err => {
console.log(err); reject(err);
reject({ })
"message": "La génération de jeton d'API n'a pas pu être conclue.", })
"code": 500, }
checkAPITokenPerms(token, permissions) {
return new Promise(async (resolve, reject) => {
// If the request doesn't have a token, reject it.
if (!token) {
reject({
"message": "Vous devez utiliser un jeton d'API dans l'en-tête de votre requête.",
"code": 401,
})
}
// Fetches user from token
new token_model()
.where({ 'value': token })
.fetch({ withRelated: 'user.role.permissions' })
// Catches not found errors
.catch(err => {
if (err instanceof token_model.NotFoundError) {
reject({
"message": "Ce jeton n'est affilié à aucun compte.",
"code": 404,
});
} else {
reject({
"message": "Le jeton ou l'utilisateur n'a pas pu être récupéré.",
"code": 500,
});
}
})
.then(fullToken => {
token = fullToken.toJSON({ omitPivot: true });
// If the token is associated with a banned user...
if (token.user.banned) {
reject({
"message": "Le jeton est lié à un utilisateur banni, il n'est donc plus utilisable.",
"code": 401,
});
}
// If the token is associated with a non-verified user...
if (!token.user.verified) {
reject({
"message": "Le jeton est lié à un utilisateur non-vérifié, il n'est donc pas utilisable.",
"code": 401,
});
}
let user_permissions = token.user.role.permissions;
// Convert user_perm to array
user_permissions.forEach((user_perm, i) => {
user_permissions[i] = user_perm.slug;
});
// Loops to check if the person has all the permissions required...
permissions.forEach(perm => {
// If not, reject...
if (!user_permissions.includes(perm)) {
reject({
"message": "Permissions insuffisantes.",
"code": 401
})
}
});
// If everything went well, resolve the promise.
resolve({
"message": "Credentials accepted.",
"code": 200
}); });
}) })
})
.catch(err => { // Unhandled errors
reject(err); .catch(err => {
}) reject({
"message": "Une erreur inconnue est survenue.",
"code": 500,
});
});
}) })
} }
@@ -424,18 +509,18 @@ class UserRepository {
} }
this.getOneByEmail(mail, false) this.getOneByEmail(mail, false)
.then(() => { .then(() => {
reject({ reject({
"message": "Cet email est déjà lié à un compte.", "message": "Cet email est déjà lié à un compte.",
"code": 409, "code": 409,
})
})
.catch(() => {
resolve({
"message": "Cet email est disponible.",
"code": 200,
})
}) })
})
.catch(() => {
resolve({
"message": "Cet email est disponible.",
"code": 200,
})
})
}) })
} }
@@ -450,14 +535,14 @@ class UserRepository {
fetchAPIKey(uuid) { fetchAPIKey(uuid) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new token_model() new token_model()
.where({ 'user_uuid': uuid }) .where({ 'user_uuid': uuid })
.fetch() .fetch()
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })); resolve(v.toJSON({ omitPivot: true }));
}) })
.catch(err => { .catch(err => {
console.log(err); console.log(err);
}) })
}) })
} }

View File

@@ -5,9 +5,9 @@ const model = require('../models/variable-model')
// Model validation // Model validation
const Validator = require('jsonschema').Validator const Validator = require('jsonschema').Validator
const v = new Validator() const validator = new Validator()
const VariableValidation = require("../validations/VariableValidation") const VariableValidation = require("../validations/VariableValidation")
v.addSchema(VariableValidation, "/VariableValidation") validator.addSchema(VariableValidation, "/VariableValidation")
// Validations // Validations
const isXSSAttempt = require('../functions').isXSSAttempt const isXSSAttempt = require('../functions').isXSSAttempt
@@ -17,58 +17,58 @@ class VariableRepository {
constructor() { constructor() {
} }
getAll() { getAll() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.fetchAll({ withRelated: ['spells'] }) .fetchAll({ withRelated: ['spells'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Il n'existe aucune variable disponible.", "message": "Il n'existe aucune variable disponible.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getOne(id) { getOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['spells']}) .fetch({ withRelated: ['spells'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "La variable en question n'a pas pu être trouvée.", "message": "La variable en question n'a pas pu être trouvée.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
getSpellsFromOne(id) { getSpellsFromOne(id) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
new model() new model()
.where({ 'id' : id }) .where({ 'id': id })
.fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools']}) .fetch({ withRelated: ['spells', 'spells.schools', 'spells.variables', 'spells.ingredients', 'spells.schools.meta_schools'] })
.then(v => { .then(v => {
resolve(v.toJSON({ omitPivot: true })) resolve(v.toJSON({ omitPivot: true }))
}) })
.catch(err => { .catch(err => {
console.log(err) console.log(err)
reject({ reject({
"message": "Les sortilèges liés à cette variable n'ont pas pu être récupérés.", "message": "Les sortilèges liés à cette variable n'ont pas pu être récupérés.",
"code": 404, "code": 404,
}); });
}) })
}) })
} }
@@ -80,9 +80,9 @@ class VariableRepository {
"message": "Le corps de la requête ne peut pas être vide.", "message": "Le corps de la requête ne peut pas être vide.",
"code": 403, "code": 403,
}); });
} else if (!v.validate(vr, VariableValidation).valid) { } else if (!validator.validate(vr, VariableValidation).valid) {
reject({ reject({
"message": `Le modèle de variable n'est pas respecté : ${v.validate(s, VariableValidation).errors}`, "message": `Le modèle de variable n'est pas respecté : ${validator.validate(s, VariableValidation).errors}`,
"code": 403, "code": 403,
}); });
} else if (isXSSAttempt(vr.description)) { } else if (isXSSAttempt(vr.description)) {
@@ -97,61 +97,10 @@ class VariableRepository {
}).save(null, { }).save(null, {
transacting: t 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({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
});
})
}
})
}
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({
"message": "Le corps de la requête ne peut pas être vide.",
"code": 403,
});
} else if (!v.validate(vr, VariableValidation).valid) {
reject({
"message": `Le modèle de variable n'est pas respecté : ${v.validate(s, VariableValidation).errors}`,
"code": 403,
});
} else if (isXSSAttempt(vr.description)) {
reject({
"message": "Tentative d'injection XSS détectée, requête refusée.",
"code": 403,
});
} else {
new model({id: id})
.fetch({require: true, withRelated: ['spells']})
.then(v => {
bookshelf.transaction(t => {
return v.save({
'description': vr.description,
}, {
method: 'update',
transacting: t
})
.catch(err => { .catch(err => {
console.log(err)
throw err throw err
}) })
}) })
.then(v => { .then(v => {
return v.load(['spells']) return v.load(['spells'])
}) })
@@ -165,6 +114,82 @@ class VariableRepository {
"code": 500, "code": 500,
}); });
}) })
}
})
}
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({
"message": "Le corps de la requête ne peut pas être vide.",
"code": 403,
});
} else if (!validator.validate(vr, VariableValidation).valid) {
reject({
"message": `Le modèle de variable n'est pas respecté : ${validator.validate(s, VariableValidation).errors}`,
"code": 403,
});
} else if (isXSSAttempt(vr.description)) {
reject({
"message": "Tentative d'injection XSS détectée, requête refusée.",
"code": 403,
});
} else {
new model({ 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({
"message": "Une erreur d'insertion s'est produite.",
"code": 500,
});
})
})
.catch(err => {
console.log(err)
reject({
"message": "La variable en question n'a pas été trouvée.",
"code": 404,
});
})
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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 => { .catch(err => {
console.log(err) console.log(err)
@@ -173,31 +198,6 @@ class VariableRepository {
"code": 404, "code": 404,
}); });
}) })
}
})
}
deleteOne(id) {
return new Promise((resolve, reject) => {
new model()
.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({
"message": "La variable en question n'a pas été trouvée.",
"code": 404,
});
})
}) })
} }
} }

View File

@@ -1,5 +1,4 @@
'use strict' 'use strict'
// Router // Router
const express = require('express'); const express = require('express');
let router = express.Router(); let router = express.Router();
@@ -9,45 +8,22 @@ const UserRepository = require('../repositories/user-repository');
const Users = new UserRepository(); const Users = new UserRepository();
// ROUTES // ROUTES
// ENTRY POINT
const authUser = (mail, password) => {
return Users.logUserToAPI(mail, password)
.catch(err => {
throw err
})
}
router.get('/login', async (req, res) => {
authUser(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
})
)
})
})
// GEN API TOKEN // GEN API TOKEN
const generateAPIToken = (mail, password) => { const generateAPIToken = (mail, password) => {
return Users.genAPIToken(mail, password) return Users.genAPIToken(mail, password)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.get('/genToken', async (req, res) => { router.get('/genToken', async (req, res) => {
generateAPIToken(req.body.mail, req.body.password) generateAPIToken(req.body.mail, req.body.password)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify(err)) res.status(err.code).send(JSON.stringify(err))
}) })
}) })
module.exports = router module.exports = router;

View File

@@ -1,12 +1,11 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection // Connection
const connection = require('../database/bookshelf') const functions = require('../functions');
const functions = require('../functions')
// Repository // Repository
const IngredientRepository = require('../repositories/ingredient-repository'); const IngredientRepository = require('../repositories/ingredient-repository');
@@ -16,150 +15,150 @@ const Ingredients = new IngredientRepository();
// GET ALL ------------------ // GET ALL ------------------
const getIngredients = () => { const getIngredients = () => {
return Ingredients.getAll() return Ingredients.getAll()
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
getIngredients() getIngredients()
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET ONE ------------------ // GET ONE ------------------
const getIngredient = (id) => { const getIngredient = (id) => {
return Ingredients.getOne(id) return Ingredients.getOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/', async (req, res) => { router.get('/:id/', async (req, res) => {
getIngredient(req.params.id) getIngredient(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET SPELLS FROM ONE ------------------ // GET SPELLS FROM ONE ------------------
const getSpellsFromOne = (id) => { const getSpellsFromOne = (id) => {
return Ingredients.getSpellsFromOne(id) return Ingredients.getSpellsFromOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/spells', async (req, res) => { router.get('/:id/spells', async (req, res) => {
getSpellsFromOne(req.params.id) getSpellsFromOne(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// CREATE ONE ------------------ // CREATE ONE ------------------
const addIngredient = (igr) => { const addIngredient = (igr) => {
return Ingredients.addOne(igr) return Ingredients.addOne(igr)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
addIngredient(req.body) addIngredient(req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// UPDATE ONE ------------------ // UPDATE ONE ------------------
const updateIngredient = (id, igr) => { const updateIngredient = (id, igr) => {
return Ingredients.updateOne(id, igr) return Ingredients.updateOne(id, igr)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.put('/:id/', async (req, res) => { router.put('/:id/', async (req, res) => {
updateIngredient(req.params.id, req.body) updateIngredient(req.params.id, req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// DELETE ONE ------------------ // DELETE ONE ------------------
const deleteIngredient = (id) => { const deleteIngredient = (id) => {
return Ingredients.deleteOne(id) return Ingredients.deleteOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.delete('/:id/', async (req, res) => { router.delete('/:id/', async (req, res) => {
deleteIngredient(req.params.id) deleteIngredient(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// Param validations // Param validations

View File

@@ -1,12 +1,11 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection // Connection
const connection = require('../database/bookshelf') const functions = require('../functions');
const functions = require('../functions')
// Repository // Repository
const MetaSchoolRepository = require('../repositories/meta-school-repository'); const MetaSchoolRepository = require('../repositories/meta-school-repository');
@@ -16,50 +15,50 @@ const MetaSchools = new MetaSchoolRepository();
// GET ALL ------------------ // GET ALL ------------------
const getMetaSchools = () => { const getMetaSchools = () => {
return MetaSchools.getAll() return MetaSchools.getAll()
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
getMetaSchools() getMetaSchools()
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET ONE ------------------ // GET ONE ------------------
const getMetaSchool = (id) => { const getMetaSchool = (id) => {
return MetaSchools.getOne(id) return MetaSchools.getOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/', async (req, res) => { router.get('/:id/', async (req, res) => {
getMetaSchool(req.params.id) getMetaSchool(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// Param validations // Param validations

View File

@@ -0,0 +1,23 @@
// Repository
const UserRepository = require('../../repositories/user-repository');
const Users = new UserRepository();
// AUTHGUARD
const authGuard = (permissions) => {
return async (req, res, next) => {
// Get token from headers
let api_token = req.headers['auracle_key'];
// Uses repo to validate the associated perms with the token
Users.checkAPITokenPerms(api_token, permissions)
.then(v => {
next();
})
.catch(err => {
res.status(err.code).send(JSON.stringify(err))
});
}
}
module.exports = authGuard;

View File

@@ -1,12 +1,11 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection // Connection
const connection = require('../database/bookshelf') const functions = require('../functions');
const functions = require('../functions')
// Repository // Repository
const SchoolRepository = require('../repositories/school-repository'); const SchoolRepository = require('../repositories/school-repository');
@@ -16,149 +15,149 @@ const Schools = new SchoolRepository();
// GET ALL ------------------ // GET ALL ------------------
const getSchools = () => { const getSchools = () => {
return Schools.getAll() return Schools.getAll()
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
getSchools() getSchools()
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET ONE ------------------ // GET ONE ------------------
const getSchool = (id) => { const getSchool = (id) => {
return Schools.getOne(id) return Schools.getOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/', async (req, res) => { router.get('/:id/', async (req, res) => {
getSchool(req.params.id) getSchool(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET SPELLS FROM ONE ------------------ // GET SPELLS FROM ONE ------------------
const getSpellsFromOne = (id) => { const getSpellsFromOne = (id) => {
return Schools.getSpellsFromOne(id) return Schools.getSpellsFromOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/spells', async (req, res) => { router.get('/:id/spells', async (req, res) => {
getSpellsFromOne(req.params.id) getSpellsFromOne(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// CREATE ONE ------------------ // CREATE ONE ------------------
const addSchool = (s) => { const addSchool = (s) => {
return Schools.addOne(s) return Schools.addOne(s)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
addSchool(req.body) addSchool(req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// UPDATE ONE ------------------ // UPDATE ONE ------------------
const updateSchool = (id, s) => { const updateSchool = (id, s) => {
return Schools.updateOne(id, s) return Schools.updateOne(id, s)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.put('/:id/', async (req, res) => { router.put('/:id/', async (req, res) => {
updateSchool(req.params.id, req.body) updateSchool(req.params.id, req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// DELETE ONE ------------------ // DELETE ONE ------------------
const deleteSchool = (id) => { const deleteSchool = (id) => {
return Schools.deleteOne(id) return Schools.deleteOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.delete('/:id/', async (req, res) => { router.delete('/:id/', async (req, res) => {
deleteSchool(req.params.id) deleteSchool(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// Param validations // Param validations

View File

@@ -1,12 +1,14 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection // Connection
const connection = require('../database/bookshelf') const functions = require('../functions');
const functions = require('../functions')
// AuthGuard
const authGuard = require('./middleware/authGuard');
// Repository // Repository
const SpellReposity = require('../repositories/spell-repository'); const SpellReposity = require('../repositories/spell-repository');
@@ -16,173 +18,191 @@ const Spells = new SpellReposity();
// GET ALL PUBLIC ------------------ // GET ALL PUBLIC ------------------
const getPublicSpells = (name, description, level, charge, cost, ritual) => { const getPublicSpells = (name, description, level, charge, cost, ritual) => {
return Spells.getAllPublic(name, description, level, charge, cost, ritual) return Spells.getAllPublic(name, description, level, charge, cost, ritual)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('//:name?/:description?/:level?/:charge?/:cost?/:ritual?/', async (req, res) => { router.get(
getPublicSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual) '//:name?/:description?/:level?/:charge?/:cost?/:ritual?/',
.then(v => { async (req, res) => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') getPublicSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual)
res.end(JSON.stringify(v)) .then(v => {
}) res.setHeader('Content-Type', 'application/json;charset=utf-8')
.catch(err => { res.end(JSON.stringify(v))
res.status(err.code).send(JSON.stringify( })
{ .catch(err => {
"error": err.message, res.status(err.code).send(JSON.stringify(
"code": err.code {
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// GET ALL ------------------ // GET ALL ------------------
const getSpells = (name, description, level, charge, cost, ritual) => { const getSpells = (name, description, level, charge, cost, ritual) => {
return Spells.getAll(name, description, level, charge, cost, ritual) return Spells.getAll(name, description, level, charge, cost, ritual)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/private/:name?/:description?/:level?/:charge?/:cost?/:ritual?/', async (req, res) => { router.get(
getSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual) '/private/:name?/:description?/:level?/:charge?/:cost?/:ritual?/',
.then(v => { authGuard(['SECRET_SPELLS']),
res.setHeader('Content-Type', 'application/json;charset=utf-8') async (req, res) => {
res.end(JSON.stringify(v)) getSpells(req.query.name, req.query.description, req.query.level, req.query.charge, req.query.cost, req.query.ritual)
}) .then(v => {
.catch(err => { res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.status(err.code).send(JSON.stringify( res.end(JSON.stringify(v))
{ })
"error": err.message, .catch(err => {
"code": err.code res.status(err.code).send(JSON.stringify(
{
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// GET SOME ------------------ // GET SOME ------------------
const getSomeSpells = (page) => { const getSomeSpells = (page) => {
return Spells.getPage(page) return Spells.getPage(page)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/page/:page', async (req, res) => { router.get(
getSomeSpells(req.params.page) '/page/:page',
.then(v => { async (req, res) => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') getSomeSpells(req.params.page)
res.end(JSON.stringify(v)) .then(v => {
}) res.setHeader('Content-Type', 'application/json;charset=utf-8')
.catch(err => { res.end(JSON.stringify(v))
res.status(err.code).send(JSON.stringify( })
{ .catch(err => {
"error": err.message, res.status(err.code).send(JSON.stringify(
"code": err.code {
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// GET ONE ------------------ // GET ONE ------------------
const getSpell = (id) => { const getSpell = (id) => {
return Spells.getOne(id) return Spells.getOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/', async (req, res) => { router.get(
getSpell(req.params.id) '/:id/',
.then(v => { async (req, res) => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') getSpell(req.params.id)
res.end(JSON.stringify(v)) .then(v => {
}) res.setHeader('Content-Type', 'application/json;charset=utf-8')
.catch(err => { res.end(JSON.stringify(v))
res.status(err.code).send(JSON.stringify( })
{ .catch(err => {
"error": err.message, res.status(err.code).send(JSON.stringify(
"code": err.code {
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// CREATE ONE ------------------ // CREATE ONE ------------------
const addSpell = (s) => { const addSpell = (s) => {
return Spells.addOne(s) return Spells.addOne(s)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.post('/', async (req, res) => { router.post(
addSpell(req.body) '/',
.then(v => { authGuard(['SUBMIT_SPELLS']),
res.setHeader('Content-Type', 'application/json;charset=utf-8') async (req, res) => {
res.send(JSON.stringify(v)) addSpell(req.body)
}) .then(v => {
.catch(err => { res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.status(err.code).send(JSON.stringify( res.send(JSON.stringify(v))
{ })
"error": err.message, .catch(err => {
"code": err.code res.status(err.code).send(JSON.stringify(
{
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// UPDATE ONE ------------------ // UPDATE ONE ------------------
const updateSpell = (id, s) => { const updateSpell = (id, s) => {
return Spells.updateOne(id, s) return Spells.updateOne(id, s)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.put('/:id/', async (req, res) => { router.put(
updateSpell(req.params.id, req.body) '/:id/',
.then(v => { authGuard(['SUBMIT_SPELLS', 'MODIFY_SPELLS']),
res.setHeader('Content-Type', 'application/json;charset=utf-8') async (req, res) => {
res.send(JSON.stringify(v)) updateSpell(req.params.id, req.body)
}) .then(v => {
.catch(err => { res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.status(err.code).send(JSON.stringify( res.send(JSON.stringify(v))
{ })
"error": err.message, .catch(err => {
"code": err.code res.status(err.code).send(JSON.stringify(
{
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// DELETE ONE ------------------ // DELETE ONE ------------------
const deleteSpell = (id) => { const deleteSpell = (id) => {
return Spells.deleteOne(id) return Spells.deleteOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.delete('/:id/', async (req, res) => { router.delete(
deleteSpell(req.params.id) '/:id/',
.then(v => { authGuard(['SUBMIT_SPELLS', 'MODIFY_SPELLS', 'DELETE_SPELLS']),
res.setHeader('Content-Type', 'application/json;charset=utf-8') async (req, res) => {
res.send(JSON.stringify(v)) deleteSpell(req.params.id)
}) .then(v => {
.catch(err => { res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.status(err.code).send(JSON.stringify( res.send(JSON.stringify(v))
{ })
"error": err.message, .catch(err => {
"code": err.code res.status(err.code).send(JSON.stringify(
{
"error": err.message,
"code": err.code
})
)
}) })
)
}) })
})
// Param validations // Param validations
router.param('id', functions.paramIntCheck) router.param('id', functions.paramIntCheck)

View File

@@ -1,12 +1,8 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection
const connection = require('../database/bookshelf')
const db = connection.db
// Repository // Repository
const UserRepository = require('../repositories/user-repository'); const UserRepository = require('../repositories/user-repository');
@@ -16,166 +12,166 @@ const Users = new UserRepository();
// GET ALL ------------------ // GET ALL ------------------
const getUsers = () => { const getUsers = () => {
return Users.getAll() return Users.getAll()
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
getUsers() getUsers()
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET ONE FROM UUID ------------------ // GET ONE FROM UUID ------------------
const getUserByUUID = (uuid) => { const getUserByUUID = (uuid) => {
return Users.getOneByUUID(uuid) return Users.getOneByUUID(uuid)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.get('/:uuid/', async (req, res) => { router.get('/:uuid/', async (req, res) => {
getUserByUUID(req.params.uuid) getUserByUUID(req.params.uuid)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET SPELLS FROM ONE ------------------ // GET SPELLS FROM ONE ------------------
const getSpellsFromUser = (uuid) => { const getSpellsFromUser = (uuid) => {
return Users.getSpellsFromOne(uuid) return Users.getSpellsFromOne(uuid)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.get('/:uuid/spells', async (req, res) => { router.get('/:uuid/spells', async (req, res) => {
getSpellsFromUser(req.params.uuid) getSpellsFromUser(req.params.uuid)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// CHECK IF MAIL IS AVAILABLE ------------------ // CHECK IF MAIL IS AVAILABLE ------------------
const checkIfEmailAvailable = (mail) => { const checkIfEmailAvailable = (mail) => {
return Users.checkIfEmailAvailable(mail) return Users.checkIfEmailAvailable(mail)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.get('/available/:mail/', async (req, res) => { router.get('/available/:mail/', async (req, res) => {
checkIfEmailAvailable(req.params.mail) checkIfEmailAvailable(req.params.mail)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// CREATE ONE ------------------ // CREATE ONE ------------------
const addUser = (u) => { const addUser = (u) => {
return Users.addOne(u) return Users.addOne(u)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
addUser(req.body) addUser(req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// VERIFY A USER // VERIFY A USER
const verifyUser = (token) => { const verifyUser = (token) => {
return Users.verifyUser(token) return Users.verifyUser(token)
.catch(err => { .catch(err => {
throw err; throw err;
}) })
} }
router.get('/verification/:token', async (req, res) => { router.get('/verification/:token', async (req, res) => {
verifyUser(req.params.token) verifyUser(req.params.token)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}); });
// LOG A USER ------------------ // LOG A USER ------------------
const logUser = (mail, password) => { const logUser = (mail, password) => {
return Users.logUser(mail, password) return Users.logUser(mail, password)
.catch(err => { .catch(err => {
throw err throw err
}) })
} }
router.post('/login', async (req, res) => { router.post('/login', async (req, res) => {
logUser(req.body.mail, req.body.password) logUser(req.body.mail, req.body.password)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
module.exports = router module.exports = router

View File

@@ -1,12 +1,11 @@
'use strict' 'use strict'
// Router // Router
const express = require('express') const express = require('express');
let router = express.Router() let router = express.Router();
// Connection // Connection
const connection = require('../database/bookshelf') const functions = require('../functions');
const functions = require('../functions')
// Repository // Repository
const VariableRepository = require('../repositories/variable-repository'); const VariableRepository = require('../repositories/variable-repository');
@@ -16,150 +15,150 @@ const Variables = new VariableRepository();
// GET ALL ------------------ // GET ALL ------------------
const getvariables = () => { const getvariables = () => {
return Variables.getAll() return Variables.getAll()
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/', async (req, res) => { router.get('/', async (req, res) => {
getvariables() getvariables()
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET ONE ------------------ // GET ONE ------------------
const getVariable = (id) => { const getVariable = (id) => {
return Variables.getOne(id) return Variables.getOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/', async (req, res) => { router.get('/:id/', async (req, res) => {
getVariable(req.params.id) getVariable(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// GET SPELLS FROM ONE ------------------ // GET SPELLS FROM ONE ------------------
const getSpellsFromOne = (id) => { const getSpellsFromOne = (id) => {
return Variables.getSpellsFromOne(id) return Variables.getSpellsFromOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.get('/:id/spells', async (req, res) => { router.get('/:id/spells', async (req, res) => {
getSpellsFromOne(req.params.id) getSpellsFromOne(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.end(JSON.stringify(v)) res.end(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// CREATE ONE ------------------ // CREATE ONE ------------------
const addVariable = (vr) => { const addVariable = (vr) => {
return Variables.addOne(vr) return Variables.addOne(vr)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.post('/', async (req, res) => { router.post('/', async (req, res) => {
addVariable(req.body) addVariable(req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// UPDATE ONE ------------------ // UPDATE ONE ------------------
const updateVariable = (id, vr) => { const updateVariable = (id, vr) => {
return Variables.updateOne(id, vr) return Variables.updateOne(id, vr)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.put('/:id/', async (req, res) => { router.put('/:id/', async (req, res) => {
updateVariable(req.params.id, req.body) updateVariable(req.params.id, req.body)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// DELETE ONE ------------------ // DELETE ONE ------------------
const deleteVariable = (id) => { const deleteVariable = (id) => {
return Variables.deleteOne(id) return Variables.deleteOne(id)
.catch(err => { .catch(err => {
console.log(err) console.log(err)
throw err throw err
}) })
} }
router.delete('/:id/', async (req, res) => { router.delete('/:id/', async (req, res) => {
deleteVariable(req.params.id) deleteVariable(req.params.id)
.then(v => { .then(v => {
res.setHeader('Content-Type', 'application/json;charset=utf-8') res.setHeader('Content-Type', 'application/json;charset=utf-8')
res.send(JSON.stringify(v)) res.send(JSON.stringify(v))
}) })
.catch(err => { .catch(err => {
res.status(err.code).send(JSON.stringify( res.status(err.code).send(JSON.stringify(
{ {
"error": err.message, "error": err.message,
"code": err.code "code": err.code
}) })
) )
}) })
}) })
// Param validations // Param validations

View File

@@ -1,12 +1,12 @@
const nodemailer = require('nodemailer'); const nodemailer = require('nodemailer');
const transport = nodemailer.createTransport({ const transport = nodemailer.createTransport({
host: "smtp.mailtrap.io", host: "smtp.mailtrap.io",
port: 2525, port: 2525,
auth: { auth: {
user: process.env.SMTP_USER, user: process.env.SMTP_USER,
pass: process.env.SMTP_PASS, pass: process.env.SMTP_PASS,
} }
}); });
module.exports = { module.exports = {

View File

@@ -8,13 +8,13 @@ const sender = 'tymos@auracle.io';
// Fetches a HTML template file for parsing // Fetches a HTML template file for parsing
const getTemplateFile = (path) => { const getTemplateFile = (path) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
fs.readFile(path, {encoding: 'utf-8'}, (err, html) => { fs.readFile(path, { encoding: 'utf-8' }, (err, html) => {
if (err) { if (err) {
reject(err); reject(err);
} else { } else {
resolve(html); resolve(html);
} }
}) })
}) })
}; };
@@ -28,34 +28,34 @@ const getTemplateFile = (path) => {
*/ */
const sendRegistrationMail = (data) => { const sendRegistrationMail = (data) => {
getTemplateFile(__dirname + '/templates/template-sign-up.html') getTemplateFile(__dirname + '/templates/template-sign-up.html')
.then(html => { .then(html => {
let template = handlebars.compile(html); let template = handlebars.compile(html);
let template_parsed = template(data); let template_parsed = template(data);
let message = { let message = {
from: sender, from: sender,
to: data.user.mail, to: data.user.mail,
subject: 'Inscription Auracle.io', subject: 'Inscription Auracle.io',
html: template_parsed, html: template_parsed,
}; };
smtp.transport.sendMail(message, (err, info) => { smtp.transport.sendMail(message, (err, info) => {
if (err) { if (err) {
throw err; throw err;
} else { } else {
console.log(info); console.log(info);
} }
});
})
.catch(err => {
console.log(err);
}); });
})
.catch(err => {
console.log(err);
});
} }
const sendBanEmail = (date) => { const sendBanEmail = (date) => {
return null; return null;
} }
module.exports = { module.exports = {
sendRegistrationMail, sendRegistrationMail,
} }

View File

@@ -1,100 +1,114 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head>
<head>
<title>Template Email Auracle Inscription</title> <title>Template Email Auracle Inscription</title>
<style> <style>
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Playfair+Display:wght@700;800;900&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Playfair+Display:wght@700;800;900&display=swap');
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
box-sizing: border-box; box-sizing: border-box;
} }
:root { :root {
--black: 52, 58, 64; --black: 52, 58, 64;
--white: #FFF; --white: #FFF;
--primary: 89, 158, 244; --primary: 89, 158, 244;
} }
body { body {
color: rgb(var(--black)); color: rgb(var(--black));
font-family: 'Lato', sans-serif; font-family: 'Lato', sans-serif;
max-width: 100%; max-width: 100%;
} }
.display { .display {
font-family: 'Playfair Display', serif; font-family: 'Playfair Display', serif;
} }
h1 { h1 {
font-size: 32px; font-size: 32px;
} }
p:not(:last-child) { p:not(:last-child) {
margin-bottom: 15px; margin-bottom: 15px;
} }
.italics { .italics {
font-style: italic; font-style: italic;
} }
.wrapper { .wrapper {
position: relative; position: relative;
padding: 10vh 5vw; padding: 10vh 5vw;
background: url('https://i.imgur.com/IxEKKEY.png') center center fixed repeat; background: url('https://i.imgur.com/IxEKKEY.png') center center fixed repeat;
} }
.wrapper:before {
display: block;
content: '';
position: absolute;
top: 0;
height: 120px;
left: 0;
right: 0;
background-color: rgb(var(--primary));
z-index: 0;
}
.container { .wrapper:before {
position: relative; display: block;
background-color: var(--white); content: '';
z-index: 5; position: absolute;
} top: 0;
height: 120px;
left: 0;
right: 0;
background-color: rgb(var(--primary));
z-index: 0;
}
header, footer { .container {
text-align: center; position: relative;
color: var(--white); background-color: var(--white);
background-color: rgb(var(--black)); z-index: 5;
} }
header { header,
padding: 15px; footer {
} text-align: center;
color: var(--white);
background-color: rgb(var(--black));
}
main { header {
padding: 30px; padding: 15px;
} }
main {
padding: 30px;
}
</style> </style>
</head> </head>
<body> <body>
<div class="wrapper"> <div class="wrapper">
<div class="container"> <div class="container">
<header> <header>
<h1 class="display">Bienvenue sur Auracle, {{ user.name }}!</h1> <h1 class="display">Bienvenue sur Auracle, {{ user.name }}!</h1>
</header> </header>
<main> <main>
<p>Votre compte Auracle a bien été enregistré et est rattaché à cette adresse mail.</p> <p>Votre compte Auracle a bien été enregistré et est rattaché à cette adresse mail.</p>
<p>Cependant, afin de garantir la sécurité de vos données, votre compte doit être vérifié avant votre première connexion. Vous pouvez <a href="http://localhost:2814/api/users/verification/{{ user.token }}">suivre ce lien afin de confirmer votre inscription.</a></p> <p>Cependant, afin de garantir la sécurité de vos données, votre compte doit être vérifié avant votre
<p>Si vous rencontrez des problèmes, n'hésitez pas à envoyer un mail à <a href="mailto:support@auracle.io">support@auracle.io</a></p> première connexion. Vous pouvez
<p><strong>Merci de votre soutien !</strong></p> <a href="http: //localhost:2814/api/v1/users/verification/{{ user.token }}">
<p class="italics">Bien sincèrement, Izàc Tymos.</p> suivre ce lien afin de confirmer votre inscription.
</main> </a>
<footer> </p>
<div class="icon"> <p>Si vous rencontrez des problèmes, n'hésitez pas à envoyer un mail à
<a href="mailto:support@auracle.io">
support@auracle.io
</a>
</p>
<p><strong>Merci de votre soutien !</strong></p>
<p class="italics">Bien sincèrement, Izàc Tymos.</p>
</main>
<footer>
<div class="icon">
</div>
</footer>
</div> </div>
</footer>
</div> </div>
</div>
</body> </body>
</html> </html>