From 08b0b94bd8e81d9eb7b9ee9fdfbd76db5e1b5f17 Mon Sep 17 00:00:00 2001 From: Alexis <35.alexis.pele@gmail.com> Date: Sat, 23 May 2020 21:48:27 +0200 Subject: [PATCH] - [API] Added User routes (need polishing because it parses and sends sensitive data) --- database/spellsaurus_db_create.sql | 15 +- database/spellsaurus_db_data.sql | 4 + index.js | 3 +- models/User.js | 13 + package-lock.json | 412 +++++++++++++++++++++++++++++ package.json | 1 + routes/auth.js | 7 + routes/index.js | 2 + routes/spells.js | 207 +++++++-------- routes/users.js | 243 +++++++++++++++++ 10 files changed, 794 insertions(+), 113 deletions(-) create mode 100644 models/User.js create mode 100644 routes/auth.js create mode 100644 routes/users.js diff --git a/database/spellsaurus_db_create.sql b/database/spellsaurus_db_create.sql index 5d678b2..d09ead0 100644 --- a/database/spellsaurus_db_create.sql +++ b/database/spellsaurus_db_create.sql @@ -50,13 +50,14 @@ CREATE TABLE IF NOT EXISTS `variable` ( /* ==== USER TABLES ==== */ --- CREATE TABLE IF NOT EXISTS `user` ( --- `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, --- `name` VARCHAR(255) NOT NULL DEFAULT "Disciple", --- `mail` VARCHAR(255) NOT NULL, --- `password` VARCHAR(255) NOT NULL, --- PRIMARY KEY(`id`) --- ) +CREATE TABLE IF NOT EXISTS `user` ( + `id` INT UNSIGNED NOT NULL AUTO_INCREMENT, + `name` VARCHAR(255) NOT NULL DEFAULT "Disciple", + `mail` VARCHAR(255) NOT NULL, + `password` VARCHAR(255) NOT NULL, + `banned` BOOLEAN DEFAULT false, + PRIMARY KEY(`id`) +); /* ==== ASSOCIATION TABLES ==== */ diff --git a/database/spellsaurus_db_data.sql b/database/spellsaurus_db_data.sql index 1798f9a..73b4d92 100644 --- a/database/spellsaurus_db_data.sql +++ b/database/spellsaurus_db_data.sql @@ -202,6 +202,10 @@ INSERT INTO `spell` (name, description, level, charge, cost, is_ritual) VALUES ('Globules corrosives III', 'Une aura verte sombre se dégage des mains du lanceur. Une énorme nuée de globules se manifeste de cette aura et fond sur une cible unique, infligeant 3D10 de dégats de corrosion pendant 3 tours. Le sort ne peut se manifester dans un liquide.', 0, 0, '-50', false), ('Vent toxique', 'Le lanceur manifeste un courant d\'air mordant et nocif sur un petit groupe de cibles, infligeant 4D10 dégâts de corrosion pendant 3 tours à ces dernières.', 20, 1, '-70', false); +-- USERS +INSERT INTO `user` (name, mail, password) VALUES +('Kevin', '35.alexis.mail@gmail.com', 'sept777'); + -- INGREDIENTS INSERT INTO `ingredient` (name) VALUES ('Volonté'), diff --git a/index.js b/index.js index c1d340b..a6b9cc1 100644 --- a/index.js +++ b/index.js @@ -29,4 +29,5 @@ const server = app.listen( port, () => {console.log(`App listening on port ${por // Routing app.use('/api/spells', routes.spells) -app.use('/api/schools', routes.schools) \ No newline at end of file +app.use('/api/schools', routes.schools) +app.use('/api/users', routes.users) \ No newline at end of file diff --git a/models/User.js b/models/User.js new file mode 100644 index 0000000..451adad --- /dev/null +++ b/models/User.js @@ -0,0 +1,13 @@ +const User = { + "id": "/UserModel", + "type": Object, + "properties": { + "name": { "type": "string" }, + "mail": { "type": "string" }, + "password": { "type": "string" }, + "banned": { "type": "boolean"}, + }, + "required": ["name", "password", "mail"] +} + +module.exports = User \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d9f8074..6d450b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,11 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -13,11 +18,35 @@ "negotiator": "0.6.2" } }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, "basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -26,6 +55,15 @@ "safe-buffer": "5.1.2" } }, + "bcrypt": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-4.0.1.tgz", + "integrity": "sha512-hSIZHkUxIDS5zA2o00Kf2O5RfVbQ888n54xQoF/eIaquU4uaLxK8vhhBdktd0B3n2MjkcAWzv4mnhogykBKOUQ==", + "requires": { + "node-addon-api": "^2.0.0", + "node-pre-gyp": "0.14.0" + } + }, "bignumber.js": { "version": "9.0.0", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.0.0.tgz", @@ -53,6 +91,15 @@ "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.9.0.tgz", "integrity": "sha512-2ld76tuLBNFekRgmJfT2+3j5MIrP6bFict8WAIT3beq+srz1gcKNAdNKMqHqauQt63NmAa88HfP1/Ypa9Er3HA==" }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, "buffer-equal-constant-time": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", @@ -68,6 +115,26 @@ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz", "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==" + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=" + }, "content-disposition": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", @@ -123,6 +190,16 @@ "ms": "2.0.0" } }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=" + }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -133,6 +210,11 @@ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=" }, + "detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" + }, "dns-prefetch-control": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.2.0.tgz", @@ -247,6 +329,52 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=" }, + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "requires": { + "minipass": "^2.6.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=" + }, "helmet": { "version": "3.22.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.22.0.tgz", @@ -342,16 +470,46 @@ "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz", "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ==" }, + "ignore-walk": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", + "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "requires": { + "number-is-nan": "^1.0.0" + } + }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -473,6 +631,44 @@ "mime-db": "1.44.0" } }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "requires": { + "minipass": "^2.9.0" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "requires": { + "minimist": "^1.2.5" + } + }, "morgan": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", @@ -508,6 +704,31 @@ "sqlstring": "2.3.1" } }, + "needle": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.0.tgz", + "integrity": "sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA==", + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -518,6 +739,76 @@ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz", "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q==" }, + "node-addon-api": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.0.tgz", + "integrity": "sha512-ASCL5U13as7HhOExbT6OlWJJUV/lLzL2voOSP1UVehpRD8FbSrSDjfScK/KwAvVTI5AS6r4VwbOMlIqtvRidnA==" + }, + "node-pre-gyp": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.14.0.tgz", + "integrity": "sha512-+CvDC7ZttU/sSt9rFjix/P05iS43qHCOOGzcr3Ry99bXG7VX953+vFyEuph/tfqoYu8dttBkE86JSKBO2OzcxA==", + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4.4.2" + } + }, + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", + "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", + "requires": { + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npm-normalize-package-bin": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", + "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==" + }, + "npm-packlist": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", + "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1", + "npm-normalize-package-bin": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -536,11 +827,43 @@ "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", @@ -581,6 +904,17 @@ "unpipe": "1.0.0" } }, + "rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + } + }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -600,6 +934,14 @@ "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz", "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA==" }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "requires": { + "glob": "^7.1.3" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -610,6 +952,11 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", @@ -653,11 +1000,21 @@ "send": "0.17.1" } }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, "setprototypeof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==" }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" + }, "sqlstring": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.1.tgz", @@ -668,6 +1025,16 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=" }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", @@ -676,6 +1043,33 @@ "safe-buffer": "~5.1.0" } }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" + }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + } + }, "toidentifier": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", @@ -710,10 +1104,28 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=" }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, "x-xss-protection": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", "integrity": "sha512-kpyBI9TlVipZO4diReZMAHWtS0MMa/7Kgx8hwG/EuZLiA6sg4Ah/4TRdASHhRRN3boobzcYgFRUFSgHRge6Qhg==" + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/package.json b/package.json index f7bd4db..688d1af 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ }, "homepage": "https://github.com/AlexisNP/spellsaurus#readme", "dependencies": { + "bcrypt": "^4.0.1", "cors": "^2.8.5", "express": "^4.17.1", "helmet": "^3.22.0", diff --git a/routes/auth.js b/routes/auth.js new file mode 100644 index 0000000..d15e75c --- /dev/null +++ b/routes/auth.js @@ -0,0 +1,7 @@ +const jwt = require('jsonwebtoken') + +const isAuthenticated = (req, res, next) => { + if (typeof req.headers.authorization !== undefined) { + let token = req.headers.authorization.split(" ")[1] + } +} \ No newline at end of file diff --git a/routes/index.js b/routes/index.js index dcef834..021e2b2 100644 --- a/routes/index.js +++ b/routes/index.js @@ -1,7 +1,9 @@ +const users = require('./users') const spells = require('./spells') const schools = require('./schools') module.exports = { spells, schools, + users } \ No newline at end of file diff --git a/routes/spells.js b/routes/spells.js index e709ec9..6c8da89 100644 --- a/routes/spells.js +++ b/routes/spells.js @@ -121,17 +121,17 @@ const addSpell = (s) => { let query = 'INSERT INTO spell (name, description' - if (s.level != undefined) { query += ', level' } - if (s.charge != undefined) { query += ', charge' } - if (s.cost != undefined) { query += ', cost' } - if (s.is_ritual != undefined) { query += ', is_ritual' } + if (typeof s.level !== undefined) { query += ', level' } + if (typeof s.charge !== undefined) { query += ', charge' } + if (typeof s.cost !== undefined) { query += ', cost' } + if (typeof s.is_ritual !== undefined) { query += ', is_ritual' } query += `) VALUES (${db.escape(s.name)}, ${db.escape(s.description)}` - if (s.level != undefined) { query += `, ${s.level}` } - if (s.charge != undefined) { query += `, ${s.charge}` } - if (s.cost != undefined) { query += `, ${db.escape(s.cost)}` } - if (s.is_ritual != undefined) { query += `, ${s.is_ritual}` } + if (typeof s.level !== undefined) { query += `, ${s.level}` } + if (typeof s.charge !== undefined) { query += `, ${s.charge}` } + if (typeof s.cost !== undefined) { query += `, ${db.escape(s.cost)}` } + if (typeof s.is_ritual !== undefined) { query += `, ${s.is_ritual}` } query += ')' @@ -145,7 +145,7 @@ const addSpell = (s) => { let addSchoolsData = () => { return new Promise((resolve, reject) => { - if (s.schools != undefined) { + if (typeof s.schools !== undefined) { if (s.schools.length > 0) { for (let i = 0; i < s.schools.length; i++) { if (!regexInt.test(s.schools[i].id)) { @@ -174,7 +174,7 @@ const addSpell = (s) => { let addVariablesData = () => { return new Promise((resolve, reject) => { - if (s.variables != undefined) { + if (typeof s.variables !== undefined) { if (s.variables.length > 0) { for (let i = 0; i < s.variables.length; i++) { if (!regexInt.test(s.variables[i].id)) { @@ -202,7 +202,7 @@ const addSpell = (s) => { let addIngredientsData = () => { return new Promise((resolve, reject) => { - if (s.ingredients != undefined) { + if (typeof s.ingredients !== undefined) { if (s.ingredients.length > 0) { for (let i = 0; i < s.ingredients.length; i++) { if (!regexInt.test(s.ingredients[i].id)) { @@ -279,12 +279,12 @@ const updateSpell = (s, id) => { let query = 'UPDATE spell SET ' - if (s.name != undefined) { query += `name = "${s.name}" ` } - if (s.description != undefined) { query += `, description = "${s.description}" ` } - if (s.level != undefined) { query += `, level = ${s.level} ` } - if (s.charge != undefined) { query += `, charge = ${s.charge} ` } - if (s.cost != undefined) { query += `, cost = "${s.cost}" ` } - if (s.is_ritual != undefined) { query += `, is_ritual = ${s.is_ritual} ` } + if (typeof s.name !== undefined) { query += `name = "${s.name}" ` } + if (typeof s.description !== undefined) { query += `, description = "${s.description}" ` } + if (typeof s.level !== undefined) { query += `, level = ${s.level} ` } + if (typeof s.charge !== undefined) { query += `, charge = ${s.charge} ` } + if (typeof s.cost !== undefined) { query += `, cost = "${s.cost}" ` } + if (typeof s.is_ritual !== undefined) { query += `, is_ritual = ${s.is_ritual} ` } query += ` WHERE id = ${db.escape(id)}` @@ -296,7 +296,7 @@ const updateSpell = (s, id) => { let updateSchoolsData = () => { return new Promise((resolve, reject) => { - if (s.schools != undefined) { + if (typeof s.schools !== undefined) { if (s.schools.length > 0) { let delete_schools_query = `DELETE FROM spells_schools WHERE id_spell = ${old_spell.id}` @@ -333,7 +333,7 @@ const updateSpell = (s, id) => { let updateVariablesData = () => { return new Promise((resolve, reject) => { - if (s.variables != undefined) { + if (typeof s.variables !== undefined) { if (s.variables.length > 0) { let delete_variables_query = `DELETE FROM spells_variables WHERE id_spell = ${old_spell.id}` @@ -370,7 +370,7 @@ const updateSpell = (s, id) => { let updateIngredientsData = () => { return new Promise((resolve, reject) => { - if (s.ingredients != undefined) { + if (typeof s.ingredients !== undefined) { if (s.ingredients.length > 0) { let delete_ingredients_query = `DELETE FROM spells_ingredients WHERE id_spell = ${old_spell.id}` @@ -450,90 +450,86 @@ const deleteSpell = (id) => { // Check if spell exists let old_spell = await getSpell(id) + .catch(() => { + reject((new HttpError(404, 'No spell matching this ID'))) + }) + + let deleteSchoolsData = () => { + return new Promise((resolve, reject) => { + let delete_schools_query = `DELETE FROM spells_schools WHERE id_spell = ${db.escape(id)}` + db.query(delete_schools_query, async (err, result) => { + if (err) { + reject(new HttpError(500, 'Spell schools deletion failed')) + } else { + console.log(`Deleted schools associated to spell ID ${db.escape(id)}`) + resolve() + } + }) + }) + } + + let deleteVariablesData = () => { + return new Promise((resolve, reject) => { + let delete_variables_query = `DELETE FROM spells_variables WHERE id_spell = ${db.escape(id)}` + db.query(delete_variables_query, async (err, result) => { + if (err) { + console.log(err) + reject(new HttpError(500, 'Spell variables deletion failed')) + } else { + console.log(`Deleted variables associated to spell ID ${db.escape(id)}`) + resolve() + } + }) + }) + } + + let deleteIngredientsData = () => { + return new Promise((resolve, reject) => { + let delete_ingredients_query = `DELETE FROM spells_ingredients WHERE id_spell = ${db.escape(id)}` + db.query(delete_ingredients_query, async (err, result) => { + if (err) { + console.log(err) + reject(new HttpError(500, 'Spell ingredients deletion failed')) + } else { + console.log(`Deleted ingredients associated to spell ID ${db.escape(id)}`) + resolve() + } + }) + }) + } + + let deleteSpellData = () => { + return new Promise((resolve, reject) => { + let delete_spell_query = `DELETE FROM spell WHERE id = ${db.escape(id)}` + db.query(delete_spell_query, async (err, result) => { + if (err) { + console.log(err) + reject(new HttpError(500, 'Spell deletion failed')) + } else { + console.log(`Deleted spell ID ${db.escape(id)}, affecting ${result.affectedRows} rows`) + resolve() + } + }) + }) + } + + const promises = [ + deleteSchoolsData(), + deleteVariablesData(), + deleteIngredientsData() + ] + + Promise.all(promises) + .then(() => { + deleteSpellData() + let response = { + message: `Spell ID ${id} was successfully deleted.` + } + resolve(response) + }) .catch(err => { reject(err) }) - - if (old_spell == undefined) { - reject((new HttpError(404, 'No spells matching this ID'))) - } else { - let deleteSchoolsData = () => { - return new Promise((resolve, reject) => { - let delete_schools_query = `DELETE FROM spells_schools WHERE id_spell = ${db.escape(id)}` - db.query(delete_schools_query, async (err, result) => { - if (err) { - reject(new HttpError(500, 'Spell schools deletion failed')) - } else { - console.log(`Deleted schools associated to spell ID ${db.escape(id)}`) - resolve() - } - }) - }) - } - - let deleteVariablesData = () => { - return new Promise((resolve, reject) => { - let delete_variables_query = `DELETE FROM spells_variables WHERE id_spell = ${db.escape(id)}` - db.query(delete_variables_query, async (err, result) => { - if (err) { - console.log(err) - reject(new HttpError(500, 'Spell variables deletion failed')) - } else { - console.log(`Deleted variables associated to spell ID ${db.escape(id)}`) - resolve() - } - }) - }) - } - - let deleteIngredientsData = () => { - return new Promise((resolve, reject) => { - let delete_ingredients_query = `DELETE FROM spells_ingredients WHERE id_spell = ${db.escape(id)}` - db.query(delete_ingredients_query, async (err, result) => { - if (err) { - console.log(err) - reject(new HttpError(500, 'Spell ingredients deletion failed')) - } else { - console.log(`Deleted ingredients associated to spell ID ${db.escape(id)}`) - resolve() - } - }) - }) - } - - let deleteSpellData = () => { - return new Promise((resolve, reject) => { - let delete_spell_query = `DELETE FROM spell WHERE id = ${db.escape(id)}` - db.query(delete_spell_query, async (err, result) => { - if (err) { - console.log(err) - reject(new HttpError(500, 'Spell deletion failed')) - } else { - console.log(`Deleted spell ID ${db.escape(id)}, affecting ${result.affectedRows} rows`) - resolve() - } - }) - }) - } - - const promises = [ - deleteSchoolsData(), - deleteVariablesData(), - deleteIngredientsData() - ] - - Promise.all(promises) - .then(() => { - deleteSpellData() - let response = { - message: `Spell ID ${id} was successfully deleted.` - } - resolve(response) - }) - .catch(err => { - reject(err) - }) - } }) .catch(err => { throw err @@ -584,7 +580,7 @@ const buildSpell = async (spell) => { let fetchSpellSchoolData = (s) => { return new Promise((resolve, reject) => { - if (s == undefined) { reject(new HttpError(404, "Error: No spells matching this ID"))} + if (typeof s == undefined) { reject(new HttpError(404, "Error: No spell matching this ID"))} let query = "SELECT school.id, school.name " + @@ -607,7 +603,7 @@ const buildSpell = async (spell) => { let fetchSpellVariablesData = (s) => { return new Promise((resolve, reject) => { - if (s == undefined) { reject(new HttpError(404, "Error: No spells matching this ID"))} + if (typeof s == undefined) { reject(new HttpError(404, "Error: No spell matching this ID"))} let query = "SELECT variable.id, variable.description " + @@ -630,7 +626,7 @@ const buildSpell = async (spell) => { let fetchSpellIngredientsData = (s) => { return new Promise((resolve, reject) => { - if (s == undefined) { reject(new HttpError(404, "Error: No spells matching this ID"))} + if (typeof s == undefined) { reject(new HttpError(404, "Error: No spell matching this ID"))} let query = "SELECT ingredient.id, ingredient.name " + @@ -660,7 +656,7 @@ const buildSpell = async (spell) => { return s } -// Check if spell is null +// Check if object is null const isEmptyObject = (obj) => { if (Object.keys(obj).length === 0 && obj.constructor === Object) { return true @@ -669,6 +665,7 @@ const isEmptyObject = (obj) => { } } +// Check if script injection attempt const isXSSAttempt = (string) => { if (regexXSS.test(string)) { return true diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..744ee50 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,243 @@ +// Router +const express = require('express') +let router = express.Router() + +// Connection +const connection = require('../database/connection') +const db = connection.db + +// Hashing and passwords +const bcrypt = require('bcrypt') + +// Validations +const regexInt = RegExp(/^[1-9]\d*$/) +const regexXSS = RegExp(/<[^>]*script/) + +// Model validation +const Validator = require('jsonschema').Validator +const v = new Validator() +const User = require("../models/User") +v.addSchema(User, "/UserModel") + +// Error handling +const { HttpError } = require('../models/Errors') + +// ROUTES +// GET ALL ------------------ +const getUsers = () => { + return new Promise((resolve, reject) => { + + let query = "SELECT DISTINCT * FROM user" + + db.query(query, async (err, result) => { + if (err) { + reject(new HttpError(500, 'Database error')) + } else if (result.length == 0) { + reject(new HttpError(404, 'No users were found')) + } else { + resolve(result) + } + }) + }) + .catch(err => { + throw err + }) +} +router.get('/', async (req, res) => { + getUsers() + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// GET ONE ------------------ +const getUser = (id) => { + return new Promise((resolve, reject) => { + + let query = "SELECT * FROM user WHERE id = " + db.escape(id) + + db.query(query, async (err, result) => { + if (err) { + reject(new HttpError(500, 'Database error')) + } else if (result.length == 0) { + reject(new HttpError(404, 'No User matching this ID')) + } else { + resolve(result) + } + }) + }) + .catch(err => { + throw err + }) +} +router.get('/:id/', async (req, res) => { + getUser(req.params.id) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.end(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// CREATE ONE ------------------ +const addUser = (u) => { + return new Promise(async (resolve, reject) => { + + // Checks if body exists and if the model fits, and throws errors if it doesn't + if (isEmptyObject(u)) { + reject(new HttpError(403, "Error: User cannot be empty !")) + } else if (!v.validate(u, User).valid) { + reject(new HttpError(403, "Error: Schema is not valid - " + v.validate(u, User).errors)) + } else if (isXSSAttempt(u.name) || isXSSAttempt(u.mail) || isXSSAttempt(u.password)) { + reject(new HttpError(403, 'Injection attempt detected, aborting the request.')) + } else { + let query = `INSERT INTO user (name, mail, password) VALUES (${db.escape(u.name)}, ${db.escape(u.mail)}, ${db.escape(u.password)})` + + db.query(query, async (err, result) => { + if (err) { + reject(new HttpError(500, 'Database error')) + } else { + console.log(`Inserted "${u.name}" with ID ${result.insertId}, affecting ${result.affectedRows} row(s)`) + const new_user_id = result.insertId + let response = { + "message": `User created successfully !`, + "inserted_id": `${new_user_id}` + } + resolve(response) + } + }) + } + }).catch(err => { + throw err + }) +} +router.post('/', async (req, res) => { + addUser(req.body) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.send(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + + +// DELETE ONE ------------------ +const deleteUser = (id) => { + return new Promise(async (resolve, reject) => { + + // Check if user exists + let old_user = await getUser(id) + .catch(() => { + reject((new HttpError(404, 'No user matching this ID'))) + }) + + console.log(old_user) + + let deleteUserData = () => { + return new Promise((resolve, reject) => { + let delete_user_query = `DELETE FROM user WHERE id = ${db.escape(id)}` + db.query(delete_user_query, async (err, result) => { + if (err) { + console.log(err) + reject(new HttpError(500, 'Spell deletion failed')) + } else { + let response = { + "message": "User delete successully", + "deleted_id": `${id}` + } + resolve(response) + } + }) + }) + } + + deleteUserData() + .then(v => { + resolve(v) + }) + .catch(err => { + reject(err) + }) + }) + .catch(err => { + throw err + }) +} +router.delete('/:id/', async (req, res) => { + deleteUser(req.params.id) + .then(v => { + res.setHeader('Content-Type', 'application/json;charset=utf-8') + res.send(JSON.stringify(v)) + }) + .catch(err => { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + "code": err.code + }) + ) + }) +}) + +// Param validation for single user +// (check if id is int) (could be refactored) +router.param('id', (req, res, next, id) => { + try { + if (regexInt.test(id)) { + next() + } else { + throw new HttpError(403, 'Provided ID must be an integer and not zero') + } + } catch (err) { + res.status(err.code).send(JSON.stringify( + { + "error": err.message, + }) + ) + } +}) + +// Check if object is null +const isEmptyObject = (obj) => { + if (Object.keys(obj).length === 0 && obj.constructor === Object) { + return true + } else { + return false + } +} + +// Check if script injection attempt +const isXSSAttempt = (string) => { + if (regexXSS.test(string)) { + return true + } else { + return false + } +} + +module.exports = router