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) {}
|