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:
|