diff options
author | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-05-27 18:15:33 +0200 |
---|---|---|
committer | Flam3rboy <34555296+Flam3rboy@users.noreply.github.com> | 2021-05-27 18:15:33 +0200 |
commit | b00815b025575bfe79f6f5d2d4004b8da9b9b946 (patch) | |
tree | 1d86d7767ba8f29396421ca0ed37afb892214252 | |
parent | :bug: fix bans (diff) | |
parent | :arrow_up: npm i @fosscord/server-util@1.3.5 (diff) | |
download | server-b00815b025575bfe79f6f5d2d4004b8da9b9b946.tar.xz |
Merge branch 'master' of https://github.com/fosscord/fosscord-api
27 files changed, 827 insertions, 264 deletions
diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..0573c605 --- /dev/null +++ b/.env.example @@ -0,0 +1,4 @@ +MONGO_URL=mongodb://localhost/fosscord +PORT=3001 +PRODUCTION=TRUE +THREADS=# automatically use all available cores, only available if production = true \ No newline at end of file diff --git a/.gitignore b/.gitignore index ee4c71a5..628444bf 100644 --- a/.gitignore +++ b/.gitignore @@ -105,3 +105,7 @@ dist .DS_STORE src/ready.json + +# Docker +.docker/config/* +!.docker/config/.keep \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index e0d5ae68..1113978f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ FROM node:lts-alpine -RUN mkdir -p /usr/src/fosscord-api WORKDIR /usr/src/fosscord-api -COPY package.json /usr/src/fosscord-api +COPY package.json . RUN npm install -COPY . /usr/src/fosscord-api RUN npx patch-package +COPY . . +EXPOSE 3001 CMD ["npm", "start"] \ No newline at end of file diff --git a/client_test/index.html b/client_test/index.html index 915a3378..de2fe44b 100644 --- a/client_test/index.html +++ b/client_test/index.html @@ -18,6 +18,7 @@ MEDIA_PROXY_ENDPOINT: "https://media.discordapp.net", WIDGET_ENDPOINT: "//discord.com/widget", INVITE_HOST: "discord.gg", + GUILD_TEMPLATE_HOST: "discord.new", GIFT_CODE_HOST: "discord.gift", RELEASE_CHANNEL: "stable", @@ -32,10 +33,9 @@ MIGRATION_SOURCE_ORIGIN: "https://discordapp.com", MIGRATION_DESTINATION_ORIGIN: "https://discord.com", HTML_TIMESTAMP: Date.now(), - ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0", + ALGOLIA_KEY: "aca0d7082e4e63af5ba5917d5e96bed0" }; - </script> - <script> + localStorage.removeItem("gatewayURL"); localStorage.setItem( "DeveloperOptionsStore", `{"trace":false,"canary":false,"logGatewayEvents":true,"logOverlayEvents":false,"logAnalyticsEvents":false,"sourceMapsEnabled":false,"axeEnabled":false}` diff --git a/locales/zh/auth.json b/locales/zh/auth.json index 025a3876..db5f1eb4 100644 --- a/locales/zh/auth.json +++ b/locales/zh/auth.json @@ -1,15 +1,15 @@ { "login": { - "INVALID_LOGIN": "E-Mail or Phone not found", - "INVALID_PASSWORD": "Invalid Password" + "INVALID_LOGIN": "找不到电子邮件或电话", + "INVALID_PASSWORD": "无效密码" }, "register": { - "REGISTRATION_DISABLED": "New user registration is disabled", - "INVITE_ONLY": "You must be invited to register", + "REGISTRATION_DISABLED": "新用户注册已禁用", + "INVITE_ONLY": "您必须被邀请注册", "EMAIL_INVALID": "Invalid Email", - "EMAIL_ALREADY_REGISTERED": "Email is already registered", - "DATE_OF_BIRTH_UNDERAGE": "You need to be {{years}} years or older", - "CONSENT_REQUIRED": "You must agree to Terms of Service and Privacy Policy.", - "USERNAME_TOO_MANY_USERS": "Too many users have this username, please try another" + "EMAIL_ALREADY_REGISTERED": "电子邮件已注册", + "DATE_OF_BIRTH_UNDERAGE": "您需要有 {{years}} 岁以上", + "CONSENT_REQUIRED": "您必须同意服务条款和隐私政策。", + "USERNAME_TOO_MANY_USERS": "用户名太多,请尝试另一个" } } diff --git a/locales/zh/common.json b/locales/zh/common.json index 7a0254fc..a9e8532e 100644 --- a/locales/zh/common.json +++ b/locales/zh/common.json @@ -1,18 +1,18 @@ { "field": { - "BASE_TYPE_REQUIRED": "This field is required", - "BASE_TYPE_STRING": "This field must be a string", - "BASE_TYPE_NUMBER": "This field must be a number", - "BASE_TYPE_BIGINT": "This field must be a bigint", - "BASE_TYPE_BOOLEAN": "This field must be a boolean", - "BASE_TYPE_CHOICES": "This field must be one of ({{types}})", - "BASE_TYPE_CLASS": "This field must be an instance of {{type}}", - "BASE_TYPE_OBJECT": "This field must be a object", - "BASE_TYPE_ARRAY": "This field must be an array", - "UNKOWN_FIELD": "Unkown key: {{key}}", - "BASE_TYPE_CONSTANT": "This field must be {{value}}", - "EMAIL_TYPE_INVALID_EMAIL": "Not a well formed email address", - "DATE_TYPE_PARSE": "Could not parse {{date}}. Should be ISO8601", - "BASE_TYPE_BAD_LENGTH": "Must be between {{length}} in length" + "BASE_TYPE_REQUIRED": "此字段是必填项", + "BASE_TYPE_STRING": "此字段必须是字符串", + "BASE_TYPE_NUMBER": "此字段必须是一个数字", + "BASE_TYPE_BIGINT": "此字段必须是很大的", + "BASE_TYPE_BOOLEAN": "此字段必须是布尔值", + "BASE_TYPE_CHOICES": "此字段必须是 ({{types}})", + "BASE_TYPE_CLASS": "此字段必须是 {{type}} 的实例", + "BASE_TYPE_OBJECT": "此字段必须是对象", + "BASE_TYPE_ARRAY": "此字段必须是一个数组", + "UNKOWN_FIELD": "未知密钥: {{key}}", + "BASE_TYPE_CONSTANT": "此字段必须是 {{value}}", + "EMAIL_TYPE_INVALID_EMAIL": "格式不正确的电子邮件地址", + "DATE_TYPE_PARSE": "无法解析 {{date}}。应该为 ISO8601", + "BASE_TYPE_BAD_LENGTH": "长度必须介于 {{length}} 之间" } } \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 81fd6eb2..309e7209 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,14 +7,20 @@ "": { "name": "@fosscord/api", "version": "1.0.0", - "hasInstallScript": true, "license": "ISC", "dependencies": { - "@fosscord/server-util": "^1.2.6", + "@fosscord/server-util": "^1.3.5", "@types/jest": "^26.0.22", + "@types/json-schema": "^7.0.7", + "ajv": "^8.4.0", + "ajv-formats": "^2.1.0", + "assert": "^1.5.0", + "atomically": "^1.7.0", "bcrypt": "^5.0.1", "body-parser": "^1.19.0", + "dot-prop": "^6.0.1", "dotenv": "^8.2.0", + "env-paths": "^2.2.1", "express": "^4.17.1", "express-validator": "^6.9.2", "i18next": "^19.8.5", @@ -46,6 +52,27 @@ "typescript": "^4.1.2" } }, + "../server-util": { + "name": "@fosscord/server-util", + "version": "1.3.4", + "extraneous": true, + "license": "ISC", + "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", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "jsonwebtoken": "^8.5.1", + "missing-native-js-functions": "^1.2.2", + "mongodb": "^3.6.8", + "mongoose": "^5.12.3", + "mongoose-autopopulate": "^0.12.3", + "typescript": "^4.1.3" + } + }, "node_modules/@babel/code-frame": { "version": "7.12.13", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", @@ -492,31 +519,34 @@ } }, "node_modules/@fosscord/server-util": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.2.6.tgz", - "integrity": "sha512-HFa/DX+4Ze9e8j/tT/Je6at2UEygAH4xsHYay/SObFQKC1Oo+G5aIYvak0kwyzO12lg91i0FBRUEHuMviwNe8A==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.5.tgz", + "integrity": "sha512-gXtpiw1LoGeYxmIOKHVv6iAShye6SVYKuwjvLrnsrAXPeyE3h5/YwYAEnjycuKIVjafF9RVBWluWzWSj/TOPbA==", "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", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", "missing-native-js-functions": "^1.2.2", - "mongodb": "^3.6.6", + "mongodb": "^3.6.8", "mongoose": "^5.12.3", "mongoose-autopopulate": "^0.12.3", "typescript": "^4.1.3" } }, "node_modules/@fosscord/server-util/node_modules/mongodb": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.6.tgz", - "integrity": "sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", "dependencies": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", - "optional-require": "^1.0.2", + "optional-require": "^1.0.3", "safe-buffer": "^5.1.2" }, "engines": { @@ -524,6 +554,26 @@ }, "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/@istanbuljs/load-nyc-config": { @@ -1513,6 +1563,11 @@ "pretty-format": "^26.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, "node_modules/@types/jsonwebtoken": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz", @@ -1710,6 +1765,28 @@ "node": ">=8.5.0" } }, + "node_modules/0x/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/0x/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/0x/node_modules/make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -1811,15 +1888,34 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", + "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", "dependencies": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } } }, "node_modules/ansi-escapes": { @@ -1987,7 +2083,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, "dependencies": { "object-assign": "^4.1.1", "util": "0.10.3" @@ -2005,14 +2100,12 @@ "node_modules/assert/node_modules/inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "node_modules/assert/node_modules/util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "dependencies": { "inherits": "2.0.1" } @@ -2044,6 +2137,14 @@ "node": ">= 4.5.0" } }, + "node_modules/atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "engines": { + "node": ">=10.12.0" + } + }, "node_modules/aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -3871,6 +3972,20 @@ "node": ">=8" } }, + "node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", @@ -3991,6 +4106,14 @@ "once": "^1.4.0" } }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, "node_modules/env-string": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/env-string/-/env-string-1.0.1.tgz", @@ -4493,8 +4616,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", @@ -4856,6 +4978,28 @@ "node": ">=6" } }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -5443,6 +5587,14 @@ "node": ">=0.10.0" } }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -7422,10 +7574,9 @@ "dev": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "node_modules/json-stable-stringify": { "version": "0.0.1", @@ -9777,6 +9928,14 @@ "node": ">=0.10.0" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -10626,6 +10785,11 @@ "safer-buffer": "^2.0.2", "tweetnacl": "~0.14.0" }, + "bin": { + "sshpk-conv": "bin/sshpk-conv", + "sshpk-sign": "bin/sshpk-sign", + "sshpk-verify": "bin/sshpk-verify" + }, "engines": { "node": ">=0.10.0" } @@ -11454,9 +11618,9 @@ } }, "node_modules/typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -11589,7 +11753,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -11598,7 +11761,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true, "engines": { "node": ">=6" } @@ -12531,31 +12693,34 @@ } }, "@fosscord/server-util": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.2.6.tgz", - "integrity": "sha512-HFa/DX+4Ze9e8j/tT/Je6at2UEygAH4xsHYay/SObFQKC1Oo+G5aIYvak0kwyzO12lg91i0FBRUEHuMviwNe8A==", + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@fosscord/server-util/-/server-util-1.3.5.tgz", + "integrity": "sha512-gXtpiw1LoGeYxmIOKHVv6iAShye6SVYKuwjvLrnsrAXPeyE3h5/YwYAEnjycuKIVjafF9RVBWluWzWSj/TOPbA==", "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", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", "jsonwebtoken": "^8.5.1", "missing-native-js-functions": "^1.2.2", - "mongodb": "^3.6.6", + "mongodb": "^3.6.8", "mongoose": "^5.12.3", "mongoose-autopopulate": "^0.12.3", "typescript": "^4.1.3" }, "dependencies": { "mongodb": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.6.tgz", - "integrity": "sha512-WlirMiuV1UPbej5JeCMqE93JRfZ/ZzqE7nJTwP85XzjAF4rRSeq2bGCb1cjfoHLOF06+HxADaPGqT0g3SbVT1w==", + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.6.8.tgz", + "integrity": "sha512-sDjJvI73WjON1vapcbyBD3Ao9/VN3TKYY8/QX9EPbs22KaCSrQ5rXo5ZZd44tWJ3wl3FlnrFZ+KyUtNH6+1ZPQ==", "requires": { "bl": "^2.2.1", "bson": "^1.1.4", "denque": "^1.4.1", - "optional-require": "^1.0.2", + "optional-require": "^1.0.3", "safe-buffer": "^5.1.2", "saslprep": "^1.0.0" } @@ -13375,6 +13540,11 @@ "pretty-format": "^26.0.0" } }, + "@types/json-schema": { + "version": "7.0.7", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.7.tgz", + "integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==" + }, "@types/jsonwebtoken": { "version": "8.5.0", "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.5.0.tgz", @@ -13566,6 +13736,24 @@ "which": "^1.2.4" }, "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", @@ -13648,17 +13836,24 @@ } }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.5.0.tgz", + "integrity": "sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==", "requires": { "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, + "ajv-formats": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.0.tgz", + "integrity": "sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q==", + "requires": { + "ajv": "^8.0.0" + } + }, "ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", @@ -13799,7 +13994,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, "requires": { "object-assign": "^4.1.1", "util": "0.10.3" @@ -13808,14 +14002,12 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, "requires": { "inherits": "2.0.1" } @@ -13846,6 +14038,11 @@ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", "dev": true }, + "atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==" + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -15431,6 +15628,14 @@ } } }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "requires": { + "is-obj": "^2.0.0" + } + }, "dotenv": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz", @@ -15544,6 +15749,11 @@ "once": "^1.4.0" } }, + "env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==" + }, "env-string": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/env-string/-/env-string-1.0.1.tgz", @@ -15957,8 +16167,7 @@ "fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "fast-json-stable-stringify": { "version": "2.1.0", @@ -16247,6 +16456,26 @@ "requires": { "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + } } }, "has": { @@ -16731,6 +16960,11 @@ } } }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -18305,10 +18539,9 @@ "dev": true }, "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==" }, "json-stable-stringify": { "version": "0.0.1", @@ -20266,6 +20499,11 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==" + }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -21662,9 +21900,9 @@ } }, "typescript": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.1.3.tgz", - "integrity": "sha512-B3ZIOf1IKeH2ixgHhj6la6xdwR9QrLC5d1VKeCSY4tvkqhF2eqd9O7txNlS0PO3GrBAFIdr3L1ndNwteUbZLYg==" + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz", + "integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg==" }, "umd": { "version": "3.0.3", @@ -21766,7 +22004,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "requires": { "punycode": "^2.1.0" }, @@ -21774,8 +22011,7 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" } } }, diff --git a/package.json b/package.json index e3b6155c..9879e874 100644 --- a/package.json +++ b/package.json @@ -29,11 +29,18 @@ }, "homepage": "https://github.com/fosscord/fosscord-api#readme", "dependencies": { - "@fosscord/server-util": "^1.2.6", + "@fosscord/server-util": "^1.3.5", "@types/jest": "^26.0.22", + "@types/json-schema": "^7.0.7", + "ajv": "^8.4.0", + "ajv-formats": "^2.1.0", + "assert": "^1.5.0", + "atomically": "^1.7.0", "bcrypt": "^5.0.1", "body-parser": "^1.19.0", + "dot-prop": "^6.0.1", "dotenv": "^8.2.0", + "env-paths": "^2.2.1", "express": "^4.17.1", "express-validator": "^6.9.2", "i18next": "^19.8.5", diff --git a/scripts/config_generator.js b/scripts/config_generator.js new file mode 100644 index 00000000..5b5c52d4 --- /dev/null +++ b/scripts/config_generator.js @@ -0,0 +1,93 @@ +const { Snowflake } = require("@fosscord/server-util"); +const crypto = require('crypto'); +const fs = require('fs'); + + +const defaultConfig = { + // TODO: Get the network interfaces dinamically + gateway: "ws://localhost", + general: { + instance_id: Snowflake.generate(), + }, + permissions: { + user: { + createGuilds: true, + } + }, + limits: { + user: { + maxGuilds: 100, + maxUsername: 32, + maxFriends: 1000, + }, + guild: { + maxRoles: 250, + maxMembers: 250000, + maxChannels: 500, + maxChannelsInCategory: 50, + hideOfflineMember: 1000, + }, + message: { + characters: 2000, + ttsCharacters: 200, + maxReactions: 20, + maxAttachmentSize: 8388608, + maxBulkDelete: 100, + }, + channel: { + maxPins: 50, + maxTopic: 1024, + }, + rate: { + ip: { + enabled: true, + count: 1000, + timespan: 1000 * 60 * 10, + }, + routes: {}, + }, + }, + security: { + jwtSecret: crypto.randomBytes(256).toString("base64"), + forwadedFor: null, + // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy + // forwadedFor: "CF-Connecting-IP" // cloudflare: + captcha: { + enabled: false, + service: null, + sitekey: null, + secret: null, + }, + }, + login: { + requireCaptcha: false, + }, + register: { + email: { + necessary: true, + allowlist: false, + blocklist: true, + domains: [], // TODO: efficiently save domain blocklist in database + // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), + }, + dateOfBirth: { + necessary: true, + minimum: 13, + }, + requireInvite: false, + requireCaptcha: true, + allowNewRegistration: true, + allowMultipleAccounts: true, + password: { + minLength: 8, + minNumbers: 2, + minUpperCase: 2, + minSymbols: 0, + blockInsecureCommonPasswords: false, + }, + }, +} + +let data = JSON.stringify(defaultConfig); +fs.writeFileSync('./.docker/config/api.json', data); + diff --git a/src/Server.ts b/src/Server.ts index e6d3d9c9..b1fe3c90 100644 --- a/src/Server.ts +++ b/src/Server.ts @@ -3,16 +3,16 @@ import fs from "fs/promises"; import { Connection } from "mongoose"; import { Server, ServerOptions } from "lambert-server"; import { Authentication, CORS, GlobalRateLimit } from "./middlewares/"; -import Config from "./util/Config"; -import { db } from "@fosscord/server-util"; +import { Config, db } from "@fosscord/server-util"; import i18next from "i18next"; import i18nextMiddleware, { I18next } from "i18next-http-middleware"; import i18nextBackend from "i18next-node-fs-backend"; import { ErrorHandler } from "./middlewares/ErrorHandler"; import { BodyParser } from "./middlewares/BodyParser"; -import { Router } from "express"; +import express, { Router } from "express"; import fetch from "node-fetch"; import mongoose from "mongoose"; +import path from "path"; // this will return the new updated document for findOneAndUpdate mongoose.set("returnOriginal", false); // https://mongoosejs.com/docs/api/model.html#model_Model.findOneAndUpdate @@ -55,14 +55,14 @@ export class FosscordServer extends Server { await (db as Promise<Connection>); await this.setupSchema(); console.log("[DB] connected"); - await Promise.all([Config.init()]); + await Config.init(); this.app.use(GlobalRateLimit); this.app.use(Authentication); this.app.use(CORS); this.app.use(BodyParser({ inflate: true })); - const languages = await fs.readdir(__dirname + "/../locales/"); - const namespaces = await fs.readdir(__dirname + "/../locales/en/"); + const languages = await fs.readdir(path.join(__dirname, "..", "locales")); + const namespaces = await fs.readdir(path.join(__dirname, "..", "locales", "en")); const ns = namespaces.filter((x) => x.endsWith(".json")).map((x) => x.slice(0, x.length - 5)); await i18next @@ -85,11 +85,13 @@ export class FosscordServer extends Server { // @ts-ignore this.app = prefix; - this.routes = await this.registerRoutes(__dirname + "/routes/"); + this.routes = await this.registerRoutes(path.join(__dirname, "routes", "/")); app.use("/api/v8", prefix); this.app = app; this.app.use(ErrorHandler); - const indexHTML = await fs.readFile(__dirname + "/../client_test/index.html"); + const indexHTML = await fs.readFile(path.join(__dirname, "..", "client_test", "index.html")); + + this.app.use("/assets", express.static(path.join(__dirname, "..", "assets"))); this.app.get("/assets/:file", async (req, res) => { delete req.headers.host; diff --git a/src/middlewares/Authentication.ts b/src/middlewares/Authentication.ts index 0ecc1bc0..630a45ff 100644 --- a/src/middlewares/Authentication.ts +++ b/src/middlewares/Authentication.ts @@ -1,13 +1,13 @@ import { NextFunction, Request, Response } from "express"; import { HTTPError } from "lambert-server"; -import { checkToken } from "@fosscord/server-util"; +import { checkToken, Config } from "@fosscord/server-util"; export const NO_AUTHORIZATION_ROUTES = [ "/api/v8/auth/login", "/api/v8/auth/register", "/api/v8/webhooks/", "/api/v8/gateway", - "/api/v8/experiments", + "/api/v8/experiments" ]; declare global { @@ -24,10 +24,11 @@ export async function Authentication(req: Request, res: Response, next: NextFunc if (req.url.startsWith("/api/v8/invites") && req.method === "GET") return next(); if (NO_AUTHORIZATION_ROUTES.some((x) => req.url.startsWith(x))) return next(); if (!req.headers.authorization) return next(new HTTPError("Missing Authorization Header", 401)); - // TODO: check if user is banned/token expired try { - const decoded: any = await checkToken(req.headers.authorization); + const { jwtSecret } = Config.get().security; + + const decoded: any = await checkToken(req.headers.authorization, jwtSecret); req.token = decoded; req.user_id = decoded.id; diff --git a/src/middlewares/CORS.ts b/src/middlewares/CORS.ts index e6cc5544..88e90a4b 100644 --- a/src/middlewares/CORS.ts +++ b/src/middlewares/CORS.ts @@ -9,7 +9,7 @@ export function CORS(req: Request, res: Response, next: NextFunction) { "Content-security-policy", "default-src * data: blob: filesystem: about: ws: wss: 'unsafe-inline' 'unsafe-eval'; script-src * data: blob: 'unsafe-inline' 'unsafe-eval'; connect-src * data: blob: 'unsafe-inline'; img-src * data: blob: 'unsafe-inline'; frame-src * data: blob: ; style-src * data: blob: 'unsafe-inline'; font-src * data: blob: 'unsafe-inline';" ); - res.set("Access-Control-Allow-Headers", req.header("Access-Control-Request-Headers")); + res.set("Access-Control-Allow-Headers", req.header("Access-Control-Request-Headers") || "*"); next(); } diff --git a/src/middlewares/GlobalRateLimit.ts b/src/middlewares/GlobalRateLimit.ts index fc121911..7260d1a2 100644 --- a/src/middlewares/GlobalRateLimit.ts +++ b/src/middlewares/GlobalRateLimit.ts @@ -1,5 +1,5 @@ import { NextFunction, Request, Response } from "express"; -import Config from "../util/Config"; +import { Config } from "@fosscord/server-util"; // TODO: use mongodb ttl index // TODO: increment count on serverside diff --git a/src/routes/auth/login.ts b/src/routes/auth/login.ts index a0fc1190..2c4084ea 100644 --- a/src/routes/auth/login.ts +++ b/src/routes/auth/login.ts @@ -2,8 +2,7 @@ import { Request, Response, Router } from "express"; import { check, FieldErrors, Length } from "../../util/instanceOf"; import bcrypt from "bcrypt"; import jwt from "jsonwebtoken"; -import { UserModel } from "@fosscord/server-util"; -import Config from "../../util/Config"; +import { Config, UserModel } from "@fosscord/server-util"; import { adjustEmail } from "./register"; const router: Router = Router(); @@ -17,7 +16,7 @@ router.post( $undelete: Boolean, $captcha_key: String, $login_source: String, - $gift_code_sku_id: String, + $gift_code_sku_id: String }), async (req: Request, res: Response) => { const { login, password, captcha_key } = req.body; @@ -25,6 +24,8 @@ router.post( const query: any[] = [{ phone: login }]; if (email) query.push({ email }); + // TODO: Rewrite this to have the proper config syntax on the new method + const config = Config.get(); if (config.login.requireCaptcha && config.security.captcha.enabled) { @@ -33,7 +34,7 @@ router.post( return res.status(400).json({ captcha_key: ["captcha-required"], captcha_sitekey: sitekey, - captcha_service: service, + captcha_service: service }); } @@ -71,7 +72,7 @@ export async function generateToken(id: string) { { id: id, iat }, Config.get().security.jwtSecret, { - algorithm, + algorithm }, (err, token) => { if (err) return rej(err); diff --git a/src/routes/auth/register.ts b/src/routes/auth/register.ts index 265516d7..e24485da 100644 --- a/src/routes/auth/register.ts +++ b/src/routes/auth/register.ts @@ -1,6 +1,5 @@ import { Request, Response, Router } from "express"; -import Config from "../../util/Config"; -import { trimSpecial, User, Snowflake, UserModel } from "@fosscord/server-util"; +import { trimSpecial, User, Snowflake, UserModel, Config } from "@fosscord/server-util"; import bcrypt from "bcrypt"; import { check, Email, EMAIL_REGEX, FieldErrors, Length } from "../../util/instanceOf"; import "missing-native-js-functions"; @@ -21,7 +20,7 @@ router.post( $invite: String, $date_of_birth: Date, // "2000-04-03" $gift_code_sku_id: String, - $captcha_key: String, + $captcha_key: String }), async (req: Request, res: Response) => { const { @@ -33,14 +32,14 @@ router.post( invite, date_of_birth, gift_code_sku_id, // ? what is this - captcha_key, + captcha_key } = req.body; // TODO: automatically join invite // TODO: gift_code_sku_id? // TODO: check password strength // adjusted_email will be slightly modified version of the user supplied email -> e.g. protection against GMail Trick - let adjusted_email: string | undefined = adjustEmail(email); + let adjusted_email: string | null = adjustEmail(email); // adjusted_password will be the hash of the password let adjusted_password: string = ""; @@ -57,21 +56,21 @@ router.post( // check if registration is allowed if (!register.allowNewRegistration) { throw FieldErrors({ - email: { code: "REGISTRATION_DISABLED", message: req.t("auth:register.REGISTRATION_DISABLED") }, + email: { code: "REGISTRATION_DISABLED", message: req.t("auth:register.REGISTRATION_DISABLED") } }); } // check if the user agreed to the Terms of Service if (!consent) { throw FieldErrors({ - consent: { code: "CONSENT_REQUIRED", message: req.t("auth:register.CONSENT_REQUIRED") }, + consent: { code: "CONSENT_REQUIRED", message: req.t("auth:register.CONSENT_REQUIRED") } }); } // require invite to register -> e.g. for organizations to send invites to their employees if (register.requireInvite && !invite) { throw FieldErrors({ - email: { code: "INVITE_ONLY", message: req.t("auth:register.INVITE_ONLY") }, + email: { code: "INVITE_ONLY", message: req.t("auth:register.INVITE_ONLY") } }); } @@ -86,19 +85,19 @@ router.post( throw FieldErrors({ email: { code: "EMAIL_ALREADY_REGISTERED", - message: req.t("auth.register.EMAIL_ALREADY_REGISTERED"), - }, + message: req.t("auth:register.EMAIL_ALREADY_REGISTERED") + } }); } - } else if (register.email.required) { + } else if (register.email.necessary) { throw FieldErrors({ - email: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") }, + email: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") } }); } - if (register.dateOfBirth.required && !date_of_birth) { + if (register.dateOfBirth.necessary && !date_of_birth) { throw FieldErrors({ - date_of_birth: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") }, + date_of_birth: { code: "BASE_TYPE_REQUIRED", message: req.t("common:field.BASE_TYPE_REQUIRED") } }); } else if (register.dateOfBirth.minimum) { const minimum = new Date(); @@ -109,8 +108,8 @@ router.post( throw FieldErrors({ date_of_birth: { code: "DATE_OF_BIRTH_UNDERAGE", - message: req.t("auth:register.DATE_OF_BIRTH_UNDERAGE", { years: register.dateOfBirth.minimum }), - }, + message: req.t("auth:register.DATE_OF_BIRTH_UNDERAGE", { years: register.dateOfBirth.minimum }) + } }); } } @@ -123,8 +122,8 @@ router.post( throw FieldErrors({ email: { code: "EMAIL_ALREADY_REGISTERED", - message: req.t("auth:register.EMAIL_ALREADY_REGISTERED"), - }, + message: req.t("auth:register.EMAIL_ALREADY_REGISTERED") + } }); } } @@ -135,7 +134,7 @@ router.post( return res.status(400).json({ captcha_key: ["captcha-required"], captcha_sitekey: sitekey, - captcha_service: service, + captcha_service: service }); } @@ -160,8 +159,8 @@ router.post( throw FieldErrors({ username: { code: "USERNAME_TOO_MANY_USERS", - message: req.t("auth:register.USERNAME_TOO_MANY_USERS"), - }, + message: req.t("auth:register.USERNAME_TOO_MANY_USERS") + } }); } @@ -181,17 +180,19 @@ router.post( mobile: false, premium: false, premium_type: 0, - phone: undefined, + phone: null, mfa_enabled: false, verified: false, + disabled: false, + deleted: false, presence: { activities: [], client_status: { desktop: undefined, mobile: undefined, - web: undefined, + web: undefined }, - status: "offline", + status: "offline" }, email: adjusted_email, nsfw_allowed: true, // TODO: depending on age @@ -203,7 +204,7 @@ router.post( valid_tokens_since: new Date(), relationships: [], connected_accounts: [], - fingerprints: [], + fingerprints: [] }, user_settings: { afk_timeout: 300, @@ -216,7 +217,7 @@ router.post( emoji_id: null, emoji_name: null, expires_at: null, - text: null, + text: null }, default_guilds_restricted: false, detect_platform_accounts: true, @@ -241,9 +242,9 @@ router.post( status: "offline", stream_notifications_enabled: true, theme: "dark", - timezone_offset: 0, + timezone_offset: 0 // timezone_offset: // TODO: timezone from request - }, + } }; // insert user into database @@ -253,7 +254,7 @@ router.post( } ); -export function adjustEmail(email: string): string | undefined { +export function adjustEmail(email: string): string | null { // body parser already checked if it is a valid email const parts = <RegExpMatchArray>email.match(EMAIL_REGEX); // @ts-ignore diff --git a/src/routes/channels/#channel_id/messages/bulk-delete.ts b/src/routes/channels/#channel_id/messages/bulk-delete.ts index ac032c0e..24724d34 100644 --- a/src/routes/channels/#channel_id/messages/bulk-delete.ts +++ b/src/routes/channels/#channel_id/messages/bulk-delete.ts @@ -1,7 +1,6 @@ import { Router } from "express"; -import { ChannelModel, getPermission, MessageDeleteBulkEvent, MessageModel } from "@fosscord/server-util"; +import { ChannelModel, Config, getPermission, MessageDeleteBulkEvent, MessageModel } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; -import Config from "../../../../util/Config"; import { emitEvent } from "../../../../util/Event"; import { check } from "../../../../util/instanceOf"; diff --git a/src/routes/channels/#channel_id/messages/index.ts b/src/routes/channels/#channel_id/messages/index.ts index 7fdff809..cdc46d14 100644 --- a/src/routes/channels/#channel_id/messages/index.ts +++ b/src/routes/channels/#channel_id/messages/index.ts @@ -71,9 +71,11 @@ router.get("/", async (req, res) => { id: { $gt: (BigInt(around) - BigInt(halfLimit)).toString(), $lt: (BigInt(around) + BigInt(halfLimit)).toString() } }); else { - query = MessageModel.find({ channel_id }).sort({ id: -1 }); + query = MessageModel.find({ channel_id }); } + query = query.sort({ id: -1 }); + const messages = await query.limit(limit).exec(); return res.json( diff --git a/src/routes/channels/#channel_id/pins.ts b/src/routes/channels/#channel_id/pins.ts index 9d36b5c1..43c504d8 100644 --- a/src/routes/channels/#channel_id/pins.ts +++ b/src/routes/channels/#channel_id/pins.ts @@ -1,6 +1,13 @@ -import { ChannelModel, ChannelPinsUpdateEvent, getPermission, MessageModel, MessageUpdateEvent, toObject } from "@fosscord/server-util"; +import { + ChannelModel, + ChannelPinsUpdateEvent, + Config, + getPermission, + MessageModel, + MessageUpdateEvent, + toObject +} from "@fosscord/server-util"; import { Router, Request, Response } from "express"; -import Config from "../../../util/Config"; import { HTTPError } from "lambert-server"; import { emitEvent } from "../../../util/Event"; diff --git a/src/routes/gateway.ts b/src/routes/gateway.ts index 5b6a87e7..ffbbe74c 100644 --- a/src/routes/gateway.ts +++ b/src/routes/gateway.ts @@ -1,12 +1,11 @@ +import { Config } from "@fosscord/server-util"; import { Router } from "express"; -import Config from "../util/Config"; const router = Router(); router.get("/", (req, res) => { - const endpoint = Config.getAll()?.gateway?.endpoint; - - res.send({ url: endpoint || "ws://localhost:3002" }); + const { endpoint } = Config.get().gateway; + res.send({ url: endpoint || process.env.GATEWAY || "ws://localhost:3002" }); }); export default router; diff --git a/src/routes/guilds/index.ts b/src/routes/guilds/index.ts index c286ad51..17ade355 100644 --- a/src/routes/guilds/index.ts +++ b/src/routes/guilds/index.ts @@ -1,9 +1,8 @@ import { Router, Request, Response } from "express"; -import { RoleModel, GuildModel, Snowflake, Guild, RoleDocument } from "@fosscord/server-util"; +import { RoleModel, GuildModel, Snowflake, Guild, RoleDocument, Config } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; import { check } from "./../../util/instanceOf"; import { GuildCreateSchema } from "../../schema/Guild"; -import Config from "../../util/Config"; import { getPublicUser } from "../../util/User"; import { addMember } from "../../util/Member"; import { createChannel } from "../../util/Channel"; diff --git a/src/routes/guilds/templates/index.ts b/src/routes/guilds/templates/index.ts index 7e32e94c..f23d4fbe 100644 --- a/src/routes/guilds/templates/index.ts +++ b/src/routes/guilds/templates/index.ts @@ -1,11 +1,10 @@ import { Request, Response, Router } from "express"; const router: Router = Router(); -import { TemplateModel, GuildModel, toObject, UserModel, RoleModel, Snowflake, Guild } from "@fosscord/server-util"; +import { TemplateModel, GuildModel, toObject, UserModel, RoleModel, Snowflake, Guild, Config } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; import { GuildTemplateCreateSchema } from "../../../schema/Guild"; import { getPublicUser } from "../../../util/User"; import { check } from "../../../util/instanceOf"; -import Config from "../../../util/Config"; import { addMember } from "../../../util/Member"; router.get("/:code", async (req: Request, res: Response) => { @@ -37,7 +36,7 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res ...body, ...template.serialized_source_guild, id: guild_id, - owner_id: req.user_id, + owner_id: req.user_id }; const [guild_doc, role] = await Promise.all([ @@ -52,8 +51,8 @@ router.post("/:code", check(GuildTemplateCreateSchema), async (req: Request, res name: "@everyone", permissions: 2251804225n, position: 0, - tags: null, - }).save(), + tags: null + }).save() ]); await addMember(req.user_id, guild_id, { guild: guild_doc }); diff --git a/src/routes/users/@me/delete.ts b/src/routes/users/@me/delete.ts new file mode 100644 index 00000000..ec4cc223 --- /dev/null +++ b/src/routes/users/@me/delete.ts @@ -0,0 +1,30 @@ +import { Router, Request, Response } from "express"; +import { UserModel,UserDocument, toObject } from "@fosscord/server-util"; +import { getPublicUser } from "../../../util/User"; +import { HTTPError } from "lambert-server"; +import { UserUpdateSchema } from "../../../schema/User"; +import { check, FieldErrors, Length } from "../../../util/instanceOf"; +import { db } from "@fosscord/server-util"; +import bcrypt from "bcrypt"; +const router = Router(); + +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.deleteOne({id: req.user_id}).exec() //Yeetus user deletus + + res.sendStatus(204); + } + else{ + res.sendStatus(401); + + } +}); + +export default router; diff --git a/src/routes/users/@me/disable.ts b/src/routes/users/@me/disable.ts new file mode 100644 index 00000000..ab3ce58c --- /dev/null +++ b/src/routes/users/@me/disable.ts @@ -0,0 +1,10 @@ +import { Router } from "express"; + +const router = Router(); + +router.post("/", (req, res) => { + // TODO: + res.sendStatus(204); +}); + +export default router; diff --git a/src/start.ts b/src/start.ts index 8d5c33ce..d799c190 100644 --- a/src/start.ts +++ b/src/start.ts @@ -7,9 +7,9 @@ config(); import { FosscordServer } from "./Server"; import cluster from "cluster"; import os from "os"; -const cores = os.cpus().length; +const cores = Number(process.env.threads) || os.cpus().length; -if (cluster.isMaster && process.env.production == "true") { +if (cluster.isMaster && process.env.NODE_ENV == "production") { console.log(`Primary ${process.pid} is running`); // Fork workers. @@ -22,8 +22,7 @@ if (cluster.isMaster && process.env.production == "true") { cluster.fork(); }); } else { - var port = Number(process.env.PORT); - if (isNaN(port)) port = 3001; + var port = Number(process.env.PORT) || 3001; const server = new FosscordServer({ port }); server.start().catch(console.error); diff --git a/src/util/Config.ts b/src/util/Config.ts index f1f0f458..e2e0d312 100644 --- a/src/util/Config.ts +++ b/src/util/Config.ts @@ -1,19 +1,7 @@ -import { Config, Snowflake } from "@fosscord/server-util"; -import crypto from "crypto"; - -export default { - init() { - return Config.init({ api: DefaultOptions }); - }, - get(): DefaultOptions { - return Config.getAll().api; - }, - set(val: any) { - return Config.setAll({ api: val }); - }, - getAll: Config.getAll, - setAll: Config.setAll, -}; +// @ts-nocheck +import Ajv, { JSONSchemaType } from "ajv"; +import { getConfigPathForFile } from "@fosscord/server-util/dist/util/Config"; +import { Config } from "@fosscord/server-util"; export interface RateLimitOptions { count: number; @@ -21,6 +9,7 @@ export interface RateLimitOptions { } export interface DefaultOptions { + gateway: string; general: { instance_id: string; }; @@ -64,7 +53,7 @@ export interface DefaultOptions { login?: RateLimitOptions; register?: RateLimitOptions; }; - channel?: {}; + channel?: string; // TODO: rate limit configuration for all routes }; }; @@ -84,13 +73,13 @@ export interface DefaultOptions { }; register: { email: { - required: boolean; + necessary: boolean; allowlist: boolean; blocklist: boolean; domains: string[]; }; dateOfBirth: { - required: boolean; + necessary: boolean; minimum: number; // in years }; requireCaptcha: boolean; @@ -107,85 +96,277 @@ export interface DefaultOptions { }; } -export const DefaultOptions: DefaultOptions = { - general: { - instance_id: Snowflake.generate(), - }, - permissions: { - user: { - createGuilds: true, - }, +const schema: JSONSchemaType<DefaultOptions> & { + definitions: { + rateLimitOptions: JSONSchemaType<RateLimitOptions>; + }; +} = { + type: "object", + definitions: { + rateLimitOptions: { + type: "object", + properties: { + count: { type: "number" }, + timespan: { type: "number" } + }, + required: ["count", "timespan"] + } }, - limits: { - user: { - maxGuilds: 100, - maxUsername: 32, - maxFriends: 1000, - }, - guild: { - maxRoles: 250, - maxMembers: 250000, - maxChannels: 500, - maxChannelsInCategory: 50, - hideOfflineMember: 1000, - }, - message: { - characters: 2000, - ttsCharacters: 200, - maxReactions: 20, - maxAttachmentSize: 8388608, - maxBulkDelete: 100, - }, - channel: { - maxPins: 50, - maxTopic: 1024, + properties: { + gateway: { + type: "string" }, - rate: { - ip: { - enabled: true, - count: 1000, - timespan: 1000 * 60 * 10, + general: { + type: "object", + properties: { + instance_id: { + type: "string" + } }, - routes: {}, + required: ["instance_id"], + additionalProperties: false }, - }, - security: { - jwtSecret: crypto.randomBytes(256).toString("base64"), - forwadedFor: null, - // forwadedFor: "X-Forwarded-For" // nginx/reverse proxy - // forwadedFor: "CF-Connecting-IP" // cloudflare: - captcha: { - enabled: false, - service: null, - sitekey: null, - secret: null, + permissions: { + type: "object", + properties: { + user: { + type: "object", + properties: { + createGuilds: { + type: "boolean" + } + }, + required: ["createGuilds"], + additionalProperties: false + } + }, + required: ["user"], + additionalProperties: false }, - }, - login: { - requireCaptcha: false, - }, - register: { - email: { - required: true, - allowlist: false, - blocklist: true, - domains: [], // TODO: efficiently save domain blocklist in database - // domains: fs.readFileSync(__dirname + "/blockedEmailDomains.txt", { encoding: "utf8" }).split("\n"), + limits: { + type: "object", + properties: { + user: { + type: "object", + properties: { + maxFriends: { + type: "number" + }, + maxGuilds: { + type: "number" + }, + maxUsername: { + type: "number" + } + }, + required: ["maxFriends", "maxGuilds", "maxUsername"], + additionalProperties: false + }, + guild: { + type: "object", + properties: { + maxRoles: { + type: "number" + }, + maxMembers: { + type: "number" + }, + maxChannels: { + type: "number" + }, + maxChannelsInCategory: { + type: "number" + }, + hideOfflineMember: { + type: "number" + } + }, + required: ["maxRoles", "maxMembers", "maxChannels", "maxChannelsInCategory", "hideOfflineMember"], + additionalProperties: false + }, + message: { + type: "object", + properties: { + characters: { + type: "number" + }, + ttsCharacters: { + type: "number" + }, + maxReactions: { + type: "number" + }, + maxAttachmentSize: { + type: "number" + }, + maxBulkDelete: { + type: "number" + } + }, + required: ["characters", "ttsCharacters", "maxReactions", "maxAttachmentSize", "maxBulkDelete"], + additionalProperties: false + }, + channel: { + type: "object", + properties: { + maxPins: { + type: "number" + }, + maxTopic: { + type: "number" + } + }, + required: ["maxPins", "maxTopic"], + additionalProperties: false + }, + rate: { + type: "object", + properties: { + ip: { + type: "object", + properties: { + enabled: { type: "boolean" }, + count: { type: "number" }, + timespan: { type: "number" } + }, + required: ["enabled", "count", "timespan"], + additionalProperties: false + }, + routes: { + type: "object", + properties: { + auth: { + type: "object", + properties: { + login: { $ref: "#/definitions/rateLimitOptions" }, + register: { $ref: "#/definitions/rateLimitOptions" } + }, + nullable: true, + required: [], + additionalProperties: false + }, + channel: { + type: "string", + nullable: true + } + }, + required: [], + additionalProperties: false + } + }, + required: ["ip", "routes"] + } + }, + required: ["channel", "guild", "message", "rate", "user"], + additionalProperties: false }, - dateOfBirth: { - required: true, - minimum: 13, + security: { + type: "object", + properties: { + jwtSecret: { + type: "string" + }, + forwadedFor: { + type: "string", + nullable: true + }, + captcha: { + type: "object", + properties: { + enabled: { type: "boolean" }, + service: { + type: "string", + enum: ["hcaptcha", "recaptcha", null], + nullable: true + }, + sitekey: { + type: "string", + nullable: true + }, + secret: { + type: "string", + nullable: true + } + }, + required: ["enabled", "secret", "service", "sitekey"], + additionalProperties: false + } + }, + required: ["captcha", "forwadedFor", "jwtSecret"], + additionalProperties: false }, - requireInvite: false, - requireCaptcha: true, - allowNewRegistration: true, - allowMultipleAccounts: true, - password: { - minLength: 8, - minNumbers: 2, - minUpperCase: 2, - minSymbols: 0, - blockInsecureCommonPasswords: false, + login: { + type: "object", + properties: { + requireCaptcha: { type: "boolean" } + }, + required: ["requireCaptcha"], + additionalProperties: false }, + register: { + type: "object", + properties: { + email: { + type: "object", + properties: { + necessary: { type: "boolean" }, + allowlist: { type: "boolean" }, + blocklist: { type: "boolean" }, + domains: { + type: "array", + items: { + type: "string" + } + } + }, + required: ["allowlist", "blocklist", "domains", "necessary"], + additionalProperties: false + }, + dateOfBirth: { + type: "object", + properties: { + necessary: { type: "boolean" }, + minimum: { type: "number" } + }, + required: ["minimum", "necessary"], + additionalProperties: false + }, + requireCaptcha: { type: "boolean" }, + requireInvite: { type: "boolean" }, + allowNewRegistration: { type: "boolean" }, + allowMultipleAccounts: { type: "boolean" }, + password: { + type: "object", + properties: { + minLength: { type: "number" }, + minNumbers: { type: "number" }, + minUpperCase: { type: "number" }, + minSymbols: { type: "number" }, + blockInsecureCommonPasswords: { type: "boolean" } + }, + required: ["minLength", "minNumbers", "minUpperCase", "minSymbols", "blockInsecureCommonPasswords"], + additionalProperties: false + } + }, + required: [ + "allowMultipleAccounts", + "allowNewRegistration", + "dateOfBirth", + "email", + "password", + "requireCaptcha", + "requireInvite" + ], + additionalProperties: false + } }, + required: ["gateway", "general", "limits", "login", "permissions", "register", "security"], + additionalProperties: false }; + +const ajv = new Ajv(); +const validator = ajv.compile(schema); + +const configPath = getConfigPathForFile("fosscord", "api", ".json"); + +export const apiConfig = new Config<DefaultOptions>({ path: configPath, schemaValidator: validator, schema: schema }); diff --git a/src/util/Member.ts b/src/util/Member.ts index e6df5d2c..7b06720b 100644 --- a/src/util/Member.ts +++ b/src/util/Member.ts @@ -10,11 +10,11 @@ import { RoleModel, toObject, UserModel, - GuildDocument + GuildDocument, + Config } from "@fosscord/server-util"; import { HTTPError } from "lambert-server"; -import Config from "./Config"; import { emitEvent } from "./Event"; import { getPublicUser } from "./User"; diff --git a/src/util/passwordStrength.ts b/src/util/passwordStrength.ts index f6cec9da..cc503843 100644 --- a/src/util/passwordStrength.ts +++ b/src/util/passwordStrength.ts @@ -1,5 +1,5 @@ +import { Config } from "@fosscord/server-util"; import "missing-native-js-functions"; -import Config from "./Config"; const reNUMBER = /[0-9]/g; const reUPPERCASELETTER = /[A-Z]/g; @@ -17,13 +17,7 @@ const blocklist: string[] = []; // TODO: update ones passwordblocklist is stored * Returns: 0 > pw > 1 */ export function check(password: string): number { - const { - minLength, - minNumbers, - minUpperCase, - minSymbols, - blockInsecureCommonPasswords, - } = Config.get().register.password; + const { minLength, minNumbers, minUpperCase, minSymbols } = Config.get().register.password; var strength = 0; // checks for total password len @@ -51,10 +45,5 @@ export function check(password: string): number { strength = 0; } - if (blockInsecureCommonPasswords) { - if (blocklist.includes(password)) { - strength = 0; - } - } return strength; } |