Compare commits
69 Commits
releases/v
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
da6cd44987 | ||
|
|
4b25f63531 | ||
|
|
b318a88023 | ||
|
|
615cced6ed | ||
|
|
b5e6f73d01 | ||
|
|
efb9195053 | ||
|
|
e2061d6595 | ||
|
|
e8ca2416b7 | ||
|
|
410a58fc09 | ||
|
|
413d458a80 | ||
|
|
bb721e6ab4 | ||
|
|
39ee29c65a | ||
|
|
b7cc851cd6 | ||
|
|
d3c5e0a20c | ||
|
|
7170eb0dee | ||
|
|
50ba8b7f9c | ||
|
|
e9640ec2d2 | ||
|
|
2b3b890228 | ||
|
|
16b7b81166 | ||
|
|
5cf2c1daa7 | ||
|
|
2959d777b7 | ||
|
|
b313393af6 | ||
|
|
1759f71876 | ||
|
|
dde2e63b61 | ||
|
|
41575f40db | ||
|
|
70283da8e0 | ||
|
|
0a77206bcb | ||
|
|
28c869070a | ||
|
|
3bdf43d11b | ||
|
|
0fd0253fb4 | ||
|
|
23ab785163 | ||
|
|
f7a09c02ae | ||
|
|
5f7e5499f7 | ||
|
|
3c2326ef92 | ||
|
|
752cfb4227 | ||
|
|
1b11db4890 | ||
|
|
32c17407e2 | ||
|
|
da73fa5241 | ||
|
|
d64e447b67 | ||
|
|
dba451c588 | ||
|
|
39521f063a | ||
|
|
1ea21df4d9 | ||
|
|
10fdbade66 | ||
|
|
bdfdb1d21e | ||
|
|
dba0521ad9 | ||
|
|
c9bd0aa0ab | ||
|
|
15ba9e19c9 | ||
|
|
d311042b51 | ||
|
|
3cf131ef6f | ||
|
|
1ac0968e57 | ||
|
|
36a82a643e | ||
|
|
79c34a6ad1 | ||
|
|
167722fab6 | ||
|
|
a95a617e8b | ||
|
|
b8e12c1665 | ||
|
|
7b932f1b86 | ||
|
|
d69ea0fa72 | ||
|
|
02c0216c26 | ||
|
|
ad84673fba | ||
|
|
1e334b8c05 | ||
|
|
01df57f510 | ||
|
|
772b225072 | ||
|
|
65abb41a9f | ||
|
|
fdad47e84e | ||
|
|
20f946a945 | ||
|
|
eba2669176 | ||
|
|
fa945e45c9 | ||
|
|
0587656ba6 | ||
|
|
de90b7d747 |
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
node_modules
|
node_modules
|
||||||
/dist
|
dist
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env.local
|
.env.local
|
||||||
@@ -21,4 +21,8 @@ yarn-error.log*
|
|||||||
*.sw?
|
*.sw?
|
||||||
|
|
||||||
# creds
|
# creds
|
||||||
.env
|
.env
|
||||||
|
|
||||||
|
# db files
|
||||||
|
*.csv
|
||||||
|
*.ods
|
||||||
@@ -4,83 +4,104 @@ USE auracle;
|
|||||||
|
|
||||||
/* =========== PRIMARY TABLES =========== */
|
/* =========== PRIMARY TABLES =========== */
|
||||||
|
|
||||||
/* PERMISSIONS */
|
-- ROLES
|
||||||
CREATE TABLE IF NOT EXISTS `role` (
|
CREATE TABLE IF NOT EXISTS `role` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL,
|
`name` VARCHAR(255) NOT NULL,
|
||||||
`description` VARCHAR(255) NOT NULL,
|
`description` VARCHAR(255) NOT NULL,
|
||||||
PRIMARY KEY(`id`)
|
PRIMARY KEY(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* USERS */
|
-- PERMISSIONS
|
||||||
|
CREATE TABLE IF NOT EXISTS `permission` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
|
`slug` VARCHAR(255) NOT NULL,
|
||||||
|
PRIMARY KEY(`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- USERS
|
||||||
CREATE TABLE IF NOT EXISTS `user` (
|
CREATE TABLE IF NOT EXISTS `user` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`uuid` VARCHAR(36) NOT NULL,
|
`uuid` VARCHAR(36) NOT NULL UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL DEFAULT "Disciple",
|
`name` VARCHAR(255) NOT NULL DEFAULT "Disciple",
|
||||||
`mail` VARCHAR(255) NOT NULL,
|
`mail` VARCHAR(255) NOT NULL,
|
||||||
`avatar` VARCHAR(255),
|
`avatar` VARCHAR(255),
|
||||||
`gender` VARCHAR(255),
|
`gender` VARCHAR(255),
|
||||||
|
`register_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`password` VARCHAR(255) NOT NULL,
|
`password` VARCHAR(255) NOT NULL,
|
||||||
`role_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
`role_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
||||||
`verified` BOOLEAN DEFAULT false,
|
`verified` BOOLEAN DEFAULT false,
|
||||||
|
`verification_token` VARCHAR(255),
|
||||||
`banned` BOOLEAN DEFAULT false,
|
`banned` BOOLEAN DEFAULT false,
|
||||||
PRIMARY KEY(`id`),
|
PRIMARY KEY(`id`),
|
||||||
FOREIGN KEY(`role_id`) REFERENCES role(`id`)
|
FOREIGN KEY(`role_id`) REFERENCES role(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* SPELLS */
|
-- API_TOKENS
|
||||||
|
CREATE TABLE IF NOT EXISTS `api_token` (
|
||||||
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
|
`value` VARCHAR(255) NOT NULL,
|
||||||
|
`user_uuid` VARCHAR(36) NOT NULL UNIQUE,
|
||||||
|
PRIMARY KEY(`id`),
|
||||||
|
FOREIGN KEY(`user_uuid`) REFERENCES user(`uuid`)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- SPELLS
|
||||||
CREATE TABLE IF NOT EXISTS `spell` (
|
CREATE TABLE IF NOT EXISTS `spell` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom du sort",
|
`name` VARCHAR(255) NOT NULL DEFAULT "Nom du sort",
|
||||||
`description` VARCHAR(1000) NOT NULL DEFAULT "Description du sort",
|
`description` VARCHAR(1000) NOT NULL DEFAULT "Description du sort",
|
||||||
`level` INT UNSIGNED DEFAULT 0,
|
`level` INT UNSIGNED DEFAULT 0,
|
||||||
`charge` INT UNSIGNED DEFAULT 0,
|
`charge` INT UNSIGNED DEFAULT 0,
|
||||||
`cost` VARCHAR(255) DEFAULT "0",
|
`cost` VARCHAR(255) DEFAULT 0,
|
||||||
`is_ritual` BOOLEAN DEFAULT false,
|
`is_ritual` BOOLEAN DEFAULT false,
|
||||||
`published` BOOLEAN DEFAULT true,
|
`published` BOOLEAN DEFAULT false,
|
||||||
`public` BOOLEAN DEFAULT true,
|
`public` BOOLEAN DEFAULT true,
|
||||||
`author_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
`author_id` INT UNSIGNED NOT NULL DEFAULT 1,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
FOREIGN KEY(`author_id`) REFERENCES user(`id`)
|
FOREIGN KEY(`author_id`) REFERENCES user(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* META SCHOOLS */
|
-- META SCHOOLS
|
||||||
CREATE TABLE IF NOT EXISTS `meta_school` (
|
CREATE TABLE IF NOT EXISTS `meta_school` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école mère",
|
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école mère",
|
||||||
`description` VARCHAR(255) DEFAULT "Description de l'école mère",
|
`description` VARCHAR(255) DEFAULT "Description de l'école mère",
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* SCHOOLS */
|
-- SCHOOLS
|
||||||
CREATE TABLE IF NOT EXISTS `school` (
|
CREATE TABLE IF NOT EXISTS `school` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école",
|
`name` VARCHAR(255) NOT NULL DEFAULT "Nom de l'école",
|
||||||
`description` VARCHAR(255) DEFAULT "Description de l'école",
|
`description` VARCHAR(255) DEFAULT "Description de l'école",
|
||||||
|
`published` BOOLEAN DEFAULT false,
|
||||||
`meta_school_id` INT UNSIGNED NOT NULL,
|
`meta_school_id` INT UNSIGNED NOT NULL,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
FOREIGN KEY(`meta_school_id`) REFERENCES meta_school(`id`)
|
FOREIGN KEY(`meta_school_id`) REFERENCES meta_school(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* COMMON INGREDIENTS */
|
-- COMMON INGREDIENTS
|
||||||
CREATE TABLE IF NOT EXISTS `ingredient` (
|
CREATE TABLE IF NOT EXISTS `ingredient` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`name` VARCHAR(255) NOT NULL DEFAULT "Langue de salamandre",
|
`name` VARCHAR(255) NOT NULL DEFAULT "Langue de salamandre",
|
||||||
`description` VARCHAR(255) NOT NULL DEFAULT "Une langue de salamandre de feu encore chaude.",
|
`description` VARCHAR(255) NOT NULL DEFAULT "Une langue de salamandre de feu encore chaude.",
|
||||||
|
`published` BOOLEAN DEFAULT false,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* COMMON VARIABLES */
|
-- COMMON VARIABLES
|
||||||
CREATE TABLE IF NOT EXISTS `variable` (
|
CREATE TABLE IF NOT EXISTS `variable` (
|
||||||
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
|
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
`description` VARCHAR(255) NOT NULL DEFAULT "Nombre de créatures affectées",
|
`description` VARCHAR(255) NOT NULL DEFAULT "Nombre de créatures affectées",
|
||||||
|
`published` BOOLEAN DEFAULT false,
|
||||||
PRIMARY KEY (`id`)
|
PRIMARY KEY (`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* ==== ASSOCIATION TABLES ==== */
|
/* ==== ASSOCIATION TABLES ==== */
|
||||||
|
|
||||||
/* SPELLS' SCHOOLS */
|
-- SPELLS' SCHOOLS
|
||||||
/* One spell can have multiple (up to 3) schools */
|
-- One spell can have multiple (up to 3) schools
|
||||||
CREATE TABLE IF NOT EXISTS `spell_school` (
|
CREATE TABLE IF NOT EXISTS `spell_school` (
|
||||||
`spell_id` INT UNSIGNED NOT NULL,
|
`spell_id` INT UNSIGNED NOT NULL,
|
||||||
`school_id` INT UNSIGNED NOT NULL,
|
`school_id` INT UNSIGNED NOT NULL,
|
||||||
@@ -89,8 +110,8 @@ CREATE TABLE IF NOT EXISTS `spell_school` (
|
|||||||
FOREIGN KEY(`school_id`) REFERENCES school(`id`)
|
FOREIGN KEY(`school_id`) REFERENCES school(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* SPELLS' VARIABLES */
|
-- SPELLS' VARIABLES
|
||||||
/* One spell can have multiple (up to 2) variables of cost */
|
-- One spell can have multiple (up to 2) variables of cost
|
||||||
CREATE TABLE IF NOT EXISTS `spell_variable` (
|
CREATE TABLE IF NOT EXISTS `spell_variable` (
|
||||||
`spell_id` INT UNSIGNED NOT NULL,
|
`spell_id` INT UNSIGNED NOT NULL,
|
||||||
`variable_id` INT UNSIGNED NOT NULL,
|
`variable_id` INT UNSIGNED NOT NULL,
|
||||||
@@ -99,8 +120,8 @@ CREATE TABLE IF NOT EXISTS `spell_variable` (
|
|||||||
FOREIGN KEY(`variable_id`) REFERENCES variable(`id`)
|
FOREIGN KEY(`variable_id`) REFERENCES variable(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* SPELLS' VARIABLES */
|
-- SPELLS' VARIABLES
|
||||||
/* One spell can have multiple ingredients */
|
-- One spell can have multiple ingredients
|
||||||
CREATE TABLE IF NOT EXISTS `spell_ingredient` (
|
CREATE TABLE IF NOT EXISTS `spell_ingredient` (
|
||||||
`spell_id` INT UNSIGNED NOT NULL,
|
`spell_id` INT UNSIGNED NOT NULL,
|
||||||
`ingredient_id` INT UNSIGNED NOT NULL,
|
`ingredient_id` INT UNSIGNED NOT NULL,
|
||||||
@@ -109,68 +130,101 @@ CREATE TABLE IF NOT EXISTS `spell_ingredient` (
|
|||||||
FOREIGN KEY(`ingredient_id`) REFERENCES ingredient(`id`)
|
FOREIGN KEY(`ingredient_id`) REFERENCES ingredient(`id`)
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Ajout d'une nouvelle ligne avant l'insert de description */
|
-- ROLES' PERMISSIONS
|
||||||
|
-- One role can have any number of permissions, or none at all
|
||||||
|
CREATE TABLE IF NOT EXISTS `role_permission` (
|
||||||
|
`role_id` INT UNSIGNED NOT NULL,
|
||||||
|
`permission_id` INT UNSIGNED NOT NULL,
|
||||||
|
PRIMARY KEY (`role_id`, `permission_id`),
|
||||||
|
FOREIGN KEY(`role_id`) REFERENCES role(`id`),
|
||||||
|
FOREIGN KEY(`permission_id`) REFERENCES permission(`id`)
|
||||||
|
);
|
||||||
|
|
||||||
|
-- Ajout d`une nouvelle ligne avant l`insert de description
|
||||||
DELIMITER $$
|
DELIMITER $$
|
||||||
CREATE TRIGGER `multiLine` BEFORE INSERT ON `spell` FOR EACH ROW
|
CREATE TRIGGER `multiLine` BEFORE INSERT ON `spell` FOR EACH ROW
|
||||||
BEGIN
|
BEGIN
|
||||||
SET NEW.description = replace(NEW.description, '<l>', '\n');
|
SET NEW.description = replace(NEW.description, "<l>", "\n");
|
||||||
END$$
|
END$$
|
||||||
DELIMITER ;
|
DELIMITER ;
|
||||||
|
|
||||||
/* =========== PRIMARY INSERTS =========== */
|
/* =========== PRIMARY INSERTS =========== */
|
||||||
SET NAMES utf8;
|
SET NAMES utf8;
|
||||||
USE auracle;
|
|
||||||
|
|
||||||
-- PERMISSIONS
|
-- CSV DATA
|
||||||
INSERT INTO `role` (name, description) VALUES
|
LOAD DATA INFILE 'C:/temp/auracle_data/permission.csv'
|
||||||
("Visiteur", "Utilisateur normal, peut consulter les sorts."),
|
INTO TABLE `permission`
|
||||||
("Scribe", "Gardiens des écrits, les scribes sont capables de modifier et d'ajouter des sortilèges."),
|
FIELDS TERMINATED BY ','
|
||||||
("Arcanologue", "Maîtres de l'arcane, ils ont le pouvoir et la responsabilité de juger les sortilèges récents et de les supprimer, ou valider."),
|
ENCLOSED BY '"'
|
||||||
("Augure", "Régents des grimoires, ils ont droit d'accès à l'intégralité des informations connues, et pouvoir absolu sur le savoir arcanique.");
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
-- META SCHOOLS
|
LOAD DATA INFILE 'C:/temp/auracle_data/role.csv'
|
||||||
INSERT INTO `meta_school` (name, description) VALUES
|
INTO TABLE `role`
|
||||||
('Magies blanches', 'Magies disciplinant les arts de soins et de lumières.'),
|
FIELDS TERMINATED BY ','
|
||||||
('Magies noires', 'Magies disciplinant l\'art de la mort et des secrets.'),
|
ENCLOSED BY '"'
|
||||||
('Magies élémentaires', 'Magies disciplinant les éléments basiques tels que l\'eau, la foudre et le feu, pour n\'en citer que les plus populaires.'),
|
LINES TERMINATED BY '\n'
|
||||||
('Magies spirituelles', 'Magies disciplinant l\'esprit, tant pour le défendre que l\'attaquer.'),
|
IGNORE 1 ROWS;
|
||||||
('Magies spatio-temporelles', 'Magies régissant le temps et l\'espace.'),
|
|
||||||
('Magies affiliées', 'Magies rattachées à une forme d\'énergie magique particulière.'),
|
|
||||||
('Magies autres', 'Magies trop spécifiques et ne rentrant dans aucune autre grande école.');
|
|
||||||
|
|
||||||
-- SCHOOLS
|
LOAD DATA INFILE 'C:/temp/auracle_data/role_permission.csv'
|
||||||
INSERT INTO `school` (name, description, meta_school_id) VALUES
|
INTO TABLE `role_permission`
|
||||||
('Lumomancie', 'Discipline arcanique de la lumière.', 1),
|
FIELDS TERMINATED BY ','
|
||||||
('Vitamancie', 'Discipline arcanique de la guérison et de l\'énergie vitale.', 1),
|
ENCLOSED BY '"'
|
||||||
('Obstrumancie', 'Discipline arcanique de la protection et des sceaux.', 1),
|
LINES TERMINATED BY '\n'
|
||||||
('Tenebromancie', 'Discipline arcanique de la lumière.', 2),
|
IGNORE 1 ROWS;
|
||||||
('Necromancie', 'Discipline arcanique de la mort.', 2),
|
|
||||||
('Morbomancie', 'Discipline arcanique des maladies et malédictions.', 2),
|
|
||||||
('Pyromancie', 'Discipline arcanique du feu.', 3),
|
|
||||||
('Hydromancie', 'Discipline arcanique de l\'eau.', 3),
|
|
||||||
('Electromancie', 'Discipline arcanique de la foudre.', 3),
|
|
||||||
('Terramancie', 'Discipline arcanique de la terre.', 3),
|
|
||||||
('Sidéromancie', 'Discipline arcanique des métaux rares et précieux.', 3),
|
|
||||||
('Caelomancie', 'Discipline arcanique de l\'air.', 3),
|
|
||||||
('Légimancie', 'Discipline arcanique de la lecture et du contrôle spirituel.', 4),
|
|
||||||
('Illusiomancie', 'Discipline arcanique des illusions.', 4),
|
|
||||||
('Cruciomancie', 'Discipline arcanique de la destruction spirituelle.', 4),
|
|
||||||
('Chronomancie', 'Discipline arcanique du temps.', 5),
|
|
||||||
('Spatiomancie', 'Discipline arcanique de l\'espace.', 5),
|
|
||||||
('Kénomancie', 'Discipline arcanique du néant.', 6),
|
|
||||||
('Lutomancie', 'Discipline arcanique des abysses.', 6),
|
|
||||||
('Échomancie', 'Discipline arcanique de la résolution animique.', 6),
|
|
||||||
('Protomancie', 'Discipline arcanique de la magie pure.', 7),
|
|
||||||
('Rebumancie', 'Discipline arcanique de la lumière.', 7),
|
|
||||||
('Vocamancie', 'Discipline arcanique de la lumière.', 7),
|
|
||||||
('Somamancie', 'Discipline arcanique de la maîtrise corporelle.', 7),
|
|
||||||
('Antimancie', 'Discipline arcanique de l\'annulation arcanique.', 7);
|
|
||||||
|
|
||||||
-- INGREDIENTS
|
LOAD DATA INFILE 'C:/temp/auracle_data/user.csv'
|
||||||
INSERT INTO `ingredient` (name, description) VALUES
|
INTO TABLE `user`
|
||||||
('Volonté', 'La force de volonté du lanceur, concentrée sur un objectif'),
|
FIELDS TERMINATED BY ','
|
||||||
('Geste', 'Un geste précis facilitant la canalisation magique');
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
-- VARIABLES
|
LOAD DATA INFILE 'C:/temp/auracle_data/api_token.csv'
|
||||||
INSERT INTO `variable` (description) VALUES
|
INTO TABLE `api_token`
|
||||||
('Nombre de personnes soignées');
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/spell.csv'
|
||||||
|
INTO TABLE `spell`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/meta_school.csv'
|
||||||
|
INTO TABLE `meta_school`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/school.csv'
|
||||||
|
INTO TABLE `school`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/ingredient.csv'
|
||||||
|
INTO TABLE `ingredient`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/variable.csv'
|
||||||
|
INTO TABLE `variable`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|
||||||
|
LOAD DATA INFILE 'C:/temp/auracle_data/spell_school.csv'
|
||||||
|
INTO TABLE `spell_school`
|
||||||
|
FIELDS TERMINATED BY ','
|
||||||
|
ENCLOSED BY '"'
|
||||||
|
LINES TERMINATED BY '\n'
|
||||||
|
IGNORE 1 ROWS;
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
USE auracle;
|
|
||||||
|
|
||||||
/* Insertions de masses */
|
|
||||||
DELIMITER $$
|
|
||||||
CREATE PROCEDURE insertIntoSchoolRange(IN delimiter_start INT, IN delimiter_end INT, IN id_school INT)
|
|
||||||
BEGIN
|
|
||||||
SET @i = delimiter_start;
|
|
||||||
WHILE @i <= delimiter_end DO
|
|
||||||
INSERT INTO spell_school (spell_id, school_id) VALUES (@i, id_school);
|
|
||||||
SET @i = @i + 1;
|
|
||||||
END WHILE;
|
|
||||||
END$$
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
||||||
CALL insertIntoSchoolRange(1, 25, 1);
|
|
||||||
CALL insertIntoSchoolRange(26, 50, 2);
|
|
||||||
CALL insertIntoSchoolRange(51, 70, 3);
|
|
||||||
CALL insertIntoSchoolRange(71, 95, 4);
|
|
||||||
CALL insertIntoSchoolRange(96, 111, 5);
|
|
||||||
CALL insertIntoSchoolRange(112, 115, 6);
|
|
||||||
CALL insertIntoSchoolRange(116, 141, 7);
|
|
||||||
CALL insertIntoSchoolRange(142, 167, 8);
|
|
||||||
CALL insertIntoSchoolRange(168, 193, 9);
|
|
||||||
CALL insertIntoSchoolRange(194, 217, 10);
|
|
||||||
CALL insertIntoSchoolRange(218, 220, 11);
|
|
||||||
CALL insertIntoSchoolRange(221, 242, 12);
|
|
||||||
CALL insertIntoSchoolRange(243, 257, 13);
|
|
||||||
CALL insertIntoSchoolRange(258, 272, 14);
|
|
||||||
CALL insertIntoSchoolRange(273, 283, 15);
|
|
||||||
CALL insertIntoSchoolRange(284, 301, 16);
|
|
||||||
CALL insertIntoSchoolRange(302, 322, 17);
|
|
||||||
CALL insertIntoSchoolRange(323, 339, 19);
|
|
||||||
CALL insertIntoSchoolRange(340, 341, 20);
|
|
||||||
CALL insertIntoSchoolRange(342, 356, 21);
|
|
||||||
CALL insertIntoSchoolRange(357, 387, 22);
|
|
||||||
CALL insertIntoSchoolRange(388, 396, 24);
|
|
||||||
CALL insertIntoSchoolRange(397, 403, 25);
|
|
||||||
@@ -1,18 +1,14 @@
|
|||||||
// MODULES
|
|
||||||
const fs = require('fs')
|
|
||||||
const mysql = require('mysql')
|
|
||||||
|
|
||||||
// Setting up the database connection
|
// Setting up the database connection
|
||||||
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 : "auracle",
|
database: process.env.DB_DATABASE,
|
||||||
charset : "utf8"
|
charset: "utf8"
|
||||||
},
|
},
|
||||||
})
|
});
|
||||||
const bookshelf = require('bookshelf')(knex)
|
const bookshelf = require('bookshelf')(knex);
|
||||||
|
|
||||||
module.exports = { bookshelf }
|
module.exports = { bookshelf };
|
||||||
@@ -1,48 +1,35 @@
|
|||||||
// Error handling
|
const regexInt = RegExp(/^[1-9]\d*$/);
|
||||||
const { HttpError } = require('./validations/Errors')
|
const regexXSS = RegExp(/<[^>]*script/);
|
||||||
|
|
||||||
const regexInt = RegExp(/^[1-9]\d*$/)
|
|
||||||
const regexXSS = RegExp(/<[^>]*script/)
|
|
||||||
|
|
||||||
// Check if int for param validation
|
// Check if int for param validation
|
||||||
const paramIntCheck = (req, res, next, input) => {
|
const paramIntCheck = (req, res, next, input) => {
|
||||||
try {
|
try {
|
||||||
if (regexInt.test(input)) {
|
if (regexInt.test(input)) {
|
||||||
next()
|
next();
|
||||||
} else {
|
} else {
|
||||||
throw new Error
|
throw new Error;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
err = new HttpError(403, 'Provided ID must be an integer and not zero')
|
res.status(err.code).send(JSON.stringify({
|
||||||
res.status(err.code).send(JSON.stringify(
|
"message": "Le paramètre doit être un entier non-nul.",
|
||||||
{
|
"code": 403,
|
||||||
"error": err.message,
|
})
|
||||||
"code": err.code
|
);
|
||||||
})
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Check if script injection attempt
|
// Check if script injection attempt
|
||||||
const isXSSAttempt = (string) => {
|
const isXSSAttempt = (string) => {
|
||||||
if (regexXSS.test(string)) {
|
return regexXSS.test(string);
|
||||||
return true
|
};
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if object is null
|
// Check if object is null
|
||||||
const isEmptyObject = (obj) => {
|
const isEmptyObject = (obj) => {
|
||||||
if (Object.keys(obj).length === 0 && obj.constructor === Object) {
|
return (Object.keys(obj).length === 0 && obj.constructor === Object);
|
||||||
return true
|
};
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
paramIntCheck,
|
paramIntCheck,
|
||||||
isXSSAttempt,
|
isXSSAttempt,
|
||||||
isEmptyObject
|
isEmptyObject
|
||||||
}
|
};
|
||||||
75
api/index.js
75
api/index.js
@@ -1,60 +1,41 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
// MODULES
|
// MODULES
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
const bodyParser = require('body-parser')
|
const bodyParser = require('body-parser');
|
||||||
const helmet = require('helmet')
|
const helmet = require('helmet');
|
||||||
const morgan = require('morgan')
|
const morgan = require('morgan');
|
||||||
const cors = require('cors') // module to format the json response
|
const cors = require('cors'); // module to format the json response
|
||||||
const dotenv = require('dotenv').config()
|
require('dotenv').config();
|
||||||
|
|
||||||
// Creates instances of database connections
|
|
||||||
const connection = require('./database/bookshelf')
|
|
||||||
const db = connection.db
|
|
||||||
|
|
||||||
// CONSTANTS
|
// CONSTANTS
|
||||||
const port = 2814
|
const port = 2814;
|
||||||
|
|
||||||
// Import routes
|
// Import routes
|
||||||
const routes = require('./routes')
|
const routes = require('./routes');
|
||||||
|
|
||||||
// Builds app w/ express
|
// Builds app w/ express
|
||||||
let app = express()
|
let app = express();
|
||||||
app.use(bodyParser.json({ limit: '10kb' }))
|
app.use(bodyParser.json({ limit: '10kb' }));
|
||||||
app.use(cors())
|
app.use(cors({
|
||||||
app.use(morgan('tiny'))
|
origin: [
|
||||||
app.use(helmet())
|
"http://localhost:8080",
|
||||||
|
],
|
||||||
|
credentials: true,
|
||||||
|
}));
|
||||||
|
app.use(morgan('dev'));
|
||||||
|
app.use(helmet());
|
||||||
|
|
||||||
// Serves
|
// Server
|
||||||
const server = app.listen( port, () => {console.log(`App listening on port ${port}`)})
|
app.listen(port, () => console.log(`App listening on port ${port}`));
|
||||||
|
|
||||||
// Get credentials
|
// Entry route
|
||||||
// app.get('/api/login', (req, res, next) => {
|
app.use('/api/v1/', routes.auth);
|
||||||
// if (req.headers.auracle_key !== process.env.API_KEY_PUBLIC) {
|
|
||||||
// return res.status(401).send('Credentials error !')
|
|
||||||
// } else {
|
|
||||||
// return res.status(200).send(JSON.stringify(
|
|
||||||
// {
|
|
||||||
// "secret_key": process.env.API_KEY_PRIVATE,
|
|
||||||
// })
|
|
||||||
// )
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// Auth guard
|
|
||||||
const authguard = (req, res, next) => {
|
|
||||||
if (req.headers.auracle_key !== process.env.API_KEY_PUBLIC) {
|
|
||||||
return res.status(401).send('The API key is either missing or incorrect.')
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Routing
|
// Routing
|
||||||
app.use('/api/spells', authguard,routes.spells)
|
app.use('/api/v1/spells', routes.spells);
|
||||||
app.use('/api/schools', authguard, routes.schools)
|
app.use('/api/v1/schools', routes.schools);
|
||||||
app.use('/api/meta_schools', authguard, routes.meta_schools)
|
app.use('/api/v1/meta_schools', routes.meta_schools);
|
||||||
app.use('/api/variables', authguard, routes.variables)
|
app.use('/api/v1/variables', routes.variables);
|
||||||
app.use('/api/ingredients', authguard, routes.ingredients)
|
app.use('/api/v1/ingredients', routes.ingredients);
|
||||||
app.use('/api/users', authguard, routes.users)
|
app.use('/api/v1/users', routes.users);
|
||||||
|
|
||||||
13
api/models/api-token-model.js
Normal file
13
api/models/api-token-model.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
|
|
||||||
|
require('./user-model');
|
||||||
|
|
||||||
|
let APIToken = bookshelf.Model.extend({
|
||||||
|
tableName: 'api_token',
|
||||||
|
hidden: ['id'],
|
||||||
|
user() {
|
||||||
|
return this.belongsTo('User', 'user_uuid', 'uuid');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = bookshelf.model('APIToken', APIToken);
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
|
||||||
require('./spell-model')
|
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');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('Ingredient', Ingredient)
|
module.exports = bookshelf.model('Ingredient', Ingredient);
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
|
||||||
require('./school-model')
|
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');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('MetaSchool', MetaSchool)
|
module.exports = bookshelf.model('MetaSchool', MetaSchool);
|
||||||
13
api/models/permission-model.js
Normal file
13
api/models/permission-model.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
|
|
||||||
|
require('./role-model');
|
||||||
|
|
||||||
|
let Permission = bookshelf.Model.extend({
|
||||||
|
tableName: 'permission',
|
||||||
|
hidden: ['id'],
|
||||||
|
role() {
|
||||||
|
return this.belongsToMany('Role', 'role_permission');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = bookshelf.model('Permission', Permission);
|
||||||
12
api/models/role-model.js
Normal file
12
api/models/role-model.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
|
|
||||||
|
require('./permission-model');
|
||||||
|
|
||||||
|
let Role = bookshelf.Model.extend({
|
||||||
|
tableName: 'role',
|
||||||
|
permissions() {
|
||||||
|
return this.belongsToMany('Permission', 'role_permission');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = bookshelf.model('Role', Role);
|
||||||
@@ -1,17 +1,16 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
|
||||||
require('./spell-model')
|
require('./spell-model');
|
||||||
require('./meta-school-model')
|
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');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('School', School)
|
module.exports = bookshelf.model('School', School);
|
||||||
@@ -1,21 +1,24 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
|
||||||
require('./school-model')
|
require('./school-model');
|
||||||
require('./variable-model')
|
require('./variable-model');
|
||||||
require('./ingredient-model')
|
require('./ingredient-model');
|
||||||
|
|
||||||
let Spell = bookshelf.Model.extend({
|
let Spell = bookshelf.Model.extend({
|
||||||
tableName: 'spell',
|
tableName: 'spell',
|
||||||
|
hidden: [ 'author_id' ],
|
||||||
|
author() {
|
||||||
|
return this.belongsTo( 'User', 'author_id' );
|
||||||
|
},
|
||||||
schools() {
|
schools() {
|
||||||
return this.belongsToMany( 'School', 'spell_school' )
|
return this.belongsToMany( 'School', 'spell_school' );
|
||||||
},
|
},
|
||||||
variables() {
|
variables() {
|
||||||
return this.belongsToMany( 'Variable', 'spell_variable' )
|
return this.belongsToMany( 'Variable', 'spell_variable' );
|
||||||
},
|
},
|
||||||
ingredients() {
|
ingredients() {
|
||||||
return this.belongsToMany( 'Ingredient', 'spell_ingredient' )
|
return this.belongsToMany( 'Ingredient', 'spell_ingredient' );
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('Spell', Spell)
|
module.exports = bookshelf.model('Spell', Spell);
|
||||||
@@ -1,9 +1,17 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
require('./role-model');
|
||||||
|
require('./spell-model');
|
||||||
|
|
||||||
let User = bookshelf.Model.extend({
|
let User = bookshelf.Model.extend({
|
||||||
tableName: 'user',
|
tableName: 'user',
|
||||||
hidden: ['id', 'password']
|
hidden: ['password', 'role_id'],
|
||||||
})
|
role() {
|
||||||
|
return this.belongsTo('Role');
|
||||||
|
},
|
||||||
|
spells() {
|
||||||
|
return this.hasMany('Spell', 'author_id');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('User', User)
|
module.exports = bookshelf.model('User', User);
|
||||||
@@ -1,13 +1,12 @@
|
|||||||
'use strict'
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
|
|
||||||
require('./spell-model')
|
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');
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = bookshelf.model('Variable', Variable)
|
module.exports = bookshelf.model('Variable', Variable);
|
||||||
6326
api/package-lock.json
generated
6326
api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
112
api/package.json
112
api/package.json
@@ -1,43 +1,73 @@
|
|||||||
{
|
{
|
||||||
"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": {
|
||||||
"run": "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",
|
||||||
"helmet": "^3.22.0",
|
"handlebars": "^4.7.6",
|
||||||
"jsonschema": "^1.2.6",
|
"helmet": "^3.22.0",
|
||||||
"jsonwebtoken": "^8.5.1",
|
"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",
|
||||||
"uuid": "^8.2.0"
|
"nodemailer": "^6.4.17",
|
||||||
}
|
"uuid": "^8.2.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"eslint": "^7.18.0",
|
||||||
|
"eslint-plugin-import": "^2.22.1"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"env": {
|
||||||
|
"es6": true,
|
||||||
|
"browser": true
|
||||||
|
},
|
||||||
|
"parser": "babel-eslint",
|
||||||
|
"rules": {
|
||||||
|
"accessor-pairs": "warn",
|
||||||
|
"array-callback-return": "error",
|
||||||
|
"brace-style": "warn",
|
||||||
|
"consistent-return": "error",
|
||||||
|
"default-case": "error",
|
||||||
|
"eqeqeq": "warn",
|
||||||
|
"no-case-declarations": "error",
|
||||||
|
"no-empty-pattern": "warn",
|
||||||
|
"no-fallthrough": "error",
|
||||||
|
"no-unused-vars": "error",
|
||||||
|
"no-useless-catch": "error",
|
||||||
|
"no-var": "error",
|
||||||
|
"semi": "warn",
|
||||||
|
"no-extra-semi": "error",
|
||||||
|
"yoda": "warn"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
'use strict'
|
|
||||||
// Bookshelf
|
// Bookshelf
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const model = require('../models/ingredient-model')
|
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;
|
||||||
const isEmptyObject = require('../functions').isEmptyObject
|
const isEmptyObject = require('../functions').isEmptyObject;
|
||||||
|
|
||||||
// Error handling
|
|
||||||
const { HttpError } = require('../validations/Errors')
|
|
||||||
|
|
||||||
class IngredientRepository {
|
class IngredientRepository {
|
||||||
|
|
||||||
@@ -23,149 +19,188 @@ class IngredientRepository {
|
|||||||
|
|
||||||
getAll() {
|
getAll() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get ingredients"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucun ingrédient disponible.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get ingredient"))
|
reject({
|
||||||
})
|
"message": "L'ingrédient en question n'a pas pu être trouvé.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSpellsFromOne(id) {
|
getSpellsFromOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get ingredient"))
|
reject({
|
||||||
})
|
"message": "Les sortilèges liés à cet ingrédient n'ont pas pu être récupérés.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(igr) {
|
addOne(igr) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(igr)) {
|
if (isEmptyObject(igr)) {
|
||||||
reject(new HttpError(403, "Error: Ingredient cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(igr, IngredientValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(igr, IngredientValidation).errors))
|
"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)) {
|
} else if (isXSSAttempt(igr.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
bookshelf.transaction(t => {
|
bookshelf.transaction(t => {
|
||||||
return model.forge({
|
return new model({
|
||||||
'name': igr.name,
|
'name': igr.name,
|
||||||
'description': igr.description,
|
'description': igr.description,
|
||||||
}).save(null, {
|
}).save(null, {
|
||||||
transacting: t
|
transacting: t
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
throw err
|
throw err;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(v => {
|
||||||
|
return v.load(['spells']);
|
||||||
})
|
})
|
||||||
})
|
.then(v => {
|
||||||
.then(v => {
|
resolve(this.getOne(v.id));
|
||||||
return v.load(['spells'])
|
})
|
||||||
})
|
.catch(err => {
|
||||||
.then(v => {
|
console.log(err);
|
||||||
resolve(this.getOne(v.id))
|
reject({
|
||||||
})
|
"message": "Une erreur d'insertion s'est produite.",
|
||||||
.catch(err => {
|
"code": 500,
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(500, "Insert Ingredient error"))
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOne(id, igr) {
|
updateOne(id, igr) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(igr)) {
|
if (isEmptyObject(igr)) {
|
||||||
reject(new HttpError(403, "Error: Ingredient cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(igr, IngredientValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(igr, IngredientValidation).errors))
|
"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)) {
|
} else if (isXSSAttempt(igr.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
model.forge({id: id})
|
new model({ id: id })
|
||||||
.fetch({require: true, withRelated: ['spells']})
|
.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 => {
|
.then(v => {
|
||||||
return v.load(['spells'])
|
bookshelf.transaction(t => {
|
||||||
})
|
return v.save({
|
||||||
.then(v => {
|
'name': igr.name,
|
||||||
resolve(this.getOne(v.id))
|
'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 => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
reject(new HttpError(500, "Update Ingredient error"))
|
reject({
|
||||||
})
|
"message": "L'ingrédient en question n'a pas été trouvé.",
|
||||||
})
|
"code": 404,
|
||||||
.catch(err => {
|
});
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(404, "Couldn't get ingredient"))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOne(id) {
|
deleteOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'id' : id })
|
.where({ 'id': id })
|
||||||
.fetch({require: true, withRelated: ['spells']})
|
.fetch({ require: true, withRelated: ['spells'] })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
v.spells().detach()
|
v.spells().detach();
|
||||||
v.destroy()
|
v.destroy();
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
resolve({
|
|
||||||
'message': 'Ingredient with ID ' + id + ' successfully deleted !'
|
|
||||||
})
|
})
|
||||||
})
|
.then(() => {
|
||||||
.catch(err => {
|
resolve({
|
||||||
console.log(err)
|
'message': 'Ingredient with ID ' + id + ' successfully deleted !'
|
||||||
reject(new HttpError(404, "Couldn't get ingredient"))
|
});
|
||||||
})
|
})
|
||||||
})
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
reject({
|
||||||
|
"message": "L'ingrédient en question n'a pas été trouvé.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = IngredientRepository
|
module.exports = IngredientRepository;
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
'use strict'
|
|
||||||
// Bookshelf
|
// Bookshelf
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
|
||||||
const model = require('../models/meta-school-model')
|
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
|
|
||||||
const regexXSS = RegExp(/<[^>]*script/)
|
|
||||||
|
|
||||||
// Error handling
|
|
||||||
const { HttpError } = require('../validations/Errors')
|
|
||||||
|
|
||||||
class MetaSchoolRepository {
|
class MetaSchoolRepository {
|
||||||
|
|
||||||
@@ -22,30 +14,36 @@ class MetaSchoolRepository {
|
|||||||
|
|
||||||
getAll() {
|
getAll() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get meta schools"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucune grande école disponible.",
|
||||||
|
"code": 404
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get meta school"))
|
reject({
|
||||||
})
|
"message": "La grande école en question n'a pas pu être trouvée.",
|
||||||
|
"code": 404
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,16 @@
|
|||||||
'use strict'
|
|
||||||
// Bookshelf
|
// Bookshelf
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const model = require('../models/school-model')
|
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;
|
||||||
const isEmptyObject = require('../functions').isEmptyObject
|
const isEmptyObject = require('../functions').isEmptyObject;
|
||||||
|
|
||||||
// Error handling
|
|
||||||
const { HttpError } = require('../validations/Errors')
|
|
||||||
|
|
||||||
class SchoolRepository {
|
class SchoolRepository {
|
||||||
|
|
||||||
@@ -23,150 +19,189 @@ class SchoolRepository {
|
|||||||
|
|
||||||
getAll() {
|
getAll() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get schools"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucune école disponible.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get school"))
|
reject({
|
||||||
})
|
"message": "L'école en question n'a pas pu être trouvée.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSpellsFromOne(id) {
|
getSpellsFromOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get spells from school"))
|
reject({
|
||||||
})
|
"message": "Les sortilèges de cette école n'ont pas pu être récupérés.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(s) {
|
addOne(s) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(s)) {
|
if (isEmptyObject(s)) {
|
||||||
reject(new HttpError(403, "Error: School cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(s, SchoolValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors))
|
"code": 403,
|
||||||
|
});
|
||||||
|
} else if (!validator.validate(s, SchoolValidation).valid) {
|
||||||
|
reject({
|
||||||
|
"message": `Le modèle d'école n'est pas respecté : ${validator.validate(s, SchoolValidation).errors}`,
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
|
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
bookshelf.transaction(t => {
|
bookshelf.transaction(t => {
|
||||||
return model.forge({
|
return new model({
|
||||||
'name': s.name,
|
'name': s.name,
|
||||||
'description': s.description,
|
'description': s.description,
|
||||||
'meta_school_id': s.meta_school_id,
|
'meta_school_id': s.meta_school_id,
|
||||||
}).save(null, {
|
}).save(null, {
|
||||||
transacting: t
|
transacting: t
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
throw err
|
throw err;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(v => {
|
||||||
|
return v.load(['meta_schools']);
|
||||||
})
|
})
|
||||||
})
|
.then(v => {
|
||||||
.then(v => {
|
resolve(this.getOne(v.id));
|
||||||
return v.load(['meta_schools'])
|
})
|
||||||
})
|
.catch(err => {
|
||||||
.then(v => {
|
console.log(err);
|
||||||
resolve(this.getOne(v.id))
|
reject({
|
||||||
})
|
"message": "Une erreur d'insertion s'est produite.",
|
||||||
.catch(err => {
|
"code": 500,
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(500, "Insert School error"))
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOne(id, s) {
|
updateOne(id, s) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(s)) {
|
if (isEmptyObject(s)) {
|
||||||
reject(new HttpError(403, "Error: School cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(s, SchoolValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SchoolValidation).errors))
|
"code": 403,
|
||||||
|
});
|
||||||
|
} else if (!validator.validate(s, SchoolValidation).valid) {
|
||||||
|
reject({
|
||||||
|
"message": `Le modèle d'école n'est pas respecté : ${validator.validate(s, SchoolValidation).errors}`,
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
|
} else if (isXSSAttempt(s.name) || isXSSAttempt(s.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
model.forge({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(new HttpError(500, "Update School error"))
|
reject({
|
||||||
})
|
"message": "L'école en question n'a pas été trouvée.",
|
||||||
})
|
"code": 404,
|
||||||
.catch(err => {
|
});
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(404, "Couldn't get school"))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOne(id) {
|
deleteOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'id' : id })
|
.where({ 'id': id })
|
||||||
.fetch({require: true, withRelated: ['spells', 'meta_schools']})
|
.fetch({ require: true, withRelated: ['spells', 'meta_schools'] })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
v.spells().detach()
|
v.spells().detach();
|
||||||
v.destroy()
|
v.destroy();
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
resolve({
|
|
||||||
'message': 'School with ID ' + id + ' successfully deleted !'
|
|
||||||
})
|
})
|
||||||
})
|
.then(() => {
|
||||||
.catch(err => {
|
resolve({
|
||||||
console.log(err)
|
'message': 'School with ID ' + id + ' successfully deleted !'
|
||||||
reject(new HttpError(404, "Couldn't get school"))
|
});
|
||||||
})
|
})
|
||||||
})
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
reject({
|
||||||
|
"message": "L'école en question n'a pas été trouvée.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = SchoolRepository
|
module.exports = SchoolRepository;
|
||||||
@@ -5,17 +5,14 @@ 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
|
||||||
const isEmptyObject = require('../functions').isEmptyObject
|
const isEmptyObject = require('../functions').isEmptyObject
|
||||||
|
|
||||||
// Error handling
|
|
||||||
const { HttpError } = require('../validations/Errors')
|
|
||||||
|
|
||||||
class SpellRepository {
|
class SpellRepository {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
@@ -24,81 +21,116 @@ class SpellRepository {
|
|||||||
getAll(name, description, level, charge, cost, ritual) {
|
getAll(name, description, level, charge, cost, ritual) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
let query = model.forge()
|
let query = new model();
|
||||||
|
|
||||||
if (name) { query.where('name', 'like', `%${name}%`) }
|
if (name) {
|
||||||
if (description) { query.where('description', 'like', `%${description}%`) }
|
query.where('name', 'like', `%${name}%`)
|
||||||
if (level) { query.where({ 'level' : level }) }
|
}
|
||||||
if (charge) { query.where({ 'charge' : charge }) }
|
if (description) {
|
||||||
if (cost) { query.where({ 'cost' : cost }) }
|
query.where('description', 'like', `%${description}%`)
|
||||||
if (ritual) { query.where({ 'is_ritual' : ritual }) }
|
}
|
||||||
|
if (level) {
|
||||||
|
query.where({ 'level': level })
|
||||||
|
}
|
||||||
|
if (charge) {
|
||||||
|
query.where({ 'charge': charge })
|
||||||
|
}
|
||||||
|
if (cost) {
|
||||||
|
query.where({ 'cost': cost })
|
||||||
|
}
|
||||||
|
if (ritual) {
|
||||||
|
query.where({ 'is_ritual': ritual })
|
||||||
|
}
|
||||||
|
|
||||||
query.fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients'] })
|
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(new HttpError(500, "Couldn't get spells"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucun sortilège disponible.",
|
||||||
|
"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 = model.forge()
|
let query = new model().where({ 'public': 1 })
|
||||||
.where({ 'public' : 1 })
|
|
||||||
|
|
||||||
if (name) { query.where('name', 'like', `%${name}%`) }
|
if (name) {
|
||||||
if (description) { query.where('description', 'like', `%${description}%`) }
|
query.where('name', 'like', `%${name}%`)
|
||||||
if (level) { query.where({ 'level' : level }) }
|
}
|
||||||
if (charge) { query.where({ 'charge' : charge }) }
|
if (description) {
|
||||||
if (cost) { query.where({ 'cost' : cost }) }
|
query.where('description', 'like', `%${description}%`)
|
||||||
if (ritual) { query.where({ 'is_ritual' : ritual }) }
|
}
|
||||||
|
if (level) {
|
||||||
|
query.where({ 'level': level })
|
||||||
|
}
|
||||||
|
if (charge) {
|
||||||
|
query.where({ 'charge': charge })
|
||||||
|
}
|
||||||
|
if (cost) {
|
||||||
|
query.where({ 'cost': cost })
|
||||||
|
}
|
||||||
|
if (ritual) {
|
||||||
|
query.where({ 'is_ritual': ritual })
|
||||||
|
}
|
||||||
|
|
||||||
query.fetchAll({ withRelated: ['schools.meta_schools', 'variables', 'ingredients'] })
|
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(new HttpError(500, "Couldn't get public spells"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucun sortilège disponible.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getPage(page) {
|
getPage(page) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'public' : 1 })
|
.where({ 'public': 1 })
|
||||||
.fetchPage({
|
.fetchPage({
|
||||||
pageSize: 20,
|
pageSize: 20,
|
||||||
page: page,
|
page: page,
|
||||||
withRelated: ['schools.meta_schools', 'variables', 'ingredients'],
|
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(new HttpError(500, "Couldn't get public spells"))
|
reject({
|
||||||
})
|
"message": "La page de sortilèges n'a pas pu être chargée",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'id' : id })
|
.where({ 'id': id })
|
||||||
.fetch({ withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
.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(new HttpError(500, "Couldn't get spell"))
|
reject({
|
||||||
})
|
"message": "Le sortilège en question n'a pas été trouvé.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,58 +138,74 @@ class SpellRepository {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(s)) {
|
if (isEmptyObject(s)) {
|
||||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(s, SpellValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors))
|
"code": 403,
|
||||||
|
});
|
||||||
|
} else if (!validator.validate(s, SpellValidation).valid) {
|
||||||
|
reject({
|
||||||
|
"message": `Le modèle de sortilège n'est pas respecté : ${validator.validate(s, SpellValidation).errors}`,
|
||||||
|
"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(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
bookshelf.transaction(t => {
|
bookshelf.transaction(t => {
|
||||||
return model.forge({
|
return new model({
|
||||||
'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 => {
|
||||||
throw err
|
console.log(err);
|
||||||
|
reject({
|
||||||
|
"message": "Le sortilège n'a pas pu être ajouté.",
|
||||||
|
"code": 500,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.then(v => {
|
|
||||||
return v.load(['schools.meta_schools', 'variables', 'ingredients'])
|
|
||||||
})
|
|
||||||
.then(v => {
|
|
||||||
resolve(this.getOne(v.id))
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
reject(new HttpError(500, "Insert Spell error"))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -166,113 +214,136 @@ class SpellRepository {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(s)) {
|
if (isEmptyObject(s)) {
|
||||||
reject(new HttpError(403, "Error: Spell cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(s, SpellValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(s, SpellValidation).errors))
|
"code": 403,
|
||||||
|
});
|
||||||
|
} else if (!validator.validate(s, SpellValidation).valid) {
|
||||||
|
reject({
|
||||||
|
"message": `Le modèle de sortilège n'est pas respecté : ${validator.validate(s, SpellValidation).errors}`,
|
||||||
|
"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(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
model.forge({id: id})
|
new model({ id: id })
|
||||||
.fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
.fetch({ require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
|
||||||
.then(v => {
|
|
||||||
bookshelf.transaction(t => {
|
|
||||||
return v.save({
|
|
||||||
'name': s.name,
|
|
||||||
'description': s.description,
|
|
||||||
'level': s.level,
|
|
||||||
'charge' : s.charge,
|
|
||||||
'cost' : s.cost,
|
|
||||||
'is_ritual' : s.is_ritual
|
|
||||||
}, {
|
|
||||||
method: 'update',
|
|
||||||
transacting: t
|
|
||||||
})
|
|
||||||
// Detaches AND attaches pivot tables, dw about it
|
|
||||||
.tap(spell => {
|
|
||||||
if (s.schools) {
|
|
||||||
let schools = spell.related('school');
|
|
||||||
return spell.schools().detach(schools, { transacting: t});
|
|
||||||
}
|
|
||||||
return
|
|
||||||
})
|
|
||||||
.tap(spell => {
|
|
||||||
if (s.variables) {
|
|
||||||
let variables = spell.related('variable');
|
|
||||||
return spell.variables().detach(variables, { transacting: t});
|
|
||||||
}
|
|
||||||
return
|
|
||||||
})
|
|
||||||
.tap(spell => {
|
|
||||||
if (s.ingredients) {
|
|
||||||
let ingredients = spell.related('ingredient');
|
|
||||||
return spell.ingredients().detach(ingredients, { transacting: t});
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.tap(spell => {
|
|
||||||
return spell
|
|
||||||
.schools()
|
|
||||||
.attach(s.schools, {
|
|
||||||
transacting: t
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.tap(spell => {
|
|
||||||
return spell
|
|
||||||
.variables()
|
|
||||||
.attach(s.variables, {
|
|
||||||
transacting: t
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.tap(spell => {
|
|
||||||
return spell
|
|
||||||
.ingredients()
|
|
||||||
.attach(s.ingredients, {
|
|
||||||
transacting: t
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
throw err
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(v => {
|
.then(v => {
|
||||||
return v.load(['schools.meta_schools', 'variables', 'ingredients'])
|
bookshelf.transaction(t => {
|
||||||
})
|
return v.save({
|
||||||
.then(v => {
|
'name': s.name,
|
||||||
resolve(this.getOne(v.id))
|
'description': s.description,
|
||||||
|
'level': s.level,
|
||||||
|
'charge': s.charge,
|
||||||
|
'cost': s.cost,
|
||||||
|
'is_ritual': s.is_ritual
|
||||||
|
}, {
|
||||||
|
method: 'update',
|
||||||
|
transacting: t
|
||||||
|
})
|
||||||
|
// Detaches AND attaches pivot tables, dw about it
|
||||||
|
.tap(spell => {
|
||||||
|
if (s.schools) {
|
||||||
|
let schools = spell.related('school');
|
||||||
|
return spell.schools().detach(schools, { transacting: t });
|
||||||
|
}
|
||||||
|
return spell
|
||||||
|
})
|
||||||
|
.tap(spell => {
|
||||||
|
if (s.variables) {
|
||||||
|
let variables = spell.related('variable');
|
||||||
|
return spell.variables().detach(variables, { transacting: t });
|
||||||
|
}
|
||||||
|
return spell;
|
||||||
|
})
|
||||||
|
.tap(spell => {
|
||||||
|
if (s.ingredients) {
|
||||||
|
let ingredients = spell.related('ingredient');
|
||||||
|
return spell.ingredients().detach(ingredients, { transacting: t });
|
||||||
|
}
|
||||||
|
return spell;
|
||||||
|
})
|
||||||
|
.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 => {
|
||||||
|
return v.load(['schools.meta_schools', 'variables', 'ingredients', 'author']);
|
||||||
|
})
|
||||||
|
.then(v => {
|
||||||
|
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(new HttpError(500, "Update Spell error"))
|
reject({
|
||||||
|
"message": "Le sortilège en question n'a pas été trouvé.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
reject(new HttpError(404, "Couldn't get spell"))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOne(id) {
|
deleteOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'id' : id })
|
.where({ 'id': id })
|
||||||
.fetch({require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients']})
|
.fetch({ require: true, withRelated: ['schools.meta_schools', 'variables', 'ingredients', 'author'] })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
v.schools().detach()
|
v.schools().detach();
|
||||||
v.variables().detach()
|
v.variables().detach();
|
||||||
v.ingredients().detach()
|
v.ingredients().detach();
|
||||||
v.destroy()
|
v.destroy();
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
resolve({
|
resolve({
|
||||||
'message': 'Spell with ID ' + id + ' successfully deleted !'
|
"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,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
reject(new HttpError(404, "Couldn't get spell"))
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,180 +1,562 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
// Bookshelf
|
// Bookshelf
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const model = require('../models/user-model')
|
const model = require('../models/user-model');
|
||||||
|
const token_model = require('../models/api-token-model');
|
||||||
|
|
||||||
// Hashing and passwords
|
// Hashing and passwords
|
||||||
const bcrypt = require('bcrypt')
|
const bcrypt = require('bcrypt');
|
||||||
const { v4: uuidv4 } = require('uuid')
|
const { v4: uuidv4 } = require('uuid');
|
||||||
|
|
||||||
|
// Mailing methods
|
||||||
|
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;
|
||||||
const isEmptyObject = require('../functions').isEmptyObject
|
const isEmptyObject = require('../functions').isEmptyObject;
|
||||||
|
|
||||||
class UserRepository {
|
class UserRepository {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all users in the dabatase.
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: Array of user objects.
|
||||||
|
*/
|
||||||
getAll() {
|
getAll() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.fetchAll()
|
.fetchAll({ withRelated: ['role.permissions'] })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
resolve(v.toJSON({ omitPivot: true }))
|
resolve(v.toJSON({ omitPivot: true }));
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(err => {
|
||||||
reject({
|
console.log(err)
|
||||||
"message": "Database error, couldn't get all users.",
|
reject({
|
||||||
"code": 500
|
"message": "Erreur de base de données, les utilisateurs n'ont pas pu être récupérés.",
|
||||||
|
"code": 500,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a user object associated with the uuid.
|
||||||
|
*
|
||||||
|
* @param { string } uuid
|
||||||
|
* @param { boolean } full
|
||||||
|
* Whether the password should also be fetched. (should never be true unless you want to log the user)
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: Queried user object.
|
||||||
|
*/
|
||||||
getOneByUUID(uuid, full) {
|
getOneByUUID(uuid, full) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
|
||||||
.where({ 'uuid' : uuid })
|
if (!(uuid)) {
|
||||||
.fetch()
|
|
||||||
.then(v => {
|
|
||||||
resolve(v.toJSON({ omitPivot: true, visibility: !full }))
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject({
|
reject({
|
||||||
"message": "User with this UUID was not found.",
|
"message": "La requête doit renseigner un uuid.",
|
||||||
"code": 404
|
"code": 400,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
new model()
|
||||||
|
.where({ 'uuid': uuid })
|
||||||
|
.fetch({ withRelated: ['role.permissions'] })
|
||||||
|
.then(v => {
|
||||||
|
resolve(v.toJSON({ omitPivot: true, visibility: !full }));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject({
|
||||||
|
"message": "L'utilisateur avec cet UUID n'a pas été trouvé.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
})
|
})
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches a user object associated with the mail address.
|
||||||
|
*
|
||||||
|
* @param { string } mail
|
||||||
|
* @param { boolean } full
|
||||||
|
* Whether the password should also be fetched. (should never be true unless you want to log the user)
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: Queried user object.
|
||||||
|
*/
|
||||||
getOneByEmail(mail, full) {
|
getOneByEmail(mail, full) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
|
||||||
.where({ 'mail': mail })
|
if (!(mail)) {
|
||||||
.fetch()
|
|
||||||
.then(v => {
|
|
||||||
resolve(v.toJSON({ omitPivot: true, visibility: !full }))
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
reject({
|
reject({
|
||||||
"message": "User with this email was not found.",
|
"message": "La requête doit renseigner un email.",
|
||||||
"code": 404
|
"code": 400,
|
||||||
})
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
new model()
|
||||||
|
.where({ 'mail': mail })
|
||||||
|
.fetch({ withRelated: ['role'] })
|
||||||
|
.then(v => {
|
||||||
|
resolve(v.toJSON({ omitPivot: true, visibility: !full }));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject({
|
||||||
|
"message": "L'utilisateur avec cet email n'a pas été trouvé.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches all spells linked to a user's uuid
|
||||||
|
*
|
||||||
|
* @param { string } uuid
|
||||||
|
*
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getSpellsFromOne(uuid) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
|
||||||
|
if (!(uuid)) {
|
||||||
|
reject({
|
||||||
|
"message": "La requête doit renseigner un uuid.",
|
||||||
|
"code": 400,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
new model()
|
||||||
|
.where({ 'uuid': uuid })
|
||||||
|
.fetch({ withRelated: ['role', 'spells.schools.meta_schools', 'spells.variables', 'spells.ingredients'] })
|
||||||
|
.then(v => {
|
||||||
|
resolve(v.toJSON({ omitPivot: true }));
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
reject({
|
||||||
|
"message": "Les sorts liés à cet utilisateur n'ont pas été trouvés.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a user based on the model at ./models/user-model.js.
|
||||||
|
*
|
||||||
|
* @param { object} u
|
||||||
|
* User object
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: Queried user object.
|
||||||
|
*/
|
||||||
addOne(u) {
|
addOne(u) {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
// 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": "Request body cannot be empty.",
|
"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": "Schema is not valid - " + 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)) {
|
||||||
reject({
|
reject({
|
||||||
"message": "Injection attempt detected, aborting the request.",
|
"message": "Essai d'injection détecté, avortement de la requête.",
|
||||||
"code": 403
|
"code": 403,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let hash = await bcrypt.hash(u.password, 10)
|
let hash = await bcrypt.hash(u.password, 10);
|
||||||
let uuid = uuidv4()
|
|
||||||
|
let uuid = uuidv4();
|
||||||
|
let verification_token = uuidv4();
|
||||||
|
|
||||||
this.checkIfEmailAvailable(u.mail)
|
this.checkIfEmailAvailable(u.mail)
|
||||||
.then(() => {
|
|
||||||
bookshelf.transaction(t => {
|
|
||||||
return model.forge({
|
|
||||||
'uuid': uuid,
|
|
||||||
'name': u.name,
|
|
||||||
'mail': u.mail,
|
|
||||||
'password': hash,
|
|
||||||
})
|
|
||||||
.save(null, {
|
|
||||||
transacting: t
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
throw err
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.then(() => {
|
.then(() => {
|
||||||
return this.getOneByUUID(uuid, false)
|
bookshelf.transaction(t => {
|
||||||
})
|
return new model({
|
||||||
.then(newUser => {
|
'uuid': uuid,
|
||||||
resolve({
|
'name': u.name,
|
||||||
"message": "Account successfully created !",
|
'mail': u.mail,
|
||||||
"user": newUser,
|
'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
|
||||||
|
mails.sendRegistrationMail({
|
||||||
|
user: {
|
||||||
|
name: newUser.name,
|
||||||
|
mail: newUser.mail,
|
||||||
|
token: verification_token,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Then resolves the api call
|
||||||
|
resolve({
|
||||||
|
"message": `Compte utilisateur #${newUser.id} créé avec succès.`,
|
||||||
|
"code": 201,
|
||||||
|
"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 => {
|
||||||
resolve({
|
reject(err)
|
||||||
"message": "An error has occured while creating your account.",
|
|
||||||
"code": 500,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
reject(err)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Log user with an email address and a password
|
/**
|
||||||
|
* Verifies an account based on a private UUID token
|
||||||
|
*
|
||||||
|
* @param { string } token
|
||||||
|
* A UUID v4 identification token provided at registration and on special demands
|
||||||
|
*
|
||||||
|
* @returns Redirects to login page
|
||||||
|
*/
|
||||||
|
verifyUser(token) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
new model()
|
||||||
|
.where({ 'verification_token': token })
|
||||||
|
.fetch()
|
||||||
|
.then(v => {
|
||||||
|
bookshelf.transaction(t => {
|
||||||
|
return v.save({
|
||||||
|
'verification_token': null,
|
||||||
|
'verified': 1,
|
||||||
|
}, {
|
||||||
|
method: 'update',
|
||||||
|
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,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user by comparing the dual mail/password inputs
|
||||||
|
*
|
||||||
|
* @param { string } mail
|
||||||
|
* @param { string } password
|
||||||
|
*
|
||||||
|
* @return { Promise }
|
||||||
|
* Fulfilled data: Queried user object.
|
||||||
|
*/
|
||||||
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);
|
||||||
delete fetchedUser.id
|
|
||||||
delete fetchedUser.password
|
|
||||||
|
|
||||||
if (match) {
|
// Makes sure no hash gets out
|
||||||
resolve({
|
delete fetchedUser.password;
|
||||||
"message": "User successfully logged in !",
|
|
||||||
"user": fetchedUser,
|
// If you found a user...
|
||||||
})
|
if (match) {
|
||||||
} else {
|
// If they're banned...
|
||||||
reject({
|
if (fetchedUser.banned) {
|
||||||
"message": "Les informations de connexion sont erronées.",
|
reject({
|
||||||
})
|
"message": `L'utilisateur #${fetchedUser.name} a été banni, la connexion est impossible.`,
|
||||||
}
|
"code": 403,
|
||||||
})
|
});
|
||||||
.catch(err => {
|
// If they're not verified...
|
||||||
reject(err)
|
} else if (!fetchedUser.verified) {
|
||||||
})
|
reject({
|
||||||
|
"message": `L'utilisateur #${fetchedUser.name} n'as pas été vérifié, le compte doit être activé avant la connexion.`,
|
||||||
|
"code": 401,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
resolve({
|
||||||
|
"message": `L'utilisateur #${fetchedUser.name} s'est connecté.`,
|
||||||
|
"code": 200,
|
||||||
|
"user": fetchedUser,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reject({
|
||||||
|
"message": "Les informations de connexions sont erronées.",
|
||||||
|
"code": 400,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if one user already has that email
|
/**
|
||||||
|
* Generate a token for the user to use the API
|
||||||
|
* Requires mail and password for verifying the user
|
||||||
|
*
|
||||||
|
* @param { string } mail
|
||||||
|
* @param { string } password
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: A unique UUID token string.
|
||||||
|
*/
|
||||||
|
genAPIToken(mail, password) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
this.logUser(mail, password)
|
||||||
|
.then(v => {
|
||||||
|
let user = v.user;
|
||||||
|
let new_token = uuidv4();
|
||||||
|
|
||||||
|
bookshelf.transaction(t => {
|
||||||
|
return new token_model({
|
||||||
|
'value': new_token,
|
||||||
|
'user_uuid': user.uuid,
|
||||||
|
})
|
||||||
|
.save(null, {
|
||||||
|
transacting: t
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
// If the account already has an API key linked...
|
||||||
|
if (err.errno === 1062) {
|
||||||
|
this.fetchAPIKey(user.uuid)
|
||||||
|
.then(old_api_key => {
|
||||||
|
reject({
|
||||||
|
"message": "Votre compte a déjà généré une clé d'API.",
|
||||||
|
"code": 409,
|
||||||
|
"API_key": old_api_key.value,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.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 => {
|
||||||
|
reject(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
// Unhandled errors
|
||||||
|
.catch(() => {
|
||||||
|
reject({
|
||||||
|
"message": "Une erreur inconnue est survenue.",
|
||||||
|
"code": 500,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the email that was input is available for account creation.
|
||||||
|
*
|
||||||
|
* @param {string} mail
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled: HTTP 200 if email is available.
|
||||||
|
* Rejected: HTTP 400-409 if email is already used.
|
||||||
|
*/
|
||||||
checkIfEmailAvailable(mail) {
|
checkIfEmailAvailable(mail) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.getOneByEmail(mail, false)
|
|
||||||
.then(() => {
|
if (!(mail)) {
|
||||||
reject({
|
reject({
|
||||||
"message": "L'email est déjà utilisé par un autre utilisateur.",
|
"message": "La requête doit renseigner un email.",
|
||||||
"code": 403
|
"code": 400,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.validateMail(mail)) {
|
||||||
|
reject({
|
||||||
|
"message": "La requête n'est pas un email valide.",
|
||||||
|
"code": 400,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getOneByEmail(mail, false)
|
||||||
|
.then(() => {
|
||||||
|
reject({
|
||||||
|
"message": "Cet email est déjà lié à un compte.",
|
||||||
|
"code": 409,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
resolve({
|
||||||
|
"message": "Cet email est disponible.",
|
||||||
|
"code": 200,
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
resolve(true)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the associated api_token from a user uuid.
|
||||||
|
*
|
||||||
|
* @param { string } uuid
|
||||||
|
*
|
||||||
|
* @returns { Promise }
|
||||||
|
* Fulfilled data: Queried API token object
|
||||||
|
*/
|
||||||
|
fetchAPIKey(uuid) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
new token_model()
|
||||||
|
.where({ 'user_uuid': uuid })
|
||||||
|
.fetch()
|
||||||
|
.then(v => {
|
||||||
|
resolve(v.toJSON({ omitPivot: true }));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether a mail is correctly formed and ripe for receiving, ie: xxx@yyy.zzz.
|
||||||
|
*
|
||||||
|
* @param { string } mail
|
||||||
|
*
|
||||||
|
* @returns { boolean }
|
||||||
|
*/
|
||||||
|
validateMail(mail) {
|
||||||
|
const regex = /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
||||||
|
return regex.test(String(mail).toLowerCase());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = UserRepository
|
module.exports = UserRepository
|
||||||
@@ -1,168 +1,204 @@
|
|||||||
'use strict'
|
|
||||||
// Bookshelf
|
// Bookshelf
|
||||||
const bookshelf = require('../database/bookshelf').bookshelf
|
const bookshelf = require('../database/bookshelf').bookshelf;
|
||||||
const model = require('../models/variable-model')
|
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;
|
||||||
const isEmptyObject = require('../functions').isEmptyObject
|
const isEmptyObject = require('../functions').isEmptyObject;
|
||||||
|
|
||||||
// Error handling
|
|
||||||
const { HttpError } = require('../validations/Errors')
|
|
||||||
class VariableRepository {
|
class VariableRepository {
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
}
|
}
|
||||||
|
|
||||||
getAll() {
|
getAll() {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get variables"))
|
reject({
|
||||||
})
|
"message": "Il n'existe aucune variable disponible.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get variable"))
|
reject({
|
||||||
})
|
"message": "La variable en question n'a pas pu être trouvée.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getSpellsFromOne(id) {
|
getSpellsFromOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
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(new HttpError(500, "Couldn't get variable"))
|
reject({
|
||||||
})
|
"message": "Les sortilèges liés à cette variable n'ont pas pu être récupérés.",
|
||||||
})
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addOne(vr) {
|
addOne(vr) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(vr)) {
|
if (isEmptyObject(vr)) {
|
||||||
reject(new HttpError(403, "Error: Variable cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(vr, VariableValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(vr, VariableValidation).errors))
|
"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)) {
|
} else if (isXSSAttempt(vr.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
bookshelf.transaction(t => {
|
bookshelf.transaction(t => {
|
||||||
return model.forge({
|
return new model({
|
||||||
'description': vr.description,
|
'description': vr.description,
|
||||||
}).save(null, {
|
}).save(null, {
|
||||||
transacting: t
|
transacting: t
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
throw err
|
throw err;
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.then(v => {
|
||||||
|
return v.load(['spells']);
|
||||||
})
|
})
|
||||||
})
|
.then(v => {
|
||||||
.then(v => {
|
resolve(this.getOne(v.id));
|
||||||
return v.load(['spells'])
|
})
|
||||||
})
|
.catch(err => {
|
||||||
.then(v => {
|
console.log(err);
|
||||||
resolve(this.getOne(v.id))
|
reject({
|
||||||
})
|
"message": "Une erreur d'insertion s'est produite.",
|
||||||
.catch(err => {
|
"code": 500,
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(500, "Insert Variable error"))
|
});
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateOne(id, vr) {
|
updateOne(id, vr) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
// 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(vr)) {
|
if (isEmptyObject(vr)) {
|
||||||
reject(new HttpError(403, "Error: Variable cannot be nothing !"))
|
reject({
|
||||||
} else if (!v.validate(vr, VariableValidation).valid) {
|
"message": "Le corps de la requête ne peut pas être vide.",
|
||||||
reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(vr, VariableValidation).errors))
|
"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)) {
|
} else if (isXSSAttempt(vr.description)) {
|
||||||
reject(new HttpError(403, 'Injection attempt detected, aborting the request.'))
|
reject({
|
||||||
|
"message": "Tentative d'injection XSS détectée, requête refusée.",
|
||||||
|
"code": 403,
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
model.forge({id: id})
|
new model({ id: id })
|
||||||
.fetch({require: true, withRelated: ['spells']})
|
.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 => {
|
.then(v => {
|
||||||
return v.load(['spells'])
|
bookshelf.transaction(t => {
|
||||||
})
|
return v.save({
|
||||||
.then(v => {
|
'description': vr.description,
|
||||||
resolve(this.getOne(v.id))
|
}, {
|
||||||
|
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 => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
reject(new HttpError(500, "Update Variable error"))
|
reject({
|
||||||
})
|
"message": "La variable en question n'a pas été trouvée.",
|
||||||
})
|
"code": 404,
|
||||||
.catch(err => {
|
});
|
||||||
console.log(err)
|
});
|
||||||
reject(new HttpError(404, "Couldn't get variable"))
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteOne(id) {
|
deleteOne(id) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
model.forge()
|
new model()
|
||||||
.where({ 'id' : id })
|
.where({ 'id': id })
|
||||||
.fetch({require: true, withRelated: ['spells']})
|
.fetch({ require: true, withRelated: ['spells'] })
|
||||||
.then(v => {
|
.then(v => {
|
||||||
v.spells().detach()
|
v.spells().detach();
|
||||||
v.destroy()
|
v.destroy();
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
resolve({
|
|
||||||
'message': 'Variable with ID ' + id + ' successfully deleted !'
|
|
||||||
})
|
})
|
||||||
})
|
.then(() => {
|
||||||
.catch(err => {
|
resolve({
|
||||||
console.log(err)
|
'message': 'Variable with ID ' + id + ' successfully deleted !'
|
||||||
reject(new HttpError(404, "Couldn't get variable"))
|
});
|
||||||
})
|
})
|
||||||
})
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
reject({
|
||||||
|
"message": "La variable en question n'a pas été trouvée.",
|
||||||
|
"code": 404,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = VariableRepository
|
module.exports = VariableRepository;
|
||||||
28
api/routes/auth.js
Normal file
28
api/routes/auth.js
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
// Router
|
||||||
|
const express = require('express');
|
||||||
|
let router = express.Router();
|
||||||
|
|
||||||
|
// Repository
|
||||||
|
const UserRepository = require('../repositories/user-repository');
|
||||||
|
const Users = new UserRepository();
|
||||||
|
|
||||||
|
// ROUTES
|
||||||
|
// GEN API TOKEN
|
||||||
|
const generateAPIToken = (mail, password) => {
|
||||||
|
return Users.genAPIToken(mail, password)
|
||||||
|
.catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
router.get('/genToken', async (req, res) => {
|
||||||
|
generateAPIToken(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(err));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
const spells = require('./spells')
|
const spells = require('./spells');
|
||||||
const schools = require('./schools')
|
const schools = require('./schools');
|
||||||
const meta_schools = require('./meta_schools')
|
const meta_schools = require('./meta_schools');
|
||||||
const variables = require('./variables')
|
const variables = require('./variables');
|
||||||
const ingredients = require('./ingredients')
|
const ingredients = require('./ingredients');
|
||||||
const users = require('./users')
|
const users = require('./users');
|
||||||
|
|
||||||
|
const auth = require('./auth');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
|
auth,
|
||||||
spells,
|
spells,
|
||||||
schools,
|
schools,
|
||||||
meta_schools,
|
meta_schools,
|
||||||
ingredients,
|
ingredients,
|
||||||
variables,
|
variables,
|
||||||
users,
|
users,
|
||||||
}
|
};
|
||||||
@@ -1,168 +1,183 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// AuthGuard
|
||||||
const connection = require('../database/bookshelf')
|
const authGuard = require('./middleware/authGuard');
|
||||||
const functions = require('../functions')
|
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
const IngredientRepository = require('../repositories/ingredient-repository');
|
const IngredientRepository = require('../repositories/ingredient-repository');
|
||||||
const Ingredients = new IngredientRepository();
|
const Ingredients = new IngredientRepository();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
const functions = require('../functions');
|
||||||
|
|
||||||
// ROUTES
|
// ROUTES
|
||||||
// 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(
|
||||||
getIngredients()
|
'/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getIngredients()
|
||||||
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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getIngredient(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getIngredient(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getSpellsFromOne(req.params.id)
|
'/:id/spells',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getSpellsFromOne(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
addIngredient(req.body)
|
'/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_INGREDIENTS']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
addIngredient(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
updateIngredient(req.params.id, req.body)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_INGREDIENTS', 'MODIFY_INGREDIENTS']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
updateIngredient(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
deleteIngredient(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_INGREDIENTS', 'MODIFY_INGREDIENTS', 'DELETE_INGREDIENTS']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
deleteIngredient(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// Functions
|
||||||
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,53 +13,53 @@ 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
|
||||||
router.param('id', functions.paramIntCheck)
|
router.param('id', functions.paramIntCheck);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
23
api/routes/middleware/authGuard.js
Normal file
23
api/routes/middleware/authGuard.js
Normal 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(() => {
|
||||||
|
next();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
res.status(err.code).send(JSON.stringify(err));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = authGuard;
|
||||||
@@ -1,167 +1,182 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// AuthGuard
|
||||||
const connection = require('../database/bookshelf')
|
const authGuard = require('./middleware/authGuard');
|
||||||
const functions = require('../functions')
|
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
const SchoolRepository = require('../repositories/school-repository');
|
const SchoolRepository = require('../repositories/school-repository');
|
||||||
const Schools = new SchoolRepository();
|
const Schools = new SchoolRepository();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
const functions = require('../functions');
|
||||||
|
|
||||||
// ROUTES
|
// ROUTES
|
||||||
// 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(
|
||||||
getSchools()
|
'/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getSchools()
|
||||||
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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getSchool(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getSchool(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getSpellsFromOne(req.params.id)
|
'/:id/spells',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getSpellsFromOne(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
addSchool(req.body)
|
'/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_SCHOOL']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
addSchool(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
updateSchool(req.params.id, req.body)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_SCHOOLS', 'MODIFY_SCHOOLS']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
updateSchool(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
deleteSchool(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_SCHOOLS', 'MODIFY_SCHOOLS', 'DELETE_SCHOOLS']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
deleteSchool(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
@@ -1,191 +1,209 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// AuthGuard
|
||||||
const connection = require('../database/bookshelf')
|
const authGuard = require('./middleware/authGuard');
|
||||||
const functions = require('../functions')
|
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
const SpellReposity = require('../repositories/spell-repository');
|
const SpellReposity = require('../repositories/spell-repository');
|
||||||
const Spells = new SpellReposity();
|
const Spells = new SpellReposity();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
const functions = require('../functions');
|
||||||
|
|
||||||
// ROUTES
|
// ROUTES
|
||||||
// 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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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);
|
||||||
router.param('page', functions.paramIntCheck)
|
router.param('page', functions.paramIntCheck);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
'use strict'
|
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// AuthGuard
|
||||||
const connection = require('../database/bookshelf')
|
// const authGuard = require('./middleware/authGuard');
|
||||||
const db = connection.db
|
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
const UserRepository = require('../repositories/user-repository');
|
const UserRepository = require('../repositories/user-repository');
|
||||||
@@ -16,98 +13,166 @@ const Users = new UserRepository();
|
|||||||
// GET ALL ------------------
|
// GET ALL ------------------
|
||||||
const getUsers = () => {
|
const getUsers = () => {
|
||||||
return Users.getAll()
|
return Users.getAll()
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(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 FORM UUID ------------------
|
// GET ONE FROM UUID ------------------
|
||||||
const getUserByUUID = (uuid) => {
|
const getUserByUUID = (uuid) => {
|
||||||
return Users.getOneByUUID(uuid)
|
return Users.getOneByUUID(uuid)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(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 ------------------
|
||||||
|
const getSpellsFromUser = (uuid) => {
|
||||||
|
return Users.getSpellsFromOne(uuid)
|
||||||
|
.catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
router.get('/:uuid/spells', async (req, res) => {
|
||||||
|
getSpellsFromUser(req.params.uuid)
|
||||||
|
.then(v => {
|
||||||
|
res.setHeader('Content-Type', 'application/json;charset=utf-8');
|
||||||
|
res.end(JSON.stringify(v));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
res.status(err.code).send(JSON.stringify(
|
||||||
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"code": err.code
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// LOG A USER ------------------
|
// CHECK IF MAIL IS AVAILABLE ------------------
|
||||||
const logUser = (mail, password) => {
|
const checkIfEmailAvailable = (mail) => {
|
||||||
return Users.logUser(mail, password)
|
return Users.checkIfEmailAvailable(mail)
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err)
|
throw err;
|
||||||
throw err
|
});
|
||||||
})
|
};
|
||||||
}
|
router.get('/available/:mail/', async (req, res) => {
|
||||||
router.post('/login', async (req, res) => {
|
checkIfEmailAvailable(req.params.mail)
|
||||||
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
|
})
|
||||||
})
|
);
|
||||||
)
|
});
|
||||||
})
|
});
|
||||||
})
|
|
||||||
|
|
||||||
// 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
|
||||||
})
|
})
|
||||||
)
|
);
|
||||||
})
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
module.exports = router
|
|
||||||
|
// VERIFY A USER
|
||||||
|
const verifyUser = (token) => {
|
||||||
|
return Users.verifyUser(token)
|
||||||
|
.catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
router.get('/verification/:token', async (req, res) => {
|
||||||
|
verifyUser(req.params.token)
|
||||||
|
.then(v => {
|
||||||
|
res.setHeader('Content-Type', 'application/json;charset=utf-8');
|
||||||
|
res.send(JSON.stringify(v));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
res.status(err.code).send(JSON.stringify(
|
||||||
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"code": err.code
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// LOG A USER ------------------
|
||||||
|
const logUser = (mail, password) => {
|
||||||
|
return Users.logUser(mail, password)
|
||||||
|
.catch(err => {
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
router.post('/login', async (req, res) => {
|
||||||
|
logUser(req.body.mail, req.body.password)
|
||||||
|
.then(v => {
|
||||||
|
res.setHeader('Content-Type', 'application/json;charset=utf-8');
|
||||||
|
res.end(JSON.stringify(v));
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
res.status(err.code).send(JSON.stringify(
|
||||||
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"code": err.code
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = router;
|
||||||
@@ -1,168 +1,185 @@
|
|||||||
'use strict'
|
'use strict';
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
const express = require('express')
|
const express = require('express');
|
||||||
let router = express.Router()
|
let router = express.Router();
|
||||||
|
|
||||||
// Connection
|
// AuthGuard
|
||||||
const connection = require('../database/bookshelf')
|
const authGuard = require('./middleware/authGuard');
|
||||||
const functions = require('../functions')
|
|
||||||
|
|
||||||
// Repository
|
// Repository
|
||||||
const VariableRepository = require('../repositories/variable-repository');
|
const VariableRepository = require('../repositories/variable-repository');
|
||||||
const Variables = new VariableRepository();
|
const Variables = new VariableRepository();
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
const functions = require('../functions');
|
||||||
|
|
||||||
// ROUTES
|
// ROUTES
|
||||||
// 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(
|
||||||
getvariables()
|
'/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getvariables()
|
||||||
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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getVariable(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getVariable(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
getSpellsFromOne(req.params.id)
|
'/:id/spells',
|
||||||
.then(v => {
|
async (req, res) => {
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
getSpellsFromOne(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(
|
|
||||||
{
|
|
||||||
"error": err.message,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
addVariable(req.body)
|
'/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_VARIABLES']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
addVariable(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
updateVariable(req.params.id, req.body)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_VARIABLES', 'MODIFY_VARIABLES']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
updateVariable(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
res.status(err.code).send(JSON.stringify(
|
||||||
})
|
{
|
||||||
|
"error": err.message,
|
||||||
|
"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(
|
||||||
deleteVariable(req.params.id)
|
'/:id/',
|
||||||
.then(v => {
|
authGuard(['SUBMIT_VARIABLES', 'MODIFY_VARIABLES', 'DELETE_VARIABLES']),
|
||||||
res.setHeader('Content-Type', 'application/json;charset=utf-8')
|
async (req, res) => {
|
||||||
res.send(JSON.stringify(v))
|
deleteVariable(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,
|
|
||||||
"code": err.code
|
|
||||||
})
|
})
|
||||||
)
|
.catch(err => {
|
||||||
})
|
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);
|
||||||
|
|
||||||
module.exports = router
|
module.exports = router;
|
||||||
14
api/smtp/config.js
Normal file
14
api/smtp/config.js
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
const nodemailer = require('nodemailer');
|
||||||
|
|
||||||
|
const transport = nodemailer.createTransport({
|
||||||
|
host: "smtp.mailtrap.io",
|
||||||
|
port: 2525,
|
||||||
|
auth: {
|
||||||
|
user: process.env.SMTP_USER,
|
||||||
|
pass: process.env.SMTP_PASS,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
transport,
|
||||||
|
};
|
||||||
61
api/smtp/mails.js
Normal file
61
api/smtp/mails.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
const smtp = require('./config');
|
||||||
|
const fs = require('fs');
|
||||||
|
const handlebars = require('handlebars');
|
||||||
|
|
||||||
|
// Sender address for mail service
|
||||||
|
const sender = 'tymos@auracle.io';
|
||||||
|
|
||||||
|
// Fetches a HTML template file for parsing
|
||||||
|
const getTemplateFile = (path) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(path, { encoding: 'utf-8' }, (err, html) => {
|
||||||
|
if (err) {
|
||||||
|
reject(err);
|
||||||
|
} else {
|
||||||
|
resolve(html);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SEND REGISTRATION MAIL FUNCTION
|
||||||
|
* @param {Object} data
|
||||||
|
* - user
|
||||||
|
* - name
|
||||||
|
* - mail
|
||||||
|
* - token
|
||||||
|
*/
|
||||||
|
const sendRegistrationMail = (data) => {
|
||||||
|
getTemplateFile(__dirname + '/templates/template-sign-up.html')
|
||||||
|
.then(html => {
|
||||||
|
let template = handlebars.compile(html);
|
||||||
|
let template_parsed = template(data);
|
||||||
|
|
||||||
|
let message = {
|
||||||
|
from: sender,
|
||||||
|
to: data.user.mail,
|
||||||
|
subject: 'Inscription Auracle.io',
|
||||||
|
html: template_parsed,
|
||||||
|
};
|
||||||
|
|
||||||
|
smtp.transport.sendMail(message, (err, info) => {
|
||||||
|
if (err) {
|
||||||
|
throw err;
|
||||||
|
} else {
|
||||||
|
console.log(info);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// const sendBanEmail = (date) => {
|
||||||
|
// return null;
|
||||||
|
// };
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
sendRegistrationMail,
|
||||||
|
};
|
||||||
114
api/smtp/templates/template-sign-up.html
Normal file
114
api/smtp/templates/template-sign-up.html
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Template Email Auracle Inscription</title>
|
||||||
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700&family=Playfair+Display:wght@700;800;900&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--black: 52, 58, 64;
|
||||||
|
--white: #FFF;
|
||||||
|
--primary: 89, 158, 244;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
color: rgb(var(--black));
|
||||||
|
font-family: 'Lato', sans-serif;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.display {
|
||||||
|
font-family: 'Playfair Display', serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p:not(:last-child) {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.italics {
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wrapper {
|
||||||
|
position: relative;
|
||||||
|
padding: 10vh 5vw;
|
||||||
|
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 {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--white);
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
header,
|
||||||
|
footer {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--white);
|
||||||
|
background-color: rgb(var(--black));
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 30px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="wrapper">
|
||||||
|
<div class="container">
|
||||||
|
<header>
|
||||||
|
<h1 class="display">Bienvenue sur Auracle, {{ user.name }}!</h1>
|
||||||
|
</header>
|
||||||
|
<main>
|
||||||
|
<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/v1/users/verification/{{ user.token }}">
|
||||||
|
suivre ce lien afin de confirmer votre inscription.
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
<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>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
// Http error w/ http code
|
|
||||||
class HttpError extends Error {
|
|
||||||
constructor(code, message) {
|
|
||||||
super(message)
|
|
||||||
this.name = "HttpError"
|
|
||||||
this.code = code
|
|
||||||
Error.captureStackTrace(this, this.constructor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
HttpError
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,6 @@ const Ingredient = {
|
|||||||
"description": { "type": "string" }
|
"description": { "type": "string" }
|
||||||
},
|
},
|
||||||
"required": ["name", "description"]
|
"required": ["name", "description"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = Ingredient
|
module.exports = Ingredient;
|
||||||
@@ -7,6 +7,6 @@ const MetaSchool = {
|
|||||||
"schools": { "type": "array" }
|
"schools": { "type": "array" }
|
||||||
},
|
},
|
||||||
"required": ["name", "description"]
|
"required": ["name", "description"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = MetaSchool
|
module.exports = MetaSchool;
|
||||||
@@ -7,6 +7,6 @@ const School = {
|
|||||||
"meta_school_id": { "type": "number" },
|
"meta_school_id": { "type": "number" },
|
||||||
},
|
},
|
||||||
"required": ["name", "description", "meta_school_id"]
|
"required": ["name", "description", "meta_school_id"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = School
|
module.exports = School;
|
||||||
@@ -34,6 +34,6 @@ const Spell = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"required": ["name", "description"]
|
"required": ["name", "description"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = Spell
|
module.exports = Spell;
|
||||||
@@ -7,6 +7,6 @@ const User = {
|
|||||||
"password": { "type": "string" },
|
"password": { "type": "string" },
|
||||||
},
|
},
|
||||||
"required": ["name", "password", "mail"]
|
"required": ["name", "password", "mail"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = User
|
module.exports = User;
|
||||||
@@ -5,6 +5,6 @@ const Variable = {
|
|||||||
"description": { "type": "string" },
|
"description": { "type": "string" },
|
||||||
},
|
},
|
||||||
"required": ["description"]
|
"required": ["description"]
|
||||||
}
|
};
|
||||||
|
|
||||||
module.exports = Variable
|
module.exports = Variable;
|
||||||
33
client/.eslintrc.json
Normal file
33
client/.eslintrc.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaVersion": 6,
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"impliedStrict": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/vue3-recommended",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"indent": ["error", 2],
|
||||||
|
"accessor-pairs": "warn",
|
||||||
|
"array-callback-return": "error",
|
||||||
|
"brace-style": "warn",
|
||||||
|
"consistent-return": "error",
|
||||||
|
"default-case": "error",
|
||||||
|
"eqeqeq": "warn",
|
||||||
|
"no-case-declarations": "error",
|
||||||
|
"no-empty-pattern": "warn",
|
||||||
|
"no-fallthrough": "error",
|
||||||
|
"no-unused-vars": "error",
|
||||||
|
"no-useless-catch": "error",
|
||||||
|
"no-var": "error",
|
||||||
|
"semi": "warn",
|
||||||
|
"no-extra-semi": "error",
|
||||||
|
"yoda": "warn"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
presets: [
|
presets: [
|
||||||
'@vue/cli-plugin-babel/preset'
|
'@vue/cli-plugin-babel/preset'
|
||||||
],
|
],
|
||||||
}
|
};
|
||||||
|
|||||||
532
client/package-lock.json
generated
532
client/package-lock.json
generated
@@ -1333,12 +1333,36 @@
|
|||||||
"webpack-merge": "^4.2.2"
|
"webpack-merge": "^4.2.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@types/json-schema": {
|
||||||
|
"version": "7.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz",
|
||||||
|
"integrity": "sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"acorn": {
|
"acorn": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
|
||||||
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
|
"integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"ajv": {
|
||||||
|
"version": "6.12.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||||
|
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fast-deep-equal": "^3.1.1",
|
||||||
|
"fast-json-stable-stringify": "^2.0.0",
|
||||||
|
"json-schema-traverse": "^0.4.1",
|
||||||
|
"uri-js": "^4.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ajv-keywords": {
|
||||||
|
"version": "3.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz",
|
||||||
|
"integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"cacache": {
|
"cacache": {
|
||||||
"version": "13.0.1",
|
"version": "13.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz",
|
||||||
@@ -1363,12 +1387,59 @@
|
|||||||
"rimraf": "^2.7.1",
|
"rimraf": "^2.7.1",
|
||||||
"ssri": "^7.0.0",
|
"ssri": "^7.0.0",
|
||||||
"unique-filename": "^1.1.1"
|
"unique-filename": "^1.1.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fs-minipass": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minipass-collect": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
|
||||||
|
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minipass-flush": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minipass-pipeline": {
|
||||||
|
"version": "1.2.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz",
|
||||||
|
"integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minipass": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-map": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"aggregate-error": "^3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"find-cache-dir": {
|
"find-cache-dir": {
|
||||||
"version": "3.3.0",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz",
|
||||||
"integrity": "sha512-PtXtQb7IrD8O+h6Cq1dbpJH5NzD8+9keN1zZ0YlpDzl1PwXEJEBj6u1Xa92t1Hwluoozd9TNKul5Hi2iqpsWwg==",
|
"integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"commondir": "^1.0.1",
|
"commondir": "^1.0.1",
|
||||||
@@ -1386,6 +1457,12 @@
|
|||||||
"path-exists": "^4.0.0"
|
"path-exists": "^4.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"locate-path": {
|
"locate-path": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
|
||||||
@@ -1396,9 +1473,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"make-dir": {
|
"make-dir": {
|
||||||
"version": "3.0.2",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
"integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"semver": "^6.0.0"
|
"semver": "^6.0.0"
|
||||||
@@ -1450,21 +1527,73 @@
|
|||||||
"minipass": "^3.1.1"
|
"minipass": "^3.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "7.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"terser-webpack-plugin": {
|
"terser-webpack-plugin": {
|
||||||
"version": "2.3.5",
|
"version": "2.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.8.tgz",
|
||||||
"integrity": "sha512-WlWksUoq+E4+JlJ+h+U+QUzXpcsMSSNXkDy9lBVkSqDn1w23Gg29L/ary9GeJVYCGiNJJX7LnVc4bwL1N3/g1w==",
|
"integrity": "sha512-/fKw3R+hWyHfYx7Bv6oPqmk4HGQcrWLtV3X6ggvPuwPNHSnzvVV51z6OaaCOus4YLjutYGOz3pEpbhe6Up2s1w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cacache": "^13.0.1",
|
"cacache": "^13.0.1",
|
||||||
"find-cache-dir": "^3.2.0",
|
"find-cache-dir": "^3.3.1",
|
||||||
"jest-worker": "^25.1.0",
|
"jest-worker": "^25.4.0",
|
||||||
"p-limit": "^2.2.2",
|
"p-limit": "^2.3.0",
|
||||||
"schema-utils": "^2.6.4",
|
"schema-utils": "^2.6.6",
|
||||||
"serialize-javascript": "^2.1.2",
|
"serialize-javascript": "^4.0.0",
|
||||||
"source-map": "^0.6.1",
|
"source-map": "^0.6.1",
|
||||||
"terser": "^4.4.3",
|
"terser": "^4.6.12",
|
||||||
"webpack-sources": "^1.4.3"
|
"webpack-sources": "^1.4.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"jest-worker": {
|
||||||
|
"version": "25.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz",
|
||||||
|
"integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"merge-stream": "^2.0.0",
|
||||||
|
"supports-color": "^7.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"p-limit": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
|
||||||
|
"integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"p-try": "^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"schema-utils": {
|
||||||
|
"version": "2.7.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz",
|
||||||
|
"integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/json-schema": "^7.0.5",
|
||||||
|
"ajv": "^6.12.4",
|
||||||
|
"ajv-keywords": "^3.5.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terser": {
|
||||||
|
"version": "4.8.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/terser/-/terser-4.8.0.tgz",
|
||||||
|
"integrity": "sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"commander": "^2.20.0",
|
||||||
|
"source-map": "~0.6.1",
|
||||||
|
"source-map-support": "~0.5.12"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1785,9 +1914,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"aggregate-error": {
|
"aggregate-error": {
|
||||||
"version": "3.0.1",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||||
"integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
|
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"clean-stack": "^2.0.0",
|
"clean-stack": "^2.0.0",
|
||||||
@@ -2111,34 +2240,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"axios": {
|
"axios": {
|
||||||
"version": "0.19.2",
|
"version": "0.21.1",
|
||||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
|
||||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"follow-redirects": "1.5.10"
|
"follow-redirects": "^1.10.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"follow-redirects": {
|
|
||||||
"version": "1.5.10",
|
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
|
|
||||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
|
||||||
"requires": {
|
|
||||||
"debug": "=3.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"babel-eslint": {
|
"babel-eslint": {
|
||||||
@@ -3366,9 +3472,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"copy-webpack-plugin": {
|
"copy-webpack-plugin": {
|
||||||
"version": "5.1.1",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-5.1.2.tgz",
|
||||||
"integrity": "sha512-P15M5ZC8dyCjQHWwd4Ia/dm0SgVvZJMYeykVIVYXbGyqO4dWB5oyPHp9i7wjwo5LhtlhKbiBCdS2NvM07Wlybg==",
|
"integrity": "sha512-Uh7crJAco3AjBvgAy9Z75CjK8IG+gxaErro71THQ+vv/bl4HaQcpkexAY8KVW/T6D2W2IRr+couF/knIRkZMIQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"cacache": "^12.0.3",
|
"cacache": "^12.0.3",
|
||||||
@@ -3381,7 +3487,7 @@
|
|||||||
"normalize-path": "^3.0.0",
|
"normalize-path": "^3.0.0",
|
||||||
"p-limit": "^2.2.1",
|
"p-limit": "^2.2.1",
|
||||||
"schema-utils": "^1.0.0",
|
"schema-utils": "^1.0.0",
|
||||||
"serialize-javascript": "^2.1.2",
|
"serialize-javascript": "^4.0.0",
|
||||||
"webpack-log": "^2.0.0"
|
"webpack-log": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -4485,12 +4591,11 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"ansi-styles": {
|
"ansi-styles": {
|
||||||
"version": "4.2.1",
|
"version": "4.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
|
||||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"@types/color-name": "^1.1.1",
|
|
||||||
"color-convert": "^2.0.1"
|
"color-convert": "^2.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -4503,6 +4608,12 @@
|
|||||||
"restore-cursor": "^3.1.0"
|
"restore-cursor": "^3.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"cli-width": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"color-convert": {
|
"color-convert": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
|
||||||
@@ -4519,15 +4630,32 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"eslint-scope": {
|
"eslint-scope": {
|
||||||
"version": "5.0.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"esrecurse": "^4.1.0",
|
"esrecurse": "^4.3.0",
|
||||||
"estraverse": "^4.1.1"
|
"estraverse": "^4.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"esrecurse": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"figures": {
|
"figures": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
|
||||||
@@ -4538,18 +4666,18 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"glob-parent": {
|
"glob-parent": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz",
|
||||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
"integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"is-glob": "^4.0.1"
|
"is-glob": "^4.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"version": "12.3.0",
|
"version": "12.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz",
|
||||||
"integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
|
"integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"type-fest": "^0.8.1"
|
"type-fest": "^0.8.1"
|
||||||
@@ -4562,9 +4690,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"import-fresh": {
|
"import-fresh": {
|
||||||
"version": "3.2.1",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
|
||||||
"integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
|
"integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"parent-module": "^1.0.0",
|
"parent-module": "^1.0.0",
|
||||||
@@ -4572,30 +4700,30 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"inquirer": {
|
"inquirer": {
|
||||||
"version": "7.0.6",
|
"version": "7.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.3.3.tgz",
|
||||||
"integrity": "sha512-7SVO4h+QIdMq6XcqIqrNte3gS5MzCCKZdsq9DO4PJziBFNYzP3PGFbDjgadDb//MCahzgjCxvQ/O2wa7kx9o4w==",
|
"integrity": "sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-escapes": "^4.2.1",
|
"ansi-escapes": "^4.2.1",
|
||||||
"chalk": "^3.0.0",
|
"chalk": "^4.1.0",
|
||||||
"cli-cursor": "^3.1.0",
|
"cli-cursor": "^3.1.0",
|
||||||
"cli-width": "^2.0.0",
|
"cli-width": "^3.0.0",
|
||||||
"external-editor": "^3.0.3",
|
"external-editor": "^3.0.3",
|
||||||
"figures": "^3.0.0",
|
"figures": "^3.0.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.19",
|
||||||
"mute-stream": "0.0.8",
|
"mute-stream": "0.0.8",
|
||||||
"run-async": "^2.4.0",
|
"run-async": "^2.4.0",
|
||||||
"rxjs": "^6.5.3",
|
"rxjs": "^6.6.0",
|
||||||
"string-width": "^4.1.0",
|
"string-width": "^4.1.0",
|
||||||
"strip-ansi": "^6.0.0",
|
"strip-ansi": "^6.0.0",
|
||||||
"through": "^2.3.6"
|
"through": "^2.3.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"chalk": {
|
"chalk": {
|
||||||
"version": "3.0.0",
|
"version": "4.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
|
||||||
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
|
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"ansi-styles": "^4.1.0",
|
"ansi-styles": "^4.1.0",
|
||||||
@@ -4632,9 +4760,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"onetime": {
|
"onetime": {
|
||||||
"version": "5.1.0",
|
"version": "5.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||||
"integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
|
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"mimic-fn": "^2.1.0"
|
"mimic-fn": "^2.1.0"
|
||||||
@@ -4656,6 +4784,15 @@
|
|||||||
"signal-exit": "^3.0.2"
|
"signal-exit": "^3.0.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"rxjs": {
|
||||||
|
"version": "6.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.3.tgz",
|
||||||
|
"integrity": "sha512-trsQc+xYYXZ3urjOiJOuCOa5N3jAZ3eiSpQB5hIT8zGlL2QfnHLJ2r7GMkBGuIausdJN1OneaI6gQlsqNHHmZQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tslib": "^1.9.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
"version": "6.3.0",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
@@ -4702,9 +4839,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"supports-color": {
|
"supports-color": {
|
||||||
"version": "7.1.0",
|
"version": "7.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"has-flag": "^4.0.0"
|
"has-flag": "^4.0.0"
|
||||||
@@ -4732,14 +4869,50 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-plugin-vue": {
|
"eslint-plugin-vue": {
|
||||||
"version": "6.2.1",
|
"version": "7.0.0-beta.4",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-6.2.1.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.0.0-beta.4.tgz",
|
||||||
"integrity": "sha512-MiIDOotoWseIfLIfGeDzF6sDvHkVvGd2JgkvjyHtN3q4RoxdAXrAMuI3SXTOKatljgacKwpNAYShmcKZa4yZzw==",
|
"integrity": "sha512-yb8Kki8b94a3A1sGum9TyVAkvPfKGPzWfZcXRmA2Tylt7TRi+b6mOtn1o6kM3NWatBs5gcGiCrH033DDPn0Msw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
|
"eslint-utils": "^2.1.0",
|
||||||
"natural-compare": "^1.4.0",
|
"natural-compare": "^1.4.0",
|
||||||
"semver": "^5.6.0",
|
"semver": "^7.3.2",
|
||||||
"vue-eslint-parser": "^7.0.0"
|
"vue-eslint-parser": "^7.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"eslint-utils": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz",
|
||||||
|
"integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"eslint-visitor-keys": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lru-cache": {
|
||||||
|
"version": "6.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||||
|
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"yallist": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "7.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
|
||||||
|
"integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"yallist": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"eslint-scope": {
|
"eslint-scope": {
|
||||||
@@ -5299,9 +5472,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flatted": {
|
"flatted": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||||
"integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
|
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"flush-write-stream": {
|
"flush-write-stream": {
|
||||||
@@ -5318,7 +5491,6 @@
|
|||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.11.0.tgz",
|
||||||
"integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==",
|
"integrity": "sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^3.0.0"
|
"debug": "^3.0.0"
|
||||||
},
|
},
|
||||||
@@ -5327,7 +5499,6 @@
|
|||||||
"version": "3.2.6",
|
"version": "3.2.6",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
|
||||||
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
"integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"ms": "^2.1.1"
|
"ms": "^2.1.1"
|
||||||
}
|
}
|
||||||
@@ -5399,15 +5570,6 @@
|
|||||||
"universalify": "^0.1.0"
|
"universalify": "^0.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"fs-minipass": {
|
|
||||||
"version": "2.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
|
|
||||||
"integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fs-write-stream-atomic": {
|
"fs-write-stream-atomic": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
|
||||||
@@ -7161,33 +7323,6 @@
|
|||||||
"integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==",
|
"integrity": "sha512-yV+gqbd5vaOYjqlbk16EG89xB5udgjqQF3C5FAORDg4f/IS1Yc5ERCv5e/57yBcfJYw05V5JyIXabhwb75Xxow==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"jest-worker": {
|
|
||||||
"version": "25.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.1.0.tgz",
|
|
||||||
"integrity": "sha512-ZHhHtlxOWSxCoNOKHGbiLzXnl42ga9CxDr27H36Qn+15pQZd3R/F24jrmjDelw9j/iHUIWMWs08/u2QN50HHOg==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"merge-stream": "^2.0.0",
|
|
||||||
"supports-color": "^7.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"has-flag": {
|
|
||||||
"version": "4.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
|
|
||||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
|
|
||||||
"dev": true
|
|
||||||
},
|
|
||||||
"supports-color": {
|
|
||||||
"version": "7.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
|
|
||||||
"integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"has-flag": "^4.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"jquery": {
|
"jquery": {
|
||||||
"version": "3.5.1",
|
"version": "3.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
|
||||||
@@ -7859,33 +7994,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"minipass-collect": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz",
|
|
||||||
"integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minipass-flush": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"minipass-pipeline": {
|
|
||||||
"version": "1.2.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.2.tgz",
|
|
||||||
"integrity": "sha512-3JS5A2DKhD2g0Gg8x3yamO0pj7YeKGwVlDS90pF++kxptwx/F+B//roxf9SqYil5tQo65bijy+dAuAFZmYOouA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"minipass": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"mississippi": {
|
"mississippi": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz",
|
||||||
@@ -7951,8 +8059,7 @@
|
|||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.2",
|
"version": "2.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
|
||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"multicast-dns": {
|
"multicast-dns": {
|
||||||
"version": "6.2.3",
|
"version": "6.2.3",
|
||||||
@@ -8051,9 +8158,9 @@
|
|||||||
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
"integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw=="
|
||||||
},
|
},
|
||||||
"node-forge": {
|
"node-forge": {
|
||||||
"version": "0.9.0",
|
"version": "0.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.10.0.tgz",
|
||||||
"integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==",
|
"integrity": "sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node-gyp": {
|
"node-gyp": {
|
||||||
@@ -8642,15 +8749,6 @@
|
|||||||
"p-limit": "^2.0.0"
|
"p-limit": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"p-map": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"aggregate-error": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"p-retry": {
|
"p-retry": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz",
|
||||||
@@ -10402,12 +10500,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"selfsigned": {
|
"selfsigned": {
|
||||||
"version": "1.10.7",
|
"version": "1.10.8",
|
||||||
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz",
|
"resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.8.tgz",
|
||||||
"integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==",
|
"integrity": "sha512-2P4PtieJeEwVgTU9QEcwIRDQ/mXJLX8/+I3ur+Pg16nS8oNbrGxEso9NyYWy8NAmXiNl4dlAp5MwoNeCWzON4w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"node-forge": "0.9.0"
|
"node-forge": "^0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"semver": {
|
"semver": {
|
||||||
@@ -10469,10 +10567,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"serialize-javascript": {
|
"serialize-javascript": {
|
||||||
"version": "2.1.2",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
"integrity": "sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==",
|
"integrity": "sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==",
|
||||||
"dev": true
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"randombytes": "^2.1.0"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"serve-index": {
|
"serve-index": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
@@ -11201,9 +11302,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"strip-json-comments": {
|
"strip-json-comments": {
|
||||||
"version": "3.0.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||||
"integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
|
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"stylehacks": {
|
"stylehacks": {
|
||||||
@@ -11911,9 +12012,9 @@
|
|||||||
"integrity": "sha512-Wg+ObZoYK6McHb5OOCFWvm0R7xHp0/p0G1ocx/8bO22jvA/yVY05rADbfiztwCokXBNfQuGv/XSd1ozcTFgekw=="
|
"integrity": "sha512-Wg+ObZoYK6McHb5OOCFWvm0R7xHp0/p0G1ocx/8bO22jvA/yVY05rADbfiztwCokXBNfQuGv/XSd1ozcTFgekw=="
|
||||||
},
|
},
|
||||||
"v8-compile-cache": {
|
"v8-compile-cache": {
|
||||||
"version": "2.1.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.2.0.tgz",
|
||||||
"integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
|
"integrity": "sha512-gTpR5XQNKFwOd4clxfnhaqvfqMpqEwr4tOtCyz4MtYZX2JYhfr1JvBFKdS+7K/9rfpZR3VLX+YWBbKoxCgS43Q==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"validate-npm-package-license": {
|
"validate-npm-package-license": {
|
||||||
@@ -11966,28 +12067,62 @@
|
|||||||
"integrity": "sha512-vuEUm6wYMMrFAHFCrkzIUAy8+MgPAbBGmYXnk2M6X6O2KHbMT1wuDD2izacmsSUp6ZM02e23MJRtPRobl88VMg=="
|
"integrity": "sha512-vuEUm6wYMMrFAHFCrkzIUAy8+MgPAbBGmYXnk2M6X6O2KHbMT1wuDD2izacmsSUp6ZM02e23MJRtPRobl88VMg=="
|
||||||
},
|
},
|
||||||
"vue-eslint-parser": {
|
"vue-eslint-parser": {
|
||||||
"version": "7.0.0",
|
"version": "7.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.3.0.tgz",
|
||||||
"integrity": "sha512-yR0dLxsTT7JfD2YQo9BhnQ6bUTLsZouuzt9SKRP7XNaZJV459gvlsJo4vT2nhZ/2dH9j3c53bIx9dnqU2prM9g==",
|
"integrity": "sha512-n5PJKZbyspD0+8LnaZgpEvNCrjQx1DyDHw8JdWwoxhhC+yRip4TAvSDpXGf9SWX6b0umeB5aR61gwUo6NVvFxw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^4.1.1",
|
"debug": "^4.1.1",
|
||||||
"eslint-scope": "^5.0.0",
|
"eslint-scope": "^5.0.0",
|
||||||
"eslint-visitor-keys": "^1.1.0",
|
"eslint-visitor-keys": "^1.1.0",
|
||||||
"espree": "^6.1.2",
|
"espree": "^6.2.1",
|
||||||
"esquery": "^1.0.1",
|
"esquery": "^1.0.1",
|
||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"acorn": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"eslint-scope": {
|
"eslint-scope": {
|
||||||
"version": "5.0.0",
|
"version": "5.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
|
||||||
"integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
|
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"esrecurse": "^4.1.0",
|
"esrecurse": "^4.3.0",
|
||||||
"estraverse": "^4.1.1"
|
"estraverse": "^4.1.1"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"espree": {
|
||||||
|
"version": "6.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz",
|
||||||
|
"integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"acorn": "^7.1.1",
|
||||||
|
"acorn-jsx": "^5.2.0",
|
||||||
|
"eslint-visitor-keys": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"esrecurse": {
|
||||||
|
"version": "4.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
|
||||||
|
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"estraverse": "^5.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"estraverse": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
|
||||||
|
"integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -12033,6 +12168,21 @@
|
|||||||
"vue": "^2.0.0"
|
"vue": "^2.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"vue-meta": {
|
||||||
|
"version": "2.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-meta/-/vue-meta-2.4.0.tgz",
|
||||||
|
"integrity": "sha512-XEeZUmlVeODclAjCNpWDnjgw+t3WA6gdzs6ENoIAgwO1J1d5p1tezDhtteLUFwcaQaTtayRrsx7GL6oXp/m2Jw==",
|
||||||
|
"requires": {
|
||||||
|
"deepmerge": "^4.2.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"deepmerge": {
|
||||||
|
"version": "4.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||||
|
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"vue-router": {
|
"vue-router": {
|
||||||
"version": "3.1.6",
|
"version": "3.1.6",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.6.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-3.1.6.tgz",
|
||||||
|
|||||||
@@ -1,70 +1,59 @@
|
|||||||
{
|
{
|
||||||
"name": "spellsaurus_client",
|
"name": "spellsaurus_client",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "The client interface of spellsaurus",
|
"description": "The client interface of spellsaurus",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"rpg",
|
"rpg",
|
||||||
"dev",
|
"dev",
|
||||||
"spells",
|
"spells",
|
||||||
"roleplay",
|
"roleplay",
|
||||||
"website",
|
"website",
|
||||||
"database"
|
"database"
|
||||||
],
|
],
|
||||||
"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",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/AlexisNP/spellsaurus.git"
|
"url": "git+https://github.com/AlexisNP/spellsaurus.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"serve": "vue-cli-service serve"
|
"lint": "vue-cli-service lint",
|
||||||
},
|
"serve": "vue-cli-service serve",
|
||||||
"dependencies": {
|
"build": "vue-cli-service build"
|
||||||
"axios": "^0.19.2",
|
},
|
||||||
"bootstrap": "^4.5.0",
|
"dependencies": {
|
||||||
"bootstrap-vue": "^2.15.0",
|
"axios": "^0.21.1",
|
||||||
"core-js": "^3.6.4",
|
"bootstrap": "^4.5.0",
|
||||||
"jquery": "^3.5.1",
|
"bootstrap-vue": "^2.15.0",
|
||||||
"popper.js": "^1.16.1",
|
"core-js": "^3.6.4",
|
||||||
"v-clipboard": "^2.2.3",
|
"jquery": "^3.5.1",
|
||||||
"vue": "^2.6.11",
|
"popper.js": "^1.16.1",
|
||||||
"vue-cookies": "^1.7.0",
|
"v-clipboard": "^2.2.3",
|
||||||
"vue-masonry": "^0.11.8",
|
"vue": "^2.6.11",
|
||||||
"vuex": "^3.5.1"
|
"vue-cookies": "^1.7.0",
|
||||||
},
|
"vue-masonry": "^0.11.8",
|
||||||
"devDependencies": {
|
"vue-meta": "^2.4.0",
|
||||||
"@vue/cli-plugin-babel": "~4.2.0",
|
"vuex": "^3.5.1"
|
||||||
"@vue/cli-plugin-eslint": "~4.2.0",
|
},
|
||||||
"@vue/cli-service": "~4.2.0",
|
"devDependencies": {
|
||||||
"babel-eslint": "^10.0.3",
|
"@vue/cli-plugin-babel": "~4.2.0",
|
||||||
"eslint": "^6.7.2",
|
"@vue/cli-plugin-eslint": "~4.2.0",
|
||||||
"eslint-plugin-vue": "^6.1.2",
|
"@vue/cli-service": "~4.2.0",
|
||||||
"node-sass": "^4.14.1",
|
"babel-eslint": "^10.0.3",
|
||||||
"sass-loader": "^8.0.2",
|
"eslint": "^6.8.0",
|
||||||
"vue-router": "^3.1.6",
|
"eslint-plugin-vue": "^7.0.0-beta.4",
|
||||||
"vue-template-compiler": "^2.6.11"
|
"node-sass": "^4.14.1",
|
||||||
},
|
"sass-loader": "^8.0.2",
|
||||||
"eslintConfig": {
|
"vue-router": "^3.1.6",
|
||||||
"root": true,
|
"vue-template-compiler": "^2.6.11"
|
||||||
"env": {
|
},
|
||||||
"node": true
|
"browserslist": [
|
||||||
},
|
"> 1%",
|
||||||
"extends": [
|
"last 2 versions"
|
||||||
"plugin:vue/essential",
|
]
|
||||||
"eslint:recommended"
|
|
||||||
],
|
|
||||||
"parserOptions": {
|
|
||||||
"parser": "babel-eslint"
|
|
||||||
},
|
|
||||||
"rules": {}
|
|
||||||
},
|
|
||||||
"browserslist": [
|
|
||||||
"> 1%",
|
|
||||||
"last 2 versions"
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
client/public/favicon.png
Normal file
BIN
client/public/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
@@ -1,9 +1,9 @@
|
|||||||
import axios from "axios"
|
import axios from "axios";
|
||||||
|
|
||||||
const url = process.env.VUE_APP_API_URL
|
const url = process.env.VUE_APP_API_URL;
|
||||||
|
|
||||||
axios.defaults.headers.common[process.env.VUE_APP_API_KEY_NAME] = process.env.VUE_APP_API_KEY_VALUE
|
axios.defaults.headers.common[process.env.VUE_APP_API_KEY_NAME] = process.env.VUE_APP_API_KEY_VALUE;
|
||||||
|
|
||||||
export default axios.create({
|
export default axios.create({
|
||||||
baseURL: url
|
baseURL: url
|
||||||
})
|
});
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import api from './api'
|
import api from './api';
|
||||||
|
|
||||||
const resource = "/ingredients"
|
const resource = "/ingredients";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getAll() {
|
getAll() {
|
||||||
return api.get(`${resource}`)
|
return api.get(`${resource}`);
|
||||||
},
|
},
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return api.get(`${resource}/${id}`)
|
return api.get(`${resource}/${id}`);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import api from './api'
|
import api from './api';
|
||||||
|
|
||||||
const resource = "/meta_schools"
|
const resource = "/meta_schools";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getAll() {
|
getAll() {
|
||||||
return api.get(`${resource}`)
|
return api.get(`${resource}`);
|
||||||
},
|
},
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return api.get(`${resource}/${id}`)
|
return api.get(`${resource}/${id}`);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
import spellsRepository from './spellsRepository'
|
import spellsRepository from './spellsRepository';
|
||||||
import schoolsRepository from './schoolsRepository'
|
import schoolsRepository from './schoolsRepository';
|
||||||
import metaschoolsRepository from './metaschoolsRepository'
|
import metaschoolsRepository from './metaschoolsRepository';
|
||||||
import variablesRepository from './variablesRepository'
|
import variablesRepository from './variablesRepository';
|
||||||
import ingredientsRepository from './ingredientsRepository'
|
import ingredientsRepository from './ingredientsRepository';
|
||||||
import usersRepository from './usersRepository'
|
import usersRepository from './usersRepository';
|
||||||
|
|
||||||
// List of possible repositories
|
// List of possible repositories
|
||||||
const repositories = {
|
const repositories = {
|
||||||
spells: spellsRepository,
|
spells: spellsRepository,
|
||||||
schools: schoolsRepository,
|
schools: schoolsRepository,
|
||||||
metaschools: metaschoolsRepository,
|
metaschools: metaschoolsRepository,
|
||||||
variables: variablesRepository,
|
variables: variablesRepository,
|
||||||
ingredients: ingredientsRepository,
|
ingredients: ingredientsRepository,
|
||||||
users: usersRepository,
|
users: usersRepository,
|
||||||
}
|
};
|
||||||
|
|
||||||
// Usage : RepositoryFactoryInstance.get('reponame');
|
// Usage : RepositoryFactoryInstance.get('reponame');
|
||||||
export const RepositoryFactory = {
|
export const RepositoryFactory = {
|
||||||
get: name => repositories[name]
|
get: name => repositories[name]
|
||||||
}
|
};
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
import api from './api'
|
import api from './api';
|
||||||
|
|
||||||
const resource = "/schools"
|
const resource = "/schools";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getAll() {
|
getAll() {
|
||||||
return api.get(`${resource}`)
|
return api.get(`${resource}`);
|
||||||
},
|
},
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return api.get(`${resource}/${id}`)
|
return api.get(`${resource}/${id}`);
|
||||||
},
|
},
|
||||||
getSpellsFromOne(id) {
|
getSpellsFromOne(id) {
|
||||||
return api.get(`${resource}/${id}/spells`)
|
return api.get(`${resource}/${id}/spells`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -1,24 +1,24 @@
|
|||||||
import api from './api'
|
import api from './api';
|
||||||
|
|
||||||
const resource = "/spells"
|
const resource = "/spells";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getAll() {
|
getAll() {
|
||||||
return api.get(`${resource}`)
|
return api.get(`${resource}`);
|
||||||
},
|
},
|
||||||
getPage(page) {
|
getPage(page) {
|
||||||
return api.get(`${resource}/page/${page}`)
|
return api.get(`${resource}/page/${page}`);
|
||||||
},
|
},
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return api.get(`${resource}/${id}`)
|
return api.get(`${resource}/${id}`);
|
||||||
},
|
},
|
||||||
addOne(data) {
|
addOne(data) {
|
||||||
return api.post(`${resource}`, data)
|
return api.post(`${resource}`, data);
|
||||||
},
|
},
|
||||||
updateOne(id, data) {
|
updateOne(id, data) {
|
||||||
return api.put(`${resource}/${id}`, data)
|
return api.put(`${resource}/${id}`, data);
|
||||||
},
|
},
|
||||||
deleteOne(id) {
|
deleteOne(id) {
|
||||||
return api.delete(`${resource}/${id}`)
|
return api.delete(`${resource}/${id}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
@@ -3,10 +3,16 @@ import api from './api'
|
|||||||
const resource = "/users"
|
const resource = "/users"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
login(data) {
|
getOneFromUUID(uuid) {
|
||||||
return api.post(`${resource}/login`, data)
|
return api.get(`${resource}/${uuid}`,)
|
||||||
},
|
},
|
||||||
register(data) {
|
checkEmailAvailable(mail) {
|
||||||
return api.post(`${resource}`, data)
|
return api.get(`${resource}/available/${mail}`)
|
||||||
},
|
},
|
||||||
|
login(data) {
|
||||||
|
return api.post(`${resource}/login`, data)
|
||||||
|
},
|
||||||
|
register(data) {
|
||||||
|
return api.post(`${resource}`, data)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
import api from './api'
|
import api from './api';
|
||||||
|
|
||||||
const resource = "/variables"
|
const resource = "/variables";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getAll() {
|
getAll() {
|
||||||
return api.get(`${resource}`)
|
return api.get(`${resource}`);
|
||||||
},
|
},
|
||||||
getOne(id) {
|
getOne(id) {
|
||||||
return api.get(`${resource}/${id}`)
|
return api.get(`${resource}/${id}`);
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
@@ -1,22 +1,25 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="srs">
|
<div id="srs">
|
||||||
<header>
|
<header>
|
||||||
<navbar/>
|
<navbar />
|
||||||
</header>
|
</header>
|
||||||
<router-view/>
|
<router-view />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'app'
|
name: 'App',
|
||||||
}
|
metaInfo: {
|
||||||
|
title: 'Auracle',
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
#srs {
|
#srs {
|
||||||
padding-top: 50px;
|
padding-top: 50px;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: url('./assets/images/bg1.png') center center fixed repeat;
|
background: url('./assets/images/bg1.png') center center fixed repeat;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -54,6 +54,11 @@ hr {
|
|||||||
font-weight: $heavy;
|
font-weight: $heavy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UTILITIES
|
||||||
|
.prewrap {
|
||||||
|
white-space: pre-wrap;
|
||||||
|
}
|
||||||
|
|
||||||
// LAYOUTS
|
// LAYOUTS
|
||||||
.fullpage {
|
.fullpage {
|
||||||
min-height: calc(100vh - 56px);
|
min-height: calc(100vh - 56px);
|
||||||
|
|||||||
@@ -1,110 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="lds-roller">
|
<div class="lds-roller">
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
<div></div>
|
<div />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'loader',
|
name: 'Loader',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.lds-roller {
|
.lds-roller {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 80px;
|
width: 80px;
|
||||||
height: 80px;
|
height: 80px;
|
||||||
div {
|
div {
|
||||||
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||||
transform-origin: 40px 40px;
|
transform-origin: 40px 40px;
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 7px;
|
width: 7px;
|
||||||
height: 7px;
|
height: 7px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--primary);
|
background: var(--primary);
|
||||||
margin: -4px 0 0 -4px;
|
margin: -4px 0 0 -4px;
|
||||||
}
|
|
||||||
&:nth-child(1) {
|
|
||||||
animation-delay: -0.036s;
|
|
||||||
&:after {
|
|
||||||
top: 63px;
|
|
||||||
left: 63px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(2) {
|
|
||||||
animation-delay: -0.072s;
|
|
||||||
&:after {
|
|
||||||
top: 68px;
|
|
||||||
left: 56px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(3) {
|
|
||||||
animation-delay: -0.108s;
|
|
||||||
&:after {
|
|
||||||
top: 71px;
|
|
||||||
left: 48px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(4) {
|
|
||||||
animation-delay: -0.144s;
|
|
||||||
&:after {
|
|
||||||
top: 72px;
|
|
||||||
left: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(5) {
|
|
||||||
animation-delay: -0.18s;
|
|
||||||
&:after {
|
|
||||||
top: 71px;
|
|
||||||
left: 32px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(6) {
|
|
||||||
animation-delay: -0.216s;
|
|
||||||
&:after {
|
|
||||||
top: 68px;
|
|
||||||
left: 24px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(7) {
|
|
||||||
animation-delay: -0.252s;
|
|
||||||
&:after {
|
|
||||||
top: 63px;
|
|
||||||
left: 17px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
&:nth-child(8) {
|
|
||||||
animation-delay: -0.288s;
|
|
||||||
&:after {
|
|
||||||
top: 56px;
|
|
||||||
left: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
&:nth-child(1) {
|
||||||
|
animation-delay: -0.036s;
|
||||||
|
&:after {
|
||||||
|
top: 63px;
|
||||||
|
left: 63px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
animation-delay: -0.072s;
|
||||||
|
&:after {
|
||||||
|
top: 68px;
|
||||||
|
left: 56px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(3) {
|
||||||
|
animation-delay: -0.108s;
|
||||||
|
&:after {
|
||||||
|
top: 71px;
|
||||||
|
left: 48px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(4) {
|
||||||
|
animation-delay: -0.144s;
|
||||||
|
&:after {
|
||||||
|
top: 72px;
|
||||||
|
left: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(5) {
|
||||||
|
animation-delay: -0.18s;
|
||||||
|
&:after {
|
||||||
|
top: 71px;
|
||||||
|
left: 32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(6) {
|
||||||
|
animation-delay: -0.216s;
|
||||||
|
&:after {
|
||||||
|
top: 68px;
|
||||||
|
left: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(7) {
|
||||||
|
animation-delay: -0.252s;
|
||||||
|
&:after {
|
||||||
|
top: 63px;
|
||||||
|
left: 17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(8) {
|
||||||
|
animation-delay: -0.288s;
|
||||||
|
&:after {
|
||||||
|
top: 56px;
|
||||||
|
left: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@keyframes lds-roller {
|
@keyframes lds-roller {
|
||||||
0% {
|
0% {
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,60 +1,110 @@
|
|||||||
<template>
|
<template>
|
||||||
<nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark">
|
<nav class="navbar navbar-expand-sm fixed-top navbar-dark bg-dark">
|
||||||
<router-link :to="'/'" class="navbar-brand font-display font-weight-700">Auracle</router-link>
|
<router-link
|
||||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
|
:to="'/'"
|
||||||
<span class="navbar-toggler-icon"></span>
|
class="navbar-brand font-display font-weight-700"
|
||||||
</button>
|
>
|
||||||
<div class="collapse navbar-collapse" id="navbar">
|
Auracle
|
||||||
<ul class="navbar-nav mr-auto" v-if="links.length != 0">
|
</router-link>
|
||||||
<li class="nav-item" v-for="(link, index) in links" :key="index">
|
<button
|
||||||
<router-link :to="link.url" class="nav-link">{{ link.text }}</router-link>
|
class="navbar-toggler"
|
||||||
</li>
|
type="button"
|
||||||
</ul>
|
data-toggle="collapse"
|
||||||
<div v-if="user" class="navbar-nav">
|
data-target="#navbar"
|
||||||
<router-link :to="'/profil'" class="nav-link">{{ user.name }}</router-link>
|
aria-controls="navbar"
|
||||||
<div @click="logoutUser()" class="nav-link">Deconnexion</div>
|
aria-expanded="false"
|
||||||
</div>
|
aria-label="Toggle navigation"
|
||||||
<div v-else class="navbar-nav">
|
>
|
||||||
<router-link :to="'/connexion'" class="nav-link">Connexion</router-link>
|
<span class="navbar-toggler-icon" />
|
||||||
</div>
|
</button>
|
||||||
|
<div
|
||||||
|
id="navbar"
|
||||||
|
class="collapse navbar-collapse"
|
||||||
|
>
|
||||||
|
<ul
|
||||||
|
v-if="links.length != 0"
|
||||||
|
class="navbar-nav mr-auto"
|
||||||
|
>
|
||||||
|
<li
|
||||||
|
v-for="(link, index) in links"
|
||||||
|
:key="index"
|
||||||
|
class="nav-item"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="link.url"
|
||||||
|
class="nav-link"
|
||||||
|
>
|
||||||
|
{{ link.text }}
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div
|
||||||
|
v-if="user"
|
||||||
|
class="navbar-nav"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="'/profil'"
|
||||||
|
class="nav-link"
|
||||||
|
>
|
||||||
|
{{ user.name }}
|
||||||
|
</router-link>
|
||||||
|
<div
|
||||||
|
class="nav-link"
|
||||||
|
@click="logoutUser()"
|
||||||
|
>
|
||||||
|
Deconnexion
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="navbar-nav"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="'/connexion'"
|
||||||
|
class="nav-link"
|
||||||
|
>
|
||||||
|
Connexion
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
|
||||||
name: 'navbar',
|
export default {
|
||||||
data() {
|
name: 'Navbar',
|
||||||
return {
|
data() {
|
||||||
links: [
|
return {
|
||||||
{
|
links: [
|
||||||
text: 'Sortilèges',
|
{
|
||||||
url: '/sorts',
|
text: 'Sortilèges',
|
||||||
},
|
url: '/sorts',
|
||||||
{
|
|
||||||
text: 'Écoles',
|
|
||||||
url: '/ecoles',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
text: 'Chronologie',
|
|
||||||
url: '/ages',
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
computed: {
|
{
|
||||||
user() {
|
text: 'Écoles',
|
||||||
return this.$store.state.user
|
url: '/ecoles',
|
||||||
}
|
|
||||||
},
|
},
|
||||||
methods: {
|
{
|
||||||
logoutUser() {
|
text: 'Chronologie',
|
||||||
this.$cookies.remove('U_')
|
url: '/ages',
|
||||||
this.$store.commit('logout')
|
|
||||||
this.$router.push('/')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.getters.getUserProfile;
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
logoutUser() {
|
||||||
|
this.$store.dispatch('user_logout');
|
||||||
|
this.$router.push('/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
|
|||||||
@@ -1,159 +1,297 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-modal
|
<b-modal
|
||||||
ref="add_spell_modal"
|
ref="add_spell_modal"
|
||||||
size="lg"
|
size="lg"
|
||||||
modal-class="b-modal">
|
modal-class="b-modal"
|
||||||
|
>
|
||||||
|
<template #modal-header="{ close }">
|
||||||
|
<div
|
||||||
|
id="spell_show_edit_modal"
|
||||||
|
class="h1 modal-title font-display font-weight-bold"
|
||||||
|
>
|
||||||
|
<div class="line-height-100">
|
||||||
|
<span v-if="!spell.name">Nouveau sort</span>
|
||||||
|
<span v-if="spell.name">{{ spell.name }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
@click="close()"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:modal-header="{ close }">
|
<template #default>
|
||||||
<div class="h1 modal-title font-display font-weight-bold" id="spell_show_edit_modal">
|
<form
|
||||||
<div class="line-height-100">
|
id="add-spell"
|
||||||
<span v-if="!spell.name">Nouveau sort</span>
|
@submit="addSpell"
|
||||||
<span v-if="spell.name">{{spell.name}}</span>
|
>
|
||||||
</div>
|
<div class="form-group">
|
||||||
</div>
|
<label
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="close()">
|
for="spell_name"
|
||||||
<span aria-hidden="true">×</span>
|
class="font-weight-bold col-form-label"
|
||||||
</button>
|
>Nom :</label>
|
||||||
</template>
|
<input
|
||||||
|
id="spell_name"
|
||||||
|
v-model="spell.name"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_name"
|
||||||
|
placeholder="(256 caractères max.)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_description"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Description :</label>
|
||||||
|
<textarea
|
||||||
|
id="spell_description"
|
||||||
|
v-model="spell.description"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_description"
|
||||||
|
placeholder="(2048 caractères max.)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
id="spell_ritual"
|
||||||
|
v-model="spell.is_ritual"
|
||||||
|
type="checkbox"
|
||||||
|
class="form-check-input"
|
||||||
|
name="spell_ritual"
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
for="spell_ritual"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Rituel ? </label>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_level"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Niveau :</label>
|
||||||
|
<input
|
||||||
|
id="spell_level"
|
||||||
|
v-model="spell.level"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_level"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
placeholder="(Nombre entier de 0 à 100)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_schools"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>École(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_schools"
|
||||||
|
v-model="spell.schools"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_schools"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(school, index) in all_schools"
|
||||||
|
:key="index"
|
||||||
|
:value="'school_' + school.id"
|
||||||
|
>
|
||||||
|
{{ school.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_charge"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Charge :</label>
|
||||||
|
<input
|
||||||
|
id="spell_charge"
|
||||||
|
v-model="spell.charge"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_charge"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
placeholder="(Nombre entier de 0 à 100)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_ingredients"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Ingrédient(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_ingredients"
|
||||||
|
v-model="spell.ingredients"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_ingredients"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(ingredient,index) in all_ingredients"
|
||||||
|
:key="index"
|
||||||
|
:value="'ingredient_' + ingredient.id"
|
||||||
|
>
|
||||||
|
{{ ingredient.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_cost"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Coût :</label>
|
||||||
|
<input
|
||||||
|
id="spell_cost"
|
||||||
|
v-model="spell.cost"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_cost"
|
||||||
|
placeholder="(32 caractères max.)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_variables"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Variable(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_variables"
|
||||||
|
v-model="spell.variables"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_variables"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(variable,index) in all_variables"
|
||||||
|
:key="index"
|
||||||
|
:value="'variable_' + variable.id"
|
||||||
|
>
|
||||||
|
{{ variable.description }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:default>
|
<template #modal-footer="{ close }">
|
||||||
<form id="add-spell" @submit="addSpell">
|
<button
|
||||||
<div class="form-group">
|
type="button"
|
||||||
<label for="spell_name" class="font-weight-bold col-form-label">Nom :</label>
|
class="btn btn-secondary"
|
||||||
<input type="text" class="form-control" name="spell_name" id="spell_name" placeholder="(256 caractères max.)" v-model="spell.name">
|
data-dismiss="modal"
|
||||||
</div>
|
@click="close()"
|
||||||
<div class="form-group">
|
>
|
||||||
<label for="spell_description" class="font-weight-bold col-form-label">Description :</label>
|
Fermer
|
||||||
<textarea class="form-control" name="spell_description" id="spell_description" placeholder="(2048 caractères max.)" v-model="spell.description"></textarea>
|
</button>
|
||||||
</div>
|
<input
|
||||||
<div class="form-check form-check-inline">
|
type="submit"
|
||||||
<input type="checkbox" class="form-check-input" id="spell_ritual" name="spell_ritual" v-model="spell.is_ritual">
|
class="btn btn-primary"
|
||||||
<label for="spell_ritual" class="font-weight-bold col-form-label">Rituel ? </label>
|
value="Enregistrer"
|
||||||
</div>
|
form="add-spell"
|
||||||
<div class="form-group">
|
>
|
||||||
<label for="spell_level" class="font-weight-bold col-form-label">Niveau :</label>
|
</template>
|
||||||
<input type="number" class="form-control" name="spell_level" id="spell_level" min="0" max="100" step="1" placeholder="(Nombre entier de 0 à 100)" v-model="spell.level">
|
</b-modal>
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="spell_schools" class="font-weight-bold col-form-label">École(s) :</label>
|
|
||||||
<select class="form-control" id="spell_schools" name="spell_schools" multiple v-model="spell.schools">
|
|
||||||
<option v-for="(school, index) in all_schools" :key="index" :value="'school_' + school.id">{{school.name}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="spell_charge" class="font-weight-bold col-form-label">Charge :</label>
|
|
||||||
<input type="number" class="form-control" name="spell_charge" id="spell_charge" min="0" max="100" step="1" placeholder="(Nombre entier de 0 à 100)" v-model="spell.charge">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="spell_ingredients" class="font-weight-bold col-form-label">Ingrédient(s) :</label>
|
|
||||||
<select class="form-control" id="spell_ingredients" name="spell_ingredients" multiple v-model="spell.ingredients">
|
|
||||||
<option v-for="(ingredient,index) in all_ingredients" :key="index" :value="'ingredient_' + ingredient.id">{{ingredient.name}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="spell_cost" class="font-weight-bold col-form-label">Coût :</label>
|
|
||||||
<input type="text" class="form-control" name="spell_cost" id="spell_cost" placeholder="(32 caractères max.)" v-model="spell.cost">
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="spell_variables" class="font-weight-bold col-form-label">Variable(s) :</label>
|
|
||||||
<select class="form-control" id="spell_variables" name="spell_variables" multiple v-model="spell.variables">
|
|
||||||
<option v-for="(variable,index) in all_variables" :key="index" :value="'variable_' + variable.id">{{variable.description}}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template v-slot:modal-footer="{ close }">
|
|
||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal" @click="close()">Fermer</button>
|
|
||||||
<input type="submit" class="btn btn-primary" value="Enregistrer" form="add-spell">
|
|
||||||
</template>
|
|
||||||
|
|
||||||
</b-modal>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// API
|
// API
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
|
|
||||||
const Spells = RepositoryFactory.get('spells')
|
const Spells = RepositoryFactory.get('spells');
|
||||||
const Schools = RepositoryFactory.get('schools')
|
const Schools = RepositoryFactory.get('schools');
|
||||||
const Variables = RepositoryFactory.get('variables')
|
const Variables = RepositoryFactory.get('variables');
|
||||||
const Ingredients = RepositoryFactory.get('ingredients')
|
const Ingredients = RepositoryFactory.get('ingredients');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
'name': 'add-spell-card',
|
'name': 'AddSpellCard',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
spell: {
|
spell: {
|
||||||
type: Object,
|
type: Object,
|
||||||
name: "",
|
name: "",
|
||||||
description: "",
|
description: "",
|
||||||
is_ritual: false,
|
is_ritual: false,
|
||||||
level: 0,
|
level: 0,
|
||||||
cost: "0",
|
cost: "0",
|
||||||
charge: 0,
|
charge: 0,
|
||||||
schools: [],
|
schools: [],
|
||||||
variables: [],
|
variables: [],
|
||||||
ingredients: [],
|
ingredients: [],
|
||||||
},
|
},
|
||||||
all_schools: [],
|
all_schools: [],
|
||||||
all_variables: [],
|
all_variables: [],
|
||||||
all_ingredients: [],
|
all_ingredients: [],
|
||||||
}
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
// Gets all relevant info for multiple selects
|
// Gets all relevant info for multiple selects
|
||||||
let fetchSchools = Schools.getAll()
|
let fetchSchools = Schools.getAll();
|
||||||
let fetchVariables = Variables.getAll()
|
let fetchVariables = Variables.getAll();
|
||||||
let fetchIngredients = Ingredients.getAll()
|
let fetchIngredients = Ingredients.getAll();
|
||||||
|
|
||||||
Promise.all([fetchSchools, fetchVariables, fetchIngredients])
|
Promise.all([fetchSchools, fetchVariables, fetchIngredients])
|
||||||
|
.then(v => {
|
||||||
|
this.all_schools = v[0].data;
|
||||||
|
this.all_variables = v[1].data;
|
||||||
|
this.all_ingredients = v[2].data;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$refs["add_spell_modal"].show();
|
||||||
|
this.$root.$on('bv::modal::hide', () => {
|
||||||
|
this.$emit('cancelAdd');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
addSpell(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let schoolsData = Object.values(this.spell.schools).map(v => {
|
||||||
|
return parseInt(v.slice(7));
|
||||||
|
});
|
||||||
|
let variablesData = Object.values(this.spell.variables).map(v => {
|
||||||
|
return parseInt(v.slice(9));
|
||||||
|
});
|
||||||
|
let ingredientsData = Object.values(this.spell.ingredients).map(v => {
|
||||||
|
return parseInt(v.slice(11));
|
||||||
|
});
|
||||||
|
|
||||||
|
let data = {
|
||||||
|
name: this.spell.name,
|
||||||
|
description: this.spell.description,
|
||||||
|
is_ritual: !!+this.spell.is_ritual,
|
||||||
|
level: parseInt(this.spell.level),
|
||||||
|
cost: this.spell.cost,
|
||||||
|
charge: parseInt(this.spell.charge),
|
||||||
|
schools: schoolsData,
|
||||||
|
variables: variablesData,
|
||||||
|
ingredients: ingredientsData,
|
||||||
|
};
|
||||||
|
|
||||||
|
Spells.addOne(data)
|
||||||
.then(v => {
|
.then(v => {
|
||||||
this.all_schools = v[0].data
|
this.$emit('addSpell', v.data);
|
||||||
this.all_variables = v[1].data
|
this.$refs["add_spell_modal"].hide();
|
||||||
this.all_ingredients = v[2].data
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
})
|
});
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$refs["add_spell_modal"].show()
|
|
||||||
this.$root.$on('bv::modal::hide', () => {
|
|
||||||
this.$emit('cancelAdd')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
addSpell(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
let schoolsData = Object.values(this.spell.schools).map(v => { return parseInt(v.slice(7)) })
|
|
||||||
let variablesData = Object.values(this.spell.variables).map(v => { return parseInt(v.slice(9)) })
|
|
||||||
let ingredientsData = Object.values(this.spell.ingredients).map(v => { return parseInt(v.slice(11)) })
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
name: this.spell.name,
|
|
||||||
description: this.spell.description,
|
|
||||||
is_ritual: !!+this.spell.is_ritual,
|
|
||||||
level: parseInt(this.spell.level),
|
|
||||||
cost: this.spell.cost,
|
|
||||||
charge: parseInt(this.spell.charge),
|
|
||||||
schools: schoolsData,
|
|
||||||
variables: variablesData,
|
|
||||||
ingredients: ingredientsData,
|
|
||||||
}
|
|
||||||
|
|
||||||
Spells.addOne(data)
|
|
||||||
.then(v => {
|
|
||||||
this.$emit('addSpell', v.data)
|
|
||||||
this.$refs["add_spell_modal"].hide()
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,196 +1,341 @@
|
|||||||
<template>
|
<template>
|
||||||
<b-modal
|
<b-modal
|
||||||
ref="edit_spell_modal"
|
ref="edit_spell_modal"
|
||||||
size="lg"
|
size="lg"
|
||||||
modal-class="b-modal"
|
modal-class="b-modal"
|
||||||
:spell="computeSpell">
|
:spell="computeSpell"
|
||||||
|
>
|
||||||
|
<template #modal-header="{ close }">
|
||||||
|
<div
|
||||||
|
id="spell_show_edit_modal"
|
||||||
|
class="h1 modal-title font-display font-weight-bold"
|
||||||
|
>
|
||||||
|
<div class="line-height-100">
|
||||||
|
{{ spell.name }}#{{ spell.id }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="close"
|
||||||
|
data-dismiss="modal"
|
||||||
|
aria-label="Close"
|
||||||
|
@click="close()"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:modal-header="{ close }">
|
<template #default>
|
||||||
<div class="h1 modal-title font-display font-weight-bold" id="spell_show_edit_modal"><div class="line-height-100">{{spell.name}}#{{spell.id}}</div></div>
|
<form
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close" @click="close()">
|
id="update-spell"
|
||||||
<span aria-hidden="true">×</span>
|
ref="update-spell"
|
||||||
</button>
|
@submit="updateSpell"
|
||||||
</template>
|
>
|
||||||
|
<div class="form-group">
|
||||||
<template v-slot:default>
|
<label
|
||||||
<form id="update-spell" ref="update-spell" @submit="updateSpell">
|
for="spell_name"
|
||||||
<div class="form-group">
|
class="font-weight-bold col-form-label"
|
||||||
<label for="spell_name" class="font-weight-bold col-form-label">Nom :</label>
|
>Nom :</label>
|
||||||
<input type="text" class="form-control" name="spell_name" id="spell_name" placeholder="(256 caractères max.)" v-model="spell.name">
|
<input
|
||||||
</div>
|
id="spell_name"
|
||||||
<div class="form-group">
|
v-model="spell.name"
|
||||||
<label for="spell_description" class="font-weight-bold col-form-label">Description :</label>
|
type="text"
|
||||||
<textarea class="form-control" name="spell_description" id="spell_description" placeholder="(2048 caractères max.)" v-model="spell.description"></textarea>
|
class="form-control"
|
||||||
</div>
|
name="spell_name"
|
||||||
<div class="form-check form-check-inline">
|
placeholder="(256 caractères max.)"
|
||||||
<input type="checkbox" class="form-check-input" id="spell_ritual" name="spell_ritual" v-model="spell.is_ritual">
|
>
|
||||||
<label for="spell_ritual" class="font-weight-bold col-form-label">Rituel ? </label>
|
</div>
|
||||||
</div>
|
<div class="form-group">
|
||||||
<div class="form-group">
|
<label
|
||||||
<label for="spell_level" class="font-weight-bold col-form-label">Niveau :</label>
|
for="spell_description"
|
||||||
<input type="number" class="form-control" name="spell_level" id="spell_level" min="0" max="100" step="1" placeholder="(Nombre entier de 0 à 100)" v-model="spell.level">
|
class="font-weight-bold col-form-label"
|
||||||
</div>
|
>Description :</label>
|
||||||
<div class="form-group">
|
<textarea
|
||||||
<label for="spell_schools" class="font-weight-bold col-form-label">École(s) :</label>
|
id="spell_description"
|
||||||
<select class="form-control" id="spell_schools" name="spell_schools" multiple v-model="spell.spell_school_ids_value">
|
v-model="spell.description"
|
||||||
<option v-for="(school, index) in all_schools" :key="index" :value="'school_' + school.id">{{school.name}}</option>
|
class="form-control"
|
||||||
</select>
|
name="spell_description"
|
||||||
</div>
|
placeholder="(2048 caractères max.)"
|
||||||
<div class="form-group">
|
/>
|
||||||
<label for="spell_charge" class="font-weight-bold col-form-label">Charge :</label>
|
</div>
|
||||||
<input type="number" class="form-control" name="spell_charge" id="spell_charge" min="0" max="100" step="1" placeholder="(Nombre entier de 0 à 100)" v-model="spell.charge">
|
<div class="form-check form-check-inline">
|
||||||
</div>
|
<input
|
||||||
<div class="form-group">
|
id="spell_ritual"
|
||||||
<label for="spell_ingredients" class="font-weight-bold col-form-label">Ingrédient(s) :</label>
|
v-model="spell.is_ritual"
|
||||||
<select class="form-control" id="spell_ingredients" name="spell_ingredients" multiple v-model="spell.spell_ingredient_ids_value">
|
type="checkbox"
|
||||||
<option v-for="(ingredient,index) in all_ingredients" :key="index" :value="'ingredient_' + ingredient.id">{{ingredient.name}}</option>
|
class="form-check-input"
|
||||||
</select>
|
name="spell_ritual"
|
||||||
</div>
|
>
|
||||||
<div class="form-group">
|
<label
|
||||||
<label for="spell_cost" class="font-weight-bold col-form-label">Coût :</label>
|
for="spell_ritual"
|
||||||
<input type="text" class="form-control" name="spell_cost" id="spell_cost" placeholder="(32 caractères max.)" v-model="spell.cost">
|
class="font-weight-bold col-form-label"
|
||||||
</div>
|
>Rituel ? </label>
|
||||||
<div class="form-group">
|
</div>
|
||||||
<label for="spell_variables" class="font-weight-bold col-form-label">Variable(s) :</label>
|
<div class="form-group">
|
||||||
<select class="form-control" id="spell_variables" name="spell_variables" multiple v-model="spell.spell_variable_ids_value">
|
<label
|
||||||
<option v-for="(variable,index) in all_variables" :key="index" :value="'variable_' + variable.id">{{variable.description}}</option>
|
for="spell_level"
|
||||||
</select>
|
class="font-weight-bold col-form-label"
|
||||||
</div>
|
>Niveau :</label>
|
||||||
</form>
|
<input
|
||||||
</template>
|
id="spell_level"
|
||||||
|
v-model="spell.level"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_level"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
placeholder="(Nombre entier de 0 à 100)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_schools"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>École(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_schools"
|
||||||
|
v-model="spell.spell_school_ids_value"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_schools"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(school, index) in all_schools"
|
||||||
|
:key="index"
|
||||||
|
:value="'school_' + school.id"
|
||||||
|
>
|
||||||
|
{{ school.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_charge"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Charge :</label>
|
||||||
|
<input
|
||||||
|
id="spell_charge"
|
||||||
|
v-model="spell.charge"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_charge"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="1"
|
||||||
|
placeholder="(Nombre entier de 0 à 100)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_ingredients"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Ingrédient(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_ingredients"
|
||||||
|
v-model="spell.spell_ingredient_ids_value"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_ingredients"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(ingredient,index) in all_ingredients"
|
||||||
|
:key="index"
|
||||||
|
:value="'ingredient_' + ingredient.id"
|
||||||
|
>
|
||||||
|
{{ ingredient.name }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_cost"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Coût :</label>
|
||||||
|
<input
|
||||||
|
id="spell_cost"
|
||||||
|
v-model="spell.cost"
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_cost"
|
||||||
|
placeholder="(32 caractères max.)"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label
|
||||||
|
for="spell_variables"
|
||||||
|
class="font-weight-bold col-form-label"
|
||||||
|
>Variable(s) :</label>
|
||||||
|
<select
|
||||||
|
id="spell_variables"
|
||||||
|
v-model="spell.spell_variable_ids_value"
|
||||||
|
class="form-control"
|
||||||
|
name="spell_variables"
|
||||||
|
multiple
|
||||||
|
>
|
||||||
|
<option
|
||||||
|
v-for="(variable,index) in all_variables"
|
||||||
|
:key="index"
|
||||||
|
:value="'variable_' + variable.id"
|
||||||
|
>
|
||||||
|
{{ variable.description }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
<template v-slot:modal-footer="{ close }">
|
<template #modal-footer="{ close }">
|
||||||
<button type="button" class="btn btn-danger" data-dismiss="modal" @click="close()">Fermer</button>
|
<button
|
||||||
<input type="submit" class="btn btn-primary" value="Enregistrer" form="update-spell">
|
type="button"
|
||||||
</template>
|
class="btn btn-danger"
|
||||||
</b-modal>
|
data-dismiss="modal"
|
||||||
|
@click="close()"
|
||||||
|
>
|
||||||
|
Fermer
|
||||||
|
</button>
|
||||||
|
<!-- <input type="button" class="btn btn-success" value="Enregistrer comme nouveau" @click="cloneSpell()"> -->
|
||||||
|
<input
|
||||||
|
type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
value="Enregistrer"
|
||||||
|
form="update-spell"
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</b-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// API
|
// API
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
const Spells = RepositoryFactory.get('spells')
|
const Spells = RepositoryFactory.get('spells');
|
||||||
const Schools = RepositoryFactory.get('schools')
|
const Schools = RepositoryFactory.get('schools');
|
||||||
const Variables = RepositoryFactory.get('variables')
|
const Variables = RepositoryFactory.get('variables');
|
||||||
const Ingredients = RepositoryFactory.get('ingredients')
|
const Ingredients = RepositoryFactory.get('ingredients');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'edit-spell-card',
|
name: 'EditSpellCard',
|
||||||
props: {
|
props: {
|
||||||
spell: {
|
spell: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
id: Number,
|
id: Number,
|
||||||
name: String,
|
name: String,
|
||||||
description: String,
|
description: String,
|
||||||
is_ritual: Boolean,
|
is_ritual: Boolean,
|
||||||
schools: Array,
|
schools: Array,
|
||||||
variables: Array,
|
variables: Array,
|
||||||
ingredients: Array,
|
ingredients: Array,
|
||||||
},
|
|
||||||
},
|
},
|
||||||
data() {
|
},
|
||||||
return {
|
data() {
|
||||||
all_schools: [],
|
return {
|
||||||
all_variables: [],
|
all_schools: [],
|
||||||
all_ingredients: [],
|
all_variables: [],
|
||||||
}
|
all_ingredients: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
computeSpell() {
|
||||||
|
let output = this.spell;
|
||||||
|
output.spell_school_ids = [];
|
||||||
|
output.spell_variable_ids = [];
|
||||||
|
output.spell_ingredient_ids = [];
|
||||||
|
output.spell_school_ids_value = [];
|
||||||
|
output.spell_variable_ids_value = [];
|
||||||
|
output.spell_ingredient_ids_value = [];
|
||||||
|
|
||||||
|
output.schools.forEach(element => {
|
||||||
|
output.spell_school_ids.push(element['id']);
|
||||||
|
});
|
||||||
|
output.variables.forEach(element => {
|
||||||
|
output.spell_variable_ids.push(element['id']);
|
||||||
|
});
|
||||||
|
output.ingredients.forEach(element => {
|
||||||
|
output.spell_ingredient_ids.push(element['id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
output.spell_school_ids.forEach(element => {
|
||||||
|
output.spell_school_ids_value.push("school_" + element);
|
||||||
|
});
|
||||||
|
output.spell_variable_ids.forEach(element => {
|
||||||
|
output.spell_variable_ids_value.push("variable_" + element);
|
||||||
|
});
|
||||||
|
output.spell_ingredient_ids.forEach(element => {
|
||||||
|
output.spell_ingredient_ids_value.push("ingredient_" + element);
|
||||||
|
});
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
computeSpell: {
|
||||||
|
deep: true,
|
||||||
|
handler() {
|
||||||
|
this.$refs["edit_spell_modal"].show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// Gets all relevant info for multiple selects
|
||||||
|
let fetchSchools = Schools.getAll();
|
||||||
|
let fetchVariables = Variables.getAll();
|
||||||
|
let fetchIngredients = Ingredients.getAll();
|
||||||
|
|
||||||
|
Promise.all([fetchSchools, fetchVariables, fetchIngredients])
|
||||||
|
.then(v => {
|
||||||
|
this.all_schools = v[0].data;
|
||||||
|
this.all_variables = v[1].data;
|
||||||
|
this.all_ingredients = v[2].data;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.$refs["edit_spell_modal"].show();
|
||||||
|
this.$root.$on('bv::modal::hide', () => {
|
||||||
|
this.$emit('editSpell', {});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cloneSpell() {
|
||||||
},
|
},
|
||||||
computed: {
|
updateSpell(e) {
|
||||||
computeSpell() {
|
e.preventDefault();
|
||||||
let output = this.spell
|
|
||||||
output.spell_school_ids = []
|
|
||||||
output.spell_variable_ids = []
|
|
||||||
output.spell_ingredient_ids = []
|
|
||||||
output.spell_school_ids_value = []
|
|
||||||
output.spell_variable_ids_value = []
|
|
||||||
output.spell_ingredient_ids_value = []
|
|
||||||
|
|
||||||
output.schools.forEach(element => {
|
let schoolsData = Object.values(this.spell.spell_school_ids_value).map(v => {
|
||||||
output.spell_school_ids.push(element['id'])
|
return parseInt(v.slice(7));
|
||||||
})
|
});
|
||||||
output.variables.forEach(element => {
|
let variablesData = Object.values(this.spell.spell_variable_ids_value).map(v => {
|
||||||
output.spell_variable_ids.push(element['id'])
|
return parseInt(v.slice(9));
|
||||||
})
|
});
|
||||||
output.ingredients.forEach(element => {
|
let ingredientsData = Object.values(this.spell.spell_ingredient_ids_value).map(v => {
|
||||||
output.spell_ingredient_ids.push(element['id'])
|
return parseInt(v.slice(11));
|
||||||
})
|
});
|
||||||
|
|
||||||
output.spell_school_ids.forEach(element => {
|
let data = {
|
||||||
output.spell_school_ids_value.push("school_" + element)
|
name: this.spell.name,
|
||||||
})
|
description: this.spell.description,
|
||||||
output.spell_variable_ids.forEach(element => {
|
is_ritual: !!+this.spell.is_ritual,
|
||||||
output.spell_variable_ids_value.push("variable_" + element)
|
level: parseInt(this.spell.level),
|
||||||
})
|
cost: this.spell.cost,
|
||||||
output.spell_ingredient_ids.forEach(element => {
|
charge: parseInt(this.spell.charge),
|
||||||
output.spell_ingredient_ids_value.push("ingredient_" + element)
|
schools: schoolsData,
|
||||||
})
|
variables: variablesData,
|
||||||
|
ingredients: ingredientsData,
|
||||||
|
};
|
||||||
|
|
||||||
return output
|
Spells.updateOne(this.spell.id, data)
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
// Gets all relevant info for multiple selects
|
|
||||||
let fetchSchools = Schools.getAll()
|
|
||||||
let fetchVariables = Variables.getAll()
|
|
||||||
let fetchIngredients = Ingredients.getAll()
|
|
||||||
|
|
||||||
Promise.all([fetchSchools, fetchVariables, fetchIngredients])
|
|
||||||
.then(v => {
|
.then(v => {
|
||||||
this.all_schools = v[0].data
|
this.$emit('updateSpell', v.data);
|
||||||
this.all_variables = v[1].data
|
|
||||||
this.all_ingredients = v[2].data
|
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
console.log(err)
|
console.log(err);
|
||||||
})
|
});
|
||||||
},
|
},
|
||||||
mounted() {
|
}
|
||||||
this.$refs["edit_spell_modal"].show()
|
};
|
||||||
this.$root.$on('bv::modal::hide', () => {
|
|
||||||
this.$emit('editSpell', {})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
computeSpell: {
|
|
||||||
deep: true,
|
|
||||||
handler() {
|
|
||||||
this.$refs["edit_spell_modal"].show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
cloneSpell() {
|
|
||||||
},
|
|
||||||
updateSpell(e) {
|
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
let schoolsData = Object.values(this.spell.spell_school_ids_value).map(v => { return parseInt(v.slice(7)) })
|
|
||||||
let variablesData = Object.values(this.spell.spell_variable_ids_value).map(v => { return parseInt(v.slice(9)) })
|
|
||||||
let ingredientsData = Object.values(this.spell.spell_ingredient_ids_value).map(v => { return parseInt(v.slice(11)) })
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
name: this.spell.name,
|
|
||||||
description: this.spell.description,
|
|
||||||
is_ritual: !!+this.spell.is_ritual,
|
|
||||||
level: parseInt(this.spell.level),
|
|
||||||
cost: this.spell.cost,
|
|
||||||
charge: parseInt(this.spell.charge),
|
|
||||||
schools: schoolsData,
|
|
||||||
variables: variablesData,
|
|
||||||
ingredients: ingredientsData,
|
|
||||||
}
|
|
||||||
|
|
||||||
Spells.updateOne(this.spell.id, data)
|
|
||||||
.then(v => {
|
|
||||||
this.$emit('updateSpell', v.data)
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,150 +1,204 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div
|
||||||
|
:class="main_school"
|
||||||
|
class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4 grid-item grid-sizer"
|
||||||
|
>
|
||||||
<div
|
<div
|
||||||
:class="main_school"
|
class="spellcard bg-white p-4 rounded text-dark shadow"
|
||||||
class="col-12 col-sm-6 col-lg-4 col-xl-3 mb-4 grid-item grid-sizer">
|
style="border-left-width:4px;border-left-style:solid;"
|
||||||
<div class="spellcard bg-white p-4 rounded text-dark shadow" style="border-left-width:4px;border-left-style:solid;">
|
>
|
||||||
|
<div
|
||||||
|
:title="spell.name"
|
||||||
|
class="h3 font-display font-weight-bold text-wrap word-break"
|
||||||
|
style="line-height:100%;"
|
||||||
|
>
|
||||||
|
<router-link
|
||||||
|
:to="`/sorts/${spell.id}`"
|
||||||
|
class="text-decoration-none"
|
||||||
|
>
|
||||||
|
{{ spell.name }}
|
||||||
|
</router-link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div :title="spell.name" class="h3 font-display font-weight-bold text-wrap word-break" style="line-height:100%;">
|
<div>
|
||||||
<router-link :to="`/sorts/${spell.id}`" class="text-decoration-none">{{spell.name}}</router-link>
|
<div class="font-weight-700 text-muted d-inline-block">
|
||||||
</div>
|
Niveau {{ spell.level }}
|
||||||
|
|
||||||
<div>
|
|
||||||
<div class="font-weight-700 text-muted d-inline-block">Niveau {{spell.level}}</div>
|
|
||||||
<span> · </span>
|
|
||||||
<div class="text-muted d-inline-block">
|
|
||||||
<span v-for="(school,index) in spell.schools" :key="index">
|
|
||||||
<span v-if="index!=0">, </span>
|
|
||||||
<router-link :to="`ecoles/${school.id}`" class="text-secondary">{{school.name}}</router-link>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="spell.charge!=0" class="small font-weight-bold">
|
|
||||||
<span>Charge {{spell.charge}} tour(s)</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="spell.is_ritual" class="small font-weight-bold">
|
|
||||||
<span>Rituel</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="spell.ingredients.length>0" class="small">
|
|
||||||
<span class="font-weight-bold">Nécessite </span>
|
|
||||||
<span v-for="(ingredient,index) in spell.ingredients" :key="index">
|
|
||||||
<span v-if="index!=0">, </span>
|
|
||||||
<span>{{ingredient.name}}</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
v-clipboard="spell.description"
|
|
||||||
:id="'spell_description_' + spell.id"
|
|
||||||
v-b-tooltip.click
|
|
||||||
placement="bottom"
|
|
||||||
title="Description copiée !"
|
|
||||||
class="small text-muted mt-2">
|
|
||||||
<span style="white-space: pre-wrap;">{{spell.description}}</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-2">
|
|
||||||
<div class="font-weight-bold d-inline-block"><span>Coût </span>{{spell.cost}}</div>
|
|
||||||
<div v-if="spell.variables.length>0" class="small d-inline-block">, où :</div>
|
|
||||||
<div class=small>
|
|
||||||
<span v-for="(variable,index) in spell.variables" :key="index">
|
|
||||||
<span class="font-weight-bold">
|
|
||||||
<span v-if="index!=0"><br></span>
|
|
||||||
<span>{{String.fromCharCode(120+index)}}</span>
|
|
||||||
</span>
|
|
||||||
<span> = {{variable.description}}</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<footer v-if="user" class="text-right">
|
|
||||||
<a class="h5 text-secondary mr-1">
|
|
||||||
<i class="mad" @click="editSpell(spell)">edit</i>
|
|
||||||
</a>
|
|
||||||
<a class="h5 text-danger">
|
|
||||||
<i class="mad" @click="deleteSpell(spell)">delete</i>
|
|
||||||
</a>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<span> · </span>
|
||||||
|
<div class="text-muted d-inline-block">
|
||||||
|
<span
|
||||||
|
v-for="(school,index) in spell.schools"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<span v-if="index!=0">, </span>
|
||||||
|
<router-link
|
||||||
|
:to="`ecoles/${school.id}`"
|
||||||
|
class="text-secondary"
|
||||||
|
>{{ school.name }}</router-link>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="spell.charge!=0"
|
||||||
|
class="small font-weight-bold"
|
||||||
|
>
|
||||||
|
<span>Charge {{ spell.charge }} tour(s)</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="spell.is_ritual"
|
||||||
|
class="small font-weight-bold"
|
||||||
|
>
|
||||||
|
<span>Rituel</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="spell.ingredients.length>0"
|
||||||
|
class="small"
|
||||||
|
>
|
||||||
|
<span class="font-weight-bold">Nécessite </span>
|
||||||
|
<span
|
||||||
|
v-for="(ingredient,index) in spell.ingredients"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<span v-if="index!=0">, </span>
|
||||||
|
<span>{{ ingredient.name }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
:id="'spell_description_' + spell.id"
|
||||||
|
v-clipboard="spell.description"
|
||||||
|
v-b-tooltip.click
|
||||||
|
placement="bottom"
|
||||||
|
title="Description copiée !"
|
||||||
|
class="small text-muted mt-2"
|
||||||
|
>
|
||||||
|
<span class="prewrap">{{ spell.description }}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mt-2">
|
||||||
|
<div class="font-weight-bold d-inline-block">
|
||||||
|
<span>Coût : </span>{{ spell.cost }}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="spell.variables.length>0"
|
||||||
|
class="small d-inline-block"
|
||||||
|
>
|
||||||
|
, où :
|
||||||
|
</div>
|
||||||
|
<div class="small">
|
||||||
|
<span
|
||||||
|
v-for="(variable,index) in spell.variables"
|
||||||
|
:key="index"
|
||||||
|
>
|
||||||
|
<span class="font-weight-bold">
|
||||||
|
<span v-if="index!=0"><br></span>
|
||||||
|
<span>{{ String.fromCharCode(120+index) }}</span>
|
||||||
|
</span>
|
||||||
|
<span> = {{ variable.description }}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<footer
|
||||||
|
v-if="user"
|
||||||
|
class="text-right"
|
||||||
|
>
|
||||||
|
<a class="h5 text-secondary mr-1">
|
||||||
|
<i
|
||||||
|
class="mad"
|
||||||
|
@click="editSpell(spell)"
|
||||||
|
>edit</i>
|
||||||
|
</a>
|
||||||
|
<a class="h5 text-danger">
|
||||||
|
<i
|
||||||
|
class="mad"
|
||||||
|
@click="deleteSpell(spell)"
|
||||||
|
>delete</i>
|
||||||
|
</a>
|
||||||
|
</footer>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// API
|
// API
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
const Spells = RepositoryFactory.get('spells')
|
const Spells = RepositoryFactory.get('spells');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'spell-card',
|
name: 'SpellCard',
|
||||||
props: {
|
props: {
|
||||||
spell: Object,
|
spell: Object,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
main_school: this.spell.schools[0].name,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.getters.getUserProfile;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.main_school = this.main_school.toLowerCase();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
editSpell(spell) {
|
||||||
|
this.$emit('editSpell', spell);
|
||||||
},
|
},
|
||||||
data() {
|
deleteSpell(spell) {
|
||||||
return {
|
Spells.deleteOne(this.spell.id)
|
||||||
main_school: this.spell.schools[0].name,
|
.then(() => {
|
||||||
}
|
this.$emit('deleteSpell', spell);
|
||||||
},
|
});
|
||||||
created() {
|
}
|
||||||
this.main_school = this.main_school.toLowerCase()
|
},
|
||||||
},
|
};
|
||||||
computed: {
|
|
||||||
user() {
|
|
||||||
return this.$store.state.user
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
editSpell(spell) {
|
|
||||||
this.$emit('editSpell', spell)
|
|
||||||
},
|
|
||||||
deleteSpell(spell) {
|
|
||||||
Spells.deleteOne(this.spell.id)
|
|
||||||
.then(() => {
|
|
||||||
this.$emit('deleteSpell', spell)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.spell-card {
|
|
||||||
footer {
|
.spell-card {
|
||||||
a {
|
footer {
|
||||||
cursor: pointer;
|
a {
|
||||||
}
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
@mixin colorschool($sname,$scolor) {
|
|
||||||
&.#{$sname} {
|
|
||||||
.spellcard { border-left-color: $scolor; }
|
|
||||||
.h3>a { color: $scolor; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@include colorschool(lumomancie,#babaa4);
|
|
||||||
@include colorschool(vitamancie,#57ab6e);
|
|
||||||
@include colorschool(obstrumancie,#bd4a66);
|
|
||||||
@include colorschool(tenebromancie,#404842);
|
|
||||||
@include colorschool(necromancie,#5d4777);
|
|
||||||
@include colorschool(morbomancie,#d8733d);
|
|
||||||
@include colorschool(pyromancie,#b6362a);
|
|
||||||
@include colorschool(hydromancie,#3f68c7);
|
|
||||||
@include colorschool(electromancie,#cd9731);
|
|
||||||
@include colorschool(terramancie,#7e5540);
|
|
||||||
@include colorschool(sidéromancie,#58697a);
|
|
||||||
@include colorschool(caelomancie,#a8a8a8);
|
|
||||||
@include colorschool(légimancie,#5dbabd);
|
|
||||||
@include colorschool(illusiomancie,#9f63a1);
|
|
||||||
@include colorschool(cruciomancie,#252451);
|
|
||||||
@include colorschool(chronomancie,#79896a);
|
|
||||||
@include colorschool(spatiomancie,#2d4776);
|
|
||||||
@include colorschool(kénomancie,#101010);
|
|
||||||
@include colorschool(lutomancie,#4e2827);
|
|
||||||
@include colorschool(échomancie,#6d9fd1);
|
|
||||||
@include colorschool(protomancie,#4f5751);
|
|
||||||
@include colorschool(rebumancie,#8e7245);
|
|
||||||
@include colorschool(vocamancie,#247864);
|
|
||||||
@include colorschool(somamancie,#976c67);
|
|
||||||
@include colorschool(antimancie,#ad95c1);
|
|
||||||
}
|
}
|
||||||
|
@mixin colorschool($sname,$scolor) {
|
||||||
|
&.#{$sname} {
|
||||||
|
.spellcard { border-left-color: $scolor; }
|
||||||
|
.h3>a { color: $scolor; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@include colorschool(lumomancie,#babaa4);
|
||||||
|
@include colorschool(vitamancie,#57ab6e);
|
||||||
|
@include colorschool(obstrumancie,#bd4a66);
|
||||||
|
@include colorschool(tenebromancie,#404842);
|
||||||
|
@include colorschool(necromancie,#5d4777);
|
||||||
|
@include colorschool(morbomancie,#d8733d);
|
||||||
|
@include colorschool(pyromancie,#b6362a);
|
||||||
|
@include colorschool(hydromancie,#3f68c7);
|
||||||
|
@include colorschool(electromancie,#cd9731);
|
||||||
|
@include colorschool(terramancie,#7e5540);
|
||||||
|
@include colorschool(sidéromancie,#58697a);
|
||||||
|
@include colorschool(caelomancie,#a8a8a8);
|
||||||
|
@include colorschool(légimancie,#5dbabd);
|
||||||
|
@include colorschool(illusiomancie,#9f63a1);
|
||||||
|
@include colorschool(cruciomancie,#252451);
|
||||||
|
@include colorschool(chronomancie,#79896a);
|
||||||
|
@include colorschool(spatiomancie,#2d4776);
|
||||||
|
@include colorschool(kénomancie,#101010);
|
||||||
|
@include colorschool(lutomancie,#4e2827);
|
||||||
|
@include colorschool(échomancie,#6d9fd1);
|
||||||
|
@include colorschool(protomancie,#4f5751);
|
||||||
|
@include colorschool(rebumancie,#8e7245);
|
||||||
|
@include colorschool(vocamancie,#247864);
|
||||||
|
@include colorschool(somamancie,#976c67);
|
||||||
|
@include colorschool(antimancie,#ad95c1);
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,224 +1,290 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="spell-list-wrapper">
|
<div class="spell-list-wrapper">
|
||||||
|
<div class="mb-4">
|
||||||
<div class="mb-4">
|
<form>
|
||||||
<form>
|
<div class="form-group mb-2">
|
||||||
<div class="form-group mb-2">
|
<input
|
||||||
<input type="text" class="form-control" v-model="search_text" name="search_terms" id="search_terms" placeholder="Rechercher l'arcane">
|
id="search_terms"
|
||||||
</div>
|
v-model="search_text"
|
||||||
<div class="mb-3">
|
type="text"
|
||||||
<div class="form-check form-check-inline">
|
class="form-control"
|
||||||
<input class="form-check-input" type="radio" name="search_term" id="search_fields_name" value="search_fields_name">
|
name="search_terms"
|
||||||
<label class="form-check-label" for="search_fields_name">Nom</label>
|
placeholder="Rechercher l'arcane"
|
||||||
</div>
|
>
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="radio" name="search_term" id="search_fields_description" value="search_fields_description" checked>
|
|
||||||
<label class="form-check-label" for="search_fields_description">Description</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="radio" name="search_term" id="search_fields_schools" value="search_fields_schools" disabled>
|
|
||||||
<label class="form-check-label" for="search_fields_schools">École(s)</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="radio" name="search_term" id="search_fields_ingredients" value="search_fields_ingredients" disabled>
|
|
||||||
<label class="form-check-label" for="search_fields_ingredients">Ingrédients</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check form-check-inline">
|
|
||||||
<input class="form-check-input" type="radio" name="search_term" id="search_fields_variables" value="search_fields_variables" disabled>
|
|
||||||
<label class="form-check-label" for="search_fields_variables">Variables</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
<div class="mb-3">
|
||||||
<button
|
<div class="form-check form-check-inline">
|
||||||
v-if="user"
|
<input
|
||||||
@click="showAdd"
|
id="search_fields_name"
|
||||||
type="button"
|
class="form-check-input"
|
||||||
class="btn font-display font-weight-bold btn-lg btn-outline-dark btn-block shadow-sm mb-4">
|
type="radio"
|
||||||
|
name="search_term"
|
||||||
<i class="mad">add</i>
|
value="search_fields_name"
|
||||||
<span>Ajouter un sort</span>
|
>
|
||||||
</button>
|
<label
|
||||||
|
class="form-check-label"
|
||||||
<div
|
for="search_fields_name"
|
||||||
v-if="filteredSpells.length > 0"
|
>Nom</label>
|
||||||
class="spell-list-wrapper">
|
</div>
|
||||||
<div
|
<div class="form-check form-check-inline">
|
||||||
class="row spells-list"
|
<input
|
||||||
v-masonry
|
id="search_fields_description"
|
||||||
transition-duration="1s"
|
class="form-check-input"
|
||||||
item-selector=".spell-card">
|
type="radio"
|
||||||
<spell-card
|
name="search_term"
|
||||||
class="spell-card"
|
value="search_fields_description"
|
||||||
v-masonry-tile
|
checked
|
||||||
v-for="(spell) in filteredSpells"
|
>
|
||||||
:key="spell.id"
|
<label
|
||||||
:spell="spell"
|
class="form-check-label"
|
||||||
@editSpell="editSpell"
|
for="search_fields_description"
|
||||||
@deleteSpell="deleteSpell" />
|
>Description</label>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
<edit-spell-card
|
<input
|
||||||
v-if="Object.keys(current_edit_spell).length > 0"
|
id="search_fields_schools"
|
||||||
:spell="current_edit_spell"
|
class="form-check-input"
|
||||||
@editSpell="editSpell"
|
type="radio"
|
||||||
@updateSpell="updateSpell"/>
|
name="search_term"
|
||||||
|
value="search_fields_schools"
|
||||||
<add-spell-card
|
disabled
|
||||||
v-if="adding_spell"
|
>
|
||||||
@cancelAdd="cancelAdd"
|
<label
|
||||||
@addSpell="addSpell"/>
|
class="form-check-label"
|
||||||
</div>
|
for="search_fields_schools"
|
||||||
<div
|
>
|
||||||
v-else
|
École(s)
|
||||||
class="loader-wrapper">
|
</label>
|
||||||
<loader/>
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
id="search_fields_ingredients"
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="search_term"
|
||||||
|
value="search_fields_ingredients"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="search_fields_ingredients"
|
||||||
|
>Ingrédients</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check form-check-inline">
|
||||||
|
<input
|
||||||
|
id="search_fields_variables"
|
||||||
|
class="form-check-input"
|
||||||
|
type="radio"
|
||||||
|
name="search_term"
|
||||||
|
value="search_fields_variables"
|
||||||
|
disabled
|
||||||
|
>
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="search_fields_variables"
|
||||||
|
>Variables</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
v-if="user"
|
||||||
|
type="button"
|
||||||
|
class="btn font-display font-weight-bold btn-lg btn-outline-dark btn-block shadow-sm mb-4"
|
||||||
|
@click="showAdd"
|
||||||
|
>
|
||||||
|
<i class="mad">add</i>
|
||||||
|
<span>Ajouter un sort</span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="filteredSpells.length > 0"
|
||||||
|
class="spell-list-wrapper"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
v-masonry
|
||||||
|
class="row spells-list"
|
||||||
|
transition-duration="1s"
|
||||||
|
item-selector=".spell-card"
|
||||||
|
>
|
||||||
|
<spell-card
|
||||||
|
v-for="(spell) in filteredSpells"
|
||||||
|
:key="spell.id"
|
||||||
|
v-masonry-tile
|
||||||
|
class="spell-card"
|
||||||
|
:spell="spell"
|
||||||
|
@editSpell="editSpell"
|
||||||
|
@deleteSpell="deleteSpell"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<edit-spell-card
|
||||||
|
v-if="Object.keys(current_edit_spell).length > 0"
|
||||||
|
:spell="current_edit_spell"
|
||||||
|
@editSpell="editSpell"
|
||||||
|
@updateSpell="updateSpell"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<add-spell-card
|
||||||
|
v-if="adding_spell"
|
||||||
|
@cancelAdd="cancelAdd"
|
||||||
|
@addSpell="addSpell"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else
|
||||||
|
class="loader-wrapper"
|
||||||
|
>
|
||||||
|
<loader />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Components
|
// Components
|
||||||
import SpellCard from "./spell-card"
|
import SpellCard from "./spell-card";
|
||||||
import EditSpellCard from "./edit-spell-card"
|
import EditSpellCard from "./edit-spell-card";
|
||||||
import AddSpellCard from "./add-spell-card"
|
import AddSpellCard from "./add-spell-card";
|
||||||
|
|
||||||
// API
|
// API
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
const Spells = RepositoryFactory.get('spells')
|
const Spells = RepositoryFactory.get('spells');
|
||||||
const Schools = RepositoryFactory.get('schools')
|
const Schools = RepositoryFactory.get('schools');
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'spellslist',
|
name: 'Spellslist',
|
||||||
components: {
|
components: {
|
||||||
'spell-card': SpellCard,
|
'spell-card': SpellCard,
|
||||||
'edit-spell-card': EditSpellCard,
|
'edit-spell-card': EditSpellCard,
|
||||||
'add-spell-card': AddSpellCard,
|
'add-spell-card': AddSpellCard,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
schoolId: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
},
|
},
|
||||||
props: {
|
},
|
||||||
school_id: String,
|
data() {
|
||||||
|
return {
|
||||||
|
spells: [],
|
||||||
|
loading: false,
|
||||||
|
current_edit_spell: {},
|
||||||
|
currentIndex: 1,
|
||||||
|
adding_spell: false,
|
||||||
|
search_text: "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filteredSpells() {
|
||||||
|
return this.spells;
|
||||||
},
|
},
|
||||||
data() {
|
user() {
|
||||||
return {
|
return this.$store.state.user;
|
||||||
spells: [],
|
|
||||||
loading: false,
|
|
||||||
current_edit_spell: {},
|
|
||||||
currentIndex: 1,
|
|
||||||
adding_spell: false,
|
|
||||||
search_text: "",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
filteredSpells() {
|
|
||||||
return this.spells
|
|
||||||
},
|
|
||||||
user() {
|
|
||||||
return this.$store.state.user
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeMount() {
|
|
||||||
this.spells = this.filteredSpells
|
|
||||||
if (!this.school_id) {
|
|
||||||
this.getInitialSpells()
|
|
||||||
} else {
|
|
||||||
this.getInitialSchoolSpells()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
if (!this.school_id) {
|
|
||||||
this.scroll()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
getInitialSpells() {
|
|
||||||
Spells.getPage(this.currentIndex)
|
|
||||||
.then(v => {
|
|
||||||
this.loading = true
|
|
||||||
let spells = this.filteredSpells
|
|
||||||
spells.push(v.data)
|
|
||||||
this.spells = spells[0]
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.currentIndex++
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
getInitialSchoolSpells() {
|
|
||||||
Schools.getSpellsFromOne(this.school_id)
|
|
||||||
.then(v => {
|
|
||||||
this.loading = true
|
|
||||||
let spells = this.filteredSpells
|
|
||||||
spells.push(v.data.spells)
|
|
||||||
this.spells = spells[0]
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.currentIndex++
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
scroll() {
|
|
||||||
window.onscroll = () => {
|
|
||||||
if (((window.innerHeight + window.scrollY) - document.body.offsetHeight) >= -1) {
|
|
||||||
Spells.getPage(this.currentIndex)
|
|
||||||
.then(v => {
|
|
||||||
this.loading = true
|
|
||||||
let spells = this.filteredSpells
|
|
||||||
for (let i = 0; i < v.data.length; i++) {
|
|
||||||
const element = v.data[i];
|
|
||||||
spells.push(element)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.currentIndex++
|
|
||||||
this.loading = false
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
editSpell(e) {
|
|
||||||
this.current_edit_spell = e;
|
|
||||||
},
|
|
||||||
showAdd() {
|
|
||||||
this.adding_spell = true
|
|
||||||
},
|
|
||||||
cancelAdd() {
|
|
||||||
this.adding_spell = false
|
|
||||||
},
|
|
||||||
// Receives events to update the data
|
|
||||||
addSpell(e) {
|
|
||||||
Spells.getOne(e.id)
|
|
||||||
.then(v => {
|
|
||||||
let spells = this.filteredSpells
|
|
||||||
spells.unshift(v.data)
|
|
||||||
})
|
|
||||||
.then(() => {
|
|
||||||
this.adding_spell = false
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
console.log(err)
|
|
||||||
})
|
|
||||||
},
|
|
||||||
updateSpell(e) {
|
|
||||||
let oldSpell = this.spells.find(x => x.id === e.id)
|
|
||||||
this.spells.splice(this.spells.indexOf(oldSpell), 1, e)
|
|
||||||
this.current_edit_spell = {}
|
|
||||||
},
|
|
||||||
deleteSpell(e) {
|
|
||||||
this.spells.splice(this.spells.indexOf(e), 1)
|
|
||||||
this.current_edit_spell = {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
beforeMount() {
|
||||||
|
this.spells = this.filteredSpells;
|
||||||
|
if (!this.school_id) {
|
||||||
|
this.getInitialSpells();
|
||||||
|
} else {
|
||||||
|
this.getInitialSchoolSpells();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.school_id) {
|
||||||
|
this.scroll();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getInitialSpells() {
|
||||||
|
Spells.getPage(this.currentIndex)
|
||||||
|
.then(v => {
|
||||||
|
this.loading = true;
|
||||||
|
let spells = this.filteredSpells;
|
||||||
|
spells.push(v.data);
|
||||||
|
this.spells = spells[0];
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.currentIndex++;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getInitialSchoolSpells() {
|
||||||
|
Schools.getSpellsFromOne(this.school_id)
|
||||||
|
.then(v => {
|
||||||
|
this.loading = true;
|
||||||
|
let spells = this.filteredSpells;
|
||||||
|
spells.push(v.data.spells);
|
||||||
|
this.spells = spells[0];
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.currentIndex++;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
scroll() {
|
||||||
|
window.onscroll = () => {
|
||||||
|
if (((window.innerHeight + window.scrollY) - document.body.offsetHeight) >= -1) {
|
||||||
|
Spells.getPage(this.currentIndex)
|
||||||
|
.then(v => {
|
||||||
|
this.loading = true;
|
||||||
|
let spells = this.filteredSpells;
|
||||||
|
for (let i = 0; i < v.data.length; i++) {
|
||||||
|
const element = v.data[i];
|
||||||
|
spells.push(element);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.currentIndex++;
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
editSpell(e) {
|
||||||
|
this.current_edit_spell = e;
|
||||||
|
},
|
||||||
|
showAdd() {
|
||||||
|
this.adding_spell = true;
|
||||||
|
},
|
||||||
|
cancelAdd() {
|
||||||
|
this.adding_spell = false;
|
||||||
|
},
|
||||||
|
// Receives events to update the data
|
||||||
|
addSpell(e) {
|
||||||
|
Spells.getOne(e.id)
|
||||||
|
.then(v => {
|
||||||
|
let spells = this.filteredSpells;
|
||||||
|
spells.unshift(v.data);
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
this.adding_spell = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
updateSpell(e) {
|
||||||
|
let oldSpell = this.spells.find(x => x.id === e.id);
|
||||||
|
this.spells.splice(this.spells.indexOf(oldSpell), 1, e);
|
||||||
|
this.current_edit_spell = {};
|
||||||
|
},
|
||||||
|
deleteSpell(e) {
|
||||||
|
this.spells.splice(this.spells.indexOf(e), 1);
|
||||||
|
this.current_edit_spell = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<ul class="timeline">
|
<ul class="timeline">
|
||||||
<li class="timeline-item period first">
|
<li class="timeline-item period first">
|
||||||
<div class="timeline-info"></div>
|
<div class="timeline-info" />
|
||||||
<div class="timeline-content">
|
<div class="timeline-content">
|
||||||
<h2 class="timeline-title">LE RENOUVEAU</h2>
|
<h2 class="timeline-title">
|
||||||
</div>
|
LE RENOUVEAU
|
||||||
</li>
|
</h2>
|
||||||
<li class="timeline-item">
|
</div>
|
||||||
<div class="timeline-info">
|
</li>
|
||||||
<span>March 12, 2016</span>
|
<li class="timeline-item">
|
||||||
</div>
|
<div class="timeline-info">
|
||||||
<div class="timeline-marker"></div>
|
<span>March 12, 2016</span>
|
||||||
<div class="timeline-content">
|
</div>
|
||||||
<h3 class="timeline-title">Event Title</h3>
|
<div class="timeline-marker" />
|
||||||
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque.</p>
|
<div class="timeline-content">
|
||||||
</div>
|
<h3 class="timeline-title">
|
||||||
</li>
|
Event Title
|
||||||
<li class="timeline-item">
|
</h3>
|
||||||
<div class="timeline-info">
|
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque.</p>
|
||||||
<span>March 23, 2016</span>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
<div class="timeline-marker"></div>
|
<li class="timeline-item">
|
||||||
<div class="timeline-content">
|
<div class="timeline-info">
|
||||||
<h3 class="timeline-title">Event Title</h3>
|
<span>March 23, 2016</span>
|
||||||
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
</div>
|
||||||
</div>
|
<div class="timeline-marker" />
|
||||||
</li>
|
<div class="timeline-content">
|
||||||
<li class="timeline-item period">
|
<h3 class="timeline-title">
|
||||||
<div class="timeline-info"></div>
|
Event Title
|
||||||
<div class="timeline-marker"></div>
|
</h3>
|
||||||
<div class="timeline-content">
|
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
||||||
<h2 class="timeline-title">April 2016</h2>
|
</div>
|
||||||
</div>
|
</li>
|
||||||
</li>
|
<li class="timeline-item period">
|
||||||
<li class="timeline-item">
|
<div class="timeline-info" />
|
||||||
<div class="timeline-info">
|
<div class="timeline-marker" />
|
||||||
<span>April 02, 2016</span>
|
<div class="timeline-content">
|
||||||
</div>
|
<h2 class="timeline-title">
|
||||||
<div class="timeline-marker"></div>
|
April 2016
|
||||||
<div class="timeline-content">
|
</h2>
|
||||||
<h3 class="timeline-title">Event Title</h3>
|
</div>
|
||||||
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
</li>
|
||||||
</div>
|
<li class="timeline-item">
|
||||||
</li>
|
<div class="timeline-info">
|
||||||
<li class="timeline-item">
|
<span>April 02, 2016</span>
|
||||||
<div class="timeline-info">
|
</div>
|
||||||
<span>April 28, 2016</span>
|
<div class="timeline-marker" />
|
||||||
</div>
|
<div class="timeline-content">
|
||||||
<div class="timeline-marker"></div>
|
<h3 class="timeline-title">
|
||||||
<div class="timeline-content">
|
Event Title
|
||||||
<h3 class="timeline-title">Event Title</h3>
|
</h3>
|
||||||
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
<li class="timeline-item">
|
||||||
|
<div class="timeline-info">
|
||||||
|
<span>April 28, 2016</span>
|
||||||
|
</div>
|
||||||
|
<div class="timeline-marker" />
|
||||||
|
<div class="timeline-content">
|
||||||
|
<h3 class="timeline-title">
|
||||||
|
Event Title
|
||||||
|
</h3>
|
||||||
|
<p>Nullam vel sem. Nullam vel sem. Integer ante arcu, accumsan a, consectetuer eget, posuere ut, mauris. Donec orci lectus, aliquam ut, faucibus non, euismod id, nulla. Donec vitae sapien ut libero venenatis faucibus. ullam dictum felis eu pede mollis pretium. Pellentesque ut neque. </p>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'timeline',
|
name: 'Timeline',
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
17
client/src/components/user/profile/update-form.vue
Normal file
17
client/src/components/user/profile/update-form.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<form>
|
||||||
|
<div>Update profile for {{ user.name }}</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'UpdateForm',
|
||||||
|
props: {
|
||||||
|
user: {
|
||||||
|
type: Object,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
import Navbar from './components/global/navbar/navbar'
|
import Navbar from './components/global/navbar/navbar';
|
||||||
import Loader from './components/global/loader'
|
import Loader from './components/global/loader';
|
||||||
|
|
||||||
export default [
|
export default [
|
||||||
Navbar,
|
Navbar,
|
||||||
Loader
|
Loader
|
||||||
]
|
];
|
||||||
@@ -1,96 +1,76 @@
|
|||||||
// Core
|
// Core
|
||||||
import Vue from 'vue'
|
import Vue from 'vue';
|
||||||
import Vuex from 'vuex'
|
import VueRouter from 'vue-router';
|
||||||
import VueRouter from 'vue-router'
|
import App from './app.vue';
|
||||||
import App from './app.vue'
|
import VueMeta from 'vue-meta';
|
||||||
|
|
||||||
import Globals from './global-components.js'
|
Vue.use(VueMeta, {
|
||||||
Globals.forEach(component => {
|
// optional pluginOptions
|
||||||
Vue.component(component.name, component)
|
refreshOnceOnNavigation: true
|
||||||
});
|
});
|
||||||
|
|
||||||
// Environment
|
// Environment
|
||||||
require('dotenv').config()
|
import dotenv from 'dotenv';
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
// Store
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
|
// Global components
|
||||||
|
import Globals from './global-components.js';
|
||||||
|
Globals.forEach(component => {
|
||||||
|
Vue.component(component.name, component);
|
||||||
|
});
|
||||||
|
|
||||||
// Cookies
|
// Cookies
|
||||||
import VueCookies from 'vue-cookies'
|
import VueCookies from 'vue-cookies';
|
||||||
Vue.use(VueCookies)
|
Vue.use(VueCookies);
|
||||||
Vue.$cookies.config('30d','','')
|
|
||||||
|
|
||||||
// Jquery
|
// Jquery
|
||||||
import jquery from 'jquery'
|
import jquery from 'jquery';
|
||||||
window.$ = jquery
|
window.$ = jquery;
|
||||||
window.jquery = jquery
|
window.jquery = jquery;
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
// Fonts
|
// Fonts
|
||||||
import './assets/scss/_fonts.scss'
|
import './assets/scss/_fonts.scss';
|
||||||
import './assets/scss/_global.scss'
|
import './assets/scss/_global.scss';
|
||||||
|
|
||||||
import 'bootstrap/dist/css/bootstrap.css'
|
import 'bootstrap/dist/css/bootstrap.css';
|
||||||
import 'bootstrap-vue/dist/bootstrap-vue.css'
|
import 'bootstrap-vue/dist/bootstrap-vue.css';
|
||||||
import 'bootstrap/dist/js/bootstrap.js'
|
import 'bootstrap/dist/js/bootstrap.js';
|
||||||
|
|
||||||
// Plugins
|
// Plugins
|
||||||
import { BootstrapVue } from 'bootstrap-vue'
|
import { BootstrapVue } from 'bootstrap-vue';
|
||||||
Vue.use(BootstrapVue)
|
Vue.use(BootstrapVue);
|
||||||
|
|
||||||
import { VueMasonryPlugin } from 'vue-masonry'
|
// Masonry (will probably get removed in the very very near future lmao)
|
||||||
Vue.use(VueMasonryPlugin)
|
import { VueMasonryPlugin } from 'vue-masonry';
|
||||||
|
Vue.use(VueMasonryPlugin);
|
||||||
|
|
||||||
import clipboard from 'v-clipboard'
|
// Clipboard (might find a better one or code it myself idk)
|
||||||
Vue.use(clipboard)
|
import clipboard from 'v-clipboard';
|
||||||
|
Vue.use(clipboard);
|
||||||
|
|
||||||
// FUNCTIONS
|
// FUNCTIONS
|
||||||
var filter = function(text, length, clamp){
|
// Let's be honest i will 1000% refactor this.
|
||||||
clamp = clamp || '...';
|
let filter = (text, length, clamp) => {
|
||||||
var node = document.createElement('div');
|
clamp = clamp || '...';
|
||||||
node.innerHTML = text;
|
let node = document.createElement('div');
|
||||||
var content = node.textContent;
|
node.innerHTML = text;
|
||||||
return content.length > length ? content.slice(0, length) + clamp : content;
|
let content = node.textContent;
|
||||||
}
|
return content.length > length ? content.slice(0, length) + clamp : content;
|
||||||
Vue.filter('truncate', filter)
|
};
|
||||||
|
Vue.filter('truncate', filter);
|
||||||
|
|
||||||
// Router
|
// Router
|
||||||
import router from './routes'
|
import router from './routes';
|
||||||
Vue.use(VueRouter)
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
// Store
|
|
||||||
Vue.use(Vuex)
|
|
||||||
let user = Vue.$cookies.get('U_')
|
|
||||||
|
|
||||||
const store = new Vuex.Store({
|
|
||||||
state: user ?
|
|
||||||
{ status: { loggedIn: true }, user }
|
|
||||||
: { status: { loggedIn: false }, user: null },
|
|
||||||
mutations: {
|
|
||||||
loginSucceed (state, user) {
|
|
||||||
state.status.loggedIn = true
|
|
||||||
state.user = user
|
|
||||||
},
|
|
||||||
loginFail (state) {
|
|
||||||
state.status.loggedIn = false
|
|
||||||
state.user = null
|
|
||||||
},
|
|
||||||
logout(state) {
|
|
||||||
state.status.loggedIn = false;
|
|
||||||
state.user = null;
|
|
||||||
},
|
|
||||||
registerSucceed (state, user) {
|
|
||||||
state.status.loggedIn = true
|
|
||||||
state.user = user
|
|
||||||
},
|
|
||||||
registerFail (state) {
|
|
||||||
state.status.loggedIn = false
|
|
||||||
state.user = null
|
|
||||||
},
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// Mount Vue
|
// Mount Vue
|
||||||
const app = new Vue({
|
const app = new Vue({
|
||||||
render: h => h(App),
|
render: h => h(App),
|
||||||
router,
|
router,
|
||||||
store: store
|
store: store
|
||||||
})
|
});
|
||||||
app.$mount('#srs')
|
app.$mount('#srs');
|
||||||
|
|||||||
@@ -1,41 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<section class="d-flex justify-content-center align-items-center">
|
<section class="d-flex justify-content-center align-items-center">
|
||||||
<main class="px-4">
|
<main class="px-4">
|
||||||
<h1 class="title text-dark mb-4 font-display font-weight-black line-height-100">"C'est magique, ta gueule."</h1>
|
<h1 class="title text-dark mb-4 font-display font-weight-black line-height-100">
|
||||||
<div class="lead font-display font-weight-bold">— N'importe quel MJ, une fois dans sa vie</div>
|
"C'est magique, ta gueule."
|
||||||
<hr class="w-50">
|
</h1>
|
||||||
<div class="lead"><span class="font-display font-weight-bold">Auracle</span> est une base de données publique en ligne pour sortilèges, en soutien au jeu de rôle sur table <span class="font-weight-bold text-secondary">Leïm</span>.</div>
|
<div class="lead font-display font-weight-bold">
|
||||||
</main>
|
— N'importe quel MJ, une fois dans sa vie
|
||||||
</section>
|
</div>
|
||||||
</div>
|
<hr class="w-50">
|
||||||
|
<div class="lead">
|
||||||
|
<span class="font-display font-weight-bold">Auracle</span> est une base de données publique en ligne pour sortilèges, en soutien au jeu de rôle sur table <span class="font-weight-bold text-secondary">Leïm</span>.
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
name: 'index-page',
|
name: 'IndexPage',
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
section {
|
section {
|
||||||
min-height: calc(100vh - 56px);
|
min-height: calc(100vh - 56px);
|
||||||
main {
|
main {
|
||||||
width: 1000px;
|
width: 1000px;
|
||||||
.title {
|
.title {
|
||||||
color: $white;
|
color: $white;
|
||||||
font-size: 64px;
|
font-size: 64px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (max-width: $bp-md) {
|
@media only screen and (max-width: $bp-md) {
|
||||||
section {
|
section {
|
||||||
main {
|
main {
|
||||||
.title {
|
.title {
|
||||||
font-size: 48px;
|
font-size: 48px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<h1 class="display-3 font-display mb-3">Écoles</h1>
|
id="spell-container"
|
||||||
</div>
|
class="container-fluid p-4"
|
||||||
|
>
|
||||||
|
<h1 class="display-3 font-display mb-3">
|
||||||
|
Écoles
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
|
||||||
name: 'schools-page'
|
export default {
|
||||||
}
|
name: 'SchoolsPage',
|
||||||
|
metaInfo: {
|
||||||
|
titleTemplate: '%s - Maîtrises'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,46 +1,52 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<h1 class="display-3 font-display mb-3">{{ school.name }}</h1>
|
id="spell-container"
|
||||||
<p>{{ school.description }}</p>
|
class="container-fluid p-4"
|
||||||
<spell-list :school_id="id"/>
|
>
|
||||||
</div>
|
<h1 class="display-3 font-display mb-3">
|
||||||
|
{{ school.name }}
|
||||||
|
</h1>
|
||||||
|
<p>{{ school.description }}</p>
|
||||||
|
<spell-list :school_id="id" />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SpellsList from "~/components/spells/spells-list"
|
|
||||||
|
|
||||||
// API
|
// API
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
const Schools = RepositoryFactory.get('schools')
|
const Schools = RepositoryFactory.get('schools');
|
||||||
|
|
||||||
|
import SpellsList from "@/components/spells/spells-list";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'single-school-page',
|
name: 'SingleSchoolPage',
|
||||||
components: {
|
metaInfo() {
|
||||||
'spell-list': SpellsList,
|
return {
|
||||||
},
|
titleTemplate: `%s - ${this.school.name}`,
|
||||||
data() {
|
};
|
||||||
return {
|
},
|
||||||
loading: false,
|
components: {
|
||||||
school: {},
|
'spell-list': SpellsList,
|
||||||
id: this.$route.params.id
|
},
|
||||||
}
|
data() {
|
||||||
},
|
return {
|
||||||
created() {
|
id: this.$route.params.id,
|
||||||
this.computeSchool()
|
school: {},
|
||||||
},
|
errors: {
|
||||||
methods: {
|
loading: "",
|
||||||
async fetchSchool(id) {
|
}
|
||||||
const { data } = await Schools.getOne(id)
|
};
|
||||||
return data
|
},
|
||||||
},
|
created() {
|
||||||
async computeSchool() {
|
Schools.getOne(this.id)
|
||||||
this.loading = true
|
.then(v => {
|
||||||
const displaySchool = await this.fetchSchool(this.id)
|
this.school = v.data;
|
||||||
this.loading = false
|
})
|
||||||
this.school = displaySchool
|
.catch(err => {
|
||||||
},
|
console.log(err);
|
||||||
}
|
});
|
||||||
}
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,13 +1,48 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<h1 class="display-3 font-display mb-3">Sortilège</h1>
|
id="spell-container"
|
||||||
|
class="container-fluid p-4"
|
||||||
|
>
|
||||||
|
<h1 class="display-3 font-display mb-3">
|
||||||
|
{{ spell.name }}
|
||||||
|
</h1>
|
||||||
|
<p class="prewrap">
|
||||||
|
{{ spell.description }}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
// API
|
||||||
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
|
const Spells = RepositoryFactory.get('spells');
|
||||||
|
|
||||||
}
|
export default {
|
||||||
|
name: 'SingleSpellPage',
|
||||||
|
metaInfo() {
|
||||||
|
return {
|
||||||
|
titleTemplate: this.spell.name ? `%s - ${this.spell.name}` : '%s',
|
||||||
|
};
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
id: this.$route.params.id,
|
||||||
|
spell: {},
|
||||||
|
errors: {
|
||||||
|
loading: "",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
Spells.getOne(this.id)
|
||||||
|
.then(v => {
|
||||||
|
this.spell = v.data;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,19 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<h1 class="display-3 font-display mb-3">Sortilèges</h1>
|
id="spell-container"
|
||||||
<spell-list/>
|
class="container-fluid p-4"
|
||||||
</div>
|
>
|
||||||
|
<h1 class="display-3 font-display mb-3">
|
||||||
|
Sortilèges
|
||||||
|
</h1>
|
||||||
|
<spell-list />
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import SpellsList from "~/components/spells/spells-list"
|
import SpellsList from "@/components/spells/spells-list.vue";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'spells-page',
|
name: 'SpellsPage',
|
||||||
|
metaInfo: {
|
||||||
|
titleTemplate: '%s - Grimoire'
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
'spell-list': SpellsList,
|
'spell-list': SpellsList,
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
<style lang="scss"></style>
|
||||||
@@ -1,19 +1,27 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<h1 class="display-3 font-display mb-3">Chronologie</h1>
|
id="spell-container"
|
||||||
<timeline/>
|
class="container-fluid p-4"
|
||||||
|
>
|
||||||
|
<h1 class="display-3 font-display mb-3">
|
||||||
|
Chronologie
|
||||||
|
</h1>
|
||||||
|
<timeline />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Timeline from '~/components/timeline/timeline'
|
import Timeline from "@/components/timeline/timeline";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'timeline-page',
|
name: 'TimelinePage',
|
||||||
|
metaInfo: {
|
||||||
|
titleTemplate: '%s - Âges'
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
'timeline': Timeline,
|
'timeline': Timeline
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
|||||||
@@ -1,92 +1,182 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<section class="d-flex justify-content-center align-items-center">
|
<section class="d-flex justify-content-center align-items-center">
|
||||||
<main>
|
<main>
|
||||||
<div class="title font-display mb-3">Connexion</div>
|
<div class="title font-display mb-3">Connexion</div>
|
||||||
<form @submit="logUser">
|
|
||||||
<div class="form-group">
|
<form @submit="logUser">
|
||||||
<label for="email">Addresse mail</label>
|
|
||||||
<input
|
<div class="form-group">
|
||||||
v-model="email"
|
<label for="email">Addresse mail</label>
|
||||||
type="email"
|
<input
|
||||||
id="email"
|
v-model="email"
|
||||||
class="form-control"
|
type="email"
|
||||||
placeholder="john.doe@gmail.com"
|
id="email"
|
||||||
autocomplete="email">
|
class="form-control"
|
||||||
<small class="form-text text-muted">Votre addresse mail nous servira principalement à vous identifier et à retrouver votre compte si vous oubliez vos informations de connexion.</small>
|
:class="{ 'is-invalid': errors.email || errors.login }"
|
||||||
</div>
|
placeholder="john.doe@gmail.com"
|
||||||
<div class="form-group">
|
autocomplete="email">
|
||||||
<label for="password">Mot de passe</label>
|
|
||||||
<input
|
<small
|
||||||
v-model="password"
|
v-if="!errors.email"
|
||||||
type="password"
|
class="form-text text-muted"
|
||||||
id="password"
|
>
|
||||||
class="form-control"
|
Votre addresse mail nous servira principalement à vous identifier et à retrouver votre compte si vous oubliez vos informations de connexion.
|
||||||
autocomplete="current-password">
|
</small>
|
||||||
</div>
|
<small
|
||||||
<button type="submit" class="btn btn-primary">Connexion</button>
|
v-if="errors.email"
|
||||||
<router-link :to="'/inscription'" class="btn btn-dark">Inscription</router-link>
|
class="form-text text-danger"
|
||||||
<small class="form-text text-muted">Vous avez oublié votre mot de passe ? Cliquez-ici pour le changer !</small>
|
>
|
||||||
</form>
|
{{ errors.email }}
|
||||||
</main>
|
</small>
|
||||||
</section>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password">Mot de passe</label>
|
||||||
|
<input
|
||||||
|
v-model="password"
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
class="form-control"
|
||||||
|
:class="{ 'is-invalid': errors.password || errors.login }"
|
||||||
|
autocomplete="current-password">
|
||||||
|
<small
|
||||||
|
v-if="!errors.password"
|
||||||
|
class="form-text text-muted"
|
||||||
|
>
|
||||||
|
Nous vous conseillons d'utiliser un mot de passe unique pour cette application seulement.
|
||||||
|
</small>
|
||||||
|
<small
|
||||||
|
v-if="errors.password"
|
||||||
|
class="form-text text-danger"
|
||||||
|
>
|
||||||
|
{{ errors.password }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="remember_me"
|
||||||
|
id="remember-me"
|
||||||
|
class="form-check-input">
|
||||||
|
<label
|
||||||
|
class="form-check-label"
|
||||||
|
for="remember-me"
|
||||||
|
>
|
||||||
|
Rester connecté
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<small v-if="errors.login" class="text-danger">{{ errors.login }}</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-primary">Connexion</button>
|
||||||
|
<router-link :to="'/inscription'" class="btn btn-dark">Inscription</router-link>
|
||||||
|
<small class="form-text text-muted">Mot de passe oublié ? <a href="#">Vous pouvez le changer ici !</a></small>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// API
|
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
|
||||||
const Users = RepositoryFactory.get('users')
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'login-page',
|
name: 'login-page',
|
||||||
|
metaInfo: {
|
||||||
|
titleTemplate: '%s - Connexion'
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
email: "",
|
email: "",
|
||||||
password: "",
|
password: "",
|
||||||
submitted: false,
|
remember_me: false,
|
||||||
errors: {
|
submitted: false,
|
||||||
login: ""
|
|
||||||
}
|
errors: {
|
||||||
|
email: "",
|
||||||
|
password: "",
|
||||||
|
login: "",
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async logUser(e) {
|
async logUser(e) {
|
||||||
e.preventDefault()
|
e.preventDefault();
|
||||||
|
|
||||||
Users.login({
|
// Resets old errors if any
|
||||||
"mail": this.email,
|
for (const o in this.errors) {
|
||||||
"password": this.password
|
this.errors[o] = ""
|
||||||
})
|
|
||||||
.then(v => {
|
|
||||||
let user = v.data.user
|
|
||||||
this.$cookies.set("U_", user, 60 * 60 * 24 * 30)
|
|
||||||
this.$store.commit('loginSucceed', user)
|
|
||||||
this.$router.push('/profil')
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.$store.commit('loginFailed')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
this.submitted = true;
|
||||||
|
|
||||||
|
let userInput = {
|
||||||
|
"user": {
|
||||||
|
"mail": this.email,
|
||||||
|
"password": this.password,
|
||||||
|
},
|
||||||
|
"remember_me": this.remember_me
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check is all inputs are set
|
||||||
|
if (!userInput.user.mail) {
|
||||||
|
this.errors.email = "Vous devez renseigner une addresse mail."
|
||||||
|
}
|
||||||
|
if (!userInput.user.password) {
|
||||||
|
this.errors.password = "Vous devez renseigner un mot de passe."
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stops the method if any errors exist
|
||||||
|
for (const o in this.errors) {
|
||||||
|
if (this.errors[o] != "") {
|
||||||
|
this.submitted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no errors are present, submits the form
|
||||||
|
if (this.submitted) {
|
||||||
|
this.$store.dispatch('user_login', userInput)
|
||||||
|
.then(() => {
|
||||||
|
this.$router.push('/profil')
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
if (err.status != 500) {
|
||||||
|
this.errors.email = err.data.error;
|
||||||
|
} else {
|
||||||
|
this.errors.login = err.data.error;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
section {
|
section {
|
||||||
min-height: calc(100vh - 56px);
|
min-height: calc(100vh - 56px);
|
||||||
main {
|
main {
|
||||||
width: 600px;
|
width: 600px;
|
||||||
.title {
|
|
||||||
font-size: 5rem;
|
|
||||||
font-weight: 700;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@media only screen and (max-width: 600px) {
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 3.5rem;
|
font-size: 5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
section {
|
||||||
|
main {
|
||||||
|
.title {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,24 +1,103 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid p-4" id="spell-container">
|
<div
|
||||||
<div class="display-3 font-display mb-3">
|
v-if="user"
|
||||||
<span class="username">{{ user.name }}</span>
|
id="spell-container"
|
||||||
<span v-if="user.verified" class="verified"><i class="mad">check_circle</i></span>
|
class="container-fluid p-4"
|
||||||
</div>
|
>
|
||||||
|
<h2 class="display-3 font-display mb-3">
|
||||||
|
<span class="username">{{ user.name }}</span>
|
||||||
|
</h2>
|
||||||
|
<span>Membre depuis le {{ registered_date }}</span>
|
||||||
|
|
||||||
|
<ul
|
||||||
|
id="tabs-tab"
|
||||||
|
class="nav nav-tabs mt-3 mb-3"
|
||||||
|
role="tablist"
|
||||||
|
>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
id="tabs-home-tab"
|
||||||
|
class="nav-link active"
|
||||||
|
data-toggle="pill"
|
||||||
|
href="#tabs-home"
|
||||||
|
role="tab"
|
||||||
|
aria-controls="tabs-home"
|
||||||
|
aria-selected="true"
|
||||||
|
>Mes sorts</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<a
|
||||||
|
id="tabs-contact-tab"
|
||||||
|
class="nav-link"
|
||||||
|
data-toggle="pill"
|
||||||
|
href="#tabs-contact"
|
||||||
|
role="tab"
|
||||||
|
aria-controls="tabs-contact"
|
||||||
|
aria-selected="false"
|
||||||
|
>Paramètres</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div
|
||||||
|
id="tabs-tabContent"
|
||||||
|
class="tab-content"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
id="tabs-home"
|
||||||
|
class="tab-pane fade show active"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="tabs-home-tab"
|
||||||
|
>
|
||||||
|
...
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
id="tabs-contact"
|
||||||
|
class="tab-pane fade"
|
||||||
|
role="tabpanel"
|
||||||
|
aria-labelledby="tabs-contact-tab"
|
||||||
|
>
|
||||||
|
<update-form :user="user" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
|
import UpdateForm from '@/components/user/profile/update-form.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'profile-page',
|
name: 'ProfilePage',
|
||||||
computed: {
|
metaInfo: {
|
||||||
user() {
|
titleTemplate: '%s - Profil'
|
||||||
return this.$store.state.user
|
},
|
||||||
}
|
components: {
|
||||||
|
UpdateForm,
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
user() {
|
||||||
|
return this.$store.getters.getUserProfile;
|
||||||
},
|
},
|
||||||
}
|
registered_date() {
|
||||||
|
let raw_date = new Date(this.user.register_date);
|
||||||
|
|
||||||
|
let date_options = {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
};
|
||||||
|
|
||||||
|
return new Intl.DateTimeFormat("fr", date_options).format(raw_date);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
font-size: 5rem;
|
font-size: 5rem;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
@@ -28,4 +107,5 @@ export default {
|
|||||||
font-size: 3.5rem;
|
font-size: 3.5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -1,143 +1,198 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<section class="d-flex justify-content-center align-items-center">
|
<section class="d-flex justify-content-center align-items-center">
|
||||||
<main>
|
<main>
|
||||||
<div class="title font-display mb-3">Inscription</div>
|
<div class="title font-display mb-3">Inscription</div>
|
||||||
<form @submit="registerUser">
|
<form @submit="registerUser">
|
||||||
<div class="form-group">
|
|
||||||
<label for="email">Pseudo</label>
|
<div class="form-group">
|
||||||
<input
|
<label for="email">Nom d'utilisateur</label>
|
||||||
v-model="name"
|
<input
|
||||||
:class="{
|
v-model="name"
|
||||||
'is-invalid': errors.name,
|
:class="{
|
||||||
'is-valid': submitted && !errors.name }"
|
'is-invalid': errors.name,
|
||||||
type="text"
|
'is-valid': submitted && !errors.name }"
|
||||||
id="username"
|
type="text"
|
||||||
class="form-control"
|
id="username"
|
||||||
placeholder="John Doe"
|
class="form-control"
|
||||||
autocomplete="username">
|
placeholder="John Doe"
|
||||||
<small v-if="!errors.name" class="form-text text-muted">Vous pouvez changer votre pseudo à tout moment.</small>
|
autocomplete="username">
|
||||||
<small v-if="errors.name" class="text-danger">{{ errors.name }}</small>
|
<small
|
||||||
</div>
|
v-if="!errors.name"
|
||||||
<div class="form-group">
|
class="form-text text-muted"
|
||||||
<label for="email">Addresse mail</label>
|
>
|
||||||
<input
|
Vous pouvez changer votre pseudo à tout moment.
|
||||||
v-model="email"
|
</small>
|
||||||
:class="{
|
|
||||||
'is-invalid': errors.email,
|
<small
|
||||||
'is-valid': submitted && !errors.email }"
|
v-if="errors.name"
|
||||||
type="email"
|
class="form-text text-danger"
|
||||||
id="email"
|
>
|
||||||
class="form-control"
|
{{ errors.name }}
|
||||||
placeholder="john.doe@gmail.com"
|
</small>
|
||||||
autocomplete="email">
|
</div>
|
||||||
<small v-if="!errors.email" class="form-text text-muted">Votre addresse mail nous servira principalement à vous identifier et à retrouver votre compte si vous oubliez vos informations de connexion.</small>
|
|
||||||
<small v-if="errors.email" class="text-danger">{{ errors.email }}</small>
|
<div class="form-group">
|
||||||
</div>
|
<label for="email">Adresse mail</label>
|
||||||
<div class="form-group">
|
<input
|
||||||
<label for="password">Mot de passe</label>
|
v-model="email"
|
||||||
<input
|
:class="{
|
||||||
:class="{
|
'is-invalid': errors.email,
|
||||||
'is-invalid': errors.password,
|
'is-valid': submitted && !errors.email }"
|
||||||
'is-valid': submitted && !errors.password }"
|
type="email"
|
||||||
v-model="password"
|
id="email"
|
||||||
type="password"
|
class="form-control"
|
||||||
id="password"
|
placeholder="john.doe@gmail.com"
|
||||||
class="form-control"
|
autocomplete="email">
|
||||||
autocomplete="password">
|
<small
|
||||||
</div>
|
v-if="!errors.email"
|
||||||
<div class="form-group">
|
class="form-text text-muted"
|
||||||
<label for="password_check">Confirmer le mot de passe</label>
|
>
|
||||||
<input
|
Votre addresse mail nous servira principalement à vous identifier et à retrouver votre compte si vous oubliez vos informations de connexion.
|
||||||
v-model="password_check"
|
</small>
|
||||||
:class="{
|
|
||||||
'is-invalid': errors.password_check || errors.password,
|
<small
|
||||||
'is-valid': submitted && !errors.password_check}"
|
v-if="errors.email"
|
||||||
type="password"
|
class="form-text text-danger"
|
||||||
id="password_check"
|
>
|
||||||
class="form-control"
|
{{ errors.email }}
|
||||||
autocomplete="password-verification">
|
</small>
|
||||||
<small v-if="!errors.password && !errors.password_check" class="form-text text-muted">Votre mot de passe doit idéalement contenir des symboles ainsi que des lettres et des chiffres.</small>
|
</div>
|
||||||
<small v-if="errors.password" class="text-danger">{{ errors.password }}</small>
|
|
||||||
<small v-if="errors.password_check" class="text-danger">{{ errors.password_check }}</small>
|
<div class="form-group">
|
||||||
</div>
|
<label for="password">Mot de passe</label>
|
||||||
<button type="submit" class="btn btn-dark">Inscription</button>
|
<input
|
||||||
</form>
|
:class="{
|
||||||
</main>
|
'is-invalid': errors.password,
|
||||||
</section>
|
'is-valid': submitted && !errors.password }"
|
||||||
</div>
|
v-model="password"
|
||||||
|
type="password"
|
||||||
|
id="password"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="password_check">Confirmer le mot de passe</label>
|
||||||
|
<input
|
||||||
|
v-model="password_check"
|
||||||
|
:class="{
|
||||||
|
'is-invalid': errors.password_check || errors.password,
|
||||||
|
'is-valid': submitted && !errors.password_check}"
|
||||||
|
type="password"
|
||||||
|
id="password_check"
|
||||||
|
class="form-control"
|
||||||
|
autocomplete="password-verification">
|
||||||
|
<small
|
||||||
|
v-if="!errors.password && !errors.password_check"
|
||||||
|
class="form-text text-muted"
|
||||||
|
>
|
||||||
|
Votre mot de passe doit idéalement contenir des symboles ainsi que des lettres et des chiffres.
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<small
|
||||||
|
v-if="errors.password"
|
||||||
|
class="form-text text-danger"
|
||||||
|
>
|
||||||
|
{{ errors.password }}
|
||||||
|
</small>
|
||||||
|
<small
|
||||||
|
v-if="errors.password_check"
|
||||||
|
class="form-text text-danger"
|
||||||
|
>
|
||||||
|
{{ errors.password_check }}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<small v-if="errors.register" class="text-danger">{{ errors.register }}</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-dark">Inscription</button>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// API
|
|
||||||
import { RepositoryFactory } from "~/api/repositories"
|
|
||||||
const Users = RepositoryFactory.get('users')
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'register-page',
|
name: 'register-page',
|
||||||
data() {
|
metaInfo: {
|
||||||
return {
|
titleTemplate: '%s - Inscription'
|
||||||
name: "",
|
},
|
||||||
email: "",
|
data() {
|
||||||
password: "",
|
return {
|
||||||
password_check: "",
|
name: "",
|
||||||
submitted: false,
|
email: "",
|
||||||
errors: {
|
password: "",
|
||||||
name: "",
|
password_check: "",
|
||||||
email: "",
|
submitted: false,
|
||||||
password: "",
|
errors: {
|
||||||
password_check: "",
|
name: "",
|
||||||
},
|
email: "",
|
||||||
}
|
password: "",
|
||||||
},
|
password_check: "",
|
||||||
methods: {
|
register: "",
|
||||||
async registerUser(e) {
|
},
|
||||||
e.preventDefault()
|
|
||||||
|
|
||||||
// Resets old errors if any
|
|
||||||
for (const o in this.errors) {
|
|
||||||
this.errors[o] = ""
|
|
||||||
}
|
|
||||||
this.submitted = true
|
|
||||||
|
|
||||||
if (!this.name) {
|
|
||||||
this.errors.name = "Vous devez renseigner un pseudonyme."
|
|
||||||
}
|
|
||||||
if (!this.email) {
|
|
||||||
this.errors.email = "Vous devez renseigner une addresse mail."
|
|
||||||
}
|
|
||||||
if (!this.password) {
|
|
||||||
this.errors.password = "Vous devez renseigner un mot de passe."
|
|
||||||
}
|
|
||||||
if ((this.password.localeCompare(this.password_check)) != 0) {
|
|
||||||
this.errors.password_check = "Les mots de passe ne correspondent pas."
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stops the method if any errors exist
|
|
||||||
for (const o in this.errors) {
|
|
||||||
if (this.errors[o]) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Users.register({
|
|
||||||
"name": this.name,
|
|
||||||
"mail": this.email,
|
|
||||||
"password": this.password
|
|
||||||
})
|
|
||||||
.then(v => {
|
|
||||||
let user = v.data.user
|
|
||||||
this.$cookies.set("U_", user, 60 * 60 * 24 * 30)
|
|
||||||
this.$store.commit('registerSucceed', user)
|
|
||||||
this.$router.push('/profil')
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
let error = err.response.data.error
|
|
||||||
this.errors.email = error
|
|
||||||
this.$store.commit('registerFail')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async registerUser(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
// Resets old errors if any
|
||||||
|
for (const o in this.errors) {
|
||||||
|
this.errors[o] = ""
|
||||||
|
}
|
||||||
|
this.submitted = true;
|
||||||
|
|
||||||
|
let userInput = {
|
||||||
|
"user": {
|
||||||
|
"name": this.name,
|
||||||
|
"mail": this.email,
|
||||||
|
"password": this.password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if all inputs are valid without sending anything
|
||||||
|
if (!userInput.user.name) {
|
||||||
|
this.errors.name = "Vous devez renseigner un pseudonyme."
|
||||||
|
}
|
||||||
|
if (!userInput.user.mail) {
|
||||||
|
this.errors.email = "Vous devez renseigner une addresse mail."
|
||||||
|
}
|
||||||
|
if (!userInput.user.password) {
|
||||||
|
this.errors.password = "Vous devez renseigner un mot de passe."
|
||||||
|
}
|
||||||
|
if ((userInput.user.password.localeCompare(this.password_check)) != 0) {
|
||||||
|
this.errors.password_check = "Les mots de passe ne correspondent pas."
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stops the method if any errors exist
|
||||||
|
for (const o in this.errors) {
|
||||||
|
if (this.errors[o] != "") {
|
||||||
|
this.submitted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If no errors are present, submits the form
|
||||||
|
if (this.submitted) {
|
||||||
|
this.$store.dispatch('user_register', userInput)
|
||||||
|
.then(() => {
|
||||||
|
this.$router.push('/');
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
// Sets errors in case something wrong comes back from the API
|
||||||
|
if (err.status === 409) {
|
||||||
|
this.errors.email = err.data.error;
|
||||||
|
} else {
|
||||||
|
this.errors.register = "Une erreur inconnue est survenue, rééssayez plus tard.";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,97 +1,102 @@
|
|||||||
import Vue from 'vue'
|
import VueRouter from 'vue-router';
|
||||||
import VueRouter from 'vue-router'
|
|
||||||
|
import store from './store';
|
||||||
|
|
||||||
// Pages
|
// Pages
|
||||||
import Index from "~/pages/index-page"
|
import Index from "@/pages/index-page";
|
||||||
|
|
||||||
import Spells from "~/pages/spells/spells-page"
|
import Spells from "@/pages/spells/spells-page";
|
||||||
import SpellSingle from "~/pages/spells/single-spell-page"
|
import SpellSingle from "@/pages/spells/single-spell-page";
|
||||||
|
|
||||||
import Schools from "./pages/schools/schools-page"
|
import Schools from "./pages/schools/schools-page";
|
||||||
import SchoolSingle from "~/pages/schools/single-school-page"
|
import SchoolSingle from "@/pages/schools/single-school-page";
|
||||||
|
|
||||||
import Timeline from "./pages/timelines/timeline-page"
|
import Timeline from "./pages/timelines/timeline-page";
|
||||||
|
|
||||||
import Login from "~/pages/user/login-page"
|
import Profile from "@/pages/user/profile-page";
|
||||||
import Register from "~/pages/user/register-page"
|
import Login from "@/pages/user/login-page";
|
||||||
import Profile from "~/pages/user/profile-page"
|
import Register from "@/pages/user/register-page";
|
||||||
|
|
||||||
// Routes
|
// Routes
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
path: "*",
|
path: "*",
|
||||||
redirect: "/",
|
redirect: "/",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: Index,
|
component: Index,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/connexion',
|
path: '/connexion',
|
||||||
component: Login,
|
component: Login,
|
||||||
meta: {
|
meta: {
|
||||||
antiAuthGuard: true
|
loginFilter: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/inscription',
|
path: '/inscription',
|
||||||
component: Register,
|
component: Register,
|
||||||
meta: {
|
meta: {
|
||||||
antiAuthGuard: true
|
loginFilter: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sorts',
|
path: '/sorts',
|
||||||
component: Spells,
|
component: Spells,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/sorts/:id',
|
path: '/sorts/:id',
|
||||||
component: SpellSingle,
|
component: SpellSingle,
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ecoles',
|
path: '/ecoles',
|
||||||
component: Schools,
|
component: Schools,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ecoles/:id',
|
path: '/ecoles/:id',
|
||||||
component: SchoolSingle,
|
component: SchoolSingle,
|
||||||
props: true,
|
props: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/ages',
|
path: '/ages',
|
||||||
component: Timeline,
|
component: Timeline,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/profil',
|
path: '/profil',
|
||||||
component: Profile,
|
component: Profile,
|
||||||
props: true,
|
props: true,
|
||||||
meta: {
|
meta: {
|
||||||
authGuard: true,
|
logoutFilter: true,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
]
|
];
|
||||||
|
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
routes,
|
routes,
|
||||||
linkActiveClass: "",
|
linkActiveClass: "",
|
||||||
linkExactActiveClass: "active",
|
linkExactActiveClass: "active",
|
||||||
})
|
});
|
||||||
|
|
||||||
router.beforeEach((to, from, next) => {
|
router.beforeEach((to, from, next) => {
|
||||||
if (to.matched.some(record => record.meta.authGuard)) {
|
if (to.matched.some(record => record.meta.loginFilter)) {
|
||||||
if (Vue.$cookies.get('U_') == null) {
|
if (store.getters.getUserProfile) {
|
||||||
next({
|
next({
|
||||||
path: '/connexion',
|
path: '/',
|
||||||
params: { nextUrl: to.fullPath },
|
});
|
||||||
})
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
next()
|
|
||||||
}
|
}
|
||||||
})
|
next();
|
||||||
|
} else if (to.matched.some(record => record.meta.logoutFilter)) {
|
||||||
|
if (!store.getters.getUserProfile) {
|
||||||
|
next({
|
||||||
|
path: '/connexion',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
19
client/src/store/index.js
Normal file
19
client/src/store/index.js
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import Vue from 'vue';
|
||||||
|
import Vuex from 'vuex';
|
||||||
|
|
||||||
|
import VueCookies from 'vue-cookies';
|
||||||
|
Vue.use(VueCookies);
|
||||||
|
Vue.$cookies.config('30d','','');
|
||||||
|
|
||||||
|
Vue.use(Vuex);
|
||||||
|
|
||||||
|
import user from './modules/user.store';
|
||||||
|
|
||||||
|
const debug = process.env.NODE_ENV !== 'production';
|
||||||
|
|
||||||
|
export default new Vuex.Store({
|
||||||
|
modules: {
|
||||||
|
user
|
||||||
|
},
|
||||||
|
strict: debug
|
||||||
|
});
|
||||||
23
client/src/store/modules/spell.store.js
Normal file
23
client/src/store/modules/spell.store.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const state = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
namespaced: true,
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
mutations,
|
||||||
|
};
|
||||||
91
client/src/store/modules/user.store.js
Normal file
91
client/src/store/modules/user.store.js
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
import cookie from 'vue-cookies';
|
||||||
|
|
||||||
|
// API
|
||||||
|
import { RepositoryFactory } from "@/api/repositories";
|
||||||
|
const Users = RepositoryFactory.get('users');
|
||||||
|
|
||||||
|
export const namespaced = true;
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
profile: cookie.get('user_profile') || null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const getters = {
|
||||||
|
getUserProfile: state => {
|
||||||
|
return state.profile;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const mutations = {
|
||||||
|
loginUser(state, user) {
|
||||||
|
state.profile = user;
|
||||||
|
},
|
||||||
|
|
||||||
|
logoutUser(state) {
|
||||||
|
state.profile = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
registerUser() {
|
||||||
|
// Will contain the email call eventually
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const actions = {
|
||||||
|
/**
|
||||||
|
* @param data
|
||||||
|
* An object containing :
|
||||||
|
* - user object with mail and password hash properties
|
||||||
|
* - remember_me boolean to check cookie expiration time
|
||||||
|
*/
|
||||||
|
user_login ({ commit }, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Users.login(data.user)
|
||||||
|
.then(v => {
|
||||||
|
let user = v.data.user;
|
||||||
|
|
||||||
|
// Check if the use wishes to be remembered
|
||||||
|
if (data.remember_me) {
|
||||||
|
cookie.set('user_profile', user, 60 * 60 * 24 * 30); // Expires after a month
|
||||||
|
} else {
|
||||||
|
cookie.set('user_profile', user, 0); // Expires after browser session expires
|
||||||
|
}
|
||||||
|
|
||||||
|
commit('loginUser', user);
|
||||||
|
resolve(user);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err.response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
user_logout ({ commit }) {
|
||||||
|
cookie.remove('user_profile');
|
||||||
|
commit('logoutUser');
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param data
|
||||||
|
* An object containing :
|
||||||
|
* - user object with string mail, string name, and string password
|
||||||
|
*/
|
||||||
|
user_register ({ commit }, data) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Users.register(data.user)
|
||||||
|
.then(() => {
|
||||||
|
commit('registerUser');
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
reject(err.response);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
state,
|
||||||
|
getters,
|
||||||
|
actions,
|
||||||
|
mutations,
|
||||||
|
};
|
||||||
@@ -1,20 +1,19 @@
|
|||||||
const path = require('path')
|
const path = require('path');
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
configureWebpack: {
|
lintOnSave: false,
|
||||||
resolve: {
|
configureWebpack: {
|
||||||
alias: {
|
resolve: {
|
||||||
"~": path.resolve(__dirname, 'src/')
|
alias: {
|
||||||
}
|
"@": path.resolve(__dirname, 'src/')
|
||||||
}
|
}
|
||||||
},
|
|
||||||
css: {
|
|
||||||
loaderOptions: {
|
|
||||||
scss: {
|
|
||||||
prependData: `
|
|
||||||
@import "@/assets/scss/_variables.scss";
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
css: {
|
||||||
|
loaderOptions: {
|
||||||
|
scss: {
|
||||||
|
prependData: `@import "@/assets/scss/_variables.scss";`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
Reference in New Issue
Block a user