summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--package-lock.json242
-rw-r--r--package.json4
-rw-r--r--src/Server.ts2
-rw-r--r--src/middlewares/RateLimit.ts4
-rw-r--r--src/routes/auth/login.ts2
-rw-r--r--src/routes/auth/register.ts2
-rw-r--r--src/routes/channels/#channel_id/index.ts3
-rw-r--r--src/routes/channels/#channel_id/messages/#message_id/index.ts2
-rw-r--r--src/routes/channels/#channel_id/messages/#message_id/reactions.ts4
-rw-r--r--src/routes/channels/#channel_id/permissions.ts2
-rw-r--r--src/routes/channels/#channel_id/pins.ts4
-rw-r--r--src/routes/channels/#channel_id/typing.ts1
-rw-r--r--src/routes/guilds/#guild_id/channels.ts41
-rw-r--r--src/routes/users/@me/index.ts26
-rw-r--r--src/schema/User.ts8
-rw-r--r--src/util/Event.ts26
16 files changed, 326 insertions, 47 deletions
diff --git a/package-lock.json b/package-lock.json

index 59d3f585..d183ca94 100644 --- a/package-lock.json +++ b/package-lock.json
@@ -9,11 +9,12 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@fosscord/server-util": "^1.3.46", + "@fosscord/server-util": "^1.3.48", "@types/jest": "^26.0.22", "@types/json-schema": "^7.0.7", "ajv": "^8.4.0", "ajv-formats": "^2.1.0", + "amqplib": "^0.8.0", "assert": "^1.5.0", "atomically": "^1.7.0", "bcrypt": "^5.0.1", @@ -41,6 +42,7 @@ "require_optional": "^1.0.1" }, "devDependencies": { + "@types/amqplib": "^0.8.1", "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.9", "@types/i18next-node-fs-backend": "^2.1.0", @@ -678,15 +680,16 @@ } }, "node_modules/@fosscord/server-util": { - "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==", + "version": "1.3.48", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.48.tgz", + "integrity": "sha512-2UK/uplgbBksFCr5mFVqD1Z5DdcSSHj+SlKb3dHAUl2MfiU5ro24gf870ZcD/gZeesdbR3yEePRiYdnX4CzI+Q==", "dependencies": { "@types/jsonwebtoken": "^8.5.0", "@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "ajv": "^8.5.0", + "amqplib": "^0.8.0", "dot-prop": "^6.0.1", "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", @@ -1107,6 +1110,16 @@ "node": ">= 6" } }, + "node_modules/@types/amqplib": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.8.1.tgz", + "integrity": "sha512-8dCjF+dHZ8Y6JOoHD1BMnxP0quAncvZq4wA/lS072NjX9vIzVRSMcmfKy2Os8ZQ8VWWp74MD09GMbVbKS6/Fxw==", + "dev": true, + "dependencies": { + "@types/bluebird": "*", + "@types/node": "*" + } + }, "node_modules/@types/babel__core": { "version": "7.1.15", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", @@ -1157,6 +1170,12 @@ "@types/node": "*" } }, + "node_modules/@types/bluebird": { + "version": "3.5.36", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.36.tgz", + "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==", + "dev": true + }, "node_modules/@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -1592,6 +1611,48 @@ } } }, + "node_modules/amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "dependencies": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/amqplib/node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "node_modules/amqplib/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "node_modules/amqplib/node_modules/readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "node_modules/amqplib/node_modules/string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -2041,6 +2102,37 @@ "node": ">=8" } }, + "node_modules/bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "dependencies": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/bitsyntax/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/bitsyntax/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "node_modules/bitsyntax/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, "node_modules/bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -2376,6 +2468,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "node_modules/buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -8217,6 +8314,11 @@ "node": ">=0.4.x" } }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "node_modules/queue": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", @@ -8484,6 +8586,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "node_modules/resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -10546,6 +10653,15 @@ "querystring": "0.2.0" } }, + "node_modules/url-parse": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "dependencies": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "node_modules/url/node_modules/punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", @@ -11457,15 +11573,16 @@ } }, "@fosscord/server-util": { - "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==", + "version": "1.3.48", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.48.tgz", + "integrity": "sha512-2UK/uplgbBksFCr5mFVqD1Z5DdcSSHj+SlKb3dHAUl2MfiU5ro24gf870ZcD/gZeesdbR3yEePRiYdnX4CzI+Q==", "requires": { "@types/jsonwebtoken": "^8.5.0", "@types/mongoose-autopopulate": "^0.10.1", "@types/mongoose-lean-virtuals": "^0.5.1", "@types/node": "^14.14.25", "ajv": "^8.5.0", + "amqplib": "^0.8.0", "dot-prop": "^6.0.1", "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", @@ -11816,6 +11933,16 @@ "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", "dev": true }, + "@types/amqplib": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@types/amqplib/-/amqplib-0.8.1.tgz", + "integrity": "sha512-8dCjF+dHZ8Y6JOoHD1BMnxP0quAncvZq4wA/lS072NjX9vIzVRSMcmfKy2Os8ZQ8VWWp74MD09GMbVbKS6/Fxw==", + "dev": true, + "requires": { + "@types/bluebird": "*", + "@types/node": "*" + } + }, "@types/babel__core": { "version": "7.1.15", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.15.tgz", @@ -11866,6 +11993,12 @@ "@types/node": "*" } }, + "@types/bluebird": { + "version": "3.5.36", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.36.tgz", + "integrity": "sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==", + "dev": true + }, "@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -12259,6 +12392,47 @@ "ajv": "^8.0.0" } }, + "amqplib": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.8.0.tgz", + "integrity": "sha512-icU+a4kkq4Y1PS4NNi+YPDMwdlbFcZ1EZTQT2nigW3fvOb6AOgUQ9+Mk4ue0Zu5cBg/XpDzB40oH10ysrk2dmA==", + "requires": { + "bitsyntax": "~0.1.0", + "bluebird": "^3.7.2", + "buffer-more-ints": "~1.0.0", + "readable-stream": "1.x >=1.1.9", + "safe-buffer": "~5.2.1", + "url-parse": "~1.5.1" + }, + "dependencies": { + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==" + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + } + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -12605,6 +12779,36 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bitsyntax": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.1.0.tgz", + "integrity": "sha512-ikAdCnrloKmFOugAfxWws89/fPc+nw0OOG1IzIE72uSOg/A3cYptKCjSUhDTuj7fhsJtzkzlv7l3b8PzRHLN0Q==", + "requires": { + "buffer-more-ints": "~1.0.0", + "debug": "~2.6.9", + "safe-buffer": "~5.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, "bl": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", @@ -12910,6 +13114,11 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "buffer-more-ints": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-1.0.0.tgz", + "integrity": "sha512-EMetuGFz5SLsT0QTnXzINh4Ksr+oo4i+UGTXEshiGCQWnsgSs7ZhJ8fzlwQ+OzEMs0MpDAMr1hxnblp5a4vcHg==" + }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -17616,6 +17825,11 @@ "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", "dev": true }, + "querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==" + }, "queue": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", @@ -17833,6 +18047,11 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" + }, "resolve": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", @@ -19486,6 +19705,15 @@ } } }, + "url-parse": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.3.tgz", + "integrity": "sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ==", + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/package.json b/package.json
index 3b82df12..d225dba6 100644 --- a/package.json +++ b/package.json
@@ -33,11 +33,12 @@ }, "homepage": "https://github.com/fosscord/fosscord-api#readme", "dependencies": { - "@fosscord/server-util": "^1.3.46", + "@fosscord/server-util": "^1.3.48", "@types/jest": "^26.0.22", "@types/json-schema": "^7.0.7", "ajv": "^8.4.0", "ajv-formats": "^2.1.0", + "amqplib": "^0.8.0", "assert": "^1.5.0", "atomically": "^1.7.0", "bcrypt": "^5.0.1", @@ -65,6 +66,7 @@ "require_optional": "^1.0.1" }, "devDependencies": { + "@types/amqplib": "^0.8.1", "@types/bcrypt": "^5.0.0", "@types/express": "^4.17.9", "@types/i18next-node-fs-backend": "^2.1.0", diff --git a/src/Server.ts b/src/Server.ts
index fcc5374b..69222636 100644 --- a/src/Server.ts +++ b/src/Server.ts
@@ -86,7 +86,7 @@ export class FosscordServer extends Server { // @ts-ignore 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(RateLimit({ bucket: "error", count: 5, error: true, window: 5, bot: 15, onlyIp: 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 })); diff --git a/src/middlewares/RateLimit.ts b/src/middlewares/RateLimit.ts
index 088c3161..0858744a 100644 --- a/src/middlewares/RateLimit.ts +++ b/src/middlewares/RateLimit.ts
@@ -42,14 +42,14 @@ export default function RateLimit(opts: { MODIFY?: number; error?: boolean; success?: boolean; - onylIp?: boolean; + onlyIp?: boolean; }): any { Cache.init(); // will only initalize it once 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; + if (!opts.onlyIp && req.user_id) user_id = req.user_id; var max_hits = opts.count; if (opts.bot && req.user_bot) max_hits = opts.bot; diff --git a/src/routes/auth/login.ts b/src/routes/auth/login.ts
index c92ddccc..8d1a8df3 100644 --- a/src/routes/auth/login.ts +++ b/src/routes/auth/login.ts
@@ -13,7 +13,7 @@ export default router; router.post( "/", - RateLimit({ count: 5, window: 60, onylIp: true }), + RateLimit({ count: 5, window: 60, onlyIp: true }), check({ login: new Length(String, 2, 100), // email or telephone password: new Length(String, 8, 72), diff --git a/src/routes/auth/register.ts b/src/routes/auth/register.ts
index eb5cd97d..0dd92e16 100644 --- a/src/routes/auth/register.ts +++ b/src/routes/auth/register.ts
@@ -12,7 +12,7 @@ const router: Router = Router(); router.post( "/", - RateLimit({ count: 2, window: 60 * 60 * 12, onylIp: true, success: true }), + RateLimit({ count: 2, window: 60 * 60 * 12, onlyIp: true, success: true }), check({ username: new Length(String, 2, 32), // TODO: check min password length in config diff --git a/src/routes/channels/#channel_id/index.ts b/src/routes/channels/#channel_id/index.ts
index 434f61a5..81e5054e 100644 --- a/src/routes/channels/#channel_id/index.ts +++ b/src/routes/channels/#channel_id/index.ts
@@ -30,7 +30,7 @@ router.delete("/", async (req: Request, res: Response) => { // TODO: Dm channel "close" not delete const data = toObject(channel); - await emitEvent({ event: "CHANNEL_DELETE", data, guild_id: channel?.guild_id, channel_id } as ChannelDeleteEvent); + await emitEvent({ event: "CHANNEL_DELETE", data, channel_id } as ChannelDeleteEvent); await ChannelModel.deleteOne({ id: channel_id }); @@ -51,7 +51,6 @@ router.patch("/", check(ChannelModifySchema), async (req: Request, res: Response await emitEvent({ event: "CHANNEL_UPDATE", data, - guild_id: channel.guild_id, channel_id } as ChannelUpdateEvent); diff --git a/src/routes/channels/#channel_id/messages/#message_id/index.ts b/src/routes/channels/#channel_id/messages/#message_id/index.ts
index 9cd63d26..a7c23d2f 100644 --- a/src/routes/channels/#channel_id/messages/#message_id/index.ts +++ b/src/routes/channels/#channel_id/messages/#message_id/index.ts
@@ -35,7 +35,6 @@ router.patch("/", check(MessageCreateSchema), async (req: Request, res: Response await emitEvent({ event: "MESSAGE_UPDATE", channel_id, - guild_id: message.guild_id, data: { ...toObject(message), nonce: undefined } } as MessageUpdateEvent); @@ -60,7 +59,6 @@ router.delete("/", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_DELETE", channel_id, - guild_id: channel.guild_id, data: { id: message_id, channel_id, diff --git a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
index 9f68b5cd..168a870f 100644 --- a/src/routes/channels/#channel_id/messages/#message_id/reactions.ts +++ b/src/routes/channels/#channel_id/messages/#message_id/reactions.ts
@@ -48,7 +48,6 @@ router.delete("/", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_REACTION_REMOVE_ALL", channel_id, - guild_id: channel.guild_id, data: { channel_id, message_id, @@ -79,7 +78,6 @@ router.delete("/:emoji", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_REACTION_REMOVE_EMOJI", channel_id, - guild_id: channel.guild_id, data: { channel_id, message_id, @@ -140,7 +138,6 @@ router.put("/:emoji/:user_id", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_REACTION_ADD", channel_id, - guild_id: channel.guild_id, data: { user_id: req.user_id, channel_id, @@ -179,7 +176,6 @@ router.delete("/:emoji/:user_id", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_REACTION_REMOVE", channel_id, - guild_id: channel.guild_id, data: { user_id: req.user_id, channel_id, diff --git a/src/routes/channels/#channel_id/permissions.ts b/src/routes/channels/#channel_id/permissions.ts
index f3cef53e..12364293 100644 --- a/src/routes/channels/#channel_id/permissions.ts +++ b/src/routes/channels/#channel_id/permissions.ts
@@ -44,7 +44,6 @@ router.put("/:overwrite_id", check({ allow: String, deny: String, type: Number, await emitEvent({ event: "CHANNEL_UPDATE", channel_id, - guild_id: channel.guild_id, data: channel } as ChannelUpdateEvent); @@ -64,7 +63,6 @@ router.delete("/:overwrite_id", async (req: Request, res: Response) => { await emitEvent({ event: "CHANNEL_UPDATE", channel_id, - guild_id: channel.guild_id, data: channel } as ChannelUpdateEvent); diff --git a/src/routes/channels/#channel_id/pins.ts b/src/routes/channels/#channel_id/pins.ts
index f5bd2ef7..65d6b975 100644 --- a/src/routes/channels/#channel_id/pins.ts +++ b/src/routes/channels/#channel_id/pins.ts
@@ -32,14 +32,12 @@ router.put("/:message_id", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_UPDATE", channel_id, - guild_id: channel.guild_id, data: message } as MessageUpdateEvent); await emitEvent({ event: "CHANNEL_PINS_UPDATE", channel_id, - guild_id: channel.guild_id, data: { channel_id, guild_id: channel.guild_id, @@ -64,14 +62,12 @@ router.delete("/:message_id", async (req: Request, res: Response) => { await emitEvent({ event: "MESSAGE_UPDATE", channel_id, - guild_id: channel.guild_id, data: message } as MessageUpdateEvent); await emitEvent({ event: "CHANNEL_PINS_UPDATE", channel_id, - guild_id: channel.guild_id, data: { channel_id, guild_id: channel.guild_id, diff --git a/src/routes/channels/#channel_id/typing.ts b/src/routes/channels/#channel_id/typing.ts
index 2c2b9bc9..de549883 100644 --- a/src/routes/channels/#channel_id/typing.ts +++ b/src/routes/channels/#channel_id/typing.ts
@@ -16,7 +16,6 @@ router.post("/", async (req: Request, res: Response) => { await emitEvent({ event: "TYPING_START", channel_id: channel_id, - guild_id: channel.guild_id, data: { // this is the paylod member: toObject(member), diff --git a/src/routes/guilds/#guild_id/channels.ts b/src/routes/guilds/#guild_id/channels.ts
index 15cc7394..52361f5e 100644 --- a/src/routes/guilds/#guild_id/channels.ts +++ b/src/routes/guilds/#guild_id/channels.ts
@@ -7,7 +7,8 @@ import { Snowflake, toObject, ChannelUpdateEvent, - AnyChannel + AnyChannel, + getPermission } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; import { ChannelModifySchema } from "../../../schema/Channel"; @@ -25,7 +26,9 @@ router.get("/", async (req: Request, res: Response) => { // TODO: check if channel type is permitted // TODO: check if parent_id exists + router.post("/", check(ChannelModifySchema), async (req: Request, res: Response) => { + // creates a new guild channel https://discord.com/developers/docs/resources/guild#create-guild-channel const { guild_id } = req.params; const body = req.body as ChannelModifySchema; @@ -35,16 +38,36 @@ router.post("/", check(ChannelModifySchema), async (req: Request, res: Response) }); // 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; +router.patch( + "/", + check([{ id: String, $position: Number, $lock_permissions: Boolean, $parent_id: String }]), + async (req: Request, res: Response) => { + // changes guild channel position + const { guild_id } = req.params; + const body = req.body as { id: string; position?: number; lock_permissions?: boolean; parent_id?: string }; + body.position = Math.floor(body.position || 0); + if (!body.position && !body.parent_id) throw new HTTPError(`You need to at least specify position or parent_id`, 400); - const guild = await GuildModel.findOne({ id: guild_id }, { id: true }).exec(); - const channel = await ChannelModel.findOneAndUpdate({ guild_id }, body).exec(); + const permission = await getPermission(req.user_id, guild_id); + permission.hasThrow("MANAGE_CHANNELS"); - await emitEvent({ event: "CHANNEL_UPDATE", data: channel } as ChannelUpdateEvent); + const opts: any = {}; + if (body.position) opts.position = body.position; - res.json(toObject(channel)); -}); + if (body.parent_id) { + opts.parent_id = body.parent_id; + const parent_channel = await ChannelModel.findOne({ id: body.parent_id, guild_id }, { permission_overwrites: true }).exec(); + if (body.lock_permissions) { + opts.permission_overwrites = parent_channel.permission_overwrites; + } + } + + const channel = await ChannelModel.findOneAndUpdate({ id: req.body, guild_id }, opts).exec(); + + await emitEvent({ event: "CHANNEL_UPDATE", data: channel, channel_id: body.id, guild_id } as ChannelUpdateEvent); + + res.json(toObject(channel)); + } +); export default router; diff --git a/src/routes/users/@me/index.ts b/src/routes/users/@me/index.ts
index f6b29958..7bd4a486 100644 --- a/src/routes/users/@me/index.ts +++ b/src/routes/users/@me/index.ts
@@ -11,16 +11,38 @@ router.get("/", async (req: Request, res: Response) => { res.json(await getPublicUser(req.user_id)); }); +const UserUpdateProjection = { + accent_color: true, + avatar: true, + banner: true, + bio: true, + bot: true, + discriminator: true, + email: true, + flags: true, + id: true, + locale: true, + mfa_enabled: true, + nsfw_alllowed: true, + phone: true, + public_flags: true, + purchased_flags: true, + // token: true, // this isn't saved in the db and needs to be set manually + username: true, + verified: true +}; + router.patch("/", check(UserModifySchema), async (req: Request, res: Response) => { const body = req.body as UserModifySchema; - if(body.avatar) body.avatar = await handleFile(`/avatars/${req.user_id}`, body.avatar as string); + 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(); + const user = await UserModel.findOneAndUpdate({ id: req.user_id }, body, { projection: UserUpdateProjection }).exec(); // TODO: dispatch user update event res.json(toObject(user)); }); export default router; +// {"message": "Invalid two-factor code", "code": 60008} diff --git a/src/schema/User.ts b/src/schema/User.ts
index 77ee08b4..c7478f8d 100644 --- a/src/schema/User.ts +++ b/src/schema/User.ts
@@ -5,7 +5,10 @@ export const UserModifySchema = { $avatar: String, $bio: new Length(String, 0, 190), $accent_color: Number, - $banner: String + $banner: String, + $password: String, + $new_password: String, + $code: String // 2fa code }; export interface UserModifySchema { @@ -14,4 +17,7 @@ export interface UserModifySchema { bio?: string; accent_color?: number | null; banner?: string | null; + password?: string; + new_password?: string; + code?: string; } diff --git a/src/util/Event.ts b/src/util/Event.ts
index 5ff027e5..d0b78a53 100644 --- a/src/util/Event.ts +++ b/src/util/Event.ts
@@ -1,13 +1,25 @@ -import { Event, EventModel } from "@fosscord/server-util"; +import { Config, Event, EventModel, rabbitCon, rabbitCh } from "@fosscord/server-util"; export async function emitEvent(payload: Omit<Event, "created_at">) { - const obj = { - created_at: new Date(), // in seconds - ...payload, - }; - // TODO: bigint isn't working + if (rabbitCon) { + const id = (payload.channel_id || payload.user_id || payload.guild_id) as string; + if (!id) console.error("event doesn't contain any id", payload); + const data = typeof payload.data === "object" ? JSON.stringify(payload.data) : payload.data; // use rabbitmq for event transmission - return await new EventModel(obj).save(); + // assertQueue isn't needed, because a queue will automatically created if it doesn't exist + const successful = rabbitCh.sendToQueue(id, Buffer.from(`${data}`), { type: payload.event }); + if (!successful) throw new Error("failed to send event"); + } else { + // use mongodb for event transmission + // TODO: use event emitter for local server bundle + const obj = { + created_at: new Date(), // in seconds + ...payload + }; + // TODO: bigint isn't working + + return await new EventModel(obj).save(); + } } export async function emitAuditLog(payload: any) {}