summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--assets/features.json26
-rw-r--r--client_test/index.html8
-rw-r--r--locales/en/auth.json3
-rw-r--r--package-lock.json695
-rw-r--r--package.json2
-rw-r--r--src/Server.ts89
-rw-r--r--src/middlewares/Authentication.ts1
-rw-r--r--src/middlewares/RateLimit.ts6
-rw-r--r--src/middlewares/TestClient.ts66
-rw-r--r--src/routes/auth/login.ts20
-rw-r--r--src/routes/auth/register.ts5
-rw-r--r--src/routes/channels/#channel_id/messages/index.ts20
-rw-r--r--src/routes/guilds/#guild_id/bans.ts2
-rw-r--r--src/routes/guilds/#guild_id/channels.ts7
-rw-r--r--src/routes/guilds/#guild_id/delete.ts18
-rw-r--r--src/routes/guilds/#guild_id/index.ts7
-rw-r--r--src/routes/guilds/#guild_id/vanity-url.ts33
-rw-r--r--src/routes/ping.ts9
-rw-r--r--src/routes/users/#id/profile.ts1
-rw-r--r--src/routes/users/@me/disable.ts16
-rw-r--r--src/routes/users/@me/index.ts17
-rw-r--r--src/routes/users/@me/profile.ts1
-rw-r--r--src/routes/users/@me/relationships.ts60
-rw-r--r--src/schema/Channel.ts2
-rw-r--r--src/schema/Guild.ts21
-rw-r--r--src/schema/User.ts4
-rw-r--r--src/util/Message.ts8
-rw-r--r--src/util/cdn.ts16
-rw-r--r--src/util/instanceOf.ts2
29 files changed, 715 insertions, 450 deletions
diff --git a/assets/features.json b/assets/features.json
new file mode 100644

index 00000000..05a858a0 --- /dev/null +++ b/assets/features.json
@@ -0,0 +1,26 @@ +[ + "ANIMATED_ICON", + "BANNER", + "COMMERCE", + "COMMUNITY", + "DISCOVERABLE", + "DISCOVERABLE_DISABLED", + "ENABLED_DISCOVERABLE_BEFORE", + "HUB", + "INVITE_SPLASH", + "MONETIZATION_ENABLED", + "MORE_EMOJI", + "MORE_STICKERS", + "NEWS", + "PARTNERED", + "PREVIEW_ENABLED", + "PRIVATE_THREADS", + "SEVEN_DAY_THREAD_ARCHIVE", + "THREE_DAY_THREAD_ARCHIVE", + "THREADS_ENABLED", + "TICKETED_EVENTS_ENABLED", + "VANITY_URL", + "VERIFIED", + "VIP_REGIONS", + "WELCOME_SCREEN_ENABLED" +] diff --git a/client_test/index.html b/client_test/index.html
index da970e4f..1a979419 100644 --- a/client_test/index.html +++ b/client_test/index.html
@@ -13,13 +13,13 @@ window.GLOBAL_ENV = { API_ENDPOINT: "/api", API_VERSION: 9, - GATEWAY_ENDPOINT: "ws://localhost:3002", + GATEWAY_ENDPOINT: `${location.protocol === "https:" ? "wss://" : "ws://"}${location.hostname}:3002`, WEBAPP_ENDPOINT: "", - CDN_HOST: "//localhost:3003", + CDN_HOST: `${location.hostname}:3003`, ASSET_ENDPOINT: "", MEDIA_PROXY_ENDPOINT: "https://media.discordapp.net", - WIDGET_ENDPOINT: "//localhost:3001/widget", - INVITE_HOST: "discord.gg", + WIDGET_ENDPOINT: `//${location.host}/widget`, + INVITE_HOST: `${location.hostname}`, GUILD_TEMPLATE_HOST: "discord.new", GIFT_CODE_HOST: "discord.gift", RELEASE_CHANNEL: "stable", diff --git a/locales/en/auth.json b/locales/en/auth.json
index bcf6fca5..e19547a0 100644 --- a/locales/en/auth.json +++ b/locales/en/auth.json
@@ -1,7 +1,8 @@ { "login": { "INVALID_LOGIN": "E-Mail or Phone not found", - "INVALID_PASSWORD": "Invalid Password" + "INVALID_PASSWORD": "Invalid Password", + "ACCOUNT_DISABLED": "This account is disabled" }, "register": { "REGISTRATION_DISABLED": "New user registration is disabled", diff --git a/package-lock.json b/package-lock.json
index 44edadbb..59d3f585 100644 --- a/package-lock.json +++ b/package-lock.json
@@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@fosscord/server-util": "^1.3.37", + "@fosscord/server-util": "^1.3.46", "@types/jest": "^26.0.22", "@types/json-schema": "^7.0.7", "ajv": "^8.4.0", @@ -71,29 +71,29 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", - "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", - "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", - "@babel/helper-compilation-targets": "^7.14.5", - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helpers": "^7.14.6", - "@babel/parser": "^7.14.6", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -149,12 +149,12 @@ } }, "node_modules/@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.15.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" }, @@ -163,12 +163,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", - "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.14.5", + "@babel/compat-data": "^7.15.0", "@babel/helper-validator-option": "^7.14.5", "browserslist": "^4.16.6", "semver": "^6.3.0" @@ -228,12 +228,12 @@ } }, "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", - "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.0" }, "engines": { "node": ">=6.9.0" @@ -252,19 +252,19 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", - "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", "dev": true, "dependencies": { "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" }, "engines": { "node": ">=6.9.0" @@ -292,27 +292,27 @@ } }, "node_modules/@babel/helper-replace-supers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", - "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", "dev": true, "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.15.0", "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", - "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "dev": true, "dependencies": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.14.8" }, "engines": { "node": ">=6.9.0" @@ -331,9 +331,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", "dev": true, "engines": { "node": ">=6.9.0" @@ -349,14 +349,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", - "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.8.tgz", + "integrity": "sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw==", "dev": true, "dependencies": { "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8" }, "engines": { "node": ">=6.9.0" @@ -439,9 +439,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-0v7oNOjr6YT9Z2RAOTv4T9aP+ubfx4Q/OhVtAet7PFDt0t9Oy6Jn+/rfC6b8HJ5zEqrQCiMxJfgtHpmIminmJQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -598,9 +598,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", - "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz", + "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==", "dependencies": { "regenerator-runtime": "^0.13.4" }, @@ -623,18 +623,18 @@ } }, "node_modules/@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.15.0", "@babel/helper-function-name": "^7.14.5", "@babel/helper-hoist-variables": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -643,12 +643,12 @@ } }, "node_modules/@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" }, "engines": { @@ -678,9 +678,9 @@ } }, "node_modules/@fosscord/server-util": { - "version": "1.3.37", - "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.37.tgz", - "integrity": "sha512-hE2QIMHo/j/rCXmw+HEr5iV2RphGO7/oU1co1f6B8PlDHmyDoC0U/g1xXo9KwrWcB9lyCWb0kxlf2mOhCCQ4yA==", + "version": "1.3.46", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.46.tgz", + "integrity": "sha512-YX2pSkgsxrFcdEVXQWuQYHmT+P0Y+BtGRopZf5HKeHbjDl4/Bblj/GRU55qvtHsW5/6XQBZCG/GoeTu/MMQ+xw==", "dependencies": { "@types/jsonwebtoken": "^8.5.0", "@types/mongoose-autopopulate": "^0.10.1", @@ -1168,9 +1168,9 @@ } }, "node_modules/@types/bson": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.4.tgz", - "integrity": "sha512-awqorHvQS0DqxkHQ/FxcPX9E+H7Du51Qw/2F+5TBMSaE3G0hm+8D3eXJ6MAzFw75nE8V7xF0QvzUSdxIjJb/GA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", + "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", "dependencies": { "@types/node": "*" } @@ -1256,9 +1256,9 @@ } }, "node_modules/@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" }, "node_modules/@types/jsonwebtoken": { "version": "8.5.4", @@ -1275,12 +1275,12 @@ "dev": true }, "node_modules/@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-4.0.7.tgz", + "integrity": "sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==", + "deprecated": "mongodb provides its own types. @types/mongodb is no longer needed.", "dependencies": { - "@types/bson": "*", - "@types/node": "*" + "mongodb": "*" } }, "node_modules/@types/mongoose": { @@ -1318,14 +1318,14 @@ } }, "node_modules/@types/node": { - "version": "14.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", - "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==" + "version": "14.17.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", + "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==" }, "node_modules/@types/node-fetch": { - "version": "2.5.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.11.tgz", - "integrity": "sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==", + "version": "2.5.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", + "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", "dev": true, "dependencies": { "@types/node": "*", @@ -1833,9 +1833,9 @@ } }, "node_modules/async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", "dev": true }, "node_modules/asynckit": { @@ -2308,16 +2308,16 @@ } }, "node_modules/browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "version": "4.16.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", + "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", "dev": true, "dependencies": { - "caniuse-lite": "^1.0.30001219", + "caniuse-lite": "^1.0.30001248", "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", + "electron-to-chromium": "^1.3.793", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "node-releases": "^1.1.73" }, "bin": { "browserslist": "cli.js" @@ -2372,9 +2372,9 @@ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "node_modules/buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "node_modules/buffer-xor": { "version": "1.0.3", @@ -2484,9 +2484,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001245", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", - "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==", + "version": "1.0.30001249", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz", + "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==", "dev": true, "funding": { "type": "opencollective", @@ -2538,9 +2538,9 @@ } }, "node_modules/chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -3818,9 +3818,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "node_modules/electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==", + "version": "1.3.799", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.799.tgz", + "integrity": "sha512-V2rbYWdGvSqrg+95KjkVuSi41bGfrhrOzjl1tSi2VLnm0mRe3FsSvhiqidSiSll9WiMhrQAhpDcW/wcqK3c+Yw==", "dev": true }, "node_modules/elliptic": { @@ -4287,9 +4287,9 @@ } }, "node_modules/express-validator": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.12.0.tgz", - "integrity": "sha512-lcQAdVeAO+pBbHD33nIsDsd+QPakLX08tJ82iEsXj6ezyWCfYjE9RY/g9SVq5z4G0NaIkH8039Oe4r0G92DRyA==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.12.1.tgz", + "integrity": "sha512-olpTAv0ZB5IhNuDQ2rodKAuJsewgFgLIsczJMAWD6T0Yvxsa+j/Hk61jl8e26lAq+oJr6hUqPRjdlOBKhFlWeQ==", "dependencies": { "lodash": "^4.17.21", "validator": "^13.5.2" @@ -4752,9 +4752,9 @@ } }, "node_modules/graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "node_modules/growly": { @@ -5420,12 +5420,15 @@ "dev": true }, "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, "engines": { "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-typedarray": { @@ -6163,9 +6166,9 @@ } }, "node_modules/jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "dependencies": { "abab": "^2.0.5", @@ -6193,7 +6196,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "engines": { @@ -6757,19 +6760,19 @@ } }, "node_modules/mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==", + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==", "engines": { "node": ">= 0.6" } }, "node_modules/mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "dependencies": { - "mime-db": "1.48.0" + "mime-db": "1.49.0" }, "engines": { "node": ">= 0.6" @@ -6847,9 +6850,9 @@ } }, "node_modules/missing-native-js-functions": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.7.tgz", - "integrity": "sha512-3JT72wOtgojsdmUaa/LIlEuPmT802Kajnr9RFxSZFCX37oL3epd3mZwSaabqFHxPOUW7nJnix+BAWKwX6O0Q5g==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.9.tgz", + "integrity": "sha512-Hv1oiFi9Wf5bsxra/UlmribNCDyLNYQULepfVJH6aF50Thh522kaMF3IuHja2mKX1oeWBkp6FvLaAfAjLuCOzw==" }, "node_modules/mixin-deep": { "version": "1.3.2", @@ -6911,9 +6914,9 @@ } }, "node_modules/mongodb": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz", - "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==", + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.11.tgz", + "integrity": "sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==", "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", @@ -6949,12 +6952,11 @@ } }, "node_modules/mongoose": { - "version": "5.13.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.3.tgz", - "integrity": "sha512-q+zX6kqHAvwxf5speMWhq6qF4vdj+x6/kfD5RSKdZKNm52yGmaUygN+zgrtQjBZPFEzG0B3vF6GP0PoAGadE+w==", + "version": "5.13.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.5.tgz", + "integrity": "sha512-sSUAk9GWgA8r3w3nVNrNjBaDem86aevwXO8ltDMKzCf+rjnteMMQkXHQdn1ePkt7alROEPZYCAjiRjptWRSPiQ==", "dependencies": { "@types/mongodb": "^3.5.27", - "@types/node": "14.x || 15.x", "bson": "^1.1.4", "kareem": "2.3.2", "mongodb": "3.6.10", @@ -6962,6 +6964,7 @@ "mpath": "0.8.3", "mquery": "3.2.5", "ms": "2.1.2", + "optional-require": "1.0.x", "regexp-clone": "1.0.0", "safe-buffer": "5.2.1", "sift": "13.5.2", @@ -6999,6 +7002,61 @@ "mongoose": "4.x || 5.x" } }, + "node_modules/mongoose/node_modules/@types/mongodb": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", + "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "dependencies": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "node_modules/mongoose/node_modules/mongodb": { + "version": "3.6.10", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz", + "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==", + "dependencies": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.0.3", + "safe-buffer": "^5.1.2" + }, + "engines": { + "node": ">=4" + }, + "optionalDependencies": { + "saslprep": "^1.0.0" + }, + "peerDependenciesMeta": { + "aws4": { + "optional": true + }, + "bson-ext": { + "optional": true + }, + "kerberos": { + "optional": true + }, + "mongodb-client-encryption": { + "optional": true + }, + "mongodb-extjson": { + "optional": true + }, + "snappy": { + "optional": true + } + } + }, + "node_modules/mongoose/node_modules/optional-require": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", + "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", + "engines": { + "node": ">=4" + } + }, "node_modules/morphdom": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/morphdom/-/morphdom-2.6.1.tgz", @@ -7597,9 +7655,12 @@ } }, "node_modules/optional-require": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", - "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.5.tgz", + "integrity": "sha512-PtR4HkBxH0Rpethop3qeZY+8gaXjN4+Ik9AJraOU+AQFm6v9rP34xQrQqJD9hNMB76UYxN3ziGExdtkB5C1TUg==", + "dependencies": { + "require-at": "^1.0.6" + }, "engines": { "node": ">=4" } @@ -8329,9 +8390,9 @@ } }, "node_modules/regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "node_modules/regex-not": { "version": "1.0.2", @@ -8392,6 +8453,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-at": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", + "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==", + "engines": { + "node": ">=4" + } + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -9790,9 +9859,9 @@ "dev": true }, "node_modules/tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", @@ -10926,26 +10995,26 @@ } }, "@babel/compat-data": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.7.tgz", - "integrity": "sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.15.0.tgz", + "integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA==", "dev": true }, "@babel/core": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.6.tgz", - "integrity": "sha512-gJnOEWSqTk96qG5BoIrl5bVtc23DCycmIePPYnamY9RboYdI4nFy5vAQMSl81O5K/W0sLDWfGysnOECC+KUUCA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.0.tgz", + "integrity": "sha512-tXtmTminrze5HEUPn/a0JtOzzfp0nk+UEXQ/tqIJo3WDGypl/2OFQEMll/zSFU8f/lfmfLXvTaORHF3cfXIQMw==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", - "@babel/helper-compilation-targets": "^7.14.5", - "@babel/helper-module-transforms": "^7.14.5", - "@babel/helpers": "^7.14.6", - "@babel/parser": "^7.14.6", + "@babel/generator": "^7.15.0", + "@babel/helper-compilation-targets": "^7.15.0", + "@babel/helper-module-transforms": "^7.15.0", + "@babel/helpers": "^7.14.8", + "@babel/parser": "^7.15.0", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5", + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -10987,23 +11056,23 @@ } }, "@babel/generator": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.5.tgz", - "integrity": "sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.0.tgz", + "integrity": "sha512-eKl4XdMrbpYvuB505KTta4AV9g+wWzmVBW69tX0H2NwKVKd2YJbKgyK6M8j/rgLbmHOYJn6rUklV677nOyJrEQ==", "dev": true, "requires": { - "@babel/types": "^7.14.5", + "@babel/types": "^7.15.0", "jsesc": "^2.5.1", "source-map": "^0.5.0" } }, "@babel/helper-compilation-targets": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz", - "integrity": "sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.0.tgz", + "integrity": "sha512-h+/9t0ncd4jfZ8wsdAsoIxSa61qhBYlycXiHWqJaQBCXAhDCMbPRSMTGnZIkkmt1u4ag+UQmuqcILwqKzZ4N2A==", "dev": true, "requires": { - "@babel/compat-data": "^7.14.5", + "@babel/compat-data": "^7.15.0", "@babel/helper-validator-option": "^7.14.5", "browserslist": "^4.16.6", "semver": "^6.3.0" @@ -11047,12 +11116,12 @@ } }, "@babel/helper-member-expression-to-functions": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz", - "integrity": "sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.0.tgz", + "integrity": "sha512-Jq8H8U2kYiafuj2xMTPQwkTBnEEdGKpT35lJEQsRRjnG0LW3neucsaMWLgKcwu3OHKNeYugfw+Z20BXBSEs2Lg==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.15.0" } }, "@babel/helper-module-imports": { @@ -11065,19 +11134,19 @@ } }, "@babel/helper-module-transforms": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.5.tgz", - "integrity": "sha512-iXpX4KW8LVODuAieD7MzhNjmM6dzYY5tfRqT+R9HDXWl0jPn/djKmA+G9s/2C2T9zggw5tK1QNqZ70USfedOwA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.0.tgz", + "integrity": "sha512-RkGiW5Rer7fpXv9m1B3iHIFDZdItnO2/BLfWVW/9q7+KqQSDY5kUfQEbzdXM1MVhJGcugKV7kRrNVzNxmk7NBg==", "dev": true, "requires": { "@babel/helper-module-imports": "^7.14.5", - "@babel/helper-replace-supers": "^7.14.5", - "@babel/helper-simple-access": "^7.14.5", + "@babel/helper-replace-supers": "^7.15.0", + "@babel/helper-simple-access": "^7.14.8", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" } }, "@babel/helper-optimise-call-expression": { @@ -11096,24 +11165,24 @@ "dev": true }, "@babel/helper-replace-supers": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz", - "integrity": "sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.15.0.tgz", + "integrity": "sha512-6O+eWrhx+HEra/uJnifCwhwMd6Bp5+ZfZeJwbqUTuqkhIT6YcRhiZCOOFChRypOIe0cV46kFrRBlm+t5vHCEaA==", "dev": true, "requires": { - "@babel/helper-member-expression-to-functions": "^7.14.5", + "@babel/helper-member-expression-to-functions": "^7.15.0", "@babel/helper-optimise-call-expression": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.15.0", + "@babel/types": "^7.15.0" } }, "@babel/helper-simple-access": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.5.tgz", - "integrity": "sha512-nfBN9xvmCt6nrMZjfhkl7i0oTV3yxR4/FztsbOASyTvVcoYd0TRHh7eMLdlEcCqobydC0LAF3LtC92Iwxo0wyw==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.14.8.tgz", + "integrity": "sha512-TrFN4RHh9gnWEU+s7JloIho2T76GPwRHhdzOWLqTrMnlas8T9O7ec+oEDNsRXndOmru9ymH9DFrEOxpzPoSbdg==", "dev": true, "requires": { - "@babel/types": "^7.14.5" + "@babel/types": "^7.14.8" } }, "@babel/helper-split-export-declaration": { @@ -11126,9 +11195,9 @@ } }, "@babel/helper-validator-identifier": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz", - "integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg==", + "version": "7.14.9", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz", + "integrity": "sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==", "dev": true }, "@babel/helper-validator-option": { @@ -11138,14 +11207,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.6.tgz", - "integrity": "sha512-yesp1ENQBiLI+iYHSJdoZKUtRpfTlL1grDIX9NRlAVppljLw/4tTyYupIB7uIYmC3stW/imAv8EqaKaS/ibmeA==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.8.tgz", + "integrity": "sha512-ZRDmI56pnV+p1dH6d+UN6GINGz7Krps3+270qqI9UJ4wxYThfAIcI5i7j5vXC4FJ3Wap+S9qcebxeYiqn87DZw==", "dev": true, "requires": { "@babel/template": "^7.14.5", - "@babel/traverse": "^7.14.5", - "@babel/types": "^7.14.5" + "@babel/traverse": "^7.14.8", + "@babel/types": "^7.14.8" } }, "@babel/highlight": { @@ -11212,9 +11281,9 @@ } }, "@babel/parser": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz", - "integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.0.tgz", + "integrity": "sha512-0v7oNOjr6YT9Z2RAOTv4T9aP+ubfx4Q/OhVtAet7PFDt0t9Oy6Jn+/rfC6b8HJ5zEqrQCiMxJfgtHpmIminmJQ==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -11326,9 +11395,9 @@ } }, "@babel/runtime": { - "version": "7.14.6", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz", - "integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==", + "version": "7.14.8", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz", + "integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==", "requires": { "regenerator-runtime": "^0.13.4" } @@ -11345,29 +11414,29 @@ } }, "@babel/traverse": { - "version": "7.14.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.7.tgz", - "integrity": "sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.15.0.tgz", + "integrity": "sha512-392d8BN0C9eVxVWd8H6x9WfipgVH5IaIoLp23334Sc1vbKKWINnvwRpb4us0xtPaCumlwbTtIYNA0Dv/32sVFw==", "dev": true, "requires": { "@babel/code-frame": "^7.14.5", - "@babel/generator": "^7.14.5", + "@babel/generator": "^7.15.0", "@babel/helper-function-name": "^7.14.5", "@babel/helper-hoist-variables": "^7.14.5", "@babel/helper-split-export-declaration": "^7.14.5", - "@babel/parser": "^7.14.7", - "@babel/types": "^7.14.5", + "@babel/parser": "^7.15.0", + "@babel/types": "^7.15.0", "debug": "^4.1.0", "globals": "^11.1.0" } }, "@babel/types": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz", - "integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==", + "version": "7.15.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.15.0.tgz", + "integrity": "sha512-OBvfqnllOIdX4ojTHpwZbpvz4j3EWyjkZEdmjH0/cgsd6QOdSgU8rLSk6ard/pcW7rlmjdVSX/AWOaORR1uNOQ==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.14.5", + "@babel/helper-validator-identifier": "^7.14.9", "to-fast-properties": "^2.0.0" } }, @@ -11388,9 +11457,9 @@ } }, "@fosscord/server-util": { - "version": "1.3.37", - "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.37.tgz", - "integrity": "sha512-hE2QIMHo/j/rCXmw+HEr5iV2RphGO7/oU1co1f6B8PlDHmyDoC0U/g1xXo9KwrWcB9lyCWb0kxlf2mOhCCQ4yA==", + "version": "1.3.46", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.46.tgz", + "integrity": "sha512-YX2pSkgsxrFcdEVXQWuQYHmT+P0Y+BtGRopZf5HKeHbjDl4/Bblj/GRU55qvtHsW5/6XQBZCG/GoeTu/MMQ+xw==", "requires": { "@types/jsonwebtoken": "^8.5.0", "@types/mongoose-autopopulate": "^0.10.1", @@ -11808,9 +11877,9 @@ } }, "@types/bson": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.4.tgz", - "integrity": "sha512-awqorHvQS0DqxkHQ/FxcPX9E+H7Du51Qw/2F+5TBMSaE3G0hm+8D3eXJ6MAzFw75nE8V7xF0QvzUSdxIjJb/GA==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@types/bson/-/bson-4.0.5.tgz", + "integrity": "sha512-vVLwMUqhYJSQ/WKcE60eFqcyuWse5fGH+NMAXHuKrUAPoryq3ATxk5o4bgYNtg5aOM4APVg7Hnb3ASqUYG0PKg==", "requires": { "@types/node": "*" } @@ -11896,9 +11965,9 @@ } }, "@types/json-schema": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.8.tgz", - "integrity": "sha512-YSBPTLTVm2e2OoQIDYx8HaeWJ5tTToLH67kXR7zYNGupXMEHa2++G8k+DczX2cFVgalypqtyZIcU19AFcmOpmg==" + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", + "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==" }, "@types/jsonwebtoken": { "version": "8.5.4", @@ -11915,12 +11984,11 @@ "dev": true }, "@types/mongodb": { - "version": "3.6.20", - "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", - "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-4.0.7.tgz", + "integrity": "sha512-lPUYPpzA43baXqnd36cZ9xxorprybxXDzteVKCPAdp14ppHtFJHnXYvNpmBvtMUTb5fKXVv6sVbzo1LHkWhJlw==", "requires": { - "@types/bson": "*", - "@types/node": "*" + "mongodb": "*" } }, "@types/mongoose": { @@ -11958,14 +12026,14 @@ } }, "@types/node": { - "version": "14.17.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.5.tgz", - "integrity": "sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==" + "version": "14.17.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.17.9.tgz", + "integrity": "sha512-CMjgRNsks27IDwI785YMY0KLt3co/c0cQ5foxHYv/shC2w8oOnVwz5Ubq1QG5KzrcW+AXk6gzdnxIkDnTvzu3g==" }, "@types/node-fetch": { - "version": "2.5.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.11.tgz", - "integrity": "sha512-2upCKaqVZETDRb8A2VTaRymqFBEgH8u6yr96b/u3+1uQEPDRo3mJLEiPk7vdXBHRtjwkjqzFYMJXrt0Z9QsYjQ==", + "version": "2.5.12", + "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.5.12.tgz", + "integrity": "sha512-MKgC4dlq4kKNa/mYrwpKfzQMB5X3ee5U6fSprkKpToBqBmX4nFZL9cW5jl6sWn+xpRJ7ypWh2yyqqr8UUCstSw==", "dev": true, "requires": { "@types/node": "*", @@ -12387,9 +12455,9 @@ "dev": true }, "async": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.0.tgz", - "integrity": "sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.1.tgz", + "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", "dev": true }, "asynckit": { @@ -12790,16 +12858,16 @@ } }, "browserslist": { - "version": "4.16.6", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", - "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "version": "4.16.7", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.7.tgz", + "integrity": "sha512-7I4qVwqZltJ7j37wObBe3SoTz+nS8APaNcrBOlgoirb6/HbEU2XxW/LpUDTCngM6iauwFqmRTuOMfyKnFGY5JA==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001219", + "caniuse-lite": "^1.0.30001248", "colorette": "^1.2.2", - "electron-to-chromium": "^1.3.723", + "electron-to-chromium": "^1.3.793", "escalade": "^3.1.1", - "node-releases": "^1.1.71" + "node-releases": "^1.1.73" } }, "bser": { @@ -12838,9 +12906,9 @@ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" }, "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, "buffer-xor": { "version": "1.0.3", @@ -12937,9 +13005,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001245", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001245.tgz", - "integrity": "sha512-768fM9j1PKXpOCKws6eTo3RHmvTUsG9UrpT4WoREFeZgJBTi4/X9g565azS/rVUGtqb8nt7FjLeF5u4kukERnA==", + "version": "1.0.30001249", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001249.tgz", + "integrity": "sha512-vcX4U8lwVXPdqzPWi6cAJ3FnQaqXbBqy/GZseKNQzRj37J7qZdGcBtxq/QLFNLLlfsoXLUdHw8Iwenri86Tagw==", "dev": true }, "canvas": { @@ -12977,9 +13045,9 @@ } }, "chalk": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", - "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -14050,9 +14118,9 @@ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=" }, "electron-to-chromium": { - "version": "1.3.779", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.779.tgz", - "integrity": "sha512-nreave0y/1Qhmo8XtO6C/LpawNyC6U26+q7d814/e+tIqUK073pM+4xW7WUXyqCRa5K4wdxHmNMBAi8ap9nEew==", + "version": "1.3.799", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.799.tgz", + "integrity": "sha512-V2rbYWdGvSqrg+95KjkVuSi41bGfrhrOzjl1tSi2VLnm0mRe3FsSvhiqidSiSll9WiMhrQAhpDcW/wcqK3c+Yw==", "dev": true }, "elliptic": { @@ -14447,9 +14515,9 @@ "requires": {} }, "express-validator": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.12.0.tgz", - "integrity": "sha512-lcQAdVeAO+pBbHD33nIsDsd+QPakLX08tJ82iEsXj6ezyWCfYjE9RY/g9SVq5z4G0NaIkH8039Oe4r0G92DRyA==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.12.1.tgz", + "integrity": "sha512-olpTAv0ZB5IhNuDQ2rodKAuJsewgFgLIsczJMAWD6T0Yvxsa+j/Hk61jl8e26lAq+oJr6hUqPRjdlOBKhFlWeQ==", "requires": { "lodash": "^4.17.21", "validator": "^13.5.2" @@ -14800,9 +14868,9 @@ } }, "graceful-fs": { - "version": "4.2.6", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", - "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", "dev": true }, "growly": { @@ -15324,9 +15392,9 @@ "dev": true }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, "is-typedarray": { @@ -15910,9 +15978,9 @@ } }, "jsdom": { - "version": "16.6.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.6.0.tgz", - "integrity": "sha512-Ty1vmF4NHJkolaEmdjtxTfSfkdb8Ywarwf63f+F8/mDD1uLSSWDxDuMiZxiPhwunLrn9LOSVItWj4bLYsLN3Dg==", + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", "dev": true, "requires": { "abab": "^2.0.5", @@ -15940,7 +16008,7 @@ "whatwg-encoding": "^1.0.5", "whatwg-mimetype": "^2.3.0", "whatwg-url": "^8.5.0", - "ws": "^7.4.5", + "ws": "^7.4.6", "xml-name-validator": "^3.0.0" }, "dependencies": { @@ -16406,16 +16474,16 @@ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" }, "mime-db": { - "version": "1.48.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.48.0.tgz", - "integrity": "sha512-FM3QwxV+TnZYQ2aRqhlKBMHxk10lTbMt3bBkMAp54ddrNeVSfcQYOOKuGuy3Ddrm38I04If834fOUSq1yzslJQ==" + "version": "1.49.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.49.0.tgz", + "integrity": "sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA==" }, "mime-types": { - "version": "2.1.31", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.31.tgz", - "integrity": "sha512-XGZnNzm3QvgKxa8dpzyhFTHmpP3l5YNusmne07VUOXxou9CqUqYa/HBy124RqtVh/O2pECas/MOcsDgpilPOPg==", + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.32.tgz", + "integrity": "sha512-hJGaVS4G4c9TSMYh2n6SQAGrC4RnfU+daP8G7cSCmaqNjiOoUY0VHCMS42pxnQmVF1GWwFhbHWn3RIxCqTmZ9A==", "requires": { - "mime-db": "1.48.0" + "mime-db": "1.49.0" } }, "mimic-fn": { @@ -16472,9 +16540,9 @@ } }, "missing-native-js-functions": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.7.tgz", - "integrity": "sha512-3JT72wOtgojsdmUaa/LIlEuPmT802Kajnr9RFxSZFCX37oL3epd3mZwSaabqFHxPOUW7nJnix+BAWKwX6O0Q5g==" + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/missing-native-js-functions/-/missing-native-js-functions-1.2.9.tgz", + "integrity": "sha512-Hv1oiFi9Wf5bsxra/UlmribNCDyLNYQULepfVJH6aF50Thh522kaMF3IuHja2mKX1oeWBkp6FvLaAfAjLuCOzw==" }, "mixin-deep": { "version": "1.3.2", @@ -16524,9 +16592,9 @@ } }, "mongodb": { - "version": "3.6.10", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz", - "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==", + "version": "3.6.11", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.11.tgz", + "integrity": "sha512-4Y4lTFHDHZZdgMaHmojtNAlqkvddX2QQBEN0K//GzxhGwlI9tZ9R0vhbjr1Decw+TF7qK0ZLjQT292XgHRRQgw==", "requires": { "bl": "^2.2.1", "bson": "^1.1.4", @@ -16537,12 +16605,11 @@ } }, "mongoose": { - "version": "5.13.3", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.3.tgz", - "integrity": "sha512-q+zX6kqHAvwxf5speMWhq6qF4vdj+x6/kfD5RSKdZKNm52yGmaUygN+zgrtQjBZPFEzG0B3vF6GP0PoAGadE+w==", + "version": "5.13.5", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.13.5.tgz", + "integrity": "sha512-sSUAk9GWgA8r3w3nVNrNjBaDem86aevwXO8ltDMKzCf+rjnteMMQkXHQdn1ePkt7alROEPZYCAjiRjptWRSPiQ==", "requires": { "@types/mongodb": "^3.5.27", - "@types/node": "14.x || 15.x", "bson": "^1.1.4", "kareem": "2.3.2", "mongodb": "3.6.10", @@ -16550,10 +16617,40 @@ "mpath": "0.8.3", "mquery": "3.2.5", "ms": "2.1.2", + "optional-require": "1.0.x", "regexp-clone": "1.0.0", "safe-buffer": "5.2.1", "sift": "13.5.2", "sliced": "1.0.1" + }, + "dependencies": { + "@types/mongodb": { + "version": "3.6.20", + "resolved": "https://registry.npmjs.org/@types/mongodb/-/mongodb-3.6.20.tgz", + "integrity": "sha512-WcdpPJCakFzcWWD9juKoZbRtQxKIMYF/JIAM4JrNHrMcnJL6/a2NWjXxW7fo9hxboxxkg+icff8d7+WIEvKgYQ==", + "requires": { + "@types/bson": "*", + "@types/node": "*" + } + }, + "mongodb": { + "version": "3.6.10", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.10.tgz", + "integrity": "sha512-fvIBQBF7KwCJnDZUnFFy4WqEFP8ibdXeFANnylW19+vOwdjOAvqIzPdsNCEMT6VKTHnYu4K64AWRih0mkFms6Q==", + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.0.3", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" + } + }, + "optional-require": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", + "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" + } } }, "mongoose-autopopulate": { @@ -17065,9 +17162,12 @@ } }, "optional-require": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.0.3.tgz", - "integrity": "sha512-RV2Zp2MY2aeYK5G+B/Sps8lW5NHAzE5QClbFP15j+PWmP+T9PxlJXBOOLoSAdgwFvS4t0aMR4vpedMkbHfh0nA==" + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.5.tgz", + "integrity": "sha512-PtR4HkBxH0Rpethop3qeZY+8gaXjN4+Ik9AJraOU+AQFm6v9rP34xQrQqJD9hNMB76UYxN3ziGExdtkB5C1TUg==", + "requires": { + "require-at": "^1.0.6" + } }, "optionator": { "version": "0.8.3", @@ -17658,9 +17758,9 @@ } }, "regenerator-runtime": { - "version": "0.13.7", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" }, "regex-not": { "version": "1.0.2", @@ -17711,6 +17811,11 @@ } } }, + "require-at": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", + "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -18849,9 +18954,9 @@ "dev": true }, "tar": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.0.tgz", - "integrity": "sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==", + "version": "6.1.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.6.tgz", + "integrity": "sha512-oaWyu5dQbHaYcyZCTfyPpC+VmI62/OM2RTUYavTk1MDr1cwW5Boi3baeYQKiZbY2uSQJGr+iMOzb/JFxLrft+g==", "requires": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", diff --git a/package.json b/package.json
index 15aa8b04..3b82df12 100644 --- a/package.json +++ b/package.json
@@ -33,7 +33,7 @@ }, "homepage": "https://github.com/fosscord/fosscord-api#readme", "dependencies": { - "@fosscord/server-util": "^1.3.37", + "@fosscord/server-util": "^1.3.46", "@types/jest": "^26.0.22", "@types/json-schema": "^7.0.7", "ajv": "^8.4.0", diff --git a/src/Server.ts b/src/Server.ts
index aa66b5b6..fcc5374b 100644 --- a/src/Server.ts +++ b/src/Server.ts
@@ -10,10 +10,10 @@ import i18nextBackend from "i18next-node-fs-backend"; import { ErrorHandler } from "./middlewares/ErrorHandler"; import { BodyParser } from "./middlewares/BodyParser"; import express, { Router, Request, Response } from "express"; -import fetch, { Response as FetchResponse } from "node-fetch"; import mongoose from "mongoose"; import path from "path"; import RateLimit from "./middlewares/RateLimit"; +import TestClient from "./middlewares/TestClient"; // this will return the new updated document for findOneAndUpdate mongoose.set("returnOriginal", false); // https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate @@ -29,14 +29,6 @@ declare global { } } -const assetCache = new Map< - string, - { - response: FetchResponse; - buffer: Buffer; - } ->(); - export class FosscordServer extends Server { public declare options: FosscordServerOptions; @@ -69,7 +61,7 @@ export class FosscordServer extends Server { this.app.use(CORS); this.app.use(Authentication); - this.app.use(BodyParser({ inflate: true, limit: 1024 * 1024 * 2 })); + this.app.use(BodyParser({ inflate: true, limit: 1024 * 1024 * 10 })); // 2MB const languages = fs.readdirSync(path.join(__dirname, "..", "locales")); const namespaces = fs.readdirSync(path.join(__dirname, "..", "locales", "en")); const ns = namespaces.filter((x) => x.endsWith(".json")).map((x) => x.slice(0, x.length - 5)); @@ -90,21 +82,21 @@ export class FosscordServer extends Server { this.app.use(i18nextMiddleware.handle(i18next, {})); const app = this.app; - const prefix = Router(); + const api = Router(); // @ts-ignore - this.app = prefix; - prefix.use(RateLimit({ bucket: "global", count: 10, window: 5, bot: 250 })); - prefix.use(RateLimit({ bucket: "error", count: 5, error: true, window: 5, bot: 15, onylIp: true })); - prefix.use("/guilds/:id", RateLimit({ count: 5, window: 5 })); - prefix.use("/webhooks/:id", RateLimit({ count: 5, window: 5 })); - prefix.use("/channels/:id", RateLimit({ count: 5, window: 5 })); + this.app = api; + api.use(RateLimit({ bucket: "global", count: 10, window: 5, bot: 250 })); + api.use(RateLimit({ bucket: "error", count: 5, error: true, window: 5, bot: 15, onylIp: true })); + api.use("/guilds/:id", RateLimit({ count: 5, window: 5 })); + api.use("/webhooks/:id", RateLimit({ count: 5, window: 5 })); + api.use("/channels/:id", RateLimit({ count: 5, window: 5 })); this.routes = await this.registerRoutes(path.join(__dirname, "routes", "/")); - app.use("/api/v8", prefix); - app.use("/api/v9", prefix); - app.use("/api", prefix); // allow unversioned requests + app.use("/api/v8", api); + app.use("/api/v9", api); + app.use("/api", api); // allow unversioned requests - prefix.get("*", (req: Request, res: Response) => { + api.get("*", (req: Request, res: Response) => { res.status(404).json({ message: "404: Not Found", code: 0 @@ -113,61 +105,8 @@ export class FosscordServer extends Server { this.app = app; this.app.use(ErrorHandler); - const indexHTML = fs.readFileSync(path.join(__dirname, "..", "client_test", "index.html"), { encoding: "utf8" }); - - this.app.use("/assets", express.static(path.join(__dirname, "..", "assets"))); - - this.app.get("/assets/:file", async (req: Request, res: Response) => { - delete req.headers.host; - var response: FetchResponse; - var buffer: Buffer; - const cache = assetCache.get(req.params.file); - if (!cache) { - response = await fetch(`https://discord.com/assets/${req.params.file}`, { - // @ts-ignore - headers: { - ...req.headers - } - }); - buffer = await response.buffer(); - } else { - response = cache.response; - buffer = cache.buffer; - } + TestClient(this.app); - response.headers.forEach((value, name) => { - if ( - [ - "content-length", - "content-security-policy", - "strict-transport-security", - "set-cookie", - "transfer-encoding", - "expect-ct", - "access-control-allow-origin", - "content-encoding" - ].includes(name.toLowerCase()) - ) { - return; - } - res.set(name, value); - }); - assetCache.set(req.params.file, { buffer, response }); - - return res.send(buffer); - }); - this.app.get("*", (req: Request, res: Response) => { - res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); - res.set("content-type", "text/html"); - res.send( - indexHTML - .replace( - /CDN_HOST: ".+"/, - `CDN_HOST: "${(Config.get().cdn.endpoint || "http://localhost:3003").replace(/https?:/, "")}"` - ) - .replace(/GATEWAY_ENDPOINT: ".+"/, `GATEWAY_ENDPOINT: "${Config.get().gateway.endpoint || "ws://localhost:3002"}"`) - ); - }); return super.start(); } } diff --git a/src/middlewares/Authentication.ts b/src/middlewares/Authentication.ts
index 76b335ad..01b7ef57 100644 --- a/src/middlewares/Authentication.ts +++ b/src/middlewares/Authentication.ts
@@ -6,6 +6,7 @@ export const NO_AUTHORIZATION_ROUTES = [ /^\/api(\/v\d+)?\/auth\/login/, /^\/api(\/v\d+)?\/auth\/register/, /^\/api(\/v\d+)?\/webhooks\//, + /^\/api(\/v\d+)?\/ping/, /^\/api(\/v\d+)?\/gateway/, /^\/api(\/v\d+)?\/experiments/, /^\/api(\/v\d+)?\/guilds\/\d+\/widget\.(json|png)/ diff --git a/src/middlewares/RateLimit.ts b/src/middlewares/RateLimit.ts
index 89e002df..088c3161 100644 --- a/src/middlewares/RateLimit.ts +++ b/src/middlewares/RateLimit.ts
@@ -1,5 +1,5 @@ import { db, MongooseCache, Bucket } from "@fosscord/server-util"; -import { NextFunction, Request, Response } from "express"; +import { IRouterHandler, NextFunction, Request, Response } from "express"; import { getIpAdress } from "../util/ipAddress"; import { API_PREFIX_TRAILING_SLASH } from "./Authentication"; @@ -43,10 +43,10 @@ export default function RateLimit(opts: { error?: boolean; success?: boolean; onylIp?: boolean; -}) { +}): any { Cache.init(); // will only initalize it once - return async (req: Request, res: Response, next: NextFunction) => { + return async (req: Request, res: Response, next: NextFunction): Promise<any> => { const bucket_id = opts.bucket || req.originalUrl.replace(API_PREFIX_TRAILING_SLASH, ""); var user_id = getIpAdress(req); if (!opts.onylIp && req.user_id) user_id = req.user_id; diff --git a/src/middlewares/TestClient.ts b/src/middlewares/TestClient.ts new file mode 100644
index 00000000..4e3c9de3 --- /dev/null +++ b/src/middlewares/TestClient.ts
@@ -0,0 +1,66 @@ +import bodyParser, { OptionsJson } from "body-parser"; +import express, { NextFunction, Request, Response, Application } from "express"; +import { HTTPError } from "lambert-server"; +import fs from "fs"; +import path from "path"; +import fetch, { Response as FetchResponse } from "node-fetch"; +import { Config } from "@fosscord/server-util"; + +export default function TestClient(app: Application) { + const assetCache = new Map<string, { response: FetchResponse; buffer: Buffer }>(); + const indexHTML = fs.readFileSync(path.join(__dirname, "..", "..", "client_test", "index.html"), { encoding: "utf8" }); + + app.use("/assets", express.static(path.join(__dirname, "..", "assets"))); + + app.get("/assets/:file", async (req: Request, res: Response) => { + delete req.headers.host; + var response: FetchResponse; + var buffer: Buffer; + const cache = assetCache.get(req.params.file); + if (!cache) { + response = await fetch(`https://discord.com/assets/${req.params.file}`, { + // @ts-ignore + headers: { + ...req.headers + } + }); + buffer = await response.buffer(); + } else { + response = cache.response; + buffer = cache.buffer; + } + + response.headers.forEach((value, name) => { + if ( + [ + "content-length", + "content-security-policy", + "strict-transport-security", + "set-cookie", + "transfer-encoding", + "expect-ct", + "access-control-allow-origin", + "content-encoding" + ].includes(name.toLowerCase()) + ) { + return; + } + res.set(name, value); + }); + assetCache.set(req.params.file, { buffer, response }); + + return res.send(buffer); + }); + app.get("*", (req: Request, res: Response) => { + res.set("Cache-Control", "public, max-age=" + 60 * 60 * 24); + res.set("content-type", "text/html"); + var html = indexHTML; + const CDN_ENDPOINT = (Config.get()?.cdn.endpoint || process.env.CDN || "").replace(/(https?)?(:\/\/?)/g, ""); + const GATEWAY_ENDPOINT = Config.get()?.gateway.endpoint || process.env.GATEWAY || ""; + + if (CDN_ENDPOINT) html = html.replace(/CDN_HOST: .+/, `CDN_HOST: "${CDN_ENDPOINT}",`); + if (GATEWAY_ENDPOINT) html = html.replace(/GATEWAY_ENDPOINT: .+/, `GATEWAY_ENDPOINT: "${GATEWAY_ENDPOINT}",`); + + res.send(html); + }); +} diff --git a/src/routes/auth/login.ts b/src/routes/auth/login.ts
index af00a46d..c92ddccc 100644 --- a/src/routes/auth/login.ts +++ b/src/routes/auth/login.ts
@@ -9,7 +9,8 @@ import RateLimit from "../../middlewares/RateLimit"; const router: Router = Router(); export default router; -// TODO: check if user is deleted/restricted +// TODO: check if user is deleted --> prohibit login + router.post( "/", RateLimit({ count: 5, window: 60, onylIp: true }), @@ -22,7 +23,7 @@ router.post( $gift_code_sku_id: String }), async (req: Request, res: Response) => { - const { login, password, captcha_key } = req.body; + const { login, password, captcha_key, undelete } = req.body; const email = adjustEmail(login); const query: any[] = [{ phone: login }]; if (email) query.push({ email }); @@ -62,6 +63,13 @@ router.post( throw FieldErrors({ login: { message: req.t("auth:login.INVALID_LOGIN"), code: "INVALID_LOGIN" } }); }); + if (user.disabled && undelete) { + // undelete refers to un'disable' here + await UserModel.updateOne({ id: req.user_id }, { disabled: false }).exec(); + } else if (user.disabled) { + return res.status(400).json({ message: req.t("auth:login.ACCOUNT_DISABLED"), code: 20013 }); + } + // the salt is saved in the password refer to bcrypt docs const same_password = await bcrypt.compare(password, user.user_data.hash || ""); if (!same_password) { @@ -100,14 +108,14 @@ export async function generateToken(id: string) { /** * POST /auth/login * @argument { login: "email@gmail.com", password: "cleartextpassword", undelete: false, captcha_key: null, login_source: null, gift_code_sku_id: null, } - + * MFA required: * @returns {"token": null, "mfa": true, "sms": true, "ticket": "SOME TICKET JWT TOKEN"} - + * Captcha required: * @returns {"captcha_key": ["captcha-required"], "captcha_sitekey": null, "captcha_service": "recaptcha"} - + * Sucess: * @returns {"token": "USERTOKEN", "user_settings": {"locale": "en", "theme": "dark"}} - + */ diff --git a/src/routes/auth/register.ts b/src/routes/auth/register.ts
index 279103bc..eb5cd97d 100644 --- a/src/routes/auth/register.ts +++ b/src/routes/auth/register.ts
@@ -197,12 +197,13 @@ router.post( discriminator, avatar: null, accent_color: null, + banner: null, bot: false, system: false, desktop: false, mobile: false, - premium: false, - premium_type: 0, + premium: true, + premium_type: 2, phone: null, bio: "", mfa_enabled: false, diff --git a/src/routes/channels/#channel_id/messages/index.ts b/src/routes/channels/#channel_id/messages/index.ts
index 4e42d546..59494c7e 100644 --- a/src/routes/channels/#channel_id/messages/index.ts +++ b/src/routes/channels/#channel_id/messages/index.ts
@@ -30,7 +30,13 @@ export function isTextChannel(type: ChannelType): boolean { // get messages router.get("/", async (req: Request, res: Response) => { const channel_id = req.params.channel_id; - const channel = await ChannelModel.findOne({ id: channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec(); + const channel = await ChannelModel.findOne( + { id: channel_id }, + { guild_id: true, type: true, permission_overwrites: true, recipient_ids: true, owner_id: true } + ) + .lean() // lean is needed, because we don't want to populate .recipients that also auto deletes .recipient_ids + .exec(); + if (!channel) throw new HTTPError("Channel not found", 404); isTextChannel(channel.type); @@ -46,6 +52,7 @@ router.get("/", async (req: Request, res: Response) => { if (!limit) limit = 50; var halfLimit = Math.floor(limit / 2); + // @ts-ignore const permissions = await getPermission(req.user_id, channel.guild_id, channel_id, { channel }); permissions.hasThrow("VIEW_CHANNEL"); if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json([]); @@ -126,7 +133,16 @@ router.post("/", messageUpload.single("file"), async (req: Request, res: Respons const embeds = []; if (body.embed) embeds.push(body.embed); - const data = await sendMessage({ ...body, type: 0, pinned: false, author_id: req.user_id, embeds, channel_id, attachments, edited_timestamp: null }); + const data = await sendMessage({ + ...body, + type: 0, + pinned: false, + author_id: req.user_id, + embeds, + channel_id, + attachments, + edited_timestamp: null + }); return res.send(data); }); diff --git a/src/routes/guilds/#guild_id/bans.ts b/src/routes/guilds/#guild_id/bans.ts
index 4d9bad37..d9752f61 100644 --- a/src/routes/guilds/#guild_id/bans.ts +++ b/src/routes/guilds/#guild_id/bans.ts
@@ -16,7 +16,7 @@ router.get("/", async (req: Request, res: Response) => { const guild = await GuildModel.exists({ id: guild_id }); if (!guild) throw new HTTPError("Guild not found", 404); - var bans = await BanModel.find({ guild_id: guild_id }, { user: true, reason: true }).exec(); + var bans = await BanModel.find({ guild_id: guild_id }, { user_id: true, reason: true }).exec(); return res.json(toObject(bans)); }); diff --git a/src/routes/guilds/#guild_id/channels.ts b/src/routes/guilds/#guild_id/channels.ts
index 90b4473d..15cc7394 100644 --- a/src/routes/guilds/#guild_id/channels.ts +++ b/src/routes/guilds/#guild_id/channels.ts
@@ -23,15 +23,18 @@ router.get("/", async (req: Request, res: Response) => { res.json(toObject(channels)); }); +// TODO: check if channel type is permitted +// TODO: check if parent_id exists router.post("/", check(ChannelModifySchema), async (req: Request, res: Response) => { const { guild_id } = req.params; const body = req.body as ChannelModifySchema; const channel = await createChannel({ ...body, guild_id }, req.user_id); - res.json(channel); + res.json(toObject(channel)); }); +// TODO: check if parent_id exists router.patch("/", check(ChannelModifySchema), async (req: Request, res: Response) => { const { guild_id } = req.params; const body = req.body as ChannelModifySchema; @@ -41,7 +44,7 @@ router.patch("/", check(ChannelModifySchema), async (req: Request, res: Response await emitEvent({ event: "CHANNEL_UPDATE", data: channel } as ChannelUpdateEvent); - res.json(channel); + res.json(toObject(channel)); }); export default router; diff --git a/src/routes/guilds/#guild_id/delete.ts b/src/routes/guilds/#guild_id/delete.ts
index c363db25..6cca289e 100644 --- a/src/routes/guilds/#guild_id/delete.ts +++ b/src/routes/guilds/#guild_id/delete.ts
@@ -4,6 +4,7 @@ import { GuildDeleteEvent, GuildModel, InviteModel, + MemberModel, MessageModel, RoleModel, UserModel @@ -30,13 +31,16 @@ router.post("/", async (req: Request, res: Response) => { guild_id: guild_id } as GuildDeleteEvent); - await GuildModel.deleteOne({ id: guild_id }).exec(); - await UserModel.updateMany({ guilds: guild_id }, { $pull: { guilds: guild_id } }).exec(); - await RoleModel.deleteMany({ guild_id }).exec(); - await ChannelModel.deleteMany({ guild_id }).exec(); - await EmojiModel.deleteMany({ guild_id }).exec(); - await InviteModel.deleteMany({ guild_id }).exec(); - await MessageModel.deleteMany({ guild_id }).exec(); + await Promise.all([ + GuildModel.deleteOne({ id: guild_id }).exec(), + UserModel.updateMany({ guilds: guild_id }, { $pull: { guilds: guild_id } }).exec(), + RoleModel.deleteMany({ guild_id }).exec(), + ChannelModel.deleteMany({ guild_id }).exec(), + EmojiModel.deleteMany({ guild_id }).exec(), + InviteModel.deleteMany({ guild_id }).exec(), + MessageModel.deleteMany({ guild_id }).exec(), + MemberModel.deleteMany({ guild_id }).exec() + ]); return res.sendStatus(204); }); diff --git a/src/routes/guilds/#guild_id/index.ts b/src/routes/guilds/#guild_id/index.ts
index 3af49106..dc4ddb39 100644 --- a/src/routes/guilds/#guild_id/index.ts +++ b/src/routes/guilds/#guild_id/index.ts
@@ -17,6 +17,7 @@ import { HTTPError } from "lambert-server"; import { GuildUpdateSchema } from "../../../schema/Guild"; import { emitEvent } from "../../../util/Event"; import { check } from "../../../util/instanceOf"; +import { handleFile } from "../../../util/cdn"; import "missing-native-js-functions"; const router = Router(); @@ -42,6 +43,10 @@ router.patch("/", check(GuildUpdateSchema), async (req: Request, res: Response) const perms = await getPermission(req.user_id, guild_id); perms.hasThrow("MANAGE_GUILD"); + if (body.icon) body.icon = await handleFile(`/icons/${guild_id}`, body.icon); + if (body.banner) body.banner = await handleFile(`/banners/${guild_id}`, body.banner); + if (body.splash) body.splash = await handleFile(`/splashes/${guild_id}`, body.splash); + const guild = await GuildModel.findOneAndUpdate({ id: guild_id }, body) .populate({ path: "joined_at", match: { id: req.user_id } }) .exec(); @@ -50,7 +55,7 @@ router.patch("/", check(GuildUpdateSchema), async (req: Request, res: Response) emitEvent({ event: "GUILD_UPDATE", data: data, guild_id } as GuildUpdateEvent); - return res.send(data); + return res.json(data); }); export default router; diff --git a/src/routes/guilds/#guild_id/vanity-url.ts b/src/routes/guilds/#guild_id/vanity-url.ts
index 30c98d19..323b2647 100644 --- a/src/routes/guilds/#guild_id/vanity-url.ts +++ b/src/routes/guilds/#guild_id/vanity-url.ts
@@ -1,16 +1,45 @@ -import { GuildModel } from "@fosscord/server-util"; +import { getPermission, GuildModel, InviteModel, trimSpecial } from "@fosscord/server-util"; import { Router, Request, Response } from "express"; import { HTTPError } from "lambert-server"; +import { check, Length } from "../../../util/instanceOf"; +import { isMember } from "../../../util/Member"; const router = Router(); +const InviteRegex = /\W/g; + router.get("/", async (req: Request, res: Response) => { const { guild_id } = req.params; + await isMember(req.user_id, guild_id); const guild = await GuildModel.findOne({ id: guild_id }).exec(); if (!guild.vanity_url) throw new HTTPError("This guild has no vanity url", 204); - return res.json({ vanity_url: guild.vanity_url }); + return res.json({ code: guild.vanity_url.code }); +}); + +// TODO: check if guild is elgible for vanity url +router.patch("/", check({ code: new Length(String, 0, 20) }), async (req: Request, res: Response) => { + const { guild_id } = req.params; + var code = req.body.code.replace(InviteRegex); + if (!code) code = null; + + const permission = await getPermission(req.user_id, guild_id); + permission.hasThrow("MANAGE_GUILD"); + + const alreadyExists = await Promise.all([ + GuildModel.findOne({ "vanity_url.code": code }) + .exec() + .catch(() => null), + InviteModel.findOne({ code: code }) + .exec() + .catch(() => null) + ]); + if (alreadyExists.some((x) => x)) throw new HTTPError("Vanity url already exists", 400); + + await GuildModel.updateOne({ id: guild_id }, { "vanity_url.code": code }).exec(); + + return res.json({ code: code }); }); export default router; diff --git a/src/routes/ping.ts b/src/routes/ping.ts new file mode 100644
index 00000000..38daf81e --- /dev/null +++ b/src/routes/ping.ts
@@ -0,0 +1,9 @@ +import { Router, Response, Request } from "express"; + +const router = Router(); + +router.get("/", (req: Request, res: Response) => { + res.send("pong"); +}); + +export default router; diff --git a/src/routes/users/#id/profile.ts b/src/routes/users/#id/profile.ts
index b86b0b90..4b4b9439 100644 --- a/src/routes/users/#id/profile.ts +++ b/src/routes/users/#id/profile.ts
@@ -17,6 +17,7 @@ router.get("/", async (req: Request, res: Response) => { public_flags: user.public_flags, avatar: user.avatar, accent_color: user.accent_color, + banner: user.banner, bio: req.user_bot ? null : user.bio, bot: user.bot, } diff --git a/src/routes/users/@me/disable.ts b/src/routes/users/@me/disable.ts
index b16ef783..0e5b734e 100644 --- a/src/routes/users/@me/disable.ts +++ b/src/routes/users/@me/disable.ts
@@ -1,10 +1,20 @@ +import { UserModel } from "@fosscord/server-util"; import { Router, Response, Request } from "express"; +import bcrypt from "bcrypt"; const router = Router(); -router.post("/", (req: Request, res: Response) => { - // TODO: - res.sendStatus(204); +router.post("/", async (req: Request, res: Response) => { + const user = await UserModel.findOne({ id: req.user_id }).exec(); //User object + + let correctpass = await bcrypt.compare(req.body.password, user!.user_data.hash); //Not sure if user typed right password :/ + if (correctpass) { + await UserModel.updateOne({ id: req.user_id }, { disabled: true }).exec(); + + res.sendStatus(204); + } else { + res.status(400).json({ message: "Password does not match", code: 50018 }); + } }); export default router; diff --git a/src/routes/users/@me/index.ts b/src/routes/users/@me/index.ts
index 68196afe..f6b29958 100644 --- a/src/routes/users/@me/index.ts +++ b/src/routes/users/@me/index.ts
@@ -1,10 +1,9 @@ import { Router, Request, Response } from "express"; import { UserModel, toObject, PublicUserProjection } from "@fosscord/server-util"; -import { HTTPError } from "lambert-server"; import { getPublicUser } from "../../../util/User"; import { UserModifySchema } from "../../../schema/User"; import { check } from "../../../util/instanceOf"; -import { uploadFile } from "../../../util/cdn"; +import { handleFile } from "../../../util/cdn"; const router: Router = Router(); @@ -15,18 +14,8 @@ router.get("/", async (req: Request, res: Response) => { router.patch("/", check(UserModifySchema), async (req: Request, res: Response) => { const body = req.body as UserModifySchema; - if (body.avatar) { - try { - const mimetype = body.avatar.split(":")[1].split(";")[0]; - const buffer = Buffer.from(body.avatar.split(",")[1], "base64"); - - // @ts-ignore - const { id } = await uploadFile(`/avatars/${req.user_id}`, { buffer, mimetype, originalname: "avatar" }); - body.avatar = id; - } catch (error) { - throw new HTTPError("Invalid avatar"); - } - } + if(body.avatar) body.avatar = await handleFile(`/avatars/${req.user_id}`, body.avatar as string); + if (body.banner) body.banner = await handleFile(`/banners/${req.user_id}`, body.banner as string); const user = await UserModel.findOneAndUpdate({ id: req.user_id }, body, { projection: PublicUserProjection }).exec(); // TODO: dispatch user update event diff --git a/src/routes/users/@me/profile.ts b/src/routes/users/@me/profile.ts
index 0d295d05..b67d1964 100644 --- a/src/routes/users/@me/profile.ts +++ b/src/routes/users/@me/profile.ts
@@ -17,6 +17,7 @@ router.get("/", async (req: Request, res: Response) => { public_flags: user.public_flags, avatar: user.avatar, accent_color: user.accent_color, + banner: user.banner, bio: user.bio, bot: user.bot, } diff --git a/src/routes/users/@me/relationships.ts b/src/routes/users/@me/relationships.ts
index b874ec9a..a8f03143 100644 --- a/src/routes/users/@me/relationships.ts +++ b/src/routes/users/@me/relationships.ts
@@ -4,43 +4,50 @@ import { PublicUserProjection, toObject, RelationshipType, - RelationshipRemoveEvent + RelationshipRemoveEvent, + UserDocument } from "@fosscord/server-util"; import { Router, Response, Request } from "express"; -import { check, HTTPError } from "lambert-server"; +import { HTTPError } from "lambert-server"; import { emitEvent } from "../../../util/Event"; +import { check, Length } from "../../../util/instanceOf"; const router = Router(); const userProjection = { "user_data.relationships": true, ...PublicUserProjection }; -router.put("/:id", check({ $type: Number }), async (req: Request, res: Response) => { - const { id } = req.params; +router.get("/", async (req: Request, res: Response) => { + const user = await UserModel.findOne({ id: req.user_id }, { user_data: { relationships: true } }) + .populate({ path: "user_data.relationships.id", model: UserModel }) + .exec(); + + return res.json(toObject(user.user_data.relationships)); +}); + +async function addRelationship(req: Request, res: Response, friend: UserDocument, type: RelationshipType) { + const id = friend.id; if (id === req.user_id) throw new HTTPError("You can't add yourself as a friend"); - const body = req.body as { type?: number }; const user = await UserModel.findOne({ id: req.user_id }, userProjection).exec(); - if (!user) throw new HTTPError("Invalid token", 400); + const newUserRelationships = [...user.user_data.relationships]; + const newFriendRelationships = [...friend.user_data.relationships]; - const friend = await UserModel.findOne({ id }, userProjection).exec(); - if (!friend) throw new HTTPError("User not found", 404); + var relationship = newUserRelationships.find((x) => x.id === id); + const friendRequest = newFriendRelationships.find((x) => x.id === req.user_id); - var relationship = user.user_data.relationships.find((x) => x.id === id); - const friendRequest = friend.user_data.relationships.find((x) => x.id === req.user_id); - - if (body.type === RelationshipType.blocked) { + if (type === RelationshipType.blocked) { if (relationship) { if (relationship.type === RelationshipType.blocked) throw new HTTPError("You already blocked the user"); relationship.type = RelationshipType.blocked; } else { relationship = { id, type: RelationshipType.blocked }; - user.user_data.relationships.push(relationship); + newUserRelationships.push(relationship); } if (friendRequest && friendRequest.type !== RelationshipType.blocked) { - friend.user_data.relationships.remove(friendRequest); + newFriendRelationships.remove(friendRequest); await Promise.all([ - friend.save(), + UserModel.updateOne({ id: friend.id }, { "user_data.relationships": newFriendRelationships }).exec(), emitEvent({ event: "RELATIONSHIP_REMOVE", data: friendRequest, @@ -50,7 +57,7 @@ router.put("/:id", check({ $type: Number }), async (req: Request, res: Response) } await Promise.all([ - user.save(), + UserModel.updateOne({ id: req.user_id }, { "user_data.relationships": newUserRelationships }).exec(), emitEvent({ event: "RELATIONSHIP_ADD", data: { @@ -74,17 +81,17 @@ router.put("/:id", check({ $type: Number }), async (req: Request, res: Response) incoming_relationship = friendRequest; incoming_relationship.type = RelationshipType.friends; outgoing_relationship.type = RelationshipType.friends; - } else friend.user_data.relationships.push(incoming_relationship); + } else newFriendRelationships.push(incoming_relationship); if (relationship) { if (relationship.type === RelationshipType.outgoing) throw new HTTPError("You already sent a friend request"); if (relationship.type === RelationshipType.blocked) throw new HTTPError("Unblock the user before sending a friend request"); if (relationship.type === RelationshipType.friends) throw new HTTPError("You are already friends with the user"); - } else user.user_data.relationships.push(outgoing_relationship); + } else newUserRelationships.push(outgoing_relationship); await Promise.all([ - user.save(), - friend.save(), + UserModel.updateOne({ id: req.user_id }, { "user_data.relationships": newUserRelationships }).exec(), + UserModel.updateOne({ id: friend.id }, { "user_data.relationships": newFriendRelationships }).exec(), emitEvent({ event: "RELATIONSHIP_ADD", data: { @@ -105,6 +112,19 @@ router.put("/:id", check({ $type: Number }), async (req: Request, res: Response) ]); return res.sendStatus(204); +} + +router.put("/:id", check({ $type: new Length(Number, 1, 4) }), async (req: Request, res: Response) => { + return await addRelationship(req, res, await UserModel.findOne({ id: req.params.id }), req.body.type); +}); + +router.post("/", check({ discriminator: String, username: String }), async (req: Request, res: Response) => { + return await addRelationship( + req, + res, + await UserModel.findOne(req.body as { discriminator: string; username: string }).exec(), + req.body.type + ); }); router.delete("/:id", async (req: Request, res: Response) => { diff --git a/src/schema/Channel.ts b/src/schema/Channel.ts
index 2cb7f7f4..48c3a1d2 100644 --- a/src/schema/Channel.ts +++ b/src/schema/Channel.ts
@@ -3,7 +3,7 @@ import { Length } from "../util/instanceOf"; export const ChannelModifySchema = { name: new Length(String, 2, 100), - type: Number, + type: new Length(Number, 0, 13), $topic: new Length(String, 0, 1024), $bitrate: Number, $user_limit: Number, diff --git a/src/schema/Guild.ts b/src/schema/Guild.ts
index 4677efd5..0443e64c 100644 --- a/src/schema/Guild.ts +++ b/src/schema/Guild.ts
@@ -8,6 +8,7 @@ export const GuildCreateSchema = { $channels: [Object], $guild_template_code: String, $system_channel_id: String, + $rules_channel_id: String }; export interface GuildCreateSchema { @@ -17,10 +18,13 @@ export interface GuildCreateSchema { channels?: GuildChannel[]; guild_template_code?: string; system_channel_id?: string; + rules_channel_id?: string; } export const GuildUpdateSchema = { ...GuildCreateSchema, + name: undefined, + $name: new Length(String, 2, 100), $banner: String, $splash: String, $description: String, @@ -34,6 +38,7 @@ export const GuildUpdateSchema = { $public_updates_channel_id: String, $afk_timeout: Number, $afk_channel_id: String, + $preferred_locale: String }; // @ts-ignore delete GuildUpdateSchema.$channels; @@ -50,6 +55,7 @@ export interface GuildUpdateSchema extends Omit<GuildCreateSchema, "channels"> { public_updates_channel_id?: string; afk_timeout?: number; afk_channel_id?: string; + preferred_locale?: string; } export const GuildGetSchema = { @@ -96,31 +102,30 @@ export const GuildGetSchema = { public_updates_channel_id: true, max_video_channel_users: true, approximate_member_count: true, - approximate_presence_count: true, + approximate_presence_count: true // welcome_screen: true, }; export const GuildTemplateCreateSchema = { name: String, - $avatar: String, - + $avatar: String }; export interface GuildTemplateCreateSchema { - name: string, - avatar?: string, + name: string; + avatar?: string; } export const GuildAddChannelToWelcomeScreenSchema = { channel_id: String, description: String, $emoji_id: String, - emoji_name: String, -} + emoji_name: String +}; export interface GuildAddChannelToWelcomeScreenSchema { channel_id: string; description: string; emoji_id?: string; emoji_name: string; -} \ No newline at end of file +} diff --git a/src/schema/User.ts b/src/schema/User.ts
index ae213ee3..77ee08b4 100644 --- a/src/schema/User.ts +++ b/src/schema/User.ts
@@ -4,7 +4,8 @@ export const UserModifySchema = { $username: new Length(String, 2, 32), $avatar: String, $bio: new Length(String, 0, 190), - $accent_color: Number + $accent_color: Number, + $banner: String }; export interface UserModifySchema { @@ -12,4 +13,5 @@ export interface UserModifySchema { avatar?: string | null; bio?: string; accent_color?: number | null; + banner?: string | null; } diff --git a/src/util/Message.ts b/src/util/Message.ts
index 3e177517..e811f522 100644 --- a/src/util/Message.ts +++ b/src/util/Message.ts
@@ -25,10 +25,16 @@ const DEFAULT_FETCH_OPTIONS: any = { }; export async function handleMessage(opts: Partial<Message>) { - const channel = await ChannelModel.findOne({ id: opts.channel_id }, { guild_id: true, type: true, permission_overwrites: true }).exec(); + const channel = await ChannelModel.findOne( + { id: opts.channel_id }, + { guild_id: true, type: true, permission_overwrites: true, recipient_ids: true, owner_id: true } + ) + .lean() // lean is needed, because we don't want to populate .recipients that also auto deletes .recipient_ids + .exec(); if (!channel || !opts.channel_id) throw new HTTPError("Channel not found", 404); // TODO: are tts messages allowed in dm channels? should permission be checked? + // @ts-ignore const permissions = await getPermission(opts.author_id, channel.guild_id, opts.channel_id, { channel }); permissions.hasThrow("SEND_MESSAGES"); if (opts.tts) permissions.hasThrow("SEND_TTS_MESSAGES"); diff --git a/src/util/cdn.ts b/src/util/cdn.ts
index a66e2215..aed8ca0a 100644 --- a/src/util/cdn.ts +++ b/src/util/cdn.ts
@@ -1,5 +1,6 @@ import { Config } from "@fosscord/server-util"; import FormData from "form-data"; +import { HTTPError } from "lambert-server"; import fetch from "node-fetch"; export async function uploadFile(path: string, file: Express.Multer.File) { @@ -22,3 +23,18 @@ export async function uploadFile(path: string, file: Express.Multer.File) { if (response.status !== 200) throw result; return result; } + +export async function handleFile(path: string, body?: string): Promise<string | undefined> { + if (!body || !body.startsWith("data:")) return body; + try { + const mimetype = body.split(":")[1].split(";")[0]; + const buffer = Buffer.from(body.split(",")[1], "base64"); + + // @ts-ignore + const { id } = await uploadFile(path, { buffer, mimetype, originalname: "banner" }); + return id; + } catch (error) { + console.error(error); + throw new HTTPError("Invalid " + path); + } +} diff --git a/src/util/instanceOf.ts b/src/util/instanceOf.ts
index 93a92805..4d9034e5 100644 --- a/src/util/instanceOf.ts +++ b/src/util/instanceOf.ts
@@ -84,6 +84,8 @@ export function instanceOf( switch (type) { case String: + value = `${value}`; + ref.obj[ref.key] = value; if (typeof value === "string") return true; throw new FieldError("BASE_TYPE_STRING", req.t("common:field.BASE_TYPE_STRING")); case Number: