diff --git a/.gitignore b/.gitignore
index 7a08aa7..2eca47b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,8 @@
node_modules
*DS_Store
.env
-cert
diplomas
-templates
+files
logs
*.log
\ No newline at end of file
diff --git a/index.js b/index.js
index f03b33c..cb81a64 100644
--- a/index.js
+++ b/index.js
@@ -2,12 +2,10 @@ require("dotenv").config();
require("module-alias/register");
const { log } = require("@logger");
-const mongo = require("@mongo/mongo");
const server = require("@express/express");
async function start() {
try {
- await mongo.start();
await server.start();
log.info("All systems running. Let's rock!");
} catch (e) {
diff --git a/package-lock.json b/package-lock.json
index 6b14a4c..bbfdc1e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "eduhund_backend",
- "version": "0.4.0",
+ "version": "0.7.3",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "eduhund_backend",
- "version": "0.4.0",
+ "version": "0.7.3",
"license": "ISC",
"dependencies": {
"@log4js-node/slack": "^1.0.0",
@@ -19,8 +19,9 @@
"module-alias": "^2.2.2",
"mongodb": "^4.5.0",
"node-fetch": "^2.6.9",
+ "nodemailer": "^6.9.7",
"pg": "^8.7.3",
- "sharp": "^0.31.3",
+ "sharp": "^0.33.0",
"supertest": "^6.3.3",
"svg-content": "^0.1.1"
},
@@ -1321,6 +1322,446 @@
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
},
+ "node_modules/@emnapi/runtime": {
+ "version": "0.44.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz",
+ "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@img/sharp-darwin-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.0.tgz",
+ "integrity": "sha512-070tEheekI1LJWTGPC9WlQEa5UoKTXzzlORBHMX4TbfUxMiL336YHR8vBEUNsjse0RJCX8dZ4ZXwT595aEF1ug==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-darwin-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.0.tgz",
+ "integrity": "sha512-pu/nvn152F3qbPeUkr+4e9zVvEhD3jhwzF473veQfMPkOYo9aoWXSfdZH/E6F+nYC3qvFjbxbvdDbUtEbghLqw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-darwin-x64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz",
+ "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "macos": ">=11",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz",
+ "integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "macos": ">=10.13",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz",
+ "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.28",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz",
+ "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz",
+ "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.28",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linux-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz",
+ "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz",
+ "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "musl": ">=1.2.2",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz",
+ "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "musl": ">=1.2.2",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.0.tgz",
+ "integrity": "sha512-4horD3wMFd5a0ddbDY8/dXU9CaOgHjEHALAddXgafoR5oWq5s8X61PDgsSeh4Qupsdo6ycfPPSSNBrfVQnwwrg==",
+ "cpu": [
+ "arm"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.28",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.0.tgz",
+ "integrity": "sha512-dcomVSrtgF70SyOr8RCOCQ8XGVThXwe71A1d8MGA+mXEVRJ/J6/TrCbBEJh9ddcEIIsrnrkolaEvYSHqVhswQw==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-arm64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-s390x": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.0.tgz",
+ "integrity": "sha512-TiVJbx38J2rNVfA309ffSOB+3/7wOsZYQEOlKqOUdWD/nqkjNGrX+YQGz7nzcf5oy2lC+d37+w183iNXRZNngQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.28",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-s390x": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-linux-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.0.tgz",
+ "integrity": "sha512-PaZM4Zi7/Ek71WgTdvR+KzTZpBqrQOFcPe7/8ZoPRlTYYRe43k6TWsf4GVH6XKRLMYeSp8J89RfAhBrSP4itNA==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "glibc": ">=2.26",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linux-x64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.0.tgz",
+ "integrity": "sha512-1QLbbN0zt+32eVrg7bb1lwtvEaZwlhEsY1OrijroMkwAqlHqFj6R33Y47s2XUv7P6Ie1PwCxK/uFnNqMnkd5kg==",
+ "cpu": [
+ "arm64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "musl": ">=1.2.2",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-linuxmusl-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.0.tgz",
+ "integrity": "sha512-CecqgB/CnkvCWFhmfN9ZhPGMLXaEBXl4o7WtA6U3Ztrlh/s7FUKX4vNxpMSYLIrWuuzjiaYdfU3+Tdqh1xaHfw==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "musl": ">=1.2.2",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.0"
+ }
+ },
+ "node_modules/@img/sharp-wasm32": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.0.tgz",
+ "integrity": "sha512-Hn4js32gUX9qkISlemZBUPuMs0k/xNJebUNl/L6djnU07B/HAA2KaxRVb3HvbU5fL242hLOcp0+tR+M8dvJUFw==",
+ "cpu": [
+ "wasm32"
+ ],
+ "optional": true,
+ "dependencies": {
+ "@emnapi/runtime": "^0.44.0"
+ },
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-ia32": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.0.tgz",
+ "integrity": "sha512-5HfcsCZi3l5nPRF2q3bllMVMDXBqEWI3Q8KQONfzl0TferFE5lnsIG0A1YrntMAGqvkzdW6y1Ci1A2uTvxhfzg==",
+ "cpu": [
+ "ia32"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
+ "node_modules/@img/sharp-win32-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.0.tgz",
+ "integrity": "sha512-i3DtP/2ce1yKFj4OzOnOYltOEL/+dp4dc4dJXJBv6god1AFTcmkaA99H/7SwOmkCOBQkbVvA3lCGm3/5nDtf9Q==",
+ "cpu": [
+ "x64"
+ ],
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0",
+ "npm": ">=9.6.5",
+ "pnpm": ">=7.1.0",
+ "yarn": ">=3.2.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/libvips"
+ }
+ },
"node_modules/@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -2946,16 +3387,6 @@
}
]
},
- "node_modules/bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "dependencies": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
"node_modules/body-parser": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
@@ -3171,11 +3602,6 @@
"node": ">=10"
}
},
- "node_modules/chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
- },
"node_modules/ci-info": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
@@ -3448,33 +3874,11 @@
"integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==",
"dev": true
},
- "node_modules/decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "dependencies": {
- "mimic-response": "^3.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA=="
},
- "node_modules/deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
- "engines": {
- "node": ">=4.0.0"
- }
- },
"node_modules/deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -3515,9 +3919,9 @@
}
},
"node_modules/detect-libc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
- "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==",
"engines": {
"node": ">=8"
}
@@ -3612,14 +4016,6 @@
"node": ">= 0.8"
}
},
- "node_modules/end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "dependencies": {
- "once": "^1.4.0"
- }
- },
"node_modules/error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -3739,14 +4135,6 @@
"node": ">= 0.8.0"
}
},
- "node_modules/expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/expect": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz",
@@ -3952,11 +4340,6 @@
"node": ">= 0.6"
}
},
- "node_modules/fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
- },
"node_modules/fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -4048,11 +4431,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
- },
"node_modules/glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -4306,11 +4684,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
- },
"node_modules/ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -5440,17 +5813,6 @@
"node": ">=6"
}
},
- "node_modules/mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -5462,19 +5824,6 @@
"node": "*"
}
},
- "node_modules/minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
- "funding": {
- "url": "https://github.com/sponsors/ljharb"
- }
- },
- "node_modules/mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
- },
"node_modules/module-alias": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
@@ -5511,54 +5860,19 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
- "node_modules/napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
- },
- "node_modules/natural-compare": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
- "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
- },
- "node_modules/negotiator": {
- "version": "0.6.3",
- "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
- "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
- "engines": {
- "node": ">= 0.6"
- }
- },
- "node_modules/node-abi": {
- "version": "3.33.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.33.0.tgz",
- "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==",
- "dependencies": {
- "semver": "^7.3.5"
- },
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/node-abi/node_modules/semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "dependencies": {
- "lru-cache": "^6.0.0"
- },
- "bin": {
- "semver": "bin/semver.js"
- },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
+ },
+ "node_modules/negotiator": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
+ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==",
"engines": {
- "node": ">=10"
+ "node": ">= 0.6"
}
},
- "node_modules/node-addon-api": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
- },
"node_modules/node-fetch": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
@@ -5607,6 +5921,14 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
"integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w=="
},
+ "node_modules/nodemailer": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz",
+ "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw==",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -5945,31 +6267,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
- "dependencies": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- },
- "bin": {
- "prebuild-install": "bin.js"
- },
- "engines": {
- "node": ">=10"
- }
- },
"node_modules/prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -6035,15 +6332,6 @@
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true
},
- "node_modules/pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dependencies": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"node_modules/punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -6109,47 +6397,12 @@
"node": ">= 0.8"
}
},
- "node_modules/rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "dependencies": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "bin": {
- "rc": "cli.js"
- }
- },
- "node_modules/rc/node_modules/strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"devOptional": true
},
- "node_modules/readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "dependencies": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -6320,25 +6573,42 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"node_modules/sharp": {
- "version": "0.31.3",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz",
- "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==",
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.0.tgz",
+ "integrity": "sha512-99DZKudjm/Rmz+M0/26t4DKpXyywAOJaayGS9boEn7FvgtG0RYBi46uPE2c+obcJRtA3AZa0QwJot63gJQ1F0Q==",
"hasInstallScript": true,
"dependencies": {
"color": "^4.2.3",
- "detect-libc": "^2.0.1",
- "node-addon-api": "^5.0.0",
- "prebuild-install": "^7.1.1",
- "semver": "^7.3.8",
- "simple-get": "^4.0.1",
- "tar-fs": "^2.1.1",
- "tunnel-agent": "^0.6.0"
+ "detect-libc": "^2.0.2",
+ "semver": "^7.5.4"
},
"engines": {
- "node": ">=14.15.0"
+ "libvips": ">=8.15.0",
+ "node": "^18.17.0 || ^20.3.0 || >=21.0.0"
},
"funding": {
"url": "https://opencollective.com/libvips"
+ },
+ "optionalDependencies": {
+ "@img/sharp-darwin-arm64": "0.33.0",
+ "@img/sharp-darwin-x64": "0.33.0",
+ "@img/sharp-libvips-darwin-arm64": "1.0.0",
+ "@img/sharp-libvips-darwin-x64": "1.0.0",
+ "@img/sharp-libvips-linux-arm": "1.0.0",
+ "@img/sharp-libvips-linux-arm64": "1.0.0",
+ "@img/sharp-libvips-linux-s390x": "1.0.0",
+ "@img/sharp-libvips-linux-x64": "1.0.0",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.0",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.0",
+ "@img/sharp-linux-arm": "0.33.0",
+ "@img/sharp-linux-arm64": "0.33.0",
+ "@img/sharp-linux-s390x": "0.33.0",
+ "@img/sharp-linux-x64": "0.33.0",
+ "@img/sharp-linuxmusl-arm64": "0.33.0",
+ "@img/sharp-linuxmusl-x64": "0.33.0",
+ "@img/sharp-wasm32": "0.33.0",
+ "@img/sharp-win32-ia32": "0.33.0",
+ "@img/sharp-win32-x64": "0.33.0"
}
},
"node_modules/sharp/node_modules/semver": {
@@ -6392,49 +6662,6 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
- "node_modules/simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
"node_modules/simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -6585,14 +6812,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
- "node_modules/string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "dependencies": {
- "safe-buffer": "~5.2.0"
- }
- },
"node_modules/string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -8029,32 +8248,6 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
- "node_modules/tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
- "dependencies": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "node_modules/tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "dependencies": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -8159,17 +8352,6 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"optional": true
},
- "node_modules/tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "dependencies": {
- "safe-buffer": "^5.0.1"
- },
- "engines": {
- "node": "*"
- }
- },
"node_modules/type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -8274,11 +8456,6 @@
"requires-port": "^1.0.0"
}
},
- "node_modules/util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- },
"node_modules/utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
@@ -9597,6 +9774,156 @@
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
},
+ "@emnapi/runtime": {
+ "version": "0.44.0",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz",
+ "integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==",
+ "optional": true,
+ "requires": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "@img/sharp-darwin-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.0.tgz",
+ "integrity": "sha512-070tEheekI1LJWTGPC9WlQEa5UoKTXzzlORBHMX4TbfUxMiL336YHR8vBEUNsjse0RJCX8dZ4ZXwT595aEF1ug==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-darwin-arm64": "1.0.0"
+ }
+ },
+ "@img/sharp-darwin-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.0.tgz",
+ "integrity": "sha512-pu/nvn152F3qbPeUkr+4e9zVvEhD3jhwzF473veQfMPkOYo9aoWXSfdZH/E6F+nYC3qvFjbxbvdDbUtEbghLqw==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-darwin-x64": "1.0.0"
+ }
+ },
+ "@img/sharp-libvips-darwin-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz",
+ "integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==",
+ "optional": true
+ },
+ "@img/sharp-libvips-darwin-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz",
+ "integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linux-arm": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz",
+ "integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linux-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz",
+ "integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linux-s390x": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz",
+ "integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linux-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz",
+ "integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linuxmusl-arm64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz",
+ "integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==",
+ "optional": true
+ },
+ "@img/sharp-libvips-linuxmusl-x64": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz",
+ "integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==",
+ "optional": true
+ },
+ "@img/sharp-linux-arm": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.0.tgz",
+ "integrity": "sha512-4horD3wMFd5a0ddbDY8/dXU9CaOgHjEHALAddXgafoR5oWq5s8X61PDgsSeh4Qupsdo6ycfPPSSNBrfVQnwwrg==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linux-arm": "1.0.0"
+ }
+ },
+ "@img/sharp-linux-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.0.tgz",
+ "integrity": "sha512-dcomVSrtgF70SyOr8RCOCQ8XGVThXwe71A1d8MGA+mXEVRJ/J6/TrCbBEJh9ddcEIIsrnrkolaEvYSHqVhswQw==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linux-arm64": "1.0.0"
+ }
+ },
+ "@img/sharp-linux-s390x": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.0.tgz",
+ "integrity": "sha512-TiVJbx38J2rNVfA309ffSOB+3/7wOsZYQEOlKqOUdWD/nqkjNGrX+YQGz7nzcf5oy2lC+d37+w183iNXRZNngQ==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linux-s390x": "1.0.0"
+ }
+ },
+ "@img/sharp-linux-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.0.tgz",
+ "integrity": "sha512-PaZM4Zi7/Ek71WgTdvR+KzTZpBqrQOFcPe7/8ZoPRlTYYRe43k6TWsf4GVH6XKRLMYeSp8J89RfAhBrSP4itNA==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linux-x64": "1.0.0"
+ }
+ },
+ "@img/sharp-linuxmusl-arm64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.0.tgz",
+ "integrity": "sha512-1QLbbN0zt+32eVrg7bb1lwtvEaZwlhEsY1OrijroMkwAqlHqFj6R33Y47s2XUv7P6Ie1PwCxK/uFnNqMnkd5kg==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.0"
+ }
+ },
+ "@img/sharp-linuxmusl-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.0.tgz",
+ "integrity": "sha512-CecqgB/CnkvCWFhmfN9ZhPGMLXaEBXl4o7WtA6U3Ztrlh/s7FUKX4vNxpMSYLIrWuuzjiaYdfU3+Tdqh1xaHfw==",
+ "optional": true,
+ "requires": {
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.0"
+ }
+ },
+ "@img/sharp-wasm32": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.0.tgz",
+ "integrity": "sha512-Hn4js32gUX9qkISlemZBUPuMs0k/xNJebUNl/L6djnU07B/HAA2KaxRVb3HvbU5fL242hLOcp0+tR+M8dvJUFw==",
+ "optional": true,
+ "requires": {
+ "@emnapi/runtime": "^0.44.0"
+ }
+ },
+ "@img/sharp-win32-ia32": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.0.tgz",
+ "integrity": "sha512-5HfcsCZi3l5nPRF2q3bllMVMDXBqEWI3Q8KQONfzl0TferFE5lnsIG0A1YrntMAGqvkzdW6y1Ci1A2uTvxhfzg==",
+ "optional": true
+ },
+ "@img/sharp-win32-x64": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.0.tgz",
+ "integrity": "sha512-i3DtP/2ce1yKFj4OzOnOYltOEL/+dp4dc4dJXJBv6god1AFTcmkaA99H/7SwOmkCOBQkbVvA3lCGm3/5nDtf9Q==",
+ "optional": true
+ },
"@istanbuljs/load-nyc-config": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz",
@@ -10904,16 +11231,6 @@
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
- "bl": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
- "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
- "requires": {
- "buffer": "^5.5.0",
- "inherits": "^2.0.4",
- "readable-stream": "^3.4.0"
- }
- },
"body-parser": {
"version": "1.20.0",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz",
@@ -11051,11 +11368,6 @@
"resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
"integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw=="
},
- "chownr": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
- "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
- },
"ci-info": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.8.0.tgz",
@@ -11277,24 +11589,11 @@
"integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==",
"dev": true
},
- "decompress-response": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
- "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
- "requires": {
- "mimic-response": "^3.1.0"
- }
- },
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA=="
},
- "deep-extend": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
- "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
- },
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -11322,9 +11621,9 @@
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
},
"detect-libc": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
- "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w=="
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
+ "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="
},
"detect-newline": {
"version": "3.1.0",
@@ -11394,14 +11693,6 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
},
- "end-of-stream": {
- "version": "1.4.4",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
- "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
- "requires": {
- "once": "^1.4.0"
- }
- },
"error-ex": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
@@ -11481,11 +11772,6 @@
"resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
"integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ=="
},
- "expand-template": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
- "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
- },
"expect": {
"version": "27.5.1",
"resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz",
@@ -11647,11 +11933,6 @@
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
},
- "fs-constants": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
- "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
- },
"fs-extra": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
@@ -11714,11 +11995,6 @@
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
},
- "github-from-package": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
- "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
- },
"glob": {
"version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
@@ -11892,11 +12168,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
- "ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
- },
"ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -12759,11 +13030,6 @@
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
},
- "mimic-response": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
- "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
- },
"minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -12772,16 +13038,6 @@
"brace-expansion": "^1.1.7"
}
},
- "minimist": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
- "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
- },
- "mkdirp-classic": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
- "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
- },
"module-alias": {
"version": "2.2.2",
"resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz",
@@ -12813,11 +13069,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
- "napi-build-utils": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
- "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
- },
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -12828,29 +13079,6 @@
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz",
"integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="
},
- "node-abi": {
- "version": "3.33.0",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.33.0.tgz",
- "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==",
- "requires": {
- "semver": "^7.3.5"
- },
- "dependencies": {
- "semver": {
- "version": "7.5.4",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
- "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
- "requires": {
- "lru-cache": "^6.0.0"
- }
- }
- }
- },
- "node-addon-api": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.1.0.tgz",
- "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA=="
- },
"node-fetch": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
@@ -12890,6 +13118,11 @@
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.10.tgz",
"integrity": "sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w=="
},
+ "nodemailer": {
+ "version": "6.9.7",
+ "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.9.7.tgz",
+ "integrity": "sha512-rUtR77ksqex/eZRLmQ21LKVH5nAAsVicAtAYudK7JgwenEDZ0UIQ1adUGqErz7sMkWYxWTTU1aeP2Jga6WQyJw=="
+ },
"normalize-path": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
@@ -13131,25 +13364,6 @@
"xtend": "^4.0.0"
}
},
- "prebuild-install": {
- "version": "7.1.1",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
- "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
- "requires": {
- "detect-libc": "^2.0.0",
- "expand-template": "^2.0.3",
- "github-from-package": "0.0.0",
- "minimist": "^1.2.3",
- "mkdirp-classic": "^0.5.3",
- "napi-build-utils": "^1.0.1",
- "node-abi": "^3.3.0",
- "pump": "^3.0.0",
- "rc": "^1.2.7",
- "simple-get": "^4.0.0",
- "tar-fs": "^2.0.0",
- "tunnel-agent": "^0.6.0"
- }
- },
"prelude-ls": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
@@ -13199,15 +13413,6 @@
"integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==",
"dev": true
},
- "pump": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
- "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
- }
- },
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -13248,40 +13453,12 @@
"unpipe": "1.0.0"
}
},
- "rc": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
- "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
- "requires": {
- "deep-extend": "^0.6.0",
- "ini": "~1.3.0",
- "minimist": "^1.2.0",
- "strip-json-comments": "~2.0.1"
- },
- "dependencies": {
- "strip-json-comments": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
- "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="
- }
- }
- },
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
"devOptional": true
},
- "readable-stream": {
- "version": "3.6.2",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
- "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
- "requires": {
- "inherits": "^2.0.3",
- "string_decoder": "^1.1.1",
- "util-deprecate": "^1.0.1"
- }
- },
"require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -13404,18 +13581,32 @@
"integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="
},
"sharp": {
- "version": "0.31.3",
- "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.31.3.tgz",
- "integrity": "sha512-XcR4+FCLBFKw1bdB+GEhnUNXNXvnt0tDo4WsBsraKymuo/IAuPuCBVAL2wIkUw2r/dwFW5Q5+g66Kwl2dgDFVg==",
- "requires": {
+ "version": "0.33.0",
+ "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.0.tgz",
+ "integrity": "sha512-99DZKudjm/Rmz+M0/26t4DKpXyywAOJaayGS9boEn7FvgtG0RYBi46uPE2c+obcJRtA3AZa0QwJot63gJQ1F0Q==",
+ "requires": {
+ "@img/sharp-darwin-arm64": "0.33.0",
+ "@img/sharp-darwin-x64": "0.33.0",
+ "@img/sharp-libvips-darwin-arm64": "1.0.0",
+ "@img/sharp-libvips-darwin-x64": "1.0.0",
+ "@img/sharp-libvips-linux-arm": "1.0.0",
+ "@img/sharp-libvips-linux-arm64": "1.0.0",
+ "@img/sharp-libvips-linux-s390x": "1.0.0",
+ "@img/sharp-libvips-linux-x64": "1.0.0",
+ "@img/sharp-libvips-linuxmusl-arm64": "1.0.0",
+ "@img/sharp-libvips-linuxmusl-x64": "1.0.0",
+ "@img/sharp-linux-arm": "0.33.0",
+ "@img/sharp-linux-arm64": "0.33.0",
+ "@img/sharp-linux-s390x": "0.33.0",
+ "@img/sharp-linux-x64": "0.33.0",
+ "@img/sharp-linuxmusl-arm64": "0.33.0",
+ "@img/sharp-linuxmusl-x64": "0.33.0",
+ "@img/sharp-wasm32": "0.33.0",
+ "@img/sharp-win32-ia32": "0.33.0",
+ "@img/sharp-win32-x64": "0.33.0",
"color": "^4.2.3",
- "detect-libc": "^2.0.1",
- "node-addon-api": "^5.0.0",
- "prebuild-install": "^7.1.1",
- "semver": "^7.3.8",
- "simple-get": "^4.0.1",
- "tar-fs": "^2.1.1",
- "tunnel-agent": "^0.6.0"
+ "detect-libc": "^2.0.2",
+ "semver": "^7.5.4"
},
"dependencies": {
"semver": {
@@ -13456,21 +13647,6 @@
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
- "simple-concat": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
- "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
- },
- "simple-get": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
- "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
- "requires": {
- "decompress-response": "^6.0.0",
- "once": "^1.3.1",
- "simple-concat": "^1.0.0"
- }
- },
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -13590,14 +13766,6 @@
}
}
},
- "string_decoder": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
- "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
- "requires": {
- "safe-buffer": "~5.2.0"
- }
- },
"string-length": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz",
@@ -14747,29 +14915,6 @@
"integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==",
"dev": true
},
- "tar-fs": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
- "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
- "requires": {
- "chownr": "^1.1.1",
- "mkdirp-classic": "^0.5.2",
- "pump": "^3.0.0",
- "tar-stream": "^2.1.4"
- }
- },
- "tar-stream": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
- "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
- "requires": {
- "bl": "^4.0.3",
- "end-of-stream": "^1.4.1",
- "fs-constants": "^1.0.0",
- "inherits": "^2.0.3",
- "readable-stream": "^3.1.1"
- }
- },
"terminal-link": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
@@ -14850,14 +14995,6 @@
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"optional": true
},
- "tunnel-agent": {
- "version": "0.6.0",
- "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
- "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
- "requires": {
- "safe-buffer": "^5.0.1"
- }
- },
"type-check": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
@@ -14925,11 +15062,6 @@
"requires-port": "^1.0.0"
}
},
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="
- },
"utils-merge": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
diff --git a/package.json b/package.json
index a2456da..c0bddcf 100644
--- a/package.json
+++ b/package.json
@@ -20,8 +20,9 @@
"module-alias": "^2.2.2",
"mongodb": "^4.5.0",
"node-fetch": "^2.6.9",
+ "nodemailer": "^6.9.7",
"pg": "^8.7.3",
- "sharp": "^0.31.3",
+ "sharp": "^0.33.0",
"supertest": "^6.3.3",
"svg-content": "^0.1.1"
},
diff --git a/src/API/student/addComment/addComment.js b/src/API/student/addComment/addComment.js
deleted file mode 100644
index c95295d..0000000
--- a/src/API/student/addComment/addComment.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const { checkModuleAccess, pushComment, getUserInfo } = require("@processes");
-
-/***
- * addComment StudentAPI method.
- * https://api.eduhund.com/docs/student#addComment
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Comments list on success; undefined on fail
- */
-async function addComment(req, res, next) {
- try {
- const { data } = req;
-
- await getUserInfo(data, next);
-
- if (!checkModuleAccess(data)) {
- next({ code: 10202 });
- return;
- }
-
- const content = await pushComment(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20209, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = addComment;
diff --git a/src/API/student/auth/auth.js b/src/API/student/auth/auth.js
deleted file mode 100644
index bc035d3..0000000
--- a/src/API/student/auth/auth.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const {
- getUserInfo,
- checkCredentials,
- authUser,
- prepareUserData,
-} = require("@processes");
-
-/***
- * auth StudentAPI method.
- * https://api.eduhund.com/docs/student#auth
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} User data on success; undefined on fail
- */
-async function auth(req, res, next) {
- try {
- const { data } = req;
-
- const userExists = await getUserInfo(data, next);
- if (!userExists) return;
-
- const credentialsValid = checkCredentials(data, next);
- if (!credentialsValid) return;
-
- await authUser(data);
-
- const content = prepareUserData(data);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20201, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = auth;
diff --git a/src/API/student/checkPayment/checkPayment.js b/src/API/student/checkPayment/checkPayment.js
deleted file mode 100644
index bd361e3..0000000
--- a/src/API/student/checkPayment/checkPayment.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const { getUserInfo, checkTransaction, authUser } = require("@processes");
-
-/***
- * checkPayment StudentAPI method.
- * https://api.eduhund.com/docs/student#checkPayment
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} User data on success; undefined on fail
- */
-async function checkPayment(req, res, next) {
- try {
- const { data } = req;
-
- const transactionIsValid = await checkTransaction(data, next);
- if (!transactionIsValid) return;
-
- const userExists = await getUserInfo(data, next);
- if (!userExists) return;
-
- const content = await authUser(data);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20203, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = checkPayment;
diff --git a/src/API/student/createPass/createPass.js b/src/API/student/createPass/createPass.js
deleted file mode 100644
index 2000d22..0000000
--- a/src/API/student/createPass/createPass.js
+++ /dev/null
@@ -1,35 +0,0 @@
-const { checkOTK, updatePass, authUser } = require("@processes");
-
-/***
- * createPass StudentAPI method.
- * https://api.eduhund.com/docs/student#createPass
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} User data on success; undefined on fail
- */
-async function createPass(req, res, next) {
- try {
- const { data } = req;
-
- const OTKIsValid = await checkOTK(data, next);
- if (!OTKIsValid) return;
-
- await updatePass(data, next);
-
- const content = await authUser(data);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20202, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = createPass;
diff --git a/src/API/student/getCertificate/getCertificate.js b/src/API/student/getCertificate/getCertificate.js
deleted file mode 100644
index d7aeb42..0000000
--- a/src/API/student/getCertificate/getCertificate.js
+++ /dev/null
@@ -1,46 +0,0 @@
-const {
- checkFinalAccess,
- getModuleInfo,
- getStateInfo,
- prepareCertificateData,
- getUserInfo,
-} = require("@processes");
-
-/***
- * getDiploma StudentAPI method.
- * https://api.eduhund.com/docs/student#getDiploma
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Certificate data on success; undefined on fail
- */
-async function getCertificate(req, res, next) {
- try {
- const { data } = req;
-
- const dataPromises = [getUserInfo(data), getModuleInfo(data)];
- const [userData, moduleData] = await Promise.all(dataPromises);
- if (!checkFinalAccess(data)) {
- next({ code: 10201 });
- return;
- }
- if (!(userData && moduleData)) return;
-
- await getStateInfo(data, next);
-
- const content = await prepareCertificateData(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20210, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getCertificate;
diff --git a/src/API/student/getCommentsList/getCommentsList.js b/src/API/student/getCommentsList/getCommentsList.js
deleted file mode 100644
index efa5bdd..0000000
--- a/src/API/student/getCommentsList/getCommentsList.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const {
- checkModuleAccess,
- getUserInfo,
- getTaskInfo,
- getStateInfo,
- prapareTaskData,
-} = require("@processes");
-
-/***
- * getCommentsList StudentAPI method.
- * https://api.eduhund.com/docs/student#getCommentsList
- *
- * Canary
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Task data on success; undefined on fail
- */
-async function getCommentsList(req, res, next) {
- try {
- const { data } = req;
-
- await getUserInfo(data, next);
-
- if (!checkModuleAccess(data)) {
- next({ code: 10201 });
- return;
- }
-
- const state = await getStateInfo(data, next);
- console.log(data.user);
- const content = { comments: state.comments || [] };
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20212, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getCommentsList;
diff --git a/src/API/student/getCounselor/getCounselor.js b/src/API/student/getCounselor/getCounselor.js
deleted file mode 100644
index 29b9528..0000000
--- a/src/API/student/getCounselor/getCounselor.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const { getCounselorInfo } = require("@processes");
-
-/***
- * getCounselor StudentAPI method.
- * https://api.eduhund.com/docs/student#getCounselor
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Counselor data on success; undefined on fail
- */
-async function getCounselor(req, res, next) {
- try {
- const { data } = req;
-
- const content = await getCounselorInfo(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20211, trace: e };
- next(err);
- }
-}
-
-module.exports = getCounselor;
diff --git a/src/API/student/getLesson/getLesson.js b/src/API/student/getLesson/getLesson.js
deleted file mode 100644
index 45f0772..0000000
--- a/src/API/student/getLesson/getLesson.js
+++ /dev/null
@@ -1,48 +0,0 @@
-const {
- checkModuleAccess,
- getUserInfo,
- getLessonInfo,
- getStateInfo,
- prepareLessonData,
-} = require("@processes");
-
-/***
- * getLesson StudentAPI method.
- * https://api.eduhund.com/docs/student#getLesson
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Lesson data on success; undefined on fail
- */
-async function getLesson(req, res, next) {
- try {
- const { data } = req;
-
- const lessonData = await getLessonInfo(data, next);
- if (!lessonData) return;
-
- await getUserInfo(data, next);
-
- if (!checkModuleAccess(data)) {
- next({ code: 10201 });
- return;
- }
-
- await getStateInfo(data, next);
-
- const content = await prepareLessonData(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20206, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getLesson;
diff --git a/src/API/student/getMe/getMe.js b/src/API/student/getMe/getMe.js
deleted file mode 100644
index bbaf9d3..0000000
--- a/src/API/student/getMe/getMe.js
+++ /dev/null
@@ -1,33 +0,0 @@
-const { getUserInfo, prepareUserData } = require("@processes");
-
-/***
- * getMe StudentAPI method.
- * https://api.eduhund.com/docs/student#getMe
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} User data on success; undefined on fail
- */
-async function getMe(req, res, next) {
- try {
- const { data } = req;
-
- const userExists = await getUserInfo(data, next);
- if (!userExists) return;
-
- const content = prepareUserData(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20204, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getMe;
diff --git a/src/API/student/getModule/getModule.js b/src/API/student/getModule/getModule.js
deleted file mode 100644
index 8b2c45c..0000000
--- a/src/API/student/getModule/getModule.js
+++ /dev/null
@@ -1,49 +0,0 @@
-const {
- checkFinalAccess,
- getUserInfo,
- getModuleInfo,
- getStateInfo,
- prepareModuleData,
-} = require("@processes");
-
-/***
- * getModule StudentAPI method.
- * https://api.eduhund.com/docs/student#getModule
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Module data on success; undefined on fail
- */
-async function getModule(req, res, next) {
- try {
- const { data } = req;
-
- const moduleData = await getModuleInfo(data, next);
- if (!moduleData) return;
-
- if (data.isAuth) {
- await getUserInfo(data, next);
- }
-
- const isUserAccess = checkFinalAccess(data, next);
-
- if (isUserAccess) {
- await getStateInfo(data, next);
- }
-
- const content = await prepareModuleData(data, next);
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20205, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getModule;
diff --git a/src/API/student/getModulesList/getModulesList.js b/src/API/student/getModulesList/getModulesList.js
deleted file mode 100644
index 3c38903..0000000
--- a/src/API/student/getModulesList/getModulesList.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const {
- checkFinalAccess,
- getUserInfo,
- getModuleInfo,
- getStateInfo,
- prepareModuleData,
-} = require("@processes");
-
-/***
- * getModulesList StudentAPI method.
- * https://api.eduhund.com/docs/student#getModulesList
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Module data on success; undefined on fail
- */
-async function getModulesList(req, res, next) {
- try {
- const { data } = req;
-
- const modulesList = await getModuleInfo(data, next);
-
- if (data.isAuth) {
- await getUserInfo(data, next);
- }
-
- const content = [];
-
- for (const moduleData of modulesList) {
- data.module = moduleData;
-
- const isUserAccess = checkFinalAccess(data, next);
-
- if (isUserAccess) {
- await getStateInfo(data, next);
- }
-
- content.push(await prepareModuleData(data, next));
- }
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20213, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getModulesList;
diff --git a/src/API/student/getTask/getTask.js b/src/API/student/getTask/getTask.js
deleted file mode 100644
index 94ad98d..0000000
--- a/src/API/student/getTask/getTask.js
+++ /dev/null
@@ -1,50 +0,0 @@
-const {
- checkModuleAccess,
- getUserInfo,
- getTaskInfo,
- getStateInfo,
- prapareTaskData,
-} = require("@processes");
-
-/***
- * getTask StudentAPI method.
- * https://api.eduhund.com/docs/student#getTask
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Task data on success; undefined on fail
- */
-async function getTask(req, res, next) {
- try {
- const { data } = req;
-
- await getUserInfo(data, next);
-
- if (!checkModuleAccess(data)) {
- next({ code: 10201 });
- return;
- }
-
- const taskData = await getTaskInfo(data, next);
- if (!taskData) return;
-
- let content = taskData;
- if (taskData.type === "practice") {
- await getStateInfo(data, next);
- content = await prapareTaskData(data, next);
- }
-
- next({ code: 0, content });
- return content;
- } catch (e) {
- const err = { code: 20207, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = getTask;
diff --git a/src/API/student/setState/setState.js b/src/API/student/setState/setState.js
deleted file mode 100644
index 6e8c2bb..0000000
--- a/src/API/student/setState/setState.js
+++ /dev/null
@@ -1,85 +0,0 @@
-const {
- checkModuleAccess,
- getUserInfo,
- getTaskInfo,
- getStateInfo,
- setTaskState,
- updateDependenciesTasks,
-} = require("@processes");
-const DB = require("@mongo/requests");
-
-/***
- * setState StudentAPI method.
- * https://api.eduhund.com/docs/student#setState
- *
- * @since 0.6.0
- *
- * @param {Object} req Express request object
- * @param {Object} res Express response object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} New task's state on success; undefined on fail
- */
-async function setState(req, res, next) {
- try {
- const { data } = req;
-
- await getUserInfo(data);
-
- if (!checkModuleAccess(data)) {
- next({ code: 10201 });
- return;
- }
-
- for (const [key, value] of Object.entries(data.newState)) {
- if (/[A-Za-z]{3}\d{8}/.test(key)) {
- const path = "data." + key + ".state";
- data.newState[path] = value;
- delete data.newState[key];
-
- const tasks = await DB.getMany("tasks", {
- query: {
- "content.questions.depends.parentId": { $regex: questionId },
- "content.questions.depends.type": "visibility",
- },
- returns: ["id", "content"],
- });
-
- await updateDependenciesTasks(data.userId, key, tasks, value);
- }
- }
-
- const taskData = await getTaskInfo(data, next);
- if (!taskData) return;
-
- const taskState = await getStateInfo(data, next);
- if (!taskState) {
- data.newState.inProcess = true;
- }
-
- if (data.newState.protest) {
- data.newState.score = taskData?.maxScore;
- data.newState.isChecked = true;
- } else {
- if (data.newState.isChecked) {
- data.newState.score = taskState?.data
- ? calculateScore(stateData?.data, taskData)
- : calculateDefaultScore(taskData?.content);
- } else {
- data.newState.score = 0;
- }
- }
-
- const newState = await setTaskState(data, next);
- delete newState.comments;
-
- next({ code: 0, content: newState });
- return newState;
- } catch (e) {
- const err = { code: 20208, trace: e };
- next(err);
- return;
- }
-}
-
-module.exports = setState;
diff --git a/src/API/student/student.js b/src/API/student/student.js
deleted file mode 100644
index e7a2a1c..0000000
--- a/src/API/student/student.js
+++ /dev/null
@@ -1,106 +0,0 @@
-const auth = require("./auth/auth");
-const checkPayment = require("./checkPayment/checkPayment");
-const createPass = require("./createPass/createPass");
-const getMe = require("./getMe/getMe");
-const getModule = require("./getModule/getModule");
-const getLesson = require("./getLesson/getLesson");
-const getTask = require("./getTask/getTask");
-const setState = require("./setState/setState");
-const addComment = require("./addComment/addComment");
-const getCommentsList = require("./getCommentsList/getCommentsList");
-const getCertificate = require("./getCertificate/getCertificate");
-const getCounselor = require("./getCounselor/getCounselor");
-const getModulesList = require("./getModulesList/getModulesList");
-
-const STUDENT = [
- {
- name: "auth",
- type: "post",
- requiredParams: ["email", "pass"],
- otherParams: ["lang"],
- exec: auth,
- },
- {
- name: "checkPayment",
- type: "get",
- requiredParams: ["paymentId"],
- exec: checkPayment,
- },
- {
- name: "createPass",
- type: "post",
- requiredParams: ["email", "pass", "key"],
- otherParams: ["lang"],
- exec: [createPass],
- },
- {
- name: "getMe",
- type: "get",
- wall: true,
- exec: getMe,
- },
- {
- name: "getModule",
- type: "get",
- wall: true,
- requiredParams: ["moduleId"],
- exec: [getModule],
- },
- {
- name: "getLesson",
- type: "get",
- wall: true,
- requiredParams: ["lessonId"],
- exec: [getLesson],
- },
- {
- name: "getTask",
- type: "get",
- wall: true,
- requiredParams: ["taskId"],
- exec: [getTask],
- },
- {
- name: "setState",
- type: "post",
- wall: true,
- requiredParams: ["taskId", "newState"],
- exec: [setState],
- },
- {
- name: "addComment",
- type: "post",
- wall: true,
- requiredParams: ["taskId", "comment"],
- exec: [addComment],
- },
- {
- name: "getCommentsList",
- type: "get",
- wall: true,
- requiredParams: ["taskId"],
- exec: [getCommentsList],
- },
- {
- name: "getCertificate",
- type: "get",
- wall: true,
- requiredParams: ["moduleId"],
- otherParams: ["isColor", "isMascot", "isResult", "isPublic"],
- exec: [getCertificate],
- },
- {
- name: "getCounselor",
- type: "get",
- requiredParams: ["lang"],
- exec: [getCounselor],
- },
- {
- name: "getModulesList",
- type: "get",
- wall: true,
- exec: [getModulesList],
- },
-];
-
-module.exports = { STUDENT };
diff --git a/src/assets/colors.json b/src/assets/colors.json
index 04c0278..fae6283 100644
--- a/src/assets/colors.json
+++ b/src/assets/colors.json
@@ -5,5 +5,5 @@
"COM": { "primary": "#6B70E2" },
"UCC": { "primary": "#295A12" },
"HSE": { "primary": "#0C356C" },
- "LGR": { "primary": "#0C356C" }
+ "LGR": { "primary": "#12C1C1" }
}
diff --git a/src/assets/lang/dicts/en.json b/src/assets/lang/dicts/en.json
index 1052ae0..5e83128 100644
--- a/src/assets/lang/dicts/en.json
+++ b/src/assets/lang/dicts/en.json
@@ -8,6 +8,6 @@
"certCheck2": "write to",
"certSignName": "Olga Pavlova",
"certSignPos": "head of insanity",
- "certSignNameLinor": "Linor Goralik",
- "certSignPosLinor": "автор смысла"
+ "certSignNameLinor": "Based on a lecture by Linor Goralik",
+ "certSignPosLinor": "recognized foreign agent"
}
diff --git a/src/assets/lang/dicts/ru.json b/src/assets/lang/dicts/ru.json
index b168a26..7d66ebd 100644
--- a/src/assets/lang/dicts/ru.json
+++ b/src/assets/lang/dicts/ru.json
@@ -8,6 +8,6 @@
"certCheck2": "напишите на",
"certSignName": "Olga Pavlova",
"certSignPos": "рквдтль безумия",
- "certSignNameLinor": "Linor Goralik",
- "certSignPosLinor": "автор смысла"
+ "certSignNameLinor": "По лекции Линор Горалик",
+ "certSignPosLinor": "признанный иностранный агент"
}
diff --git a/src/modules/apiRequests/addComment/addComment.js b/src/modules/apiRequests/addComment/addComment.js
index e3f2b93..92b1386 100644
--- a/src/modules/apiRequests/addComment/addComment.js
+++ b/src/modules/apiRequests/addComment/addComment.js
@@ -1,10 +1,11 @@
const { log } = require("@logger");
+
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
+const { sendMessage } = require("../../../services/assistant/assistant");
-async function addComment({ req, res }) {
- const userId = req?.userId;
+async function addComment(req, res) {
+ const { userId } = req;
const { taskId, comment, protest } = req.body;
const query = { userId, taskId };
@@ -15,31 +16,43 @@ async function addComment({ req, res }) {
readedByTeacher: false,
};
- try {
- await getDBRequest("setComment", {
- query,
- data: update,
- protest,
- returns: [],
- });
- const data = generateMessage(0, update);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${taskId}: Error with processing new comment`);
- log.warn(e);
- const error = generateMessage(20115);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "addComment",
- data: { taskId, comment, protest },
- req,
- });
+ await getDBRequest("setComment", {
+ query,
+ data: update,
+ protest,
+ returns: [],
+ });
+
+ const data = generateMessage(0, update);
+ res.status(200).send(data);
+
+ const {email, firstName, lastName} = await getDBRequest("getUserInfo", {
+ query: { id: userId },
+ returns: ["email", "firstName", "lastName"],
+ })
+
+ const { name } = await getDBRequest("getTaskInfo", {
+ query: { id: taskId },
+ returns: ["name"]
+ })
+
+ const messageData = {
+ type: "taskComment",
+ data: {
+ email,
+ firstName,
+ lastName,
+ taskId: taskId,
+ taskName: name
+ },
+ text: comment
}
+
+ sendMessage(messageData)
+
+ log.info(`New comment from user ${userId}: ${comment}`);
+
+ return;
}
-module.exports.addComment = addComment;
+module.exports = addComment;
diff --git a/src/modules/apiRequests/apiRequests.js b/src/modules/apiRequests/apiRequests.js
index a3fa885..1baf769 100644
--- a/src/modules/apiRequests/apiRequests.js
+++ b/src/modules/apiRequests/apiRequests.js
@@ -1,23 +1,33 @@
const { log } = require("@logger");
-const { auth } = require("./auth/auth");
-const { checkPayment } = require("./checkPayment/checkPayment");
-const { createPassword } = require("./createPassword/createPassword");
-const { getTask } = require("./getTask/getTask");
-const { checkTask } = require("./checkTask/checkTask");
-const { setState } = require("./setState/setState");
-const { setControls } = require("./setControls/setControls");
-const { getDashboard } = require("./getDashboard/getDashboard");
-const { getModuleStart } = require("./getModuleStart/getModuleStart");
-const { getModuleFinal } = require("./getModuleFinal/getModuleFinal");
-const { getLessonStart } = require("./getLessonStart/getLessonStart");
-const { getLessonFinal } = require("./getLessonFinal/getLessonFinal");
-const { getDiploma } = require("./getDiploma/getDiploma");
-const { getModuleInfo } = require("./getModuleInfo/getModuleInfo");
-const { getLessonsList } = require("./getLessonsList/getLessonsList");
-const { getTasksList } = require("./getTasksList/getTasksList");
-const { addComment } = require("./addComment/addComment");
-const { getCounselor } = require("./getCounselor/getCounselor");
+const auth = require("./auth/auth");
+const checkPayment = require("./checkPayment/checkPayment");
+const createPassword = require("./createPassword/createPassword");
+const getTask = require("./getTask/getTask");
+const checkTask = require("./checkTask/checkTask");
+const setState = require("./setState/setState");
+const setControls = require("./setControls/setControls");
+const getDashboard = require("./getDashboard/getDashboard");
+const getModuleStart = require("./getModuleStart/getModuleStart");
+const getModuleFinal = require("./getModuleFinal/getModuleFinal");
+const getLessonStart = require("./getLessonStart/getLessonStart");
+const getLessonFinal = require("./getLessonFinal/getLessonFinal");
+const getDiploma = require("./getDiploma/getDiploma");
+const getModuleInfo = require("./getModuleInfo/getModuleInfo");
+const getLessonsList = require("./getLessonsList/getLessonsList");
+const getTasksList = require("./getTasksList/getTasksList");
+const addComment = require("./addComment/addComment");
+const getCounselor = require("./getCounselor/getCounselor");
+
+
+const resetPassword = require("./resetPassword/resetPassword");
+const createUser = require("./createUser/createUser");
+const updateUser = require("./updateUser/updateUser");
+const getStudentsList = require("./getStudentsList/getStudentsList");
+const getModulesList = require("./getModulesList/getModulesList");
+const changeCommentStatus = require("./changeCommentStatus/changeCommentStatus");
+const getCommentsList = require("./getCommentsList/getCommentsList");
+const newPayment = require("./newPayment/newPayment");
const {
checkAuth,
@@ -44,6 +54,14 @@ const REQUESTS = {
getTasksList,
addComment,
getCounselor,
+ resetPassword,
+ createUser,
+ updateUser,
+ getStudentsList,
+ getModulesList,
+ changeCommentStatus,
+ getCommentsList,
+ newPayment,
};
const PUBLIC = [
@@ -218,14 +236,67 @@ const PUBLIC = [
},
];
+const TEACHER = [
+ {
+ name: "createUser",
+ method: "post",
+ path: "/createUser",
+ exec: [(req, res) => getApiRequest("createUser", { req, res })],
+ },
+ {
+ name: "resetPassword",
+ method: "post",
+ path: "/resetPassword",
+ exec: [(req, res) => getApiRequest("resetPassword", { req, res })],
+ },
+ {
+ name: "updateUser",
+ method: "post",
+ path: "/updateUser",
+ exec: [(req, res) => getApiRequest("updateUser", { req, res })],
+ },
+ {
+ name: "getStudentsList",
+ method: "get",
+ path: "/getStudentsList",
+ exec: [(req, res) => getApiRequest("getStudentsList", { req, res })],
+ },
+ {
+ name: "getModulesList",
+ method: "get",
+ path: "/getModulesList",
+ exec: [(req, res) => getApiRequest("getModulesList", { req, res })],
+ },
+ {
+ name: "getCommentsList",
+ method: "get",
+ path: "/getCommentsList",
+ exec: [(req, res) => getApiRequest("getCommentsList", { req, res })],
+ },
+ {
+ name: "changeCommentStatus",
+ method: "post",
+ path: "/changeCommentStatus",
+ exec: [(req, res) => getApiRequest("changeCommentStatus", { req, res })],
+ },
+ {
+ name: "newPayment",
+ method: "post",
+ path: "/newPayment",
+ exec: [(req, res) => getApiRequest("newPayment", { req, res })],
+ },
+]
+
async function getApiRequest(type, { req, res, next }) {
try {
- return REQUESTS[type]({ req, res, next });
+ return REQUESTS[type](req, res, next);
} catch (e) {
- log.warn(`Error in API method: ${type}.`, e);
+ log.error(`Error in API method: ${type}.`);
+ log.debug(req.userId, req.query, req.body);
+ log.debug(e);
res.sendStatus(500);
return;
}
}
-module.exports = { PUBLIC, getApiRequest };
+module.exports = { PUBLIC, TEACHER, getApiRequest };
diff --git a/src/modules/apiRequests/auth/auth.js b/src/modules/apiRequests/auth/auth.js
index b6d078c..b3d040d 100644
--- a/src/modules/apiRequests/auth/auth.js
+++ b/src/modules/apiRequests/auth/auth.js
@@ -1,13 +1,12 @@
const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
-const accessTokens = require("../../../services/tokenMachine/tokenMachine");
const { checkPass } = require("../../../utils/pass");
const { generateMessage } = require("../../../utils/messageGenerator");
-const tokens = accessTokens;
+const tokens = require("../../../services/tokenMachine/tokenMachine");
-async function auth({ req, res }) {
+async function auth(req, res) {
const { email, pass, lang } = req.body;
const user = await getDBRequest("getUserInfo", {
@@ -15,24 +14,22 @@ async function auth({ req, res }) {
});
if (!user) {
- log.info(`${email}: User didn't found!`);
+ log.warn(`${email}: User didn't found!`);
const error = generateMessage(10101);
res.status(401).send(error);
return error;
}
if (!checkPass(user, pass)) {
- log.info(`${email}: Invalid password!`);
+ log.warn(`${email}: Invalid password!`);
const error = generateMessage(10102);
res.status(401).send(error);
return error;
}
const userToken = tokens.setToken(user);
- lang &&
- lang !== user.lang &&
- getDBRequest("setUserInfo", { email, data: { lang } });
- log.info(`${user.id}: Auth success!`);
+ lang && lang !== user.lang && getDBRequest("setUserInfo", { email, data: { lang } });
+
const userData = {
id: user.id,
email: user.email,
@@ -41,11 +38,13 @@ async function auth({ req, res }) {
lang: lang || user.lang,
token: userToken,
};
- const data = generateMessage(0, userData);
+ const data = generateMessage(0, userData);
res.status(200).send(data);
- return data;
+ log.info(`${user.id}: Auth success!`);
+
+ return
}
-module.exports.auth = auth;
+module.exports = auth;
diff --git a/src/modules/apiRequests/changeCommentStatus/changeCommentStatus.js b/src/modules/apiRequests/changeCommentStatus/changeCommentStatus.js
new file mode 100644
index 0000000..ee77704
--- /dev/null
+++ b/src/modules/apiRequests/changeCommentStatus/changeCommentStatus.js
@@ -0,0 +1,25 @@
+const { log } = require("../../../services/logger/logger");
+const { STATE } = require("../../dbRequests/mongo");
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function changeCommentStatus(req, res) {
+
+ const {userId, taskId, status = false} = req.body
+
+ await STATE.findOneAndUpdate(
+ { userId, taskId },
+ {
+ $set: {
+ "comments.0.readedByTeacher": status,
+ },
+ },
+ { upsert: true, returnDocument: "after", returnNewDocument: true }
+ );
+
+ const data = generateMessage(0);
+ res.status(200).send(data);
+
+ return
+}
+
+module.exports = changeCommentStatus;
diff --git a/src/modules/apiRequests/checkPayment/checkPayment.js b/src/modules/apiRequests/checkPayment/checkPayment.js
index 8fe7df3..7a71edd 100644
--- a/src/modules/apiRequests/checkPayment/checkPayment.js
+++ b/src/modules/apiRequests/checkPayment/checkPayment.js
@@ -4,7 +4,7 @@ const { getDBRequest } = require("../../dbRequests/dbRequests");
const accessTokens = require("../../../services/tokenMachine/tokenMachine");
const { generateMessage } = require("../../../utils/messageGenerator");
-async function checkPayment({ req, res }) {
+async function checkPayment(req, res) {
const { paymentId } = req.body;
const payment = await getDBRequest("getPaymentInfo", {
@@ -12,10 +12,10 @@ async function checkPayment({ req, res }) {
});
if (!payment) {
- log.info(`${paymentId}: Payment didn't found!`);
+ log.warn(`${paymentId}: Payment didn't found!`);
const error = generateMessage(10104);
res.status(401).send(error);
- return error;
+ return;
}
const user = await getDBRequest("getUserInfo", {
@@ -24,23 +24,25 @@ async function checkPayment({ req, res }) {
});
if (!user) {
- log.info(`${payment.email}: User didn't found!`);
+ log.warn(`${payment.email}: User didn't found!`);
const error = generateMessage(10101);
res.status(401).send(error);
- return error;
+ return;
}
const userToken = accessTokens.setToken(user);
- log.info(`${user.id}: Auth success!`);
+
const userData = {
...user,
token: userToken,
};
+
const data = generateMessage(0, userData);
-
res.status(200).send(data);
- return data;
+ log.info(`${user.id}: Auth success!`);
+
+ return;
}
-module.exports = { checkPayment };
+module.exports = checkPayment;
diff --git a/src/modules/apiRequests/checkTask/checkTask.js b/src/modules/apiRequests/checkTask/checkTask.js
index d9be817..119999e 100644
--- a/src/modules/apiRequests/checkTask/checkTask.js
+++ b/src/modules/apiRequests/checkTask/checkTask.js
@@ -7,9 +7,8 @@ const {
calculateDefaultScore,
} = require("../../../utils/calculators");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function checkTask({ req, res }) {
+async function checkTask(req, res) {
const userId = req?.userId;
const { taskId, isChecked, protest } = req.body;
@@ -23,43 +22,30 @@ async function checkTask({ req, res }) {
];
let score = 0;
- try {
- const [taskData, stateData] = await Promise.all(requests);
-
- if (isChecked) {
- if (protest) {
- score = taskData?.maxScore;
- } else if (!stateData?.data) {
- score = calculateDefaultScore(taskData?.content);
- } else {
- score = calculateScore(stateData?.data, taskData);
- }
+ const [taskData, stateData] = await Promise.all(requests);
+
+ if (isChecked) {
+ if (protest) {
+ score = taskData?.maxScore;
+ } else if (!stateData?.data) {
+ score = calculateDefaultScore(taskData?.content);
+ } else {
+ score = calculateScore(stateData?.data, taskData);
}
+ }
- const query = { userId, taskId };
- getDBRequest("setState", {
- query,
- state: { score, isChecked, protest },
- returns: ["score"],
- });
- const data = generateMessage(0, { score });
+ const query = { userId, taskId };
- res.status(200).send(data);
+ getDBRequest("setState", {
+ query,
+ state: { score, isChecked, protest },
+ returns: ["score"],
+ });
- return data;
- } catch (e) {
- log.warn(`${taskId}: Error while task was checking`);
- log.warn(e);
- const error = generateMessage(20105);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "checkTask",
- data: { taskId, isChecked, protest, score },
- req,
- });
- }
+ const data = generateMessage(0, { score });
+ res.status(200).send(data);
+
+ return;
}
-module.exports.checkTask = checkTask;
+module.exports = checkTask;
diff --git a/src/modules/apiRequests/createPassword/createPassword.js b/src/modules/apiRequests/createPassword/createPassword.js
index daaf018..8aeff2d 100644
--- a/src/modules/apiRequests/createPassword/createPassword.js
+++ b/src/modules/apiRequests/createPassword/createPassword.js
@@ -4,14 +4,14 @@ const { getDBRequest } = require("../../dbRequests/dbRequests");
const { checkKey } = require("../../../services/tokenMachine/OTK");
const { generateMessage } = require("../../../utils/messageGenerator");
-async function createPassword({ req, res, next }) {
+async function createPassword(req, res, next) {
const { email, pass, key, lang } = req.body;
const verify = await checkKey(key);
if (!verify) {
const error = generateMessage(10105);
res.status(401).send(error);
- return error;
+ return ;
}
const data = { pass };
@@ -28,10 +28,13 @@ async function createPassword({ req, res, next }) {
if (!user) {
const error = generateMessage(20101);
res.status(401).send(error);
- return error;
+ return ;
}
+ log.info(`New password was setted for user ${email}!`);
+
next();
+ return
}
-module.exports = { createPassword };
+module.exports = createPassword;
diff --git a/src/modules/apiRequests/createUser/createUser.js b/src/modules/apiRequests/createUser/createUser.js
new file mode 100644
index 0000000..2e10976
--- /dev/null
+++ b/src/modules/apiRequests/createUser/createUser.js
@@ -0,0 +1,79 @@
+const { log } = require("../../../services/logger/logger");
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { setKey } = require("../../../services/tokenMachine/OTK")
+const { lowerString } = require("../../../utils/stringProcessor")
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function createUser(req, res) {
+ const { email, pass, firstName, lastName, modules, startDate, deadline, lang } = req.body
+
+ if (!email) {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "missing_parameters",
+ error_description: "Missing required parameters",
+ error_code: 10008,
+ });
+ return
+ }
+ const userEmail = lowerString(email);
+
+ const isUserExist = await getDBRequest("checkUsername", {
+ email: userEmail,
+ });
+
+ if (isUserExist) {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "user_already_exist",
+ error_description: "User with this email is already exist",
+ error_code: 10008,
+ });
+
+ return
+ }
+
+ const userModules = {};
+ (modules || []).forEach((userModule) => {
+ //const date = new Date(Date.now());
+ userModules[userModule.id] = {
+ start: startDate, // date.toISOString().split("T")[0],
+ deadline, //calculateDeadline(date, 80),
+ };
+ });
+ const newUser = {
+ email: userEmail,
+ pass: pass ? hashPass(pass) : "",
+ firstName,
+ lastName,
+ modules: userModules,
+ lang,
+ };
+ const createdUser = await getDBRequest("addUser", newUser);
+
+ const sendData = {
+ OK: true,
+ data: {
+ id: createdUser.id,
+ email: createdUser.email,
+ firstName: createdUser.firstName,
+ lastName: createdUser.lastName,
+ },
+ };
+
+ if (!createdUser.pass) {
+ const secureKey = await setKey(createdUser.id, "oneTimeKey");
+ sendData.data.key = secureKey;
+ }
+
+ const data = generateMessage(0, sendData);
+ res.status(200).send(data);
+
+ log.info(`New user was created:`, createdUser);
+
+ return
+};
+
+module.exports = createUser;
diff --git a/src/modules/apiRequests/getCommentsList/getCommentsList.js b/src/modules/apiRequests/getCommentsList/getCommentsList.js
new file mode 100644
index 0000000..3acb9c7
--- /dev/null
+++ b/src/modules/apiRequests/getCommentsList/getCommentsList.js
@@ -0,0 +1,53 @@
+const { log } = require("../../../services/logger/logger");
+const { USERS, TASKS, STATE } = require("../../dbRequests/mongo");
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function getCommentsList(req, res) {
+ const stateArray = await STATE.find(
+ { "comments.0": { $exists: true } },
+ {
+ projection: {
+ _id: 0,
+ data: 0,
+ },
+ }
+ ).toArray();
+
+ const commentList = [];
+ for (const item of stateArray) {
+ if (typeof item.comments[0] !== "string") {
+ const userName = await USERS.findOne({ id: item.userId }).then(
+ (result) => {
+ return result.firstName + " " + result?.lastName;
+ }
+ );
+ const taskInfo = await TASKS.findOne({ id: item.taskId }).then(
+ (result) => {
+ return {
+ module: result?.module,
+ lesson: result?.lesson,
+ task: result?.name,
+ };
+ }
+ );
+
+ commentList.unshift({
+ userId: item.userId,
+ userName,
+ module: taskInfo.module,
+ lesson: taskInfo.lesson,
+ task: taskInfo.task,
+ taskId: item.taskId,
+ message: item.comments[0]?.message,
+ readedByTeacher: item?.comments[0]?.readedByTeacher || false,
+ });
+ }
+ }
+
+ const data = generateMessage(0, commentList);
+ res.status(200).send(data);
+
+ return
+}
+
+module.exports = getCommentsList;
diff --git a/src/modules/apiRequests/getCounselor/getCounselor.js b/src/modules/apiRequests/getCounselor/getCounselor.js
index a10c379..53d9a64 100644
--- a/src/modules/apiRequests/getCounselor/getCounselor.js
+++ b/src/modules/apiRequests/getCounselor/getCounselor.js
@@ -1,33 +1,23 @@
const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getCounselor({ req, res }) {
+async function getCounselor(req, res) {
const userId = req?.userId;
const { lang = "en" } = req?.query;
- try {
+
const response = await getDBRequest("getCounselor", { query: { lang } });
- if (response) {
- const data = generateMessage(0, response?.pages);
- res.status(200).send(data);
- return data;
- } else {
+ if (!response) {
throw new Error("Selected language is not exist");
}
- } catch (e) {
- log.warn(`${userId}: Error with getting counselor content`);
- log.warn(e);
- const error = generateMessage(20105);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getCounselor",
- data: { userId },
- req,
- });
- }
+
+ const data = generateMessage(0, response.pages);
+ res.status(200).send(data);
+
+ log.info(`User ${userId} is watching the counselor`);
+
+ return;
+
}
-module.exports.getCounselor = getCounselor;
+module.exports = getCounselor;
diff --git a/src/modules/apiRequests/getDashboard/getDashboard.js b/src/modules/apiRequests/getDashboard/getDashboard.js
index 919e3fd..4253118 100644
--- a/src/modules/apiRequests/getDashboard/getDashboard.js
+++ b/src/modules/apiRequests/getDashboard/getDashboard.js
@@ -3,143 +3,124 @@ const { getDBRequest } = require("../../dbRequests/dbRequests");
const {
calculateTotalScore,
- calculateDeadline,
} = require("../../../utils/calculators");
const { getNextTaskId } = require("../../../utils/getNextTaskId");
const setLessonsState = require("../../../utils/setLessonsState");
const { getNumberOfDoneTasks } = require("./getNumberOfDoneTasks");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-const DEMO = process.env.DEMO;
+const { MACHINE } = process.env;
-async function getDashboard({ req, res }) {
+async function getDashboard(req, res) {
const userId = req?.userId;
- try {
- const userData = await getDBRequest("getUserInfo", {
- query: { id: userId },
- });
-
- const username = `${userData?.firstName} ${userData?.lastName}`;
- const email = userData?.email;
- const lang = userData?.lang;
- const userModules = userData?.modules;
-
- let modulesList = await getDBRequest("getModulesList", {
- query: {
- ...(DEMO ? {} : { active: true }),
- lang,
- },
- });
-
- modulesList.forEach((module) => {
- module.status = "available";
-
- delete module.intro;
- delete module.final;
- });
-
- const availableModules = [];
-
- for (const moduleId of Object.keys(userModules)) {
- const moduleData = modulesList.find((item) => item.code == moduleId);
- if (!moduleData) continue;
- const today = Date.now();
- const startDate = Date.parse(userModules[moduleId].start);
- const deadline = Date.parse(calculateDeadline(userModules[moduleId]));
- const UTCMidnight = new Date(deadline);
- UTCMidnight.setUTCHours(23, 59, 59, 0);
- const UTCDeadline = Date.parse(UTCMidnight);
-
- moduleData.startDate = userModules[moduleId].start;
- moduleData.deadline = calculateDeadline(userModules[moduleId]);
-
- if (moduleData.prevModule) {
- if (Object.keys(userModules).includes(moduleData.prevModule)) {
- module.status = "unavailable";
- }
- }
+ const { email, lang, modules, firstName, lastName } = await getDBRequest("getUserInfo", {
+ query: { id: userId },
+ });
- if (today < startDate) {
- moduleData.status = "paid";
- } else if (today > UTCDeadline) {
- moduleData.status = "past";
- } else if (today > UTCDeadline - 864000000 && today < UTCDeadline) {
- moduleData.status = "deadline";
- } else {
- moduleData.status = "active";
- }
+ const username = `${firstName} ${lastName}`;
- if (
- moduleData.status == "active" ||
- moduleData.status == "deadline" ||
- moduleData.status == "past"
- ) {
- const moduleState = await getDBRequest("getUserState", {
- query: {
- userId,
- taskId: { $regex: `^${moduleId}` },
- },
- });
-
- const nextTaskId = getNextTaskId(moduleData, moduleState);
-
- moduleData.doneTasks = getNumberOfDoneTasks(moduleState);
-
- moduleData.lessons = setLessonsState(moduleData.lessons, nextTaskId);
-
- moduleData.totalScore = calculateTotalScore(moduleState);
-
- moduleData.nextTask = await getDBRequest("getTaskInfo", {
- query: { id: nextTaskId },
- }).then((result) => {
- let nextTask;
- if (result) {
- nextTask = {
- id: nextTaskId,
- type: result?.type,
- name: result?.name,
- lesson: result?.lesson,
- };
- }
- return nextTask;
- });
-
- moduleData.moduleId = moduleId;
-
- availableModules.push(moduleData);
-
- modulesList = modulesList.filter((module) => module.code !== moduleId);
+ let modulesList = await getDBRequest("getModulesList", {
+ query: {
+ ...(MACHINE === "prod" ? { active: true } : {}),
+ lang,
+ },
+ });
+
+ modulesList.forEach((module) => {
+ module.status = "available";
+
+ delete module.intro;
+ delete module.final;
+ });
+
+ const availableModules = [];
+
+ for (const moduleId of Object.keys(modules)) {
+ const moduleData = modulesList.find((item) => item.code == moduleId);
+ if (!moduleData) continue;
+ const today = Date.now();
+ const startDate = Date.parse(modules[moduleId].start);
+ const deadline = Date.parse(modules[moduleId].deadline);
+ const UTCMidnight = new Date(deadline);
+ UTCMidnight.setUTCHours(23, 59, 59, 0);
+ const UTCDeadline = Date.parse(UTCMidnight);
+
+ moduleData.startDate = modules[moduleId].start;
+ moduleData.deadline = modules[moduleId].deadline;
+
+ if (moduleData.prevModule) {
+ if (Object.keys(modules).includes(moduleData.prevModule)) {
+ module.status = "unavailable";
}
}
- availableModules.push(...modulesList);
+ if (today < startDate) {
+ moduleData.status = "paid";
+ } else if (today > UTCDeadline) {
+ moduleData.status = "past";
+ } else if (today > UTCDeadline - 864000000 && today < UTCDeadline) {
+ moduleData.status = "deadline";
+ } else {
+ moduleData.status = "active";
+ }
- const finalData = {
- username,
- email,
- lang,
- modules: availableModules,
- };
- const data = generateMessage(0, finalData);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${userId}: Error with processing dashboard page`);
- log.warn(e);
- const error = generateMessage(20107);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getDashboard",
- data: { userId },
- req,
- });
+ if (
+ moduleData.status == "active" ||
+ moduleData.status == "deadline" ||
+ moduleData.status == "past"
+ ) {
+ const moduleState = await getDBRequest("getUserState", {
+ query: {
+ userId,
+ taskId: { $regex: `^${moduleId}` },
+ },
+ });
+
+ const nextTaskId = getNextTaskId(moduleData, moduleState);
+
+ moduleData.doneTasks = getNumberOfDoneTasks(moduleState);
+
+ moduleData.lessons = setLessonsState(moduleData.lessons, nextTaskId);
+
+ moduleData.totalScore = calculateTotalScore(moduleState);
+
+ moduleData.nextTask = await getDBRequest("getTaskInfo", {
+ query: { id: nextTaskId },
+ }).then((result) => {
+ let nextTask;
+ if (result) {
+ nextTask = {
+ id: nextTaskId,
+ type: result?.type,
+ name: result?.name,
+ lesson: result?.lesson,
+ };
+ }
+ return nextTask;
+ });
+
+ moduleData.moduleId = moduleId;
+
+ availableModules.push(moduleData);
+
+ modulesList = modulesList.filter((module) => module.code !== moduleId);
+ }
}
+
+ availableModules.push(...modulesList);
+
+ const finalData = {
+ username,
+ email,
+ lang,
+ modules: availableModules,
+ };
+
+ const data = generateMessage(0, finalData);
+ res.status(200).send(data);
+
+ return;
}
-module.exports.getDashboard = getDashboard;
+module.exports = getDashboard;
diff --git a/src/modules/apiRequests/getDiploma/getDiploma.js b/src/modules/apiRequests/getDiploma/getDiploma.js
index b422432..da5f264 100644
--- a/src/modules/apiRequests/getDiploma/getDiploma.js
+++ b/src/modules/apiRequests/getDiploma/getDiploma.js
@@ -1,9 +1,8 @@
const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateSkills } = require("./generateSkills");
-const generateCertId = require("../../../processes/prepareData/prepareCertificateData/generateCertId");
+const generateCertId = require("../../../utils/generateCertId");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
const provideData = require("./provideData");
const CyrillicToTranslit = require("cyrillic-to-translit-js");
const { fork } = require("child_process");
@@ -22,9 +21,7 @@ async function generateCert(fullInfo) {
});
}
-async function getDiploma({ req, res }) {
- //const certGen = fork(__dirname + "/../../../utils/certGenerator");
-
+async function getDiploma(req, res) {
const userId = req?.userId;
const { moduleId, lang, isColor, isMascot, isProgress, isPublic } =
req?.query;
@@ -66,127 +63,114 @@ async function getDiploma({ req, res }) {
}),
];
- try {
- const [userData, stateData, moduleData] = await Promise.all(requests);
+ const [userData, stateData, moduleData] = await Promise.all(requests);
- const start = userData?.modules?.[moduleId]?.deadline;
- const deadline = userData?.modules?.[moduleId]?.deadline;
- const now = new Date(Date.now()).toISOString().split("T")[0];
- const certDate = Date.parse(deadline) < Date.parse(now) ? deadline : now;
+ const start = userData?.modules?.[moduleId]?.deadline;
+ const deadline = userData?.modules?.[moduleId]?.deadline;
+ const now = new Date(Date.now()).toISOString().split("T")[0];
+ const certDate = Date.parse(deadline) < Date.parse(now) ? deadline : now;
- const certId =
- userData?.modules?.[moduleId]?.certId ||
- (await generateCertId(userId, moduleId, start));
+ const certId =
+ userData?.modules?.[moduleId]?.certId ||
+ (await generateCertId(userId, moduleId, start));
- const certData = await getDBRequest("getDiploma", {
- query: { id: certId },
- returns: ["lang", "isColor", "isMascot", "isProgress", "isPublic"],
- });
+ const certData = await getDBRequest("getDiploma", {
+ query: { id: certId },
+ returns: ["lang", "isColor", "isMascot", "isProgress", "isPublic"],
+ });
- if (params.lang === undefined) params.lang = certData?.lang || moduleData.lang;
- if (params.isColor === undefined) params.isColor = certData?.isColor || false;
- if (params.isMascot === undefined) params.isMascot = certData.isMascot === undefined ? true : certData?.isMascot;
- if (params.isProgress === undefined) params.isProgress = certData.isProgress === undefined ? true : certData?.isProgress;
- if (params.isPublic === undefined) params.isPublic = certData?.isPublic || false;
+ if (params.lang === undefined) params.lang = certData?.lang || moduleData.lang;
+ if (params.isColor === undefined) params.isColor = certData?.isColor || false;
+ if (params.isMascot === undefined) params.isMascot = certData?.isMascot === undefined ? true : certData?.isMascot;
+ if (params.isProgress === undefined) params.isProgress = certData?.isProgress === undefined ? true : certData?.isProgress;
+ if (params.isPublic === undefined) params.isPublic = certData?.isPublic || false;
- getDBRequest("setDiploma", {
- query: { id: certId },
- data: params,
- returns: ["lang", "isColor", "isMascot", "isProgress", "isPublic"],
- });
+ getDBRequest("setDiploma", {
+ query: { id: certId },
+ data: params,
+ returns: ["lang", "isColor", "isMascot", "isProgress", "isPublic"],
+ });
- const firstName =
- params.lang === "ru"
- ? userData.firstName
- : cyrillicToTranslit.transform(userData.firstName);
- const lastName =
- params.lang === "ru"
- ? userData.lastName
- : cyrillicToTranslit.transform(userData.lastName);
-
- const score = stateData.reduce(
- (progress, value) => progress + (value?.score || 0),
- 0
- );
-
- let maxScore = 0;
- for (const lesson of Object.values(moduleData?.lessons)) {
- for (const task of lesson.tasks) {
- const taskData = await getDBRequest("getTaskInfo", {
- query: {
- id: task,
- type: "practice",
- },
- returns: ["maxScore"],
- });
- maxScore += taskData?.maxScore || 0;
- }
+ const firstName =
+ params.lang === "ru"
+ ? userData.firstName
+ : cyrillicToTranslit.transform(userData.firstName);
+ const lastName =
+ params.lang === "ru"
+ ? userData.lastName
+ : cyrillicToTranslit.transform(userData.lastName);
+
+ const score = stateData.reduce(
+ (progress, value) => progress + (value?.score || 0),
+ 0
+ );
+
+ let maxScore = 0;
+ for (const lesson of Object.values(moduleData?.lessons)) {
+ for (const task of lesson.tasks) {
+ const taskData = await getDBRequest("getTaskInfo", {
+ query: {
+ id: task,
+ type: "practice",
+ },
+ returns: ["maxScore"],
+ });
+ maxScore += taskData?.maxScore || 0;
}
-
- const doneTasks = stateData.reduce((progress, value) => {
- if (value.isChecked) {
- return progress + 1;
- } else return progress;
- }, 0);
-
- const progress = Math.trunc((score / maxScore) * 100);
-
- const skills = await generateSkills(
- moduleId,
- userId,
- params.lang || moduleData.lang
- );
-
- const info = {
- moduleId,
- moduleName: moduleData?.name,
- firstName,
- lastName,
- certId,
- certDate,
- progress,
- skills,
- };
-
- const fullInfo = provideData(info, params);
-
- const fileId = await generateCert(fullInfo);
-
- Object.assign(moduleData, params);
-
- moduleData.firstName = firstName;
- moduleData.lastName = lastName;
- moduleData.start = start;
- moduleData.deadline = deadline;
- moduleData.certDate = certDate;
- moduleData.certId = certId;
- moduleData.score = score;
- moduleData.maxScore = maxScore;
- moduleData.skills = skills;
- moduleData.fileId = fileId;
-
- delete moduleData.lessons;
-
- moduleData.doneTasks = doneTasks;
-
- const data = generateMessage(0, moduleData);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing diploma`);
- log.warn(e);
- const error = generateMessage(20111);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getDiploma",
- data: { moduleId },
- req,
- });
}
+
+ const doneTasks = stateData.reduce((progress, value) => {
+ if (value.isChecked) {
+ return progress + 1;
+ } else return progress;
+ }, 0);
+
+ const progress = Math.trunc((score / maxScore) * 100);
+
+ const skills = await generateSkills(
+ moduleId,
+ userId,
+ params.lang || moduleData.lang
+ );
+
+ const info = {
+ moduleId,
+ moduleName: moduleData?.name,
+ firstName,
+ lastName,
+ certId,
+ certDate,
+ progress,
+ skills,
+ };
+
+ const fullInfo = provideData(info, params);
+
+ const fileId = await generateCert(fullInfo);
+
+ Object.assign(moduleData, params);
+
+ moduleData.firstName = firstName;
+ moduleData.lastName = lastName;
+ moduleData.start = start;
+ moduleData.deadline = deadline;
+ moduleData.certDate = certDate;
+ moduleData.certId = certId;
+ moduleData.score = score;
+ moduleData.maxScore = maxScore;
+ moduleData.skills = skills;
+ moduleData.fileId = fileId;
+
+ delete moduleData.lessons;
+
+ moduleData.doneTasks = doneTasks;
+
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
+
+ log.info(`${userId} created a certificate for module ${moduleId}:`, fileId, params);
+
+ return;
}
-module.exports.getDiploma = getDiploma;
+module.exports = getDiploma;
diff --git a/src/modules/apiRequests/getDiploma/moduleNameHyphenate.js b/src/modules/apiRequests/getDiploma/moduleNameHyphenate.js
index f48cfcd..bac8d18 100644
--- a/src/modules/apiRequests/getDiploma/moduleNameHyphenate.js
+++ b/src/modules/apiRequests/getDiploma/moduleNameHyphenate.js
@@ -6,7 +6,7 @@ const dict = {
UCC: "Сценарии\nвзаимодействия",
COM: "Композиция\nв дизайне интерфейсов",
HSE: "Hard Skills начинающего\nруководителя",
- LGR: "Низкобюджетный\nмаркетинг. Рассылки",
+ LGR: "Рассылки,\nкоторые читают",
},
en: {
HSB: "Novice Manager\nHard Skills",
@@ -15,7 +15,7 @@ const dict = {
UCC: "Use cases\nin Interface Design",
COM: "Composition\nin Interface Design",
HSE: "Hard Skills\nfor Managers",
- LGR: "Низкобюджетный\nмаркетинг. Рассылки",
+ LGR: "Readable maillist",
},
};
diff --git a/src/modules/apiRequests/getDiploma/skillsDict.js b/src/modules/apiRequests/getDiploma/skillsDict.js
index 574be58..0f4ba91 100644
--- a/src/modules/apiRequests/getDiploma/skillsDict.js
+++ b/src/modules/apiRequests/getDiploma/skillsDict.js
@@ -2838,7 +2838,7 @@ const en = {
],
LGR: [
{
- name: "рассылки для людей",
+ name: "Newsletters for people",
tasks: [
"LGR0102",
"LGR0207",
@@ -2850,7 +2850,7 @@ const en = {
],
},
{
- name: "воронка в email-маркетинге",
+ name: "Email marketing funnels",
tasks: [
"LGR0104",
"LGR0105",
@@ -2866,7 +2866,7 @@ const en = {
],
},
{
- name: "письмо как баннер",
+ name: "The letter as a banner",
tasks: [
"LGR0113",
"LGR0309",
@@ -2882,7 +2882,7 @@ const en = {
],
},
{
- name: "техника изменения повода",
+ name: "Letters’ occasion techniques",
tasks: [
"LGR0202",
"LGR0203",
@@ -2894,11 +2894,11 @@ const en = {
],
},
{
- name: "проектирование содержания",
+ name: "Content design",
tasks: ["LGR0302", "LGR0303", "LGR0304", "LGR0305", "LGR0306", "LGR0308"],
},
{
- name: "упрощение чтения письма",
+ name: "Making letter reading easier",
tasks: ["LGR0402", "LGR0403", "LGR0404", "LGR0405", "LGR0406", "LGR0408"],
},
],
diff --git a/src/modules/apiRequests/getLessonFinal/getLessonFinal.js b/src/modules/apiRequests/getLessonFinal/getLessonFinal.js
index 61eda03..3cb39c5 100644
--- a/src/modules/apiRequests/getLessonFinal/getLessonFinal.js
+++ b/src/modules/apiRequests/getLessonFinal/getLessonFinal.js
@@ -4,10 +4,8 @@ const { getDBRequest } = require("../../dbRequests/dbRequests");
const { getModuleId, getLessonId } = require("../../../utils/idExtractor");
const { createSummary } = require("./createSummary");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-const { calculateDeadline } = require("../../../utils/calculators");
-async function getLessonFinal({ req, res }) {
+async function getLessonFinal(req, res) {
const userId = req?.userId;
const fullLessonId = req?.query?.lessonId;
@@ -31,63 +29,48 @@ async function getLessonFinal({ req, res }) {
}),
];
- try {
- const [userData, stateData, moduleData] = await Promise.all(requests);
-
- const lessonsArray = Object.keys(moduleData.lessons || {});
- const currentLessonIndex = lessonsArray.indexOf(lessonId);
-
- moduleData.lessonNumber = Number(lessonId);
- moduleData.nextLesson = lessonsArray.length > currentLessonIndex + 1;
- moduleData.maxScore = moduleData.lessons[lessonId]?.maxScore;
- moduleData.content = moduleData.lessons[lessonId]?.final;
-
- let totalPractice = 0;
- for (const task of moduleData.lessons[lessonId]?.tasks) {
- await getDBRequest("getTaskInfo", {
- query: { id: task },
- returns: ["type"],
- }).then((result) => {
- if (result?.type == "practice") totalPractice++;
- });
- }
- moduleData.totalTasks = totalPractice;
-
- moduleData.deadline = calculateDeadline(userData?.modules?.[moduleId]);
-
- moduleData.score = stateData.reduce(
- (progress, value) => progress + (value?.score || 0),
- 0
- );
-
- moduleData.summary = createSummary(moduleData?.score, moduleData?.maxScore);
-
- moduleData.doneTasks = stateData.reduce((progress, value) => {
- if (value.isChecked) {
- return progress + 1;
- } else return progress;
- }, 0);
-
- delete moduleData.lessons;
-
- const data = generateMessage(0, moduleData);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing lesson final page`);
- log.warn(e);
- const error = generateMessage(20106);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getLessonFinal",
- data: { moduleId },
- req,
+ const [userData, stateData, moduleData] = await Promise.all(requests);
+
+ const lessonsArray = Object.keys(moduleData.lessons || {});
+ const currentLessonIndex = lessonsArray.indexOf(lessonId);
+
+ moduleData.lessonNumber = Number(lessonId);
+ moduleData.nextLesson = lessonsArray.length > currentLessonIndex + 1;
+ moduleData.maxScore = moduleData.lessons[lessonId]?.maxScore;
+ moduleData.content = moduleData.lessons[lessonId]?.final;
+
+ let totalPractice = 0;
+ for (const task of moduleData.lessons[lessonId]?.tasks) {
+ await getDBRequest("getTaskInfo", {
+ query: { id: task },
+ returns: ["type"],
+ }).then((result) => {
+ if (result?.type == "practice") totalPractice++;
});
}
+ moduleData.totalTasks = totalPractice;
+
+ moduleData.deadline = userData?.modules?.[moduleId].deadline;
+
+ moduleData.score = stateData.reduce(
+ (progress, value) => progress + (value?.score || 0),
+ 0
+ );
+
+ moduleData.summary = createSummary(moduleData?.score, moduleData?.maxScore);
+
+ moduleData.doneTasks = stateData.reduce((progress, value) => {
+ if (value.isChecked) {
+ return progress + 1;
+ } else return progress;
+ }, 0);
+
+ delete moduleData.lessons;
+
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
+
+ return;
}
-module.exports.getLessonFinal = getLessonFinal;
+module.exports = getLessonFinal;
diff --git a/src/modules/apiRequests/getLessonStart/getLessonStart.js b/src/modules/apiRequests/getLessonStart/getLessonStart.js
index be78468..7b938e7 100644
--- a/src/modules/apiRequests/getLessonStart/getLessonStart.js
+++ b/src/modules/apiRequests/getLessonStart/getLessonStart.js
@@ -2,9 +2,8 @@ const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { getModuleId, getLessonId } = require("../../../utils/idExtractor");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getLessonStart({ req, res }) {
+async function getLessonStart(req, res) {
const userId = req.userId;
const fullLessonId = req.query.lessonId;
@@ -22,35 +21,20 @@ async function getLessonStart({ req, res }) {
}),
];
- try {
- const [userData, moduleData] = await Promise.all(requests);
-
- moduleData.lessonNumber = Number(lessonId);
- moduleData.lessonName = moduleData.lessons[lessonId]?.title;
- moduleData.description = moduleData.lessons[lessonId]?.description;
- moduleData.intro = moduleData.lessons[lessonId]?.intro;
- moduleData.deadline = userData?.modules?.[moduleId]?.deadline;
-
- delete moduleData.lessons;
-
- const data = generateMessage(0, moduleData);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing lesson start page`);
- log.warn(e);
- const error = generateMessage(20105);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getLessonStart",
- data: { moduleId },
- req,
- });
- }
+ const [userData, moduleData] = await Promise.all(requests);
+
+ moduleData.lessonNumber = Number(lessonId);
+ moduleData.lessonName = moduleData.lessons[lessonId]?.title;
+ moduleData.description = moduleData.lessons[lessonId]?.description;
+ moduleData.intro = moduleData.lessons[lessonId]?.intro;
+ moduleData.deadline = userData?.modules?.[moduleId]?.deadline;
+
+ delete moduleData.lessons;
+
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
+
+ return;
}
-module.exports.getLessonStart = getLessonStart;
+module.exports = getLessonStart;
diff --git a/src/modules/apiRequests/getLessonsList/getLessonsList.js b/src/modules/apiRequests/getLessonsList/getLessonsList.js
index 96d4b1f..46a145f 100644
--- a/src/modules/apiRequests/getLessonsList/getLessonsList.js
+++ b/src/modules/apiRequests/getLessonsList/getLessonsList.js
@@ -1,9 +1,8 @@
const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getLessonsList({ req, res }) {
+async function getLessonsList(req, res) {
const userId = req?.userId;
const moduleId = req?.query?.moduleId;
@@ -12,68 +11,53 @@ async function getLessonsList({ req, res }) {
returns: ["lessons"],
});
- try {
- const lessonList = [];
+ const lessonList = [];
- for (const lesson of Object.entries(moduleData?.lessons || {})) {
- const [lessonId, lessonData] = lesson;
- const lessonStateData = await getDBRequest("getUserState", {
- query: {
- userId,
- taskId: { $regex: `^${moduleId}${lessonId}` },
- },
- });
- var inProcess = false;
- const progress =
- lessonStateData.length === 0
- ? 0
- : Math.trunc(
- (lessonStateData.reduce((progress, value) => {
- if (value.inProcess && !inProcess) inProcess = true;
- return progress + (value.score || 0);
- }, 0) /
- lessonData?.maxScore) *
- 100
- );
-
- lessonList.push({
- id: lessonId,
- title: lessonData.title,
- description: lessonData.description,
- maxScore: lessonData.maxScore,
- inProcess,
- progress,
- });
- }
-
- if (lessonList.length > 0) {
- let currentLesson = 0;
- lessonList.forEach((lesson, index) => {
- if (lesson.inProcess) {
- currentLesson = index;
- }
- });
- lessonList[currentLesson].currentLesson = true;
- }
-
- const data = generateMessage(0, lessonList);
-
- res.status(200).send(data);
+ for (const lesson of Object.entries(moduleData?.lessons || {})) {
+ const [lessonId, lessonData] = lesson;
+ const lessonStateData = await getDBRequest("getUserState", {
+ query: {
+ userId,
+ taskId: { $regex: `^${moduleId}${lessonId}` },
+ },
+ });
+ var inProcess = false;
+ const progress =
+ lessonStateData.length === 0
+ ? 0
+ : Math.trunc(
+ (lessonStateData.reduce((progress, value) => {
+ if (value.inProcess && !inProcess) inProcess = true;
+ return progress + (value.score || 0);
+ }, 0) /
+ lessonData?.maxScore) *
+ 100
+ );
+
+ lessonList.push({
+ id: lessonId,
+ title: lessonData.title,
+ description: lessonData.description,
+ maxScore: lessonData.maxScore,
+ inProcess,
+ progress,
+ });
+ }
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing lessons list`);
- log.warn(e);
- const error = generateMessage(20108);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getLessonsList",
- data: { moduleId },
- req,
+ if (lessonList.length > 0) {
+ let currentLesson = 0;
+ lessonList.forEach((lesson, index) => {
+ if (lesson.inProcess) {
+ currentLesson = index;
+ }
});
+ lessonList[currentLesson].currentLesson = true;
}
+
+ const data = generateMessage(0, lessonList);
+ res.status(200).send(data);
+
+ return;
}
-module.exports.getLessonsList = getLessonsList;
+module.exports = getLessonsList;
diff --git a/src/modules/apiRequests/getModuleFinal/getModuleFinal.js b/src/modules/apiRequests/getModuleFinal/getModuleFinal.js
index 057ee22..bd23886 100644
--- a/src/modules/apiRequests/getModuleFinal/getModuleFinal.js
+++ b/src/modules/apiRequests/getModuleFinal/getModuleFinal.js
@@ -1,13 +1,11 @@
const { log } = require("@logger");
const {
calculateModuleMaxScore,
- calculateDeadline,
} = require("../../../utils/calculators");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getModuleFinal({ req, res }) {
+async function getModuleFinal(req, res) {
const userId = req?.userId;
const moduleId = req?.query?.moduleId;
@@ -36,50 +34,35 @@ async function getModuleFinal({ req, res }) {
}),
];
- try {
- const [userData, stateData, moduleData] = await Promise.all(requests);
+ const [userData, stateData, moduleData] = await Promise.all(requests);
- if (!moduleData) {
- const error = generateMessage(10303);
- res.status(200).send(error);
- return error;
- }
-
- moduleData.deadline = calculateDeadline(userData?.modules?.[moduleId]);
+ if (!moduleData) {
+ const error = generateMessage(10303);
+ res.status(200).send(error);
+ return error;
+ }
- moduleData.maxScore = calculateModuleMaxScore(moduleData.lessons);
+ moduleData.deadline = userData?.modules?.[moduleId].deadline;
- delete moduleData.lessons;
+ moduleData.maxScore = calculateModuleMaxScore(moduleData.lessons);
- moduleData.score = stateData.reduce(
- (progress, value) => progress + (value?.score || 0),
- 0
- );
+ delete moduleData.lessons;
- moduleData.doneTasks = stateData.reduce((progress, value) => {
- if (value.isChecked) {
- return progress + 1;
- } else return progress;
- }, 0);
+ moduleData.score = stateData.reduce(
+ (progress, value) => progress + (value?.score || 0),
+ 0
+ );
- const data = generateMessage(0, moduleData);
+ moduleData.doneTasks = stateData.reduce((progress, value) => {
+ if (value.isChecked) {
+ return progress + 1;
+ } else return progress;
+ }, 0);
- res.status(200).send(data);
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing module final page`);
- log.warn(e);
- const error = generateMessage(20104);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getModuleFinal",
- data: { moduleId },
- req,
- });
- }
+ return;
}
-module.exports.getModuleFinal = getModuleFinal;
+module.exports = getModuleFinal;
diff --git a/src/modules/apiRequests/getModuleInfo/getModuleInfo.js b/src/modules/apiRequests/getModuleInfo/getModuleInfo.js
index 5d3fa16..d9a92c1 100644
--- a/src/modules/apiRequests/getModuleInfo/getModuleInfo.js
+++ b/src/modules/apiRequests/getModuleInfo/getModuleInfo.js
@@ -1,10 +1,8 @@
const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-const { calculateDeadline } = require("../../../utils/calculators");
-async function getModuleInfo({ req, res }) {
+async function getModuleInfo(req, res) {
const userId = req?.userId;
const moduleId = req?.query?.moduleId;
@@ -32,59 +30,44 @@ async function getModuleInfo({ req, res }) {
}),
];
- try {
- const [userData, stateData, moduleData] = await Promise.all(requests);
+ const [userData, stateData, moduleData] = await Promise.all(requests);
- moduleData.deadline = calculateDeadline(userData?.modules?.[moduleId]);
- moduleData.startDate = userData?.modules?.[moduleId]?.start;
+ moduleData.deadline = userData?.modules?.[moduleId]?.deadline;
+ moduleData.startDate = userData?.modules?.[moduleId]?.start;
- let maxScore = 0;
- for (const lesson of Object.values(moduleData?.lessons)) {
- for (const task of lesson.tasks) {
- const taskData = await getDBRequest("getTaskInfo", {
- query: {
- id: task,
- type: "practice",
- },
- returns: ["maxScore"],
- });
- maxScore += taskData?.maxScore || 0;
- }
+ let maxScore = 0;
+ for (const lesson of Object.values(moduleData?.lessons)) {
+ for (const task of lesson.tasks) {
+ const taskData = await getDBRequest("getTaskInfo", {
+ query: {
+ id: task,
+ type: "practice",
+ },
+ returns: ["maxScore"],
+ });
+ maxScore += taskData?.maxScore || 0;
}
+ }
- moduleData.maxScore = maxScore;
-
- delete moduleData.lessons;
+ moduleData.maxScore = maxScore;
- moduleData.score = stateData.reduce(
- (progress, value) => progress + (value?.score || 0),
- 0
- );
+ delete moduleData.lessons;
- moduleData.doneTasks = stateData.reduce((progress, value) => {
- if (value.isChecked) {
- return progress + 1;
- } else return progress;
- }, 0);
+ moduleData.score = stateData.reduce(
+ (progress, value) => progress + (value?.score || 0),
+ 0
+ );
- const data = generateMessage(0, moduleData);
+ moduleData.doneTasks = stateData.reduce((progress, value) => {
+ if (value.isChecked) {
+ return progress + 1;
+ } else return progress;
+ }, 0);
- res.status(200).send(data);
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing module Info`);
- log.warn(e);
- const error = generateMessage(20110);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getModuleInfo",
- data: { userId },
- req,
- });
- }
+ return;
}
-module.exports.getModuleInfo = getModuleInfo;
+module.exports = getModuleInfo;
diff --git a/src/modules/apiRequests/getModuleStart/getModuleStart.js b/src/modules/apiRequests/getModuleStart/getModuleStart.js
index a7e9f0e..fcaa08d 100644
--- a/src/modules/apiRequests/getModuleStart/getModuleStart.js
+++ b/src/modules/apiRequests/getModuleStart/getModuleStart.js
@@ -4,7 +4,7 @@ const { getNextTaskId } = require("../../../utils/getNextTaskId");
const { generateMessage } = require("../../../utils/messageGenerator");
const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getModuleStart({ req, res }) {
+async function getModuleStart(req, res) {
const userId = req?.userId;
const moduleId = req?.query?.moduleId;
@@ -22,43 +22,28 @@ async function getModuleStart({ req, res }) {
}),
];
- try {
- const [userModules, userState, moduleData] = await Promise.all(requests);
+ const [userModules, userState, moduleData] = await Promise.all(requests);
- if (!moduleData) {
- const error = generateMessage(10303);
- res.status(200).send(error);
- return error;
- }
-
- moduleData.deadline = userModules?.modules?.[moduleId]?.deadline;
+ if (!moduleData) {
+ const error = generateMessage(10303);
+ res.status(200).send(error);
+ return error;
+ }
- moduleData.nextTaskId = getNextTaskId(moduleData, userState);
+ moduleData.deadline = userModules?.modules?.[moduleId]?.deadline;
- moduleData.lessons = Object.entries(moduleData?.lessons).map(
- ([id, data]) => {
- return { id, title: data?.title, description: data?.description };
- }
- );
+ moduleData.nextTaskId = getNextTaskId(moduleData, userState);
- const data = generateMessage(0, moduleData);
+ moduleData.lessons = Object.entries(moduleData?.lessons).map(
+ ([id, data]) => {
+ return { id, title: data?.title, description: data?.description };
+ }
+ );
- res.status(200).send(data);
+ const data = generateMessage(0, moduleData);
+ res.status(200).send(data);
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing module start page`);
- log.warn(e);
- const error = generateMessage(20103);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getModuleStart",
- data: { moduleId },
- req,
- });
- }
+ return;
}
-module.exports.getModuleStart = getModuleStart;
+module.exports = getModuleStart;
diff --git a/src/modules/apiRequests/getModulesList/getModulesList.js b/src/modules/apiRequests/getModulesList/getModulesList.js
new file mode 100644
index 0000000..a599b82
--- /dev/null
+++ b/src/modules/apiRequests/getModulesList/getModulesList.js
@@ -0,0 +1,14 @@
+const { log } = require("../../../services/logger/logger");
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function getModulesList(req, res) {
+ const modulesList = await getDBRequest("getModulesList", {});
+
+ const data = generateMessage(0, modulesList);
+ res.status(200).send(data);
+
+ return
+}
+
+module.exports = getModulesList;
diff --git a/src/modules/apiRequests/getStudentsList/getStudentsList.js b/src/modules/apiRequests/getStudentsList/getStudentsList.js
new file mode 100644
index 0000000..824db76
--- /dev/null
+++ b/src/modules/apiRequests/getStudentsList/getStudentsList.js
@@ -0,0 +1,140 @@
+const { log } = require("../../../services/logger/logger");
+
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { calculateTotalScore } = require("../../../utils/calculators");
+const { getNextTaskId } = require("../../../utils/getNextTaskId");
+const { getDeadline } = require("../../../utils/access");
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function getStudentsList(req, res) {
+ const usersList = await getDBRequest("getUsersList", {});
+
+ const usersData = [];
+
+ for (const user of usersList) {
+ const userData = {};
+ userData.id = user.id;
+ userData.email = user.email;
+ userData.firstName = user.firstName;
+ userData.lastName = user.lastName;
+ userData.lang = user.lang;
+ userData.gender = user.gender;
+ userData.isActivated = user.pass ? true : false;
+
+ const userModules = [];
+
+ for (const moduleId of Object.keys(user.modules || {})) {
+ const start = user.modules[moduleId].start;
+ const deadline = getDeadline(user.modules[moduleId]);
+ const prolongations = user.modules[moduleId].prolongations || [];
+ const certId = user.modules[moduleId].certId;
+
+ const requests = [
+ getDBRequest("getModuleInfo", {
+ query: { code: moduleId },
+ }),
+ getDBRequest("getUserState", {
+ query: {
+ userId: user.id,
+ taskId: { $regex: `^${moduleId}` },
+ },
+ }),
+ ];
+
+ const [moduleData, userState] = await Promise.all(requests);
+
+ if (!moduleData || Object.keys(moduleData).length === 0) {
+ continue;
+ }
+
+ const moduleName = moduleData?.shortName;
+ const mascot = moduleData?.mascot;
+
+ const totalTasks = moduleData?.totalTasks;
+
+ const forsakenTasksInfo = userState.filter(
+ (task) => task?.inProcess && !task?.isChecked
+ );
+
+ const forsakenTasks = [];
+
+ for (const task of forsakenTasksInfo) {
+ const taskData = await getDBRequest("getTaskInfo", {
+ query: { id: task?.taskId },
+ returns: ["id", "type", "name", "lesson", "title"],
+ });
+
+ forsakenTasks.push({
+ id: task?.id,
+ type: taskData?.type,
+ name:
+ taskData?.type === "practice"
+ ? `Задача ${taskData?.name}`
+ : taskData?.title,
+ });
+ }
+
+ const doneTasks = userState.filter((task) => task?.isChecked).length;
+
+ const comments = userState.filter(
+ (task) => (task.comments || []).length > 0
+ ).length;
+
+ const protests = userState.filter((task) => task?.protest).length;
+
+ const nextTaskId = getNextTaskId(moduleData, userState);
+
+ const nextTask = await getDBRequest("getTaskInfo", {
+ query: { id: nextTaskId },
+ returns: ["id", "type", "name", "lesson", "title"],
+ });
+
+ if (nextTask) {
+ nextTask.name =
+ nextTask?.type === "practice"
+ ? `Задача ${nextTask?.name}`
+ : nextTask?.title;
+ }
+ const totalScore = calculateTotalScore(userState);
+
+ const maxScore = Object.keys(moduleData.lessons).reduce(
+ (sum, lessonId) => {
+ return sum + moduleData.lessons[lessonId].maxScore;
+ },
+ 0
+ );
+
+ const lessons = [];
+
+ userModules.push({
+ id: moduleId,
+ moduleName,
+ mascot,
+ start,
+ deadline,
+ prolongations,
+ certId,
+ totalTasks,
+ forsakenTasks,
+ doneTasks,
+ comments,
+ protests,
+ nextTask,
+ totalScore,
+ maxScore,
+ lessons,
+ });
+ }
+
+ userData.modules = userModules;
+
+ usersData.push(userData);
+ }
+
+ const data = generateMessage(0, usersData);
+ res.status(200).send(data);
+
+ return
+}
+
+module.exports = getStudentsList;
diff --git a/src/modules/apiRequests/getTask/getTask.js b/src/modules/apiRequests/getTask/getTask.js
index 16214e9..46e5726 100644
--- a/src/modules/apiRequests/getTask/getTask.js
+++ b/src/modules/apiRequests/getTask/getTask.js
@@ -5,9 +5,8 @@ const { getModuleId } = require("../../../utils/idExtractor");
const { prepareModuleData } = require("./prepareModuleData");
const { prepareTaskData } = require("./prepareTaskData");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getTask({ req, res }) {
+async function getTask(req, res) {
const userId = req.userId;
const { taskId } = req.query;
@@ -29,60 +28,45 @@ async function getTask({ req, res }) {
}),
];
- try {
- const [userData, moduleData, taskData, taskState] = await Promise.all(
- requests
- );
+ const [userData, moduleData, taskData, taskState] = await Promise.all(
+ requests
+ );
- if (!moduleData) {
- const error = generateMessage(10303);
- res.status(200).send(error);
- return error;
- }
-
- if (!taskData) {
- const error = generateMessage(10301);
- res.status(200).send(error);
- return error;
- }
+ if (!moduleData) {
+ const error = generateMessage(10303);
+ res.status(200).send(error);
+ return;
+ }
- const preparedModuleData = await prepareModuleData({ moduleData, taskId });
+ if (!taskData) {
+ const error = generateMessage(10301);
+ res.status(200).send(error);
+ return;
+ }
- const preparedTaskData = await prepareTaskData({
- taskData,
- taskState,
- userId,
- lang: moduleData?.lang,
- });
+ const preparedModuleData = await prepareModuleData({ moduleData, taskId });
- const preparedUserData = {
- deadline: userData?.modules[moduleId]?.deadline,
- };
+ const preparedTaskData = await prepareTaskData({
+ taskData,
+ taskState,
+ userId,
+ lang: moduleData?.lang,
+ });
- const aggData = {
- ...preparedModuleData,
- ...preparedTaskData,
- ...preparedUserData,
- };
+ const preparedUserData = {
+ deadline: userData?.modules[moduleId]?.deadline,
+ };
- const data = generateMessage(0, aggData);
+ const aggData = {
+ ...preparedModuleData,
+ ...preparedTaskData,
+ ...preparedUserData,
+ };
- res.status(200).send(data);
+ const data = generateMessage(0, aggData);
+ res.status(200).send(data);
- return data;
- } catch (e) {
- log.warn(`${taskId}: Error with processing task`);
- log.warn(e);
- const error = generateMessage(20102);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getTask",
- data: { taskId },
- req,
- });
- }
+ return;
}
-module.exports.getTask = getTask;
+module.exports = getTask;
diff --git a/src/modules/apiRequests/getTask/prepareTaskData.js b/src/modules/apiRequests/getTask/prepareTaskData.js
index 56c68ac..9e695b8 100644
--- a/src/modules/apiRequests/getTask/prepareTaskData.js
+++ b/src/modules/apiRequests/getTask/prepareTaskData.js
@@ -11,7 +11,6 @@ async function updateVisibility(userId, data) {
const { type, parentId, isVisible } = depend;
if (type == "visibility") {
const visibility = await setVisibility(userId, parentId, id);
- console.log("V", visibility);
data.isVisible = visibility;
if (!isVisible) {
break;
diff --git a/src/modules/apiRequests/getTasksList/getTasksList.js b/src/modules/apiRequests/getTasksList/getTasksList.js
index 6b15249..a4d8d04 100644
--- a/src/modules/apiRequests/getTasksList/getTasksList.js
+++ b/src/modules/apiRequests/getTasksList/getTasksList.js
@@ -3,9 +3,8 @@ const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { getModuleId, getLessonId } = require("../../../utils/idExtractor");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function getTasksList({ req, res }) {
+async function getTasksList(req, res) {
const userId = req?.userId;
const fullLessonId = req?.query?.lessonId;
@@ -23,60 +22,46 @@ async function getTasksList({ req, res }) {
return error;
}
- try {
- const tasksList = [];
+ const tasksList = [];
- const lesson = lessons[lessonId];
+ const lesson = lessons[lessonId];
- if (!lesson) {
- const error = generateMessage(10302);
+ if (!lesson) {
+ const error = generateMessage(10302);
+ res.status(200).send(error);
+ return error;
+ }
+
+ for (const taskId of lesson.tasks || []) {
+ const taskData = await getDBRequest("getTaskInfo", {
+ query: { id: taskId },
+ returns: ["id", "type", "title", "name", "maxScore"],
+ });
+
+ if (!taskData) {
+ const error = generateMessage(10301);
res.status(200).send(error);
return error;
}
- for (const taskId of lesson.tasks || []) {
- const taskData = await getDBRequest("getTaskInfo", {
- query: { id: taskId },
- returns: ["id", "type", "title", "name", "maxScore"],
+ if (taskData?.type === "practice") {
+ const taskState = await getDBRequest("getStateInfo", {
+ query: { userId, taskId },
});
- if (!taskData) {
- const error = generateMessage(10301);
- res.status(200).send(error);
- return error;
- }
+ taskData.score = taskState?.score >= 0 ? taskState?.score : null;
+ taskData.isChecked = taskState?.isChecked || false;
+ taskData.inProcess = taskState?.inProcess;
+ }
- if (taskData?.type === "practice") {
- const taskState = await getDBRequest("getStateInfo", {
- query: { userId, taskId },
- });
+ tasksList.push(taskData);
+ }
- taskData.score = taskState?.score >= 0 ? taskState?.score : null;
- taskData.isChecked = taskState?.isChecked || false;
- taskData.inProcess = taskState?.inProcess;
- }
+ const data = generateMessage(0, tasksList);
- tasksList.push(taskData);
- }
+ res.status(200).send(data);
- const data = generateMessage(0, tasksList);
-
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${moduleId}: Error with processing tasks list`);
- log.warn(e);
- const error = generateMessage(20109);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "getTasksList",
- data: { userId },
- req,
- });
- }
+ return;
}
-module.exports.getTasksList = getTasksList;
+module.exports = getTasksList;
diff --git a/src/modules/apiRequests/newPayment/newPayment.js b/src/modules/apiRequests/newPayment/newPayment.js
new file mode 100644
index 0000000..37ce144
--- /dev/null
+++ b/src/modules/apiRequests/newPayment/newPayment.js
@@ -0,0 +1,305 @@
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { createUser } = require("../createUser/createUser");
+const { calculateDeadline } = require("../../../utils/calculators");
+const { hashPass } = require("../../../utils/pass");
+const { setKey } = require("../../../services/tokenMachine/OTK");
+const { log } = require("../../../services/logger/logger");
+const { prepareMail } = require("../../../services/mailer/actions");
+const { sendMail } = require("../../../services/mailer/actions");
+
+function checkSource(body) {
+ const keys = Object.keys(body)
+
+ if (keys.includes("gumroad_fee")) {
+ return "Gumroad";
+ }
+
+ if (keys.includes("sign")) {
+ return "Tilda";
+ }
+
+ return undefined
+}
+
+function splitName(name) {
+ if (name) {
+ const [firstName, lastName] = name.split(" ", 2);
+ return {
+ firstName,
+ lastName,
+ };
+ } else return {}
+
+}
+
+function prepareData(source, data, date) {
+ const initData = { source, ts: Date.now() };
+ const products = {
+ ["_-jg_yvw1calvFhRDQaqJg=="]: "HSE",
+ ["DYGiKngRwU-N1dt_WOJ0lg=="]: "HSP",
+ };
+
+ switch (source) {
+ case "Gumroad":
+ return {
+ ...initData,
+ date,
+ email: data.email,
+ firstName: data["First Name"],
+ lastName: data["Last Name"],
+ paymentId: data.sale_id,
+ moduleId: products[data.product_id],
+ value: data.price,
+ currency: "USD",
+ };
+ case "Tilda":
+ const moduleId = data.payment.products[0].sku.slice(0, 3);
+ const isProlongation = data.payment.products[0].sku.includes("+");
+ return {
+ ...initData,
+ date,
+ email: data.email,
+ ...splitName(data.name),
+ paymentId: data.payment.orderid,
+ moduleId,
+ isProlongation,
+ value: data.payment.products[0].price,
+ currency: "RUB",
+ };
+ default:
+ throw new Error("Payment data wasn't prepared")
+ }
+}
+
+function getDateObject(date) {
+ const timestamp = date ? Date.parse(date) : Date.mow();
+ return new Date(timestamp);
+}
+
+function getISODateOny(date) {
+ const dateObject = typeof date === "string" ? getDateObject(date) : date;
+ return dateObject.toISOString().split("T")[0];
+}
+
+async function newPayment(req, res) {
+
+ const { body } = req;
+
+ if (body.test) {
+ res.sendStatus(200);
+ return;
+ }
+
+ log.debug(body);
+ const date = new Date(Date.now());
+
+ const source = checkSource(body);
+
+ if (!source) {
+ res.status(400);
+ res.send({
+ OK: false,
+ error: "invalid_params"
+ })
+ return
+ }
+
+ const payment = prepareData(source, body, date);
+
+ log.debug(payment);
+
+ const moduleInfo = await getDBRequest("getModuleInfo", {
+ query: { code: payment.moduleId.toUpperCase() },
+ });
+
+ if (!moduleInfo) {
+ res.status(400);
+ res.send({
+ OK: false,
+ error: "invalid_params"
+ })
+ return
+ }
+
+ const user = await getDBRequest("getUserInfo", {
+ query: { email: payment.email },
+ });
+
+ let start = getISODateOny(date);
+
+ if (body.start) {
+ const dateArray = body.start.split(".");
+ const startDateNormilized = `${dateArray[2]}-${dateArray[1]}-${dateArray[0]}`;
+ start = getISODateOny(startDateNormilized);
+ }
+ let deadline = calculateDeadline(start, 62);
+
+ if (!user) {
+ const userPass = Math.random().toString(36).substring(2);
+ const lang = source === "Tilda" ? "ru" : "en";
+
+ const newUser = {
+ email: payment.email,
+ pass: userPass ? hashPass(userPass) : "",
+ firstName: payment.firstName,
+ lastName: payment.lastName,
+ modules: {
+ [payment.moduleId]: {
+ start,
+ deadline,
+ prolongations: [],
+ },
+ },
+ lang,
+ };
+
+ const createdUser = await getDBRequest("addUser", newUser);
+
+ const secureKey = await setKey(createdUser?.id, "oneTimeKey");
+
+ const link = `${process.env.FRONTEND_URL}/createPassword?email=${payment.email}&verifyKey=${secureKey}&lang=${lang}`;
+
+ const params = {
+ lang,
+ status: "new",
+ type: "buy",
+ start: getISODateOny(date) < start ? "date" : "now",
+ };
+
+ const data = {
+ NAME: newUser?.firstName || "",
+ MODULE: moduleInfo?.name || "",
+ MODULELINK: moduleInfo?.moduleLink || "",
+ MASCOTLETTERTOP: moduleInfo?.mascot?.letterTop || "",
+ MASCOTLETTERBOTTOM: moduleInfo?.mascot?.letterBottom || "",
+ START_DATE: new Date(Date.parse(start)).toLocaleDateString("ru-RU", {
+ month: "long",
+ day: "numeric",
+ }),
+ PASSWORD: userPass || "",
+ PASSWORD_LINK: link,
+ };
+
+ const mail = prepareMail({ params, data });
+
+ sendMail(mail, newUser?.email, "eduHund");
+
+ } else if (payment?.isProlongation) {
+ deadline = calculateDeadline(
+ user?.modules[payment.moduleId].deadline,
+ 62
+ );
+
+ const prolData = {
+ type: "renewal",
+ paymentId: payment.paymentId,
+ until: deadline,
+ };
+
+ user.modules[payment?.moduleId].deadline = deadline
+ if (!Array.isArray(user.modules[payment?.moduleId].prolongations)) {
+ user.modules[payment?.moduleId].prolongations = []
+ }
+ user.modules[payment?.moduleId].prolongations.push(prolData)
+
+ await getDBRequest("setUserInfo", {
+ id: user?.id,
+ data: { modules: user.modules },
+ });
+
+ const params = {
+ lang: "ru" || user?.lang,
+ status: "renew",
+ };
+
+ const data = {
+ NAME: user?.firstName || "",
+ MODULE: moduleInfo?.name || "",
+ MODULELINK: moduleInfo?.moduleLink || "",
+ MASCOTLETTERTOP: moduleInfo?.mascot?.letterTop || "",
+ MASCOTLETTERBOTTOM: moduleInfo?.mascot?.letterBottom || "",
+ START_DATE: new Date(Date.parse(start)).toLocaleDateString("ru-RU", {
+ month: "long",
+ day: "numeric",
+ }),
+ };
+ const mail = prepareMail({ params, data });
+
+ sendMail(mail, user?.email, "eduHund");
+
+ } else {
+
+ const activeModules = Object.entries(user.modules || {}).filter(
+ ([, value]) =>
+ Date.now() - Date.parse(value.deadline) <= 7 * 24 * 60 * 60 * 1000
+ );
+
+ for (const [id] of activeModules) {
+ const isCurrent = id === payment?.moduleId
+ const type = isCurrent ? "newBuy" : "otherModule";
+ const data = {
+ type,
+ paymentId: payment.paymentId,
+ until: deadline,
+ };
+
+ user.modules[id].deadline = deadline
+ if (!Array.isArray(user.modules[id].prolongations)) {
+ user.modules[id].prolongations = []
+ }
+ user.modules[id].prolongations.push(data)
+ }
+
+ if (!user.modules[payment.moduleId]) {
+ user.modules[payment.moduleId] = {
+ start,
+ deadline,
+ prolongations: [{
+ type: "newBuy",
+ paymentId: payment.paymentId,
+ until: deadline,
+ }]
+ }
+ }
+
+ await getDBRequest("setUserInfo", {
+ id: user?.id,
+ data: { modules: user.modules },
+ });
+
+ const params = {
+ lang: user?.lang || "en",
+ status: "current",
+ type: "buy",
+ start: getISODateOny(date) < start ? "date" : "now",
+ };
+
+ const data = {
+ NAME: user?.firstName || "",
+ MODULE: moduleInfo?.name || "",
+ MODULELINK: moduleInfo?.moduleLink || "",
+ MASCOTLETTERTOP: moduleInfo?.mascot?.letterTop || "",
+ MASCOTLETTERBOTTOM: moduleInfo?.mascot?.letterBottom || "",
+ START_DATE: new Date(Date.parse(start)).toLocaleDateString("ru-RU", {
+ month: "long",
+ day: "numeric",
+ }),
+ };
+
+ const mail = prepareMail({ params, data });
+
+ sendMail(mail, user?.email, "eduHund");
+ }
+
+ const response = await getDBRequest("setPayment", { payment });
+
+ if (response?.acknowledged) {
+ res.sendStatus(200);
+ } else {
+ res.sendStatus(400);
+ }
+
+ return;
+}
+
+module.exports = newPayment;
diff --git a/src/modules/apiRequests/resetPassword/resetPassword.js b/src/modules/apiRequests/resetPassword/resetPassword.js
new file mode 100644
index 0000000..4d57150
--- /dev/null
+++ b/src/modules/apiRequests/resetPassword/resetPassword.js
@@ -0,0 +1,35 @@
+const { log } = require("../../../services/logger/logger");
+
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { lowerString } = require("../../../utils/stringProcessor")
+const { setKey } = require("../../../services/tokenMachine/OTK")
+
+async function resetPassword(req, res) {
+ const email = lowerString(req.body.email);
+ const user = await getDBRequest("checkUsername", { email })
+
+ if (user) {
+ const { id, email } = user
+ const secureKey = await setKey(user?.id, "oneTimeKey");
+ res.status(200);
+ res.send({
+ OK: true,
+ data: {
+ id,
+ email,
+ key: secureKey,
+ },
+ });
+ } else {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "invalid_credentials",
+ error_description: "User didn't found",
+ error_code: 10001,
+ });
+ }
+ return
+};
+
+module.exports = resetPassword
\ No newline at end of file
diff --git a/src/modules/apiRequests/setControls/setControls.js b/src/modules/apiRequests/setControls/setControls.js
index c4f953f..f29bccf 100644
--- a/src/modules/apiRequests/setControls/setControls.js
+++ b/src/modules/apiRequests/setControls/setControls.js
@@ -2,37 +2,22 @@ const { log } = require("@logger");
const { getDBRequest } = require("../../dbRequests/dbRequests");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
-async function setControls({ req, res }) {
+async function setControls(req, res) {
const userId = req?.userId;
const { taskId, controlsState } = req.body;
- try {
- const query = { userId, taskId };
- await getDBRequest("setControls", {
- query,
- controlsState,
- returns: [],
- });
- const data = generateMessage(0);
+ const query = { userId, taskId };
+ await getDBRequest("setControls", {
+ query,
+ controlsState,
+ returns: [],
+ });
+
+ const data = generateMessage(0);
+ res.status(200).send(data);
- res.status(200).send(data);
-
- return data;
- } catch (e) {
- log.warn(`${taskId}: Error while updating task's controls state`);
- log.warn(e);
- const error = generateMessage(20114);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "setControls",
- data: { taskId, controlsState },
- req,
- });
- }
+ return;
}
-module.exports.setControls = setControls;
+module.exports = setControls;
diff --git a/src/modules/apiRequests/setState/setState.js b/src/modules/apiRequests/setState/setState.js
index 2c118c6..cab0dc1 100644
--- a/src/modules/apiRequests/setState/setState.js
+++ b/src/modules/apiRequests/setState/setState.js
@@ -5,7 +5,6 @@ const { getFullTaskId } = require("../../../utils/idExtractor");
const { getVisibilityUpdateList } = require("./getVisibilityUpdateList");
const { updateDependenciesTasks } = require("./updateDependenciesTasks");
const { generateMessage } = require("../../../utils/messageGenerator");
-const { addUserAction } = require("../../../modules/statistics/addUserAction");
const { getParentContent } = require("../../../utils/getParentContent");
const { refAnswerRight } = require("../../../utils/refAnswerRight");
@@ -40,7 +39,7 @@ async function updateContent(taskData, taskState = {}, userId, lang = "en") {
return questionsDict;
}
-async function setState({ req, res }) {
+async function setState(req, res) {
const userId = req?.userId;
const { questionId, state } = req.body;
@@ -58,53 +57,38 @@ async function setState({ req, res }) {
returns: ["id", "content"],
});
- try {
- const questions = getVisibilityUpdateList(tasks, questionId);
+ const questions = getVisibilityUpdateList(tasks, questionId);
- await updateDependenciesTasks(userId, questions, state);
+ await updateDependenciesTasks(userId, questions, state);
- const path = "data." + questionId + ".state";
- const query = { userId, taskId };
- const update = {
- [path]: state,
- inProcess: true,
- };
- const newState = await getDBRequest("setState", {
- query,
- state: update,
- returns: [],
- });
-
- const updatedData = await updateContent(
- taskData,
- newState?.value?.data,
- userId
- );
+ const path = "data." + questionId + ".state";
+ const query = { userId, taskId };
+ const update = {
+ [path]: state,
+ inProcess: true,
+ };
+ const newState = await getDBRequest("setState", {
+ query,
+ state: update,
+ returns: [],
+ });
- const finalData = Object.assign(
- {},
- newState?.value?.data || {},
- updatedData
- );
+ const updatedData = await updateContent(
+ taskData,
+ newState?.value?.data,
+ userId
+ );
- const data = generateMessage(0, finalData);
+ const finalData = Object.assign(
+ {},
+ newState?.value?.data || {},
+ updatedData
+ );
- res.status(200).send(data);
+ const data = generateMessage(0, finalData);
+ res.status(200).send(data);
- return data;
- } catch (e) {
- log.warn(`${questionId}: Error while setting new question state`);
- log.warn(e);
- const error = generateMessage(20112);
- res.status(400).send(error);
- } finally {
- addUserAction({
- userId,
- action: "setState",
- data: { questionId },
- req,
- });
- }
+ return;
}
-module.exports.setState = setState;
+module.exports = setState;
diff --git a/src/modules/apiRequests/updateUser/updateUser.js b/src/modules/apiRequests/updateUser/updateUser.js
new file mode 100644
index 0000000..41eaf93
--- /dev/null
+++ b/src/modules/apiRequests/updateUser/updateUser.js
@@ -0,0 +1,59 @@
+const { log } = require("../../../services/logger/logger");
+const { getDBRequest } = require("../../dbRequests/dbRequests");
+const { lowerString } = require("../../../utils/stringProcessor")
+const { generateMessage } = require("../../../utils/messageGenerator");
+
+async function updateUser(req, res) {
+ const { id, email, firstName, lastName, lang, gender} = req.body
+
+ if (!id) {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "missing_parameters",
+ error_description: "Missing required parameters",
+ error_code: 10008,
+ });
+ return
+ }
+
+ const data = {
+ email: lowerString(email),
+ firstName,
+ lastName,
+ lang,
+ gender,
+ };
+
+ for (const key of Object.keys(data)) {
+ if (!data[key]) delete data[key]
+ }
+
+ const updatedUser = await getDBRequest("setUserInfo", {
+ id,
+ data,
+ });
+
+ if (updatedUser) {
+ delete updatedUser.pass
+ const sendData = {
+ OK: true,
+ data: updatedUser,
+ };
+
+ const data = generateMessage(0, sendData);
+ res.status(200).send(data);
+ } else {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "updating_error",
+ error_description: "Error while updating user",
+ error_code: 10009,
+ });
+ }
+
+ return
+};
+
+module.exports = updateUser;
diff --git a/src/modules/dbRequests/addUser/addUser.js b/src/modules/dbRequests/addUser/addUser.js
new file mode 100644
index 0000000..30b2907
--- /dev/null
+++ b/src/modules/dbRequests/addUser/addUser.js
@@ -0,0 +1,15 @@
+const { log } = require("../../../services/logger/logger");
+const { USERS } = require("../../dbRequests/mongo");
+
+async function addUser(user) {
+ log.info("Registering user:", user);
+ return USERS.countDocuments().then((totalUsers) => {
+ const userId = `U${(totalUsers + 1).toString().padStart(7, "0")}`;
+ user.id = userId;
+ return USERS.insertOne(user).then(() => {
+ return user;
+ });
+ });
+}
+
+module.exports = addUser
\ No newline at end of file
diff --git a/src/modules/dbRequests/addUserAction/addUserAction.js b/src/modules/dbRequests/addUserAction/addUserAction.js
index 007fe27..2094ef7 100644
--- a/src/modules/dbRequests/addUserAction/addUserAction.js
+++ b/src/modules/dbRequests/addUserAction/addUserAction.js
@@ -1,7 +1,7 @@
-const { db } = require("../mongo");
+const { ACTIONS } = require("../mongo");
function addUserAction({ userId, action, data, params }) {
- return db.ACTIONS.insertOne({
+ return ACTIONS.insertOne({
ts: Date.now(),
userId,
action,
@@ -10,4 +10,4 @@ function addUserAction({ userId, action, data, params }) {
});
}
-module.exports.addUserAction = addUserAction;
+module.exports = addUserAction;
diff --git a/src/modules/dbRequests/checkUsername/checkUsername.js b/src/modules/dbRequests/checkUsername/checkUsername.js
new file mode 100644
index 0000000..8cfc1f1
--- /dev/null
+++ b/src/modules/dbRequests/checkUsername/checkUsername.js
@@ -0,0 +1,11 @@
+const { USERS } = require("../mongo");
+
+async function checkUsername({ email }) {
+ return USERS.findOne({ email }).then((user) => {
+ if (user) {
+ return user;
+ } else return false;
+ });
+}
+
+module.exports = checkUsername
\ No newline at end of file
diff --git a/src/modules/dbRequests/dbRequests.js b/src/modules/dbRequests/dbRequests.js
index 02483ab..cff124b 100644
--- a/src/modules/dbRequests/dbRequests.js
+++ b/src/modules/dbRequests/dbRequests.js
@@ -1,20 +1,24 @@
-const { getUserInfo } = require("./getUserInfo/getUserInfo");
-const { getUserState } = require("./getUserState/getUserState");
-const { getUsersList } = require("./getUsersList/getUsersList");
-const { getModuleInfo } = require("./getModuleInfo/getModuleInfo");
-const { getTaskInfo } = require("./getTaskInfo/getTaskInfo");
-const { getStateInfo } = require("./getStateInfo/getStateInfo");
-const { getModulesList } = require("./getModulesList/getModulesList");
-const { getTasksList } = require("./getTasksList/getTasksList");
-const { setComment } = require("./setComment/setComment");
-const { setState } = require("./setState/setState");
-const { setControls } = require("./setControls/setControls");
-const { addUserAction } = require("./addUserAction/addUserAction");
-const { setUserInfo } = require("./setUserInfo/setUserInfo");
-const { getCounselor } = require("./getCounselor/getCounselor");
-const { getPaymentInfo } = require("./getPaymentInfo/getPaymentInfo");
-const { getDiploma } = require("./getDiploma/getDiploma");
-const { setDiploma } = require("./setDiploma/setDiploma");
+const getUserInfo = require("./getUserInfo/getUserInfo");
+const getUserState = require("./getUserState/getUserState");
+const getUsersList = require("./getUsersList/getUsersList");
+const getModuleInfo = require("./getModuleInfo/getModuleInfo");
+const getTaskInfo = require("./getTaskInfo/getTaskInfo");
+const getStateInfo = require("./getStateInfo/getStateInfo");
+const getModulesList = require("./getModulesList/getModulesList");
+const getTasksList = require("./getTasksList/getTasksList");
+const setComment = require("./setComment/setComment");
+const setState = require("./setState/setState");
+const setControls = require("./setControls/setControls");
+const addUserAction = require("./addUserAction/addUserAction");
+const setUserInfo = require("./setUserInfo/setUserInfo");
+const getCounselor = require("./getCounselor/getCounselor");
+const getPaymentInfo = require("./getPaymentInfo/getPaymentInfo");
+const getDiploma = require("./getDiploma/getDiploma");
+const setDiploma = require("./setDiploma/setDiploma");
+const checkUsername = require("./checkUsername/checkUsername")
+const setPayment = require("./setPayment/setPayment");
+const addUser = require("./addUser/addUser");
+
const REQUESTS = {
getUserInfo,
@@ -34,6 +38,9 @@ const REQUESTS = {
getPaymentInfo,
getDiploma,
setDiploma,
+ checkUsername,
+ setPayment,
+ addUser
};
function getDBRequest(type, params) {
diff --git a/src/modules/dbRequests/getCounselor/getCounselor.js b/src/modules/dbRequests/getCounselor/getCounselor.js
index df0cf46..f8972aa 100644
--- a/src/modules/dbRequests/getCounselor/getCounselor.js
+++ b/src/modules/dbRequests/getCounselor/getCounselor.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { COUNSELOR } = require("../mongo");
function getCounselor({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getCounselor({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.COUNSELOR.findOne(query, { projection });
+ return COUNSELOR.findOne(query, { projection });
}
-module.exports.getCounselor = getCounselor;
+module.exports = getCounselor;
diff --git a/src/modules/dbRequests/getDiploma/getDiploma.js b/src/modules/dbRequests/getDiploma/getDiploma.js
index 4544128..d8a0967 100644
--- a/src/modules/dbRequests/getDiploma/getDiploma.js
+++ b/src/modules/dbRequests/getDiploma/getDiploma.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { CERTS } = require("../mongo");
function getDiploma({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getDiploma({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.CERTS.findOne(query, { projection });
+ return CERTS.findOne(query, { projection });
}
-module.exports.getDiploma = getDiploma;
+module.exports = getDiploma;
diff --git a/src/modules/dbRequests/getModuleInfo/getModuleInfo.js b/src/modules/dbRequests/getModuleInfo/getModuleInfo.js
index a0a978c..8436741 100644
--- a/src/modules/dbRequests/getModuleInfo/getModuleInfo.js
+++ b/src/modules/dbRequests/getModuleInfo/getModuleInfo.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { MODULES } = require("../mongo");
function getModuleInfo({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getModuleInfo({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.MODULES.findOne(query, { projection });
+ return MODULES.findOne(query, { projection });
}
-module.exports.getModuleInfo = getModuleInfo;
+module.exports = getModuleInfo;
diff --git a/src/modules/dbRequests/getModulesList/getModulesList.js b/src/modules/dbRequests/getModulesList/getModulesList.js
index bc1be4e..99c6764 100644
--- a/src/modules/dbRequests/getModulesList/getModulesList.js
+++ b/src/modules/dbRequests/getModulesList/getModulesList.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { MODULES } = require("../mongo");
function getModulesList({ query = {}, returns = [] }) {
const projection = {
@@ -7,9 +7,9 @@ function getModulesList({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.MODULES.find(query, {
+ return MODULES.find(query, {
projection,
}).toArray();
}
-module.exports.getModulesList = getModulesList;
+module.exports = getModulesList;
diff --git a/src/modules/dbRequests/getPaymentInfo/getPaymentInfo.js b/src/modules/dbRequests/getPaymentInfo/getPaymentInfo.js
index b3f9d66..bd1e138 100644
--- a/src/modules/dbRequests/getPaymentInfo/getPaymentInfo.js
+++ b/src/modules/dbRequests/getPaymentInfo/getPaymentInfo.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { PAYMENTS } = require("../mongo");
function getPaymentInfo({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getPaymentInfo({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.PAYMENTS.findOne(query, { projection });
+ return PAYMENTS.findOne(query, { projection });
}
-module.exports.getPaymentInfo = getPaymentInfo;
+module.exports = getPaymentInfo;
diff --git a/src/modules/dbRequests/getStateInfo/getStateInfo.js b/src/modules/dbRequests/getStateInfo/getStateInfo.js
index ca89ade..b29b4d6 100644
--- a/src/modules/dbRequests/getStateInfo/getStateInfo.js
+++ b/src/modules/dbRequests/getStateInfo/getStateInfo.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { STATE } = require("../mongo");
function getStateInfo({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getStateInfo({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.STATE.findOne(query, { projection });
+ return STATE.findOne(query, { projection });
}
-module.exports.getStateInfo = getStateInfo;
+module.exports = getStateInfo;
diff --git a/src/modules/dbRequests/getTaskInfo/getTaskInfo.js b/src/modules/dbRequests/getTaskInfo/getTaskInfo.js
index 3eb1be5..36f41ee 100644
--- a/src/modules/dbRequests/getTaskInfo/getTaskInfo.js
+++ b/src/modules/dbRequests/getTaskInfo/getTaskInfo.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { TASKS } = require("../mongo");
function getTaskInfo({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getTaskInfo({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.TASKS.findOne(query, { projection });
+ return TASKS.findOne(query, { projection });
}
-module.exports.getTaskInfo = getTaskInfo;
+module.exports = getTaskInfo;
diff --git a/src/modules/dbRequests/getTasksList/getTasksList.js b/src/modules/dbRequests/getTasksList/getTasksList.js
index 76c1ecf..2ee7f4e 100644
--- a/src/modules/dbRequests/getTasksList/getTasksList.js
+++ b/src/modules/dbRequests/getTasksList/getTasksList.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { TASKS } = require("../mongo");
function getTasksList({ query = {}, returns = [] }) {
const projection = {
@@ -7,9 +7,9 @@ function getTasksList({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.TASKS.find(query, {
+ return TASKS.find(query, {
projection,
}).toArray();
}
-module.exports.getTasksList = getTasksList;
+module.exports = getTasksList;
diff --git a/src/modules/dbRequests/getUserInfo/getUserInfo.js b/src/modules/dbRequests/getUserInfo/getUserInfo.js
index 79a9357..1a2551b 100644
--- a/src/modules/dbRequests/getUserInfo/getUserInfo.js
+++ b/src/modules/dbRequests/getUserInfo/getUserInfo.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { USERS } = require("../mongo");
function getUserInfo({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getUserInfo({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.USERS.findOne(query, { projection });
+ return USERS.findOne(query, { projection });
}
-module.exports.getUserInfo = getUserInfo;
+module.exports = getUserInfo;
diff --git a/src/modules/dbRequests/getUserState/getUserState.js b/src/modules/dbRequests/getUserState/getUserState.js
index a082d31..1417bd6 100644
--- a/src/modules/dbRequests/getUserState/getUserState.js
+++ b/src/modules/dbRequests/getUserState/getUserState.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { STATE } = require("../mongo");
function getUserState({ query = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function getUserState({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.STATE.find(query, { projection }).toArray();
+ return STATE.find(query, { projection }).toArray();
}
-module.exports.getUserState = getUserState;
+module.exports = getUserState;
diff --git a/src/modules/dbRequests/getUsersList/getUsersList.js b/src/modules/dbRequests/getUsersList/getUsersList.js
index fa26275..2d46363 100644
--- a/src/modules/dbRequests/getUsersList/getUsersList.js
+++ b/src/modules/dbRequests/getUsersList/getUsersList.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { USERS } = require("../mongo");
function getUsersList({ query = {}, returns = [] }) {
const projection = {
@@ -7,9 +7,9 @@ function getUsersList({ query = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.USERS.find(query, {
+ return USERS.find(query, {
projection,
}).toArray();
}
-module.exports.getUsersList = getUsersList;
+module.exports = getUsersList;
diff --git a/src/modules/dbRequests/mongo.js b/src/modules/dbRequests/mongo.js
index 92bf24b..c22dfb1 100644
--- a/src/modules/dbRequests/mongo.js
+++ b/src/modules/dbRequests/mongo.js
@@ -14,7 +14,7 @@ const CERTS = mongoClient.db(DB_NAME).collection("certs");
const PAYMENTS = mongoClient.db(DB_NAME).collection("payments");
const COUNSELOR = mongoClient.db(DB_NAME).collection("counselor");
-module.exports.db = {
+module.exports = {
USERS,
TASKS,
STATE,
diff --git a/src/modules/dbRequests/setComment/setComment.js b/src/modules/dbRequests/setComment/setComment.js
index 6000759..c39a6fe 100644
--- a/src/modules/dbRequests/setComment/setComment.js
+++ b/src/modules/dbRequests/setComment/setComment.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { STATE } = require("../mongo");
function setComment({ query = {}, data = {}, protest = false, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function setComment({ query = {}, data = {}, protest = false, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.STATE.findOneAndUpdate(
+ return STATE.findOneAndUpdate(
query,
{
$push: {
@@ -29,4 +29,4 @@ function setComment({ query = {}, data = {}, protest = false, returns = [] }) {
);
}
-module.exports.setComment = setComment;
+module.exports = setComment;
diff --git a/src/modules/dbRequests/setControls/setControls.js b/src/modules/dbRequests/setControls/setControls.js
index af09f45..ce331b3 100644
--- a/src/modules/dbRequests/setControls/setControls.js
+++ b/src/modules/dbRequests/setControls/setControls.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { STATE } = require("../mongo");
function setControls({ query = {}, controlsState = {}, returns = [] }) {
const isHintActive = controlsState?.isHintActive || false;
@@ -10,7 +10,7 @@ function setControls({ query = {}, controlsState = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.STATE.findOneAndUpdate(
+ return STATE.findOneAndUpdate(
query,
{
$set: {
@@ -28,4 +28,4 @@ function setControls({ query = {}, controlsState = {}, returns = [] }) {
);
}
-module.exports.setControls = setControls;
+module.exports = setControls;
diff --git a/src/modules/dbRequests/setDiploma/setDiploma.js b/src/modules/dbRequests/setDiploma/setDiploma.js
index 8b27cc0..ffc282f 100644
--- a/src/modules/dbRequests/setDiploma/setDiploma.js
+++ b/src/modules/dbRequests/setDiploma/setDiploma.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { CERTS } = require("../mongo");
function setDiploma({ query = {}, data = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function setDiploma({ query = {}, data = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.CERTS.findOneAndUpdate(
+ return CERTS.findOneAndUpdate(
query,
{
$set: data,
@@ -21,4 +21,4 @@ function setDiploma({ query = {}, data = {}, returns = [] }) {
);
}
-module.exports.setDiploma = setDiploma;
+module.exports = setDiploma;
diff --git a/src/modules/dbRequests/setPayment/setPayment.js b/src/modules/dbRequests/setPayment/setPayment.js
new file mode 100644
index 0000000..f564af7
--- /dev/null
+++ b/src/modules/dbRequests/setPayment/setPayment.js
@@ -0,0 +1,16 @@
+const { log } = require("../../../services/logger/logger");
+const { PAYMENTS } = require("../mongo");
+
+function setPayment({ payment = {}, returns = [] }) {
+ const projection = {
+ _id: 0,
+ };
+ for (const param of returns) {
+ projection[param] = 1;
+ }
+ return PAYMENTS.insertOne(payment, {
+ projection,
+ });
+}
+
+module.exports = setPayment;
diff --git a/src/modules/dbRequests/setState/setState.js b/src/modules/dbRequests/setState/setState.js
index cbc723d..4de28d4 100644
--- a/src/modules/dbRequests/setState/setState.js
+++ b/src/modules/dbRequests/setState/setState.js
@@ -1,4 +1,4 @@
-const { db } = require("../mongo");
+const { STATE } = require("../mongo");
function setState({ query = {}, state = {}, returns = [] }) {
const projection = {
@@ -7,7 +7,7 @@ function setState({ query = {}, state = {}, returns = [] }) {
for (const param of returns) {
projection[param] = 1;
}
- return db.STATE.findOneAndUpdate(
+ return STATE.findOneAndUpdate(
query,
{
$set: state,
@@ -21,4 +21,4 @@ function setState({ query = {}, state = {}, returns = [] }) {
);
}
-module.exports.setState = setState;
+module.exports = setState;
diff --git a/src/modules/dbRequests/setUserInfo/setUserInfo.js b/src/modules/dbRequests/setUserInfo/setUserInfo.js
index ab7e0d6..6ed09c5 100644
--- a/src/modules/dbRequests/setUserInfo/setUserInfo.js
+++ b/src/modules/dbRequests/setUserInfo/setUserInfo.js
@@ -1,12 +1,22 @@
-const { db } = require("../mongo");
+const { USERS } = require("../mongo");
-async function setUserInfo({ email, data }) {
- const user = await db.USERS.findOneAndUpdate(
- { email },
+async function setUserInfo({ email, id, data }) {
+ const query = {}
+
+ if (email) {
+ query.email = email
+ }
+
+ if (id) {
+ query.id = id
+ }
+
+ const user = await USERS.findOneAndUpdate(
+ query,
{ $set: data },
{ upsert: false, returnDocument: "after" }
);
return user.value;
}
-module.exports.setUserInfo = setUserInfo;
+module.exports = setUserInfo;
diff --git a/src/modules/userTokens/accessTokens.js b/src/modules/userTokens/accessTokens.js
deleted file mode 100644
index 49877a5..0000000
--- a/src/modules/userTokens/accessTokens.js
+++ /dev/null
@@ -1,43 +0,0 @@
-function rand() {
- return Math.random().toString(36).substring(2);
-}
-
-function getToken() {
- const accessToken = rand() + rand();
- const refreshToken = rand();
- const expiresIn = Math.floor(Date.now() / 1000 + 7200);
- return {
- accessToken,
- expiresIn,
- refreshToken,
- };
-}
-
-function tokenMachine() {
- const tokens = {};
- function checkToken(token) {
- return tokens?.[token];
- }
-
- function setToken(user) {
- const newToken = getToken();
- tokens[newToken.accessToken] = {
- id: user?.id,
- };
- return newToken;
- }
-
- function checkList() {
- return tokens;
- }
- return {
- checkToken,
- setToken,
- checkList,
- };
-}
-
-const accessTokens = tokenMachine();
-
-module.exports.tokenMachine = tokenMachine;
-module.exports.accessTokens = accessTokens;
diff --git a/src/processes/authUser/authUser.js b/src/processes/authUser/authUser.js
deleted file mode 100644
index cdc007a..0000000
--- a/src/processes/authUser/authUser.js
+++ /dev/null
@@ -1,29 +0,0 @@
-const DB = require("@mongo/requests");
-const { setToken } = require("@tokenMachine/tokenMachine");
-
-/***
- * Function provides user's access token.
- * If user pushed to request a UI language, change it too.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object} User data on success
- */
-async function authUser(data) {
- const { lang, user } = data;
-
- user.token = setToken(user);
-
- if (lang && lang !== user.lang) {
- await DB.setOne("users", {
- query: { email: user.email },
- set: { lang },
- });
- user.lang = lang;
- }
-
- return user;
-}
-
-module.exports = authUser;
diff --git a/src/processes/checkAccess/checkAccess.js b/src/processes/checkAccess/checkAccess.js
deleted file mode 100644
index a84d17e..0000000
--- a/src/processes/checkAccess/checkAccess.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const { getModuleId } = require("@utils/idExtractor");
-const { calculateDeadline } = require("@utils/calculators");
-
-function checkDate(start, deadline) {
- if (!start && !deadline) return false;
- const today = Date.now();
- return today >= Date.parse(start) && today < Date.parse(deadline);
-}
-
-/**
- * Check student access to the module data
- *
- * @param {Object} data Throught API object
- *
- * @returns {boolean} Check result
- */
-function checkModuleAccess(data) {
- const { user, moduleId, lessonId, taskId, questionId } = data;
-
- const cutModuleId = moduleId || getModuleId(lessonId || taskId || questionId);
-
- const startDate = user?.modules?.[cutModuleId]?.start;
- const deadline = calculateDeadline(user?.modules?.[cutModuleId] || {});
-
- return checkDate(startDate, deadline);
-}
-
-/**
- * Checks student access to the module final page and the certificate
- *
- * @param {Object} data Throught API object
- *
- * @returns {boolean} Check result
- */
-function checkFinalAccess(data) {
- const { user, moduleId, module } = data;
- const modules = Object.keys(user?.modules);
- const isFinalAccess = modules.includes(moduleId || module.code);
- data.isFinalAccess = isFinalAccess;
- return isFinalAccess;
-}
-
-module.exports = { checkModuleAccess, checkFinalAccess };
diff --git a/src/processes/checkCredentials/checkCredentials.js b/src/processes/checkCredentials/checkCredentials.js
deleted file mode 100644
index 1c3a340..0000000
--- a/src/processes/checkCredentials/checkCredentials.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const { checkPass } = require("@utils/pass");
-
-/***
- * Function checks user's credentials.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {boolean} Check result
- */
-function checkCredentials(data, next) {
- const { user, pass } = data;
-
- const isPassValid = checkPass(user, pass);
-
- if (!isPassValid) {
- next({ code: 10102 });
- return false;
- }
-
- return true;
-}
-
-module.exports = checkCredentials;
diff --git a/src/processes/checkOTK/checkOTK.js b/src/processes/checkOTK/checkOTK.js
deleted file mode 100644
index 751a099..0000000
--- a/src/processes/checkOTK/checkOTK.js
+++ /dev/null
@@ -1,22 +0,0 @@
-const { checkKey } = require("@tokenMachine/OTK");
-
-/***
- * Function checks one-time key for password change.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {boolean} Check result
- */
-async function checkOTK(data, next) {
- const { key } = data;
-
- const verify = await checkKey(key);
- if (!verify) {
- next({ code: 10105 });
- return false;
- }
- return true;
-}
-
-module.exports = checkOTK;
diff --git a/src/processes/checkTransaction/checkTransaction.js b/src/processes/checkTransaction/checkTransaction.js
deleted file mode 100644
index 6abec4e..0000000
--- a/src/processes/checkTransaction/checkTransaction.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const DB = require("../../services/mongo/requests");
-
-/***
- * Function checks user transaction.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {boolean} Check result
- */
-async function checkTransaction(data, next) {
- const { paymentId } = data;
-
- const payment = await DB.getOne("payments", {
- query: { paymentId },
- });
-
- if (!payment) {
- next({ code: 10106 });
- return false;
- }
-
- data.email = payment.email;
-
- return true;
-}
-
-module.exports = checkTransaction;
diff --git a/src/processes/getCounselorInfo/getCounselorInfo.js b/src/processes/getCounselorInfo/getCounselorInfo.js
deleted file mode 100644
index 767401f..0000000
--- a/src/processes/getCounselorInfo/getCounselorInfo.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const DB = require("../../services/mongo/requests");
-
-/***
- * Function provides data for student counselor.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} Counselor data
- */
-async function getCounselorInfo(data) {
- const { lang } = data;
- const query = { lang };
-
- const counselor = await DB.getOne("counselor", {
- query,
- });
-
- if (!counselor) {
- throw new Error(`Can't find the counselor for language ${lang}`);
- }
-
- data.counselor = counselor;
-
- return counselor;
-}
-
-module.exports = getCounselorInfo;
diff --git a/src/processes/getLessonInfo/getLessonInfo.js b/src/processes/getLessonInfo/getLessonInfo.js
deleted file mode 100644
index ce6a4d4..0000000
--- a/src/processes/getLessonInfo/getLessonInfo.js
+++ /dev/null
@@ -1,39 +0,0 @@
-const DB = require("@mongo/requests");
-const { getModuleId, getLessonId } = require("@utils/idExtractor");
-
-/***
- * Function provides data for module's specific lesson.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Lesson's data on success; undefined on fail
- */
-async function getLessonInfo(data, next) {
- const fullLessonId = data.lessonId;
-
- const moduleId = getModuleId(fullLessonId);
- const lessonId = getLessonId(fullLessonId);
-
- const query = { code: moduleId };
-
- const moduleData = await DB.getOne("modules", { query });
-
- if (!moduleData) {
- next({ code: 10302 });
- return;
- }
-
- const lessonData = moduleData.lessons[lessonId];
-
- if (!lessonData) {
- next({ code: 10302 });
- return;
- }
-
- data.lesson = lessonData;
-
- return lessonData;
-}
-
-module.exports = getLessonInfo;
diff --git a/src/processes/getModuleInfo/getModuleInfo.js b/src/processes/getModuleInfo/getModuleInfo.js
deleted file mode 100644
index c2d3ed9..0000000
--- a/src/processes/getModuleInfo/getModuleInfo.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const DB = require("@mongo/requests");
-
-const DEMO = process.env.DEMO;
-
-/***
- * Function provides module's main data.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Lesson's data on success; undefined on fail
- */
-async function getModuleInfo(data, next) {
- const { moduleId } = data;
-
- if (moduleId) {
- const query = { code: moduleId };
- const moduleData = await DB.getOne("modules", { query });
- if (!moduleData) {
- next({ code: 10301 });
- return false;
- }
- data.module = moduleData;
- return moduleData;
- } else {
- const modulesList = await DB.getMany("modules", {
- query: DEMO ? {} : { active: true },
- });
- data.modulesList = modulesList;
- return modulesList;
- }
-}
-
-module.exports = getModuleInfo;
diff --git a/src/processes/getStateInfo/getStateInfo.js b/src/processes/getStateInfo/getStateInfo.js
deleted file mode 100644
index b7fb702..0000000
--- a/src/processes/getStateInfo/getStateInfo.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const DB = require("../../services/mongo/requests");
-
-/***
- * Function provides state data for requested item (full module | lesson | task).
- *
- * @param {Object} data Throught API object
- *
- * @returns {Array | Object} State data for task or array of state data objects
- */
-async function getStateInfo(data) {
- const { user, moduleId, lessonId, taskId } = data;
- const id = moduleId || lessonId || taskId;
- const query = {
- userId: user.id,
- taskId: { $regex: `^${id}` },
- };
-
- const stateData = taskId
- ? await DB.getOne("state", { query })
- : await DB.getMany("state", { query });
-
- data.state = stateData;
-
- return stateData;
-}
-
-module.exports = getStateInfo;
diff --git a/src/processes/getTaskInfo/getTaskInfo.js b/src/processes/getTaskInfo/getTaskInfo.js
deleted file mode 100644
index 60b5274..0000000
--- a/src/processes/getTaskInfo/getTaskInfo.js
+++ /dev/null
@@ -1,30 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function provides task data.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} Task data on success; undefined on fail
- */
-async function getTaskInfo(data, next) {
- const { taskId, returns } = data;
- const query = { id: taskId };
-
- const taskData = await DB.getOne("tasks", {
- query,
- returns,
- });
-
- if (!taskData) {
- next({ code: 10303 });
- return;
- }
-
- data.task = taskData;
-
- return taskData;
-}
-
-module.exports = getTaskInfo;
diff --git a/src/processes/getUserInfo/getUserInfo.js b/src/processes/getUserInfo/getUserInfo.js
deleted file mode 100644
index 43485a1..0000000
--- a/src/processes/getUserInfo/getUserInfo.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function provides main user info.
- *
- * @param {Object} data Throught API object
- * @param {Function} next Express middleware next function
- *
- * @returns {Object | undefined} User data on success; undefined in fail
- */
-async function getUserInfo(data, next) {
- const { email, userId } = data;
- const query = { email, id: userId };
- Object.keys(query).forEach((key) => {
- if (!query[key]) {
- delete query[key];
- }
- });
-
- const user = await DB.getOne("users", {
- query,
- });
-
- if (!user) {
- next({ code: 10101 });
- return;
- }
-
- data.user = user;
-
- return user;
-}
-
-module.exports = getUserInfo;
diff --git a/src/processes/prepareData/prepareCertificateData/certGenerator.js b/src/processes/prepareData/prepareCertificateData/certGenerator.js
deleted file mode 100644
index e6180cf..0000000
--- a/src/processes/prepareData/prepareCertificateData/certGenerator.js
+++ /dev/null
@@ -1,23 +0,0 @@
-const sharp = require("sharp");
-const crypto = require("crypto");
-const fs = require("fs");
-const path = require("node:path");
-const { buildSvg } = require("svg-content");
-
-async function createCert(data) {
- const svg = fs.readFileSync(`./templates/diplomas/poster.svg`).toString();
- const processed = buildSvg(svg, data);
- const fileId = crypto.createHash("sha256").update(data.certId).digest("hex");
-
- const buffer = Buffer.from(processed);
- const folderPath = path.resolve(`./diplomas/${fileId}`);
- if (!fs.existsSync(folderPath)) {
- fs.mkdirSync(`./diplomas/${fileId}`, { recursive: true });
- }
- await sharp(buffer, { density: 150 })
- .png()
- .toFile(folderPath + `/medium.png`);
- return fileId;
-}
-
-module.exports = createCert;
diff --git a/src/processes/prepareData/prepareCertificateData/generateCertId.js b/src/processes/prepareData/prepareCertificateData/generateCertId.js
deleted file mode 100644
index a140d22..0000000
--- a/src/processes/prepareData/prepareCertificateData/generateCertId.js
+++ /dev/null
@@ -1,36 +0,0 @@
-const DB = require("@mongo/requests");
-
-function padder(number = 0, count = 1) {
- return number.toString().padStart(count, "0");
-}
-
-async function generateCertId(userId, moduleId, startDate) {
- const certsCount =
- (await DB.count("certs", { query: { moduleId, startDate } })) || 0;
-
- const postfix = padder(certsCount + 1, 4);
- const date = new Date(Date.parse(startDate));
- const datePart = `${padder(date.getFullYear() - 2000, 2)}${padder(
- date.getMonth(),
- 2
- )}`;
- const certId = `${moduleId}${datePart}${postfix}`;
-
- DB.insertOne("certs", {
- query: {
- id: certId,
- userId,
- moduleId,
- startDate,
- public: false,
- },
- });
-
- const path = `modules.${moduleId}.certId`;
-
- DB.setOne("users", { query: { id: userId }, set: { [path]: certId } });
-
- return certId;
-}
-
-module.exports = generateCertId;
diff --git a/src/processes/prepareData/prepareCertificateData/generateSkills.js b/src/processes/prepareData/prepareCertificateData/generateSkills.js
deleted file mode 100644
index acd1d03..0000000
--- a/src/processes/prepareData/prepareCertificateData/generateSkills.js
+++ /dev/null
@@ -1,93 +0,0 @@
-const { getDBRequest } = require("../../../modules/dbRequests/dbRequests");
-const { SKILLS } = require("./skillsDict");
-
-async function getMaxScore(taskId) {
- const data = await getDBRequest("getTaskInfo", {
- query: { id: taskId },
- returns: ["maxScore"],
- });
-
- return data?.maxScore || 0;
-}
-
-async function getScore(userId, taskId) {
- const data = await getDBRequest("getStateInfo", {
- query: {
- userId,
- taskId,
- },
- returns: ["score"],
- });
-
- return data?.score || 0;
-}
-
-async function scoreIterator(userId, tasks = []) {
- let score = 0;
- let maxScore = 0;
-
- for (taskId of tasks) {
- const taskScore = await getScore(userId, taskId);
- const taskMaxScore = await getMaxScore(taskId);
-
- score += taskScore;
- maxScore += taskMaxScore;
- }
-
- return [score, maxScore];
-}
-
-async function getOneSkill(userId, skill) {
- const skillData = {
- name: skill.name,
- };
-
- let score = 0;
- let maxScore = 0;
-
- if (!skill.subskills) {
- [score, maxScore] = await scoreIterator(userId, skill.tasks);
- } else {
- const subskills = [];
- for (subskill of skill.subskills) {
- const subskillData = {
- name: subskill.name,
- code: subskill.code,
- };
-
- const [subskillScore, subskillMaxScore] = await scoreIterator(
- userId,
- subskill.tasks
- );
-
- const progress = Math.trunc((subskillScore / subskillMaxScore) * 100);
-
- subskillData.progress = progress;
-
- subskills.push(subskillData);
-
- score += subskillScore;
- maxScore += subskillMaxScore;
- }
-
- skillData.subskills = subskills;
- }
-
- const progress = Math.trunc((score / maxScore) * 100);
-
- skillData.progress = progress;
-
- return skillData;
-}
-
-async function generateSkills(moduleId, userId, lang) {
- const skills = [];
-
- for (const skill of SKILLS[lang][moduleId] || []) {
- skills.push(await getOneSkill(userId, skill));
- }
-
- return skills;
-}
-
-module.exports = generateSkills;
diff --git a/src/processes/prepareData/prepareCertificateData/moduleNameHyphenate.js b/src/processes/prepareData/prepareCertificateData/moduleNameHyphenate.js
deleted file mode 100644
index 8e00642..0000000
--- a/src/processes/prepareData/prepareCertificateData/moduleNameHyphenate.js
+++ /dev/null
@@ -1,28 +0,0 @@
-const dict = {
- ru: {
- HSB: "Hard Skills начинающего\nруководителя",
- MIO: "Информационные\nожидания",
- TXT: "Несекретные\nсекреты текстов",
- UCC: "Сценарии\nвзаимодействия",
- COM: "Композиция\nв дизайне интерфейсов",
- },
- en: {
- HSB: "Novice Manager\nHard Skills",
- MIO: "Informational\nexpectations",
- TXT: "Non-secret\nSecrets of Text Writing",
- UCC: "Use cases\nin Interface Design",
- COM: "Composition\nin Interface Design",
- },
-};
-
-/**
- * @param {string} lang
- * @param {string} code
- * @returns {string}
- */
-function hyphenate(lang, code) {
- if (dict[lang][code]) return dict[lang][code];
- throw new Error("Module name with this code wasn't found!");
-}
-
-module.exports = hyphenate;
diff --git a/src/processes/prepareData/prepareCertificateData/prepareCertificateData.js b/src/processes/prepareData/prepareCertificateData/prepareCertificateData.js
deleted file mode 100644
index 209860c..0000000
--- a/src/processes/prepareData/prepareCertificateData/prepareCertificateData.js
+++ /dev/null
@@ -1,120 +0,0 @@
-const setDiploma = require("../../setDiploma/setDiploma");
-const generateSkills = require("./generateSkills");
-const generateCertId = require("./generateCertId");
-const createCert = require("./certGenerator");
-const provideData = require("./provideData");
-const CyrillicToTranslit = require("cyrillic-to-translit-js");
-
-async function prepareCertificateData(data) {
- const cyrillicToTranslit = new CyrillicToTranslit();
- const {
- userId,
- moduleId,
- params: { lang, isColor, isMascot, isProgress, isPublic } = {},
- user,
- module,
- state,
- } = data;
-
- const params = {
- lang: lang || undefined,
- isColor: isColor ? isColor === "true" : undefined,
- isMascot: isMascot ? isMascot === "true" : undefined,
- isProgress: isProgress ? isProgress === "true" : undefined,
- isPublic: isPublic ? isPublic === "true" : undefined,
- };
-
- for (const key of Object.keys(params)) {
- if (params[key] === undefined) delete params[key];
- }
-
- const start = user?.modules?.[moduleId]?.deadline;
- const deadline = user?.modules?.[moduleId]?.deadline;
- const now = new Date(Date.now()).toISOString().split("T")[0];
- const certDate = Date.parse(deadline) < Date.parse(now) ? deadline : now;
-
- const certId =
- user?.modules?.[moduleId]?.certId ||
- (await generateCertId(userId, moduleId, start));
-
- const certData = await setDiploma({
- query: { id: certId },
- params,
- returns: ["lang", "isColor", "isMascot", "isProgress", "isPublic"],
- });
-
- Object.assign(params, certData?.value || {});
-
- if (params.lang === undefined) params.lang = module.lang;
- if (params.isColor === undefined) params.isColor = false;
- if (params.isMascot === undefined) params.isMascot = true;
- if (params.isProgress === undefined) params.isProgress = true;
- if (params.isPublic === undefined) params.isPublic = false;
-
- const firstName =
- params.lang === "ru"
- ? user.firstName
- : cyrillicToTranslit.transform(user.firstName);
- const lastName =
- params.lang === "ru"
- ? user.lastName
- : cyrillicToTranslit.transform(user.lastName);
-
- const score = state.reduce(
- (progress, value) => progress + (value?.score || 0),
- 0
- );
-
- const maxScore = Object.values(module?.lessons).reduce((sum, lesson) => {
- return (sum += lesson.maxScore || 0);
- }, 0);
-
- const doneTasks = state.reduce((progress, value) => {
- if (value.isChecked) {
- return ++progress;
- } else return progress;
- }, 0);
-
- const progress = Math.trunc((score / maxScore) * 100);
-
- const skills = await generateSkills(
- moduleId,
- userId,
- params.lang || module.lang
- );
-
- const info = {
- moduleId,
- moduleName: module?.name,
- firstName,
- lastName,
- certId,
- certDate,
- progress,
- skills,
- };
-
- const fullInfo = provideData(info, params);
-
- const fileId = await createCert(fullInfo);
-
- return {
- moduleId,
- moduleName: module.name,
- userId,
- firstName,
- lastName,
- start,
- deadline,
- certDate,
- certId,
- score,
- maxScore,
- skills,
- fileId,
- doneTasks,
- ...params,
- };
-}
-
-module.exports = prepareCertificateData;
diff --git a/src/processes/prepareData/prepareCertificateData/provideData.js b/src/processes/prepareData/prepareCertificateData/provideData.js
deleted file mode 100644
index 85a5e7c..0000000
--- a/src/processes/prepareData/prepareCertificateData/provideData.js
+++ /dev/null
@@ -1,92 +0,0 @@
-const getPhrase = require("../../../assets/lang/lang");
-const colors = require("../../../assets/colors.json");
-const hyphenate = require("./moduleNameHyphenate");
-
-const locales = {
- ru: "ru-RU",
- en: "en-US",
-};
-
-function getCertType(progress = 0) {
- return progress >= 80
- ? "certType++"
- : progress >= 60
- ? "certType+"
- : "certType";
-}
-
-function processTexts(lang, moduleId, certType, certDate) {
- const date = new Date(certDate || "2023-01-01")
- .toLocaleDateString(locales[lang], {
- day: "numeric",
- month: "long",
- year: "numeric",
- })
- .replace(" г.", "");
- return {
- moduleName: hyphenate(lang, moduleId),
- certDescription: getPhrase(lang, "certDescription"),
- certType: getPhrase(lang, certType),
- certCheck1: getPhrase(lang, "certCheck1"),
- certCheck2: getPhrase(lang, "certCheck2"),
- certSignName: getPhrase(lang, "certSignName"),
- certSignPos: getPhrase(lang, "certSignPos"),
- certDate: date,
- };
-}
-
-function processColors(moduleId, progress, params) {
- const { isColor, isMascot, isProgress } = params;
- const bgColor = isColor ? colors[moduleId]?.primary : "#FFFFFF";
-
- let primaryColor;
- if (moduleId === "MIO") {
- primaryColor = isColor ? "#000000" : colors[moduleId]?.primary;
- } else {
- primaryColor = isColor ? "#FFFFFF" : colors[moduleId]?.primary;
- }
-
- const textColor = !isColor || moduleId === "MIO" ? "#101010" : "#FFFFFF";
- const signColor = !isColor || moduleId === "MIO" ? "b" : "w";
- const skillOpacity = isProgress
- ? isColor
- ? moduleId === "MIO"
- ? "0.6"
- : "0.77"
- : "1"
- : "0";
- const mascotOpacity =
- !isMascot || isColor ? "0" : progress >= 60 ? "1" : "0.3";
- const progressOpacity = isProgress ? (progress >= 60 ? "1" : "0.3") : "0";
- const headerOpacity = progress < 60 ? "0.1" : "1";
-
- return {
- bgColor,
- primaryColor,
- textColor,
- signColor,
- skillOpacity,
- mascotOpacity,
- progressOpacity,
- headerOpacity,
- };
-}
-
-function provideData(data, params) {
- const { moduleId, progress, certDate } = data;
- const { lang } = params;
-
- const certType = getCertType(progress);
-
- const textData = processTexts(lang, moduleId, certType, certDate);
- const colorData = processColors(moduleId, progress, params);
-
- return {
- ...data,
- ...params,
- ...textData,
- ...colorData,
- };
-}
-
-module.exports = provideData;
diff --git a/src/processes/prepareData/prepareCertificateData/skillsDict.js b/src/processes/prepareData/prepareCertificateData/skillsDict.js
deleted file mode 100644
index 2389e6d..0000000
--- a/src/processes/prepareData/prepareCertificateData/skillsDict.js
+++ /dev/null
@@ -1,2409 +0,0 @@
-const ru = {
- MIO: [
- {
- name: "теоретическая часть",
- subskills: [
- {
- code: "iBase",
- name: "разбираться в основах",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0207",
- "MIO0302",
- "MIO0303",
- "MIO0306",
- "MIO0706",
- "MIO0710",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0717",
- "MIO0803",
- "MIO0804",
- "MIO0805",
- "MIO0807",
- "MIO0809",
- "MIO0810",
- "MIO0811",
- "MIO0812",
- "MIO0814",
- "MIO0815",
- "MIO0816",
- ],
- },
- {
- code: "iLook",
- name: "видеть интерфейс глазами пользователя",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0109",
- "MIO0110",
- "MIO0112",
- "MIO0113",
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0207",
- "MIO0208",
- "MIO0209",
- "MIO0302",
- "MIO0303",
- "MIO0306",
- "MIO0307",
- "MIO0404",
- "MIO0417",
- "MIO0812",
- "MIO0902",
- "MIO0903",
- "MIO0911",
- ],
- },
- {
- code: "iDraw",
- name: "рисовать интерфейс",
- tasks: [
- "MIO0308",
- "MIO00310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0612",
- "MIO0804",
- "MIO0807",
- "MIO0812",
- "MIO0905",
- ],
- },
- {
- code: "iTell",
- name: "объяснять другим",
- tasks: ["MIO0707", "MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "iSelf",
- name: "саморазвиваться",
- tasks: ["MIO0715"],
- },
- ],
- },
- {
- name: "думайте",
- subskills: [
- {
- code: "aZero",
- name: "создавать требования с нуля",
- tasks: [
- "MIO0302",
- "MIO0303",
- "MIO0509",
- "MIO0711",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0804",
- "MIO0807",
- ],
- },
- {
- code: "aLook",
- name: "понимать логику чужого интерфейса",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0109",
- "MIO0110",
- "MIO0112",
- "MIO0113",
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0207",
- "MIO0208",
- "MIO0209",
- "MIO0210",
- "MIO0306",
- "MIO0307",
- "MIO0404",
- ],
- },
- {
- code: "aImp",
- name: "находить места для локальных улучшений",
- tasks: [
- "MIO0204",
- "MIO0205",
- "MIO0304",
- "MIO0305",
- "MIO0312",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0509",
- "MIO0603",
- "MIO0604",
- "MIO0605",
- "MIO0606",
- "MIO0607",
- "MIO0609",
- "MIO0610",
- "MIO0611",
- "MIO0612",
- "MIO0613",
- "MIO0614",
- "MIO0702",
- "MIO0703",
- "MIO0707",
- "MIO0708",
- "MIO0709",
- "MIO0711",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0903",
- "MIO0906",
- ],
- },
- {
- code: "aDraft",
- name: "понимать, стоит ли доводить эскизы до ума",
- tasks: [
- "MIO0112",
- "MIO0113",
- "MIO0208",
- "MIO0209",
- "MIO0210",
- "MIO0307",
- ],
- },
- {
- code: "aWork",
- name: "понимать, будет ли интерфейс работать",
- tasks: [
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0204",
- "MIO0205",
- "MIO0404",
- "MIO0409",
- ],
- },
- {
- code: "aFix",
- name: "фиксировать приоритеты",
- tasks: [
- "MIO0204",
- "MIO0205",
- "MIO0210",
- "MIO0410",
- "MIO0415",
- "MIO0417",
- "MIO0502",
- "MIO0705",
- "MIO0913",
- "MIO0914",
- "MIO0915",
- ],
- },
- {
- code: "aLis",
- name: "составлять список экранов",
- tasks: ["MIO0109", "MIO0110", "MIO0706", "MIO0715", "MIO0904"],
- },
- {
- code: "aPlus",
- name: "понимать, какие еще экраны нужны системе",
- tasks: ["MIO0109", "MIO0110", "MIO0706", "MIO0715", "MIO0904"],
- },
- ],
- },
- {
- name: "рисуйте",
- subskills: [
- {
- code: "pSketch",
- name: "делать быстрые наброски",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- ],
- },
- {
- code: "pMain",
- name: "рисовать только самое главное, без деталей",
- tasks: ["MIO0913", "MIO0914", "MIO0915"],
- },
- {
- code: "pReq",
- name: "рисовать чётко по требованиям",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0612",
- "MIO0709",
- ],
- },
- {
- code: "pImp",
- name: "рисовать небольшие улучшения в интерфейсе",
- tasks: ["MIO0613", "MIO0614", "MIO0703", "MIO0708", "MIO0709"],
- },
- {
- code: "pStart",
- name: "просто — начать — рисовать",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0312",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0410",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0415",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0502",
- "MIO0705",
- "MIO0905",
- "MIO0916",
- ],
- },
- ],
- },
- {
- name: "тестируйте",
- subskills: [
- {
- code: "tReq",
- name: "уточнять требования",
- tasks: [
- "MIO0503",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0707",
- ],
- },
- {
- code: "tPic",
- name: "тестировать интерфейс",
- tasks: [
- "MIO0503",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0707",
- "MIO0708",
- "MIO0909",
- ],
- },
- ],
- },
- {
- name: "обсуждайте",
- subskills: [
- {
- code: "dCol",
- name: "обсудить с коллегой",
- tasks: ["MIO0503", "MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "dTeam",
- name: "обсудить в команде",
- tasks: ["MIO0503", "MIO0909", "MIO0910", "MIO0911"],
- },
- ],
- },
- {
- name: "организуйте",
- subskills: [
- {
- code: "mUser",
- name: "работать для пользователя",
- tasks: ["MIO0907", "MIO0915"],
- },
- {
- code: "mTask",
- name: "поставить задачу дизайнеру, принять результат",
- tasks: ["MIO0904", "MIO0909", "MIO0910"],
- },
- {
- code: "mDev",
- name: "внедрить дизайн в IT-производство",
- tasks: ["MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "mSale",
- name: "презентовать интерфейс",
- tasks: ["MIO0715"],
- },
- ],
- },
- {
- name: "бизнес",
- subskills: [
- {
- code: "bNew",
- name: "нарисовать новый интерфейс",
- tasks: [
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0910",
- "MIO0916",
- ],
- },
- {
- code: "bLeg",
- name: "заботиться о старой системе",
- tasks: [
- "MIO0613",
- "MIO0604",
- "MIO0605",
- "MIO0606",
- "MIO0607",
- "MIO0609",
- "MIO0610",
- "MIO0611",
- "MIO0612",
- "MIO0613",
- "MIO0614",
- "MIO0702",
- "MIO0703",
- "MIO0906",
- ],
- },
- {
- code: "bOK",
- name: "делать нормально",
- tasks: ["MIO0715"],
- },
- ],
- },
- ],
- TXT: [
- {
- name: "текст как рабочий навык",
- tasks: [
- "TXT0103",
- "TXT0104",
- "TXT0106",
- "TXT0107",
- "TXT0108",
- "TXT0109",
- "TXT0111",
- "TXT0112",
- "TXT0113",
- "TXT0114",
- "TXT0115",
- "TXT0116",
- "TXT0119",
- "TXT0120",
- "TXT0121",
- "TXT0122",
- ],
- },
- {
- name: "интерфейсный текст",
- tasks: [
- "TXT0202",
- "TXT0204",
- "TXT0205",
- "TXT0207",
- "TXT0208",
- "TXT0209",
- "TXT0210",
- "TXT0211",
- "TXT0212",
- "TXT0214",
- "TXT0215",
- "TXT0216",
- "TXT0218",
- "TXT0220",
- "TXT0222",
- "TXT0223",
- "TXT0224",
- "TXT0226",
- "TXT0227",
- ],
- },
- {
- name: "командная работа",
- tasks: [
- "TXT0303",
- "TXT0304",
- "TXT0305",
- "TXT0306",
- "TXT0307",
- "TXT0308",
- "TXT0309",
- "TXT0311",
- "TXT0312",
- "TXT0313",
- "TXT0314",
- "TXT0316",
- "TXT0317",
- "TXT0318",
- "TXT0319",
- "TXT0320",
- ],
- },
- {
- name: "понимание читателей",
- tasks: [
- "TXT0402",
- "TXT0403",
- "TXT0404",
- "TXT0405",
- "TXT0406",
- "TXT0408",
- "TXT0409",
- "TXT0410",
- "TXT0411",
- "TXT0412",
- "TXT0413",
- "TXT0414",
- "TXT0416",
- "TXT0417",
- "TXT0418",
- "TXT0420",
- "TXT0421",
- "TXT0422",
- "TXT0423",
- "TXT0424",
- "TXT0426",
- "TXT0427",
- "TXT0428",
- "TXT0429",
- "TXT0431",
- "TXT0502",
- "TXT0503",
- "TXT0505",
- "TXT0506",
- "TXT0508",
- "TXT0509",
- "TXT0510",
- "TXT0511",
- "TXT0513",
- "TXT0514",
- "TXT0516",
- "TXT0517",
- "TXT0518",
- "TXT0519",
- "TXT0521",
- ],
- },
- {
- name: "механики быстрого улучшайзинга",
- tasks: [
- "TXT0602",
- "TXT0605",
- "TXT0606",
- "TXT0607",
- "TXT0609",
- "TXT0610",
- "TXT0612",
- "TXT0614",
- "TXT0616",
- "TXT0617",
- "TXT0618",
- "TXT0619",
- "TXT0621",
- "TXT0623",
- "TXT0625",
- "TXT0627",
- "TXT0628",
- ],
- },
- {
- name: "работа на уровне текста",
- tasks: [
- "TXT0703",
- "TXT0704",
- "TXT0705",
- "TXT0707",
- "TXT0709",
- "TXT0710",
- "TXT0711",
- "TXT0713",
- "TXT0714",
- "TXT0716",
- "TXT0717",
- "TXT0718",
- "TXT0719",
- "TXT0720",
- "TXT0721",
- "TXT0723",
- "TXT0724",
- ],
- },
- {
- name: "экстремальная писанина",
- tasks: [
- "TXT0803",
- "TXT0804",
- "TXT0805",
- "TXT0807",
- "TXT0808",
- "TXT0809",
- "TXT0811",
- "TXT0812",
- "TXT0814",
- "TXT0815",
- "TXT0816",
- "TXT0817",
- "TXT0819",
- "TXT0821",
- "TXT0822",
- "TXT0823",
- "TXT0824",
- "TXT0826",
- "TXT0827",
- "TXT0828",
- "TXT0829",
- "TXT0830",
- "TXT0831",
- "TXT0832",
- "TXT0833",
- ],
- },
- {
- name: "лайфхаки",
- tasks: [
- "TXT0903",
- "TXT0904",
- "TXT0905",
- "TXT0907",
- "TXT0908",
- "TXT0909",
- "TXT0910",
- "TXT0912",
- "TXT0913",
- "TXT0914",
- "TXT0916",
- "TXT0917",
- "TXT0919",
- "TXT0920",
- "TXT0921",
- ],
- },
- ],
- HSB: [
- {
- name: "жонглирование навыками команды",
- tasks: [
- "HSB0104",
- "HSB0105",
- "HSB0107",
- "HSB0108",
- "HSB0110",
- "HSB0112",
- "HSB0113",
- "HSB0114",
- "HSB0116",
- "HSB0117",
- "HSB0119",
- "HSB0120",
- "HSB0122",
- "HSB0123",
- "HSB0125",
- "HSB0126",
- "HSB0127",
- ],
- },
- {
- name: "озадачивание подчинённых",
- tasks: [
- "HSB0203",
- "HSB0204",
- "HSB0205",
- "HSB0206",
- "HSB0208",
- "HSB0210",
- "HSB0211",
- "HSB0212",
- "HSB0213",
- "HSB0215",
- "HSB0217",
- "HSB0219",
- "HSB0220",
- "HSB0222",
- "HSB0224",
- "HSB0225",
- ],
- },
- {
- name: "работа с конкретным сотрудником",
- tasks: [
- "HSB0303",
- "HSB0305",
- "HSB0306",
- "HSB0308",
- "HSB0310",
- "HSB0311",
- "HSB0312",
- "HSB0314",
- "HSB0315",
- "HSB0316",
- "HSB0318",
- "HSB0319",
- "HSB0321",
- "HSB0323",
- "HSB0325",
- "HSB0326",
- "HSB0328",
- "HSB0330",
- "HSB0331",
- "HSB0333",
- ],
- },
- {
- name: "как стать начальником",
- tasks: [
- "HSB0404",
- "HSB0405",
- "HSB0407",
- "HSB0409",
- "HSB0411",
- "HSB0413",
- "HSB0415",
- "HSB0417",
- "HSB0419",
- "HSB0421",
- "HSB0423",
- "HSB0425",
- "HSB0426",
- "HSB0427",
- ],
- },
- {
- name: "принуждение к простоте",
- tasks: [
- "HSB0503",
- "HSB0504",
- "HSB0505",
- "HSB0506",
- "HSB0507",
- "HSB0508",
- "HSB0510",
- "HSB0511",
- "HSB0512",
- "HSB0513",
- "HSB0514",
- "HSB0516",
- "HSB0517",
- "HSB0518",
- "HSB0520",
- ],
- },
- {
- name: "внедрение серебряных пуль",
- tasks: [
- "HSB0602",
- "HSB0603",
- "HSB0604",
- "HSB0606",
- "HSB0607",
- "HSB0609",
- "HSB0611",
- "HSB0613",
- "HSB0614",
- "HSB0616",
- "HSB0618",
- "HSB0620",
- ],
- },
- {
- name: "культура переписки. Деньги",
- tasks: [
- "HSB0702",
- "HSB0703",
- "HSB0704",
- "HSB0705",
- "HSB0706",
- "HSB0707",
- "HSB0708",
- "HSB0709",
- "HSB0711",
- "HSB0712",
- "HSB0714",
- "HSB0715",
- "HSB0716",
- "HSB0717",
- "HSB0719",
- "HSB0721",
- "HSB0722",
- ],
- },
- {
- name: "навыки продалбывания задачи",
- tasks: [
- "HSB0803",
- "HSB0804",
- "HSB0806",
- "HSB0807",
- "HSB0808",
- "HSB0810",
- "HSB0811",
- "HSB0812",
- "HSB0814",
- "HSB0815",
- "HSB0817",
- "HSB0819",
- "HSB0820",
- ],
- },
- {
- name: "лайфхаки",
- tasks: [
- "HSB0902",
- "HSB0903",
- "HSB0905",
- "HSB0907",
- "HSB0909",
- "HSB0910",
- "HSB0911",
- "HSB0913",
- "HSB0915",
- "HSB0917",
- "HSB0918",
- "HSB0919",
- ],
- },
- ],
- COM: [
- {
- name: "ключевая задача интерфейсной композиции",
- tasks: [
- "COM0102",
- "COM0103",
- "COM0104",
- "COM0106",
- "COM0107",
- "COM0108",
- "COM0109",
- "COM0110",
- "COM0111",
- "COM0112",
- "COM0114",
- "COM0115",
- "COM0116",
- "COM0118",
- "COM0119",
- "COM0120",
- "COM0121",
- "COM0122",
- "COM0124",
- "COM0125",
- "COM0126",
- "COM0127",
- "COM0128",
- "COM0130",
- "COM0131",
- "COM0132",
- ],
- },
- {
- name: "история в композиции интерфейса",
- tasks: [
- "COM0203",
- "COM0204",
- "COM0205",
- "COM0207",
- "COM0210",
- "COM0211",
- "COM0212",
- "COM0214",
- "COM0215",
- "COM0216",
- "COM0218",
- "COM0219",
- "COM0220",
- ],
- },
- {
- name: "ритм в композиции интерфейса",
- tasks: [
- "COM0303",
- "COM0305",
- "COM0306",
- "COM0308",
- "COM0309",
- "COM0311",
- "COM0312",
- "COM0314",
- "COM0315",
- "COM0317",
- "COM0319",
- "COM0321",
- "COM0322",
- "COM0323",
- "COM0324",
- "COM0325",
- "COM0326",
- "COM0328",
- "COM0329",
- "COM0331",
- "COM0332",
- "COM0333",
- "COM0335",
- ],
- },
- {
- name: "симметрия",
- tasks: [
- "COM0402",
- "COM0403",
- "COM0404",
- "COM0405",
- "COM0407",
- "COM0408",
- "COM0409",
- "COM0411",
- "COM0412",
- "COM0413",
- "COM0414",
- "COM0416",
- "COM0418",
- "COM0420",
- "COM0421",
- "COM0423",
- "COM0424",
- "COM0426",
- "COM0427",
- "COM0428",
- "COM0431",
- "COM0432",
- "COM0433",
- ],
- },
- {
- name: "контраст",
- tasks: [
- "COM0502",
- "COM0503",
- "COM0504",
- "COM0506",
- "COM0507",
- "COM0509",
- "COM0511",
- "COM0512",
- "COM0514",
- "COM0515",
- "COM0517",
- "COM0519",
- "COM0520",
- "COM0522",
- "COM0524",
- "COM0525",
- "COM0527",
- "COM0528",
- "COM0530",
- "COM0531",
- "COM0532",
- "COM0533",
- ],
- },
- {
- name: "когнитивная композиция",
- tasks: [
- "COM0603",
- "COM0604",
- "COM0607",
- "COM0608",
- "COM0613",
- "COM0615",
- "COM0617",
- "COM0619",
- "COM0621",
- "COM0622",
- "COM0625",
- "COM0626",
- "COM0627",
- "COM0628",
- ],
- },
- {
- name: "композиционная грамотность",
- tasks: [
- "COM0704",
- "COM0705",
- "COM0707",
- "COM0708",
- "COM0710",
- "COM0711",
- "COM0713",
- "COM0714",
- "COM0716",
- "COM0717",
- "COM0718",
- "COM0719",
- ],
- },
- {
- name: "улучшение интерфейса",
- tasks: [
- "COM0803",
- "COM0804",
- "COM0805",
- "COM0807",
- "COM0809",
- "COM0810",
- "COM0811",
- "COM0814",
- "COM0815",
- "COM0816",
- ],
- },
- {
- name: "лайфхаки",
- tasks: [
- "COM0902",
- "COM0903",
- "COM0904",
- "COM0905",
- "COM0906",
- "COM0908",
- "COM0910",
- "COM0911",
- "COM0913",
- "COM0915",
- "COM0917",
- ],
- },
- ],
- UCC: [
- {
- name: "сценарная теория",
- tasks: [
- "UCC0107",
- "UCC0109",
- "UCC0111",
- "UCC0113",
- "UCC0115",
- "UCC0117",
- "UCC0119",
- "UCC0121",
- "UCC0123",
- "UCC0125",
- ],
- },
- {
- name: "основы работы со сценариями",
- tasks: [
- "UCC0203",
- "UCC0205",
- "UCC0209",
- "UCC0211",
- "UCC0213",
- "UCC0215",
- "UCC0217",
- "UCC0219",
- "UCC0221",
- "UCC0223",
- "UCC0225",
- "UCC0226",
- "UCC0228",
- "UCC0230",
- "UCC0232",
- "UCC0234",
- ],
- },
- {
- name: "управление дизайном и разработкой",
- tasks: [
- "UCC0303",
- "UCC0304",
- "UCC0305",
- "UCC0307",
- "UCC0308",
- "UCC0309",
- "UCC0311",
- "UCC0312",
- "UCC0313",
- "UCC0314",
- "UCC0315",
- "UCC0316",
- "UCC0317",
- "UCC0318",
- ],
- },
- {
- name: "создание интерфейсов по сценариям",
- tasks: [
- "UCC0403",
- "UCC0404",
- "UCC0405",
- "UCC0406",
- "UCC0407",
- "UCC0408",
- "UCC0409",
- "UCC0410",
- "UCC0411",
- "UCC0413",
- "UCC0415",
- "UCC0416",
- "UCC0417",
- "UCC0418",
- "UCC0419",
- "UCC0421",
- "UCC0422",
- "UCC0423",
- "UCC0424",
- "UCC0426",
- "UCC0502",
- "UCC0503",
- "UCC0504",
- "UCC0505",
- "UCC0508",
- "UCC0509",
- "UCC0510",
- "UCC0511",
- "UCC0513",
- "UCC0514",
- "UCC0515",
- "UCC0602",
- "UCC0604",
- "UCC0606",
- "UCC0608",
- "UCC0609",
- "UCC0610",
- "UCC0611",
- "UCC0612",
- "UCC0614",
- "UCC0615",
- "UCC0616",
- "UCC0617",
- ],
- },
- {
- name: "метазадачи",
- tasks: [
- "UCC0703",
- "UCC0704",
- "UCC0705",
- "UCC0706",
- "UCC0707",
- "UCC0708",
- "UCC0710",
- "UCC0711",
- "UCC0713",
- "UCC0714",
- "UCC0715",
- "UCC0716",
- "UCC0717",
- "UCC0718",
- "UCC0719",
- "UCC0721",
- "UCC0722",
- "UCC0723",
- "UCC0724",
- ],
- },
- {
- name: "логика сценарных интерфейсов",
- tasks: [
- "UCC0803",
- "UCC0805",
- "UCC0806",
- "UCC0808",
- "UCC0809",
- "UCC0810",
- "UCC0812",
- "UCC0813",
- "UCC0814",
- "UCC0816",
- "UCC0817",
- "UCC0818",
- "UCC0819",
- "UCC0821",
- "UCC0822",
- "UCC0823",
- "UCC0825",
- "UCC0826",
- ],
- },
- {
- name: "нюансы и задачи развития",
- tasks: [
- "UCC0903",
- "UCC0904",
- "UCC0905",
- "UCC0906",
- "UCC0908",
- "UCC0909",
- "UCC0910",
- "UCC0911",
- "UCC0913",
- "UCC0914",
- "UCC0915",
- "UCC0916",
- "UCC0917",
- "UCC0919",
- "UCC0920",
- "UCC0921",
- "UCC0922",
- "UCC0924",
- "UCC0925",
- "UCC0927",
- "UCC0928",
- "UCC0930",
- "UCC0931",
- "UCC0932",
- "UCC0933",
- ],
- },
- ],
-};
-
-const en = {
- MIO: [
- {
- name: "Theory",
- subskills: [
- {
- code: "iBase",
- name: "understand the basics",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0207",
- "MIO0302",
- "MIO0303",
- "MIO0306",
- "MIO0706",
- "MIO0710",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0717",
- "MIO0803",
- "MIO0804",
- "MIO0805",
- "MIO0807",
- "MIO0809",
- "MIO0810",
- "MIO0811",
- "MIO0812",
- "MIO0814",
- "MIO0815",
- "MIO0816",
- ],
- },
- {
- code: "iLook",
- name: "see the interface through the eyes of the user",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0109",
- "MIO0110",
- "MIO0112",
- "MIO0113",
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0207",
- "MIO0208",
- "MIO0209",
- "MIO0302",
- "MIO0303",
- "MIO0306",
- "MIO0307",
- "MIO0404",
- "MIO0417",
- "MIO0812",
- "MIO0902",
- "MIO0903",
- "MIO0911",
- ],
- },
- {
- code: "iDraw",
- name: "draw interface",
- tasks: [
- "MIO0308",
- "MIO00310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0612",
- "MIO0804",
- "MIO0807",
- "MIO0812",
- "MIO0905",
- ],
- },
- {
- code: "iTell",
- name: "explain to others",
- tasks: ["MIO0707", "MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "iSelf",
- name: "self-develop",
- tasks: ["MIO0715"],
- },
- ],
- },
- {
- name: "Think",
- subskills: [
- {
- code: "aZero",
- name: "create requirements from scratch",
- tasks: [
- "MIO0302",
- "MIO0303",
- "MIO0509",
- "MIO0711",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0804",
- "MIO0807",
- ],
- },
- {
- code: "aLook",
- name: "to understand the logic of another's interface",
- tasks: [
- "MIO0104",
- "MIO0105",
- "MIO0107",
- "MIO0108",
- "MIO0109",
- "MIO0110",
- "MIO0112",
- "MIO0113",
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0207",
- "MIO0208",
- "MIO0209",
- "MIO0210",
- "MIO0306",
- "MIO0307",
- "MIO0404",
- ],
- },
- {
- code: "aImp",
- name: "find places for local improvements",
- tasks: [
- "MIO0204",
- "MIO0205",
- "MIO0304",
- "MIO0305",
- "MIO0312",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0509",
- "MIO0603",
- "MIO0604",
- "MIO0605",
- "MIO0606",
- "MIO0607",
- "MIO0609",
- "MIO0610",
- "MIO0611",
- "MIO0612",
- "MIO0613",
- "MIO0614",
- "MIO0702",
- "MIO0703",
- "MIO0707",
- "MIO0708",
- "MIO0709",
- "MIO0711",
- "MIO0712",
- "MIO0713",
- "MIO0714",
- "MIO0903",
- "MIO0906",
- ],
- },
- {
- code: "aDraft",
- name: "understand whether it is worth to polish the sketches",
- tasks: [
- "MIO0112",
- "MIO0113",
- "MIO0208",
- "MIO0209",
- "MIO0210",
- "MIO0307",
- ],
- },
- {
- code: "aWork",
- name: "understand if the interface will work",
- tasks: [
- "MIO0114",
- "MIO0115",
- "MIO0117",
- "MIO0118",
- "MIO0202",
- "MIO0203",
- "MIO0204",
- "MIO0205",
- "MIO0404",
- "MIO0409",
- ],
- },
- {
- code: "aFix",
- name: "fix priorities",
- tasks: [
- "MIO0204",
- "MIO0205",
- "MIO0210",
- "MIO0410",
- "MIO0415",
- "MIO0417",
- "MIO0502",
- "MIO0705",
- "MIO0913",
- "MIO0914",
- "MIO0915",
- ],
- },
- {
- code: "aLis",
- name: "list screens",
- tasks: ["MIO0109", "MIO0110", "MIO0706", "MIO0715", "MIO0904"],
- },
- {
- code: "aPlus",
- name: "understand what other screens the system needs",
- tasks: ["MIO0109", "MIO0110", "MIO0706", "MIO0715", "MIO0904"],
- },
- ],
- },
- {
- name: "Sketch",
- subskills: [
- {
- code: "pSketch",
- name: "make quick sketches",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- ],
- },
- {
- code: "pMain",
- name: "draw the important, without details",
- tasks: ["MIO0913", "MIO0914", "MIO0915"],
- },
- {
- code: "pReq",
- name: "draw according to requirements",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0612",
- "MIO0709",
- ],
- },
- {
- code: "pImp",
- name: "draw small improvements in the interface",
- tasks: ["MIO0613", "MIO0614", "MIO0703", "MIO0708", "MIO0709"],
- },
- {
- code: "pStart",
- name: "just. start. drawing.",
- tasks: [
- "MIO0308",
- "MIO0310",
- "MIO0311",
- "MIO0312",
- "MIO0405",
- "MIO0406",
- "MIO0408",
- "MIO0410",
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0415",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0502",
- "MIO0705",
- "MIO0905",
- "MIO0916",
- ],
- },
- ],
- },
- {
- name: "Test",
- subskills: [
- {
- code: "tReq",
- name: "clarify requirements",
- tasks: [
- "MIO0503",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0707",
- ],
- },
- {
- code: "tPic",
- name: "test interface",
- tasks: [
- "MIO0503",
- "MIO0504",
- "MIO0505",
- "MIO0507",
- "MIO0508",
- "MIO0707",
- "MIO0708",
- "MIO0909",
- ],
- },
- ],
- },
- {
- name: "Discuss",
- subskills: [
- {
- code: "dCol",
- name: "discuss with a colleague",
- tasks: ["MIO0503", "MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "dTeam",
- name: "discuss in a team",
- tasks: ["MIO0503", "MIO0909", "MIO0910", "MIO0911"],
- },
- ],
- },
- {
- name: "Organize",
- subskills: [
- {
- code: "mUser",
- name: "work for the user",
- tasks: ["MIO0907", "MIO0915"],
- },
- {
- code: "mTask",
- name: "set a task for the designer, accept the result",
- tasks: ["MIO0904", "MIO0909", "MIO0910"],
- },
- {
- code: "mDev",
- name: "implement design in IT production",
- tasks: ["MIO0909", "MIO0910", "MIO0911"],
- },
- {
- code: "mSale",
- name: "present interface",
- tasks: ["MIO0715"],
- },
- ],
- },
- {
- name: "Business",
- subskills: [
- {
- code: "bNew",
- name: "draw a new interface",
- tasks: [
- "MIO0412",
- "MIO0413",
- "MIO0414",
- "MIO0418",
- "MIO0419",
- "MIO0420",
- "MIO0910",
- "MIO0916",
- ],
- },
- {
- code: "bLeg",
- name: "take care of the old system",
- tasks: [
- "MIO0613",
- "MIO0604",
- "MIO0605",
- "MIO0606",
- "MIO0607",
- "MIO0609",
- "MIO0610",
- "MIO0611",
- "MIO0612",
- "MIO0613",
- "MIO0614",
- "MIO0702",
- "MIO0703",
- "MIO0906",
- ],
- },
- {
- code: "bOK",
- name: "do okay",
- tasks: ["MIO0715"],
- },
- ],
- },
- ],
- TXT: [
- {
- name: "Writing as a work skill",
- tasks: [
- "TXT0103",
- "TXT0104",
- "TXT0106",
- "TXT0107",
- "TXT0108",
- "TXT0109",
- "TXT0111",
- "TXT0112",
- "TXT0113",
- "TXT0114",
- "TXT0115",
- "TXT0116",
- "TXT0119",
- "TXT0120",
- "TXT0121",
- "TXT0122",
- ],
- },
- {
- name: "Interface Text",
- tasks: [
- "TXT0202",
- "TXT0204",
- "TXT0205",
- "TXT0207",
- "TXT0208",
- "TXT0209",
- "TXT0210",
- "TXT0211",
- "TXT0212",
- "TXT0214",
- "TXT0215",
- "TXT0216",
- "TXT0218",
- "TXT0220",
- "TXT0222",
- "TXT0223",
- "TXT0224",
- "TXT0226",
- "TXT0227",
- ],
- },
- {
- name: "Team work",
- tasks: [
- "TXT0303",
- "TXT0304",
- "TXT0305",
- "TXT0306",
- "TXT0307",
- "TXT0308",
- "TXT0309",
- "TXT0311",
- "TXT0312",
- "TXT0313",
- "TXT0314",
- "TXT0316",
- "TXT0317",
- "TXT0318",
- "TXT0319",
- "TXT0320",
- ],
- },
- {
- name: "Understand your reader",
- tasks: [
- "TXT0402",
- "TXT0403",
- "TXT0404",
- "TXT0405",
- "TXT0406",
- "TXT0408",
- "TXT0409",
- "TXT0410",
- "TXT0411",
- "TXT0412",
- "TXT0413",
- "TXT0414",
- "TXT0416",
- "TXT0417",
- "TXT0418",
- "TXT0420",
- "TXT0421",
- "TXT0422",
- "TXT0423",
- "TXT0424",
- "TXT0426",
- "TXT0427",
- "TXT0428",
- "TXT0429",
- "TXT0431",
- "TXT0502",
- "TXT0503",
- "TXT0505",
- "TXT0506",
- "TXT0508",
- "TXT0509",
- "TXT0510",
- "TXT0511",
- "TXT0513",
- "TXT0514",
- "TXT0516",
- "TXT0517",
- "TXT0518",
- "TXT0519",
- "TXT0521",
- ],
- },
- {
- name: "Quick Improvement Techniques",
- tasks: [
- "TXT0602",
- "TXT0605",
- "TXT0606",
- "TXT0607",
- "TXT0609",
- "TXT0610",
- "TXT0612",
- "TXT0614",
- "TXT0616",
- "TXT0617",
- "TXT0618",
- "TXT0619",
- "TXT0621",
- "TXT0623",
- "TXT0625",
- "TXT0627",
- "TXT0628",
- ],
- },
- {
- name: "Working on Text Level",
- tasks: [
- "TXT0703",
- "TXT0704",
- "TXT0705",
- "TXT0707",
- "TXT0709",
- "TXT0710",
- "TXT0711",
- "TXT0713",
- "TXT0714",
- "TXT0716",
- "TXT0717",
- "TXT0718",
- "TXT0719",
- "TXT0720",
- "TXT0721",
- "TXT0723",
- "TXT0724",
- ],
- },
- {
- name: "Extreme writing",
- tasks: [
- "TXT0803",
- "TXT0804",
- "TXT0805",
- "TXT0807",
- "TXT0808",
- "TXT0809",
- "TXT0811",
- "TXT0812",
- "TXT0814",
- "TXT0815",
- "TXT0816",
- "TXT0817",
- "TXT0819",
- "TXT0821",
- "TXT0822",
- "TXT0823",
- "TXT0824",
- "TXT0826",
- "TXT0827",
- "TXT0828",
- "TXT0829",
- "TXT0830",
- "TXT0831",
- "TXT0832",
- "TXT0833",
- ],
- },
- {
- name: "Lifehacks",
- tasks: [
- "TXT0903",
- "TXT0904",
- "TXT0905",
- "TXT0907",
- "TXT0908",
- "TXT0909",
- "TXT0910",
- "TXT0912",
- "TXT0913",
- "TXT0914",
- "TXT0916",
- "TXT0917",
- "TXT0919",
- "TXT0920",
- "TXT0921",
- ],
- },
- ],
- HSB: [
- {
- name: "Team’s skills juggling",
- tasks: [
- "HSB0104",
- "HSB0105",
- "HSB0107",
- "HSB0108",
- "HSB0110",
- "HSB0112",
- "HSB0113",
- "HSB0114",
- "HSB0116",
- "HSB0117",
- "HSB0119",
- "HSB0120",
- "HSB0122",
- "HSB0123",
- "HSB0125",
- "HSB0126",
- "HSB0127",
- ],
- },
- {
- name: "Assigning tasks to the team",
- tasks: [
- "HSB0203",
- "HSB0204",
- "HSB0205",
- "HSB0206",
- "HSB0208",
- "HSB0210",
- "HSB0211",
- "HSB0212",
- "HSB0213",
- "HSB0215",
- "HSB0217",
- "HSB0219",
- "HSB0220",
- "HSB0222",
- "HSB0224",
- "HSB0225",
- ],
- },
- {
- name: "Individual work with team members",
- tasks: [
- "HSB0303",
- "HSB0305",
- "HSB0306",
- "HSB0308",
- "HSB0310",
- "HSB0311",
- "HSB0312",
- "HSB0314",
- "HSB0315",
- "HSB0316",
- "HSB0318",
- "HSB0319",
- "HSB0321",
- "HSB0323",
- "HSB0325",
- "HSB0326",
- "HSB0328",
- "HSB0330",
- "HSB0331",
- "HSB0333",
- ],
- },
- {
- name: "How to become a boss",
- tasks: [
- "HSB0404",
- "HSB0405",
- "HSB0407",
- "HSB0409",
- "HSB0411",
- "HSB0413",
- "HSB0415",
- "HSB0417",
- "HSB0419",
- "HSB0421",
- "HSB0423",
- "HSB0425",
- "HSB0426",
- "HSB0427",
- ],
- },
- {
- name: "Coercion to simplicity",
- tasks: [
- "HSB0503",
- "HSB0504",
- "HSB0505",
- "HSB0506",
- "HSB0507",
- "HSB0508",
- "HSB0510",
- "HSB0511",
- "HSB0512",
- "HSB0513",
- "HSB0514",
- "HSB0516",
- "HSB0517",
- "HSB0518",
- "HSB0520",
- ],
- },
- {
- name: "Silver bullets implementation",
- tasks: [
- "HSB0602",
- "HSB0603",
- "HSB0604",
- "HSB0606",
- "HSB0607",
- "HSB0609",
- "HSB0611",
- "HSB0613",
- "HSB0614",
- "HSB0616",
- "HSB0618",
- "HSB0620",
- ],
- },
- {
- name: "Culture of written communication. Money",
- tasks: [
- "HSB0702",
- "HSB0703",
- "HSB0704",
- "HSB0705",
- "HSB0706",
- "HSB0707",
- "HSB0708",
- "HSB0709",
- "HSB0711",
- "HSB0712",
- "HSB0714",
- "HSB0715",
- "HSB0716",
- "HSB0717",
- "HSB0719",
- "HSB0721",
- "HSB0722",
- ],
- },
- {
- name: "Task failing skills",
- tasks: [
- "HSB0803",
- "HSB0804",
- "HSB0806",
- "HSB0807",
- "HSB0808",
- "HSB0810",
- "HSB0811",
- "HSB0812",
- "HSB0814",
- "HSB0815",
- "HSB0817",
- "HSB0819",
- "HSB0820",
- ],
- },
- {
- name: "Lifehaсks",
- tasks: [
- "HSB0902",
- "HSB0903",
- "HSB0905",
- "HSB0907",
- "HSB0909",
- "HSB0910",
- "HSB0911",
- "HSB0913",
- "HSB0915",
- "HSB0917",
- "HSB0918",
- "HSB0919",
- ],
- },
- ],
- COM: [
- {
- name: "Key goal of interface composition",
- tasks: [
- "COM0102",
- "COM0103",
- "COM0104",
- "COM0106",
- "COM0107",
- "COM0108",
- "COM0109",
- "COM0110",
- "COM0111",
- "COM0112",
- "COM0114",
- "COM0115",
- "COM0116",
- "COM0118",
- "COM0119",
- "COM0120",
- "COM0121",
- "COM0122",
- "COM0124",
- "COM0125",
- "COM0126",
- "COM0127",
- "COM0128",
- "COM0130",
- "COM0131",
- "COM0132",
- ],
- },
- {
- name: "Story in interface composition",
- tasks: [
- "COM0203",
- "COM0204",
- "COM0205",
- "COM0207",
- "COM0210",
- "COM0211",
- "COM0212",
- "COM0214",
- "COM0215",
- "COM0216",
- "COM0218",
- "COM0219",
- "COM0220",
- ],
- },
- {
- name: "Rhythm",
- tasks: [
- "COM0303",
- "COM0305",
- "COM0306",
- "COM0308",
- "COM0309",
- "COM0311",
- "COM0312",
- "COM0314",
- "COM0315",
- "COM0317",
- "COM0319",
- "COM0321",
- "COM0322",
- "COM0323",
- "COM0324",
- "COM0325",
- "COM0326",
- "COM0328",
- "COM0329",
- "COM0331",
- "COM0332",
- "COM0333",
- "COM0335",
- ],
- },
- {
- name: "Symmetry",
- tasks: [
- "COM0402",
- "COM0403",
- "COM0404",
- "COM0405",
- "COM0407",
- "COM0408",
- "COM0409",
- "COM0411",
- "COM0412",
- "COM0413",
- "COM0414",
- "COM0416",
- "COM0418",
- "COM0420",
- "COM0421",
- "COM0423",
- "COM0424",
- "COM0426",
- "COM0427",
- "COM0428",
- "COM0431",
- "COM0432",
- "COM0433",
- ],
- },
- {
- name: "Contrast",
- tasks: [
- "COM0502",
- "COM0503",
- "COM0504",
- "COM0506",
- "COM0507",
- "COM0509",
- "COM0511",
- "COM0512",
- "COM0514",
- "COM0515",
- "COM0517",
- "COM0519",
- "COM0520",
- "COM0522",
- "COM0524",
- "COM0525",
- "COM0527",
- "COM0528",
- "COM0530",
- "COM0531",
- "COM0532",
- "COM0533",
- ],
- },
- {
- name: "Cognitive composition",
- tasks: [
- "COM0603",
- "COM0604",
- "COM0607",
- "COM0608",
- "COM0613",
- "COM0615",
- "COM0617",
- "COM0619",
- "COM0621",
- "COM0622",
- "COM0625",
- "COM0626",
- "COM0627",
- "COM0628",
- ],
- },
- {
- name: "Compositional literacy",
- tasks: [
- "COM0704",
- "COM0705",
- "COM0707",
- "COM0708",
- "COM0710",
- "COM0711",
- "COM0713",
- "COM0714",
- "COM0716",
- "COM0717",
- "COM0718",
- "COM0719",
- ],
- },
- {
- name: "Interface Improvement",
- tasks: [
- "COM0803",
- "COM0804",
- "COM0805",
- "COM0807",
- "COM0809",
- "COM0810",
- "COM0811",
- "COM0814",
- "COM0815",
- "COM0816",
- ],
- },
- {
- name: "Lifehaсks",
- tasks: [
- "COM0902",
- "COM0903",
- "COM0904",
- "COM0905",
- "COM0906",
- "COM0908",
- "COM0910",
- "COM0911",
- "COM0913",
- "COM0915",
- "COM0917",
- ],
- },
- ],
- UCC: [
- {
- name: "Theory",
- tasks: [
- "UCC0107",
- "UCC0109",
- "UCC0111",
- "UCC0113",
- "UCC0115",
- "UCC0117",
- "UCC0119",
- "UCC0121",
- "UCC0123",
- "UCC0125",
- ],
- },
- {
- name: "Basics",
- tasks: [
- "UCC0203",
- "UCC0205",
- "UCC0209",
- "UCC0211",
- "UCC0213",
- "UCC0215",
- "UCC0217",
- "UCC0219",
- "UCC0221",
- "UCC0223",
- "UCC0225",
- "UCC0226",
- "UCC0228",
- "UCC0230",
- "UCC0232",
- "UCC0234",
- ],
- },
- {
- name: "Design and development management",
- tasks: [
- "UCC0303",
- "UCC0304",
- "UCC0305",
- "UCC0307",
- "UCC0308",
- "UCC0309",
- "UCC0311",
- "UCC0312",
- "UCC0313",
- "UCC0314",
- "UCC0315",
- "UCC0316",
- "UCC0317",
- "UCC0318",
- ],
- },
- {
- name: "Interfaces creation based on use cases",
- tasks: [
- "UCC0403",
- "UCC0404",
- "UCC0405",
- "UCC0406",
- "UCC0407",
- "UCC0408",
- "UCC0409",
- "UCC0410",
- "UCC0411",
- "UCC0413",
- "UCC0415",
- "UCC0416",
- "UCC0417",
- "UCC0418",
- "UCC0419",
- "UCC0421",
- "UCC0422",
- "UCC0423",
- "UCC0424",
- "UCC0426",
- "UCC0502",
- "UCC0503",
- "UCC0504",
- "UCC0505",
- "UCC0508",
- "UCC0509",
- "UCC0510",
- "UCC0511",
- "UCC0513",
- "UCC0514",
- "UCC0515",
- "UCC0602",
- "UCC0604",
- "UCC0606",
- "UCC0608",
- "UCC0609",
- "UCC0610",
- "UCC0611",
- "UCC0612",
- "UCC0614",
- "UCC0615",
- "UCC0616",
- "UCC0617",
- ],
- },
- {
- name: "Metagoals",
- tasks: [
- "UCC0703",
- "UCC0704",
- "UCC0705",
- "UCC0706",
- "UCC0707",
- "UCC0708",
- "UCC0710",
- "UCC0711",
- "UCC0713",
- "UCC0714",
- "UCC0715",
- "UCC0716",
- "UCC0717",
- "UCC0718",
- "UCC0719",
- "UCC0721",
- "UCC0722",
- "UCC0723",
- "UCC0724",
- ],
- },
- {
- name: "Case based scenarios logic",
- tasks: [
- "UCC0803",
- "UCC0805",
- "UCC0806",
- "UCC0808",
- "UCC0809",
- "UCC0810",
- "UCC0812",
- "UCC0813",
- "UCC0814",
- "UCC0816",
- "UCC0817",
- "UCC0818",
- "UCC0819",
- "UCC0821",
- "UCC0822",
- "UCC0823",
- "UCC0825",
- "UCC0826",
- ],
- },
- {
- name: "Nuances and goals of development",
- tasks: [
- "UCC0903",
- "UCC0904",
- "UCC0905",
- "UCC0906",
- "UCC0908",
- "UCC0909",
- "UCC0910",
- "UCC0911",
- "UCC0913",
- "UCC0914",
- "UCC0915",
- "UCC0916",
- "UCC0917",
- "UCC0919",
- "UCC0920",
- "UCC0921",
- "UCC0922",
- "UCC0924",
- "UCC0925",
- "UCC0927",
- "UCC0928",
- "UCC0930",
- "UCC0931",
- "UCC0932",
- "UCC0933",
- ],
- },
- ],
-};
-
-module.exports.SKILLS = { ru, en };
diff --git a/src/processes/prepareData/prepareData.js b/src/processes/prepareData/prepareData.js
deleted file mode 100644
index 7033580..0000000
--- a/src/processes/prepareData/prepareData.js
+++ /dev/null
@@ -1,15 +0,0 @@
-const prepareUserData = require("./prepareUserData/prepareUserData");
-const prepareModuleData = require("./prepareModuleData/prepareModuleData");
-const prepareLessonData = require("./prepareLessonData/prepareLessonData");
-const prapareTaskData = require("./prepareTaskData/prapareTaskData");
-const prepareCertificateData = require("./prepareCertificateData/prepareCertificateData");
-
-const prepareData = {
- prepareUserData,
- prepareModuleData,
- prepareLessonData,
- prapareTaskData,
- prepareCertificateData,
-};
-
-module.exports = prepareData;
diff --git a/src/processes/prepareData/prepareLessonData/prepareLessonData.js b/src/processes/prepareData/prepareLessonData/prepareLessonData.js
deleted file mode 100644
index 669c42d..0000000
--- a/src/processes/prepareData/prepareLessonData/prepareLessonData.js
+++ /dev/null
@@ -1,52 +0,0 @@
-const { setTasksState } = require("../../setListState/setListState");
-const {
- calculateUserScore,
- calculateDoneTasks,
-} = require("@utils/calculators");
-const { getLessonId } = require("@utils/idExtractor");
-
-/***
- * Function prepares lesson data to send to user.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} Lesson content
- */
-async function prepareLessonData(data) {
- const fullLessonId = data.lessonId;
- const lessonId = getLessonId(fullLessonId);
- const { lesson, state, isAuth } = data;
- const { intro, final, maxScore } = lesson;
-
- const content = {
- id: lessonId,
- title: lesson.title,
- description: lesson.description,
- };
-
- if (!isAuth) {
- return content;
- }
-
- const tasks = await setTasksState(lesson.tasks, state);
-
- const scoped = { intro, final, tasks };
-
- const totalTasks = tasks.reduce((count, task) => {
- if (task.type === "practice") {
- return count + 1;
- }
- return count;
- }, 0);
-
- const progress = {
- score: calculateUserScore(state),
- maxScore,
- doneTasks: calculateDoneTasks(state),
- totalTasks,
- };
-
- return Object.assign(content, scoped, progress);
-}
-
-module.exports = prepareLessonData;
diff --git a/src/processes/prepareData/prepareModuleData/prepareModuleData.js b/src/processes/prepareData/prepareModuleData/prepareModuleData.js
deleted file mode 100644
index 187132d..0000000
--- a/src/processes/prepareData/prepareModuleData/prepareModuleData.js
+++ /dev/null
@@ -1,110 +0,0 @@
-const getTaskInfo = require("../../getTaskInfo/getTaskInfo");
-const { setLessonsState } = require("../../setListState/setListState");
-const {
- calculateUserScore,
- calculateModuleMaxScore,
- calculateDoneTasks,
- calculateDeadline,
-} = require("@utils/calculators");
-const { getNextTaskId } = require("@utils/getNextTaskId");
-
-function checkMuduleStatus({ start, deadline, modules, prevModule }) {
- const now = Date.now();
- const startTS = Date.parse(start);
- const deadlineTS = Date.parse(deadline);
- const caution = 1000 * 60 * 60 * 24 * 10;
-
- if (Object.keys(modules).includes(prevModule)) {
- return "unavailable";
- }
-
- if (startTS > now) {
- return "paid";
- }
- if (now > deadlineTS) {
- return "past";
- }
- if (now >= deadlineTS - caution && now < deadlineTS) {
- return "deadline";
- }
- if (now < deadlineTS) {
- return "active";
- }
-
- return "available";
-}
-
-/***
- * Function prepares module data to send to user.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} Module content
- */
-async function prepareModuleData(data, next) {
- const { user, module, state, isAuth, isFinalAccess } = data;
- const { intro, final } = module;
-
- const content = {
- id: module.code,
- name: module.name,
- shortName: module.shortName,
- description: module.description,
- lang: module.lang,
- moduleLink: module.moduleLink,
- features: module.features,
- mascot: module.mascot,
- price: module.price,
- buyLink: module.buyLink,
- prevModule: module.prevModule,
- group: module.group,
- status: "available",
- };
-
- if (!isFinalAccess || !isAuth || !user.modules[module.code]) {
- return content;
- }
-
- const prolongation = {
- prolongation: module.prolongation,
- prolongationLink: module.prolongationLink,
- };
-
- const nextTaskId = getNextTaskId(module, state);
-
- const lessons = setLessonsState(module.lessons, nextTaskId);
-
- const scoped = { intro, final, lessons };
-
- const { start, deadline, prolongations } = user.modules[module.code];
-
- const lastDeadline = calculateDeadline({ deadline, prolongations });
-
- const status = checkMuduleStatus({
- start,
- deadline: lastDeadline,
- modules: user.modules,
- prevModule: module.prevModule,
- });
-
- const progress = {
- score: calculateUserScore(state),
- maxScore: calculateModuleMaxScore(module.lessons),
- doneTasks: calculateDoneTasks(state),
- totalTasks: module.totalTasks,
- start,
- deadline: lastDeadline,
- status,
- nextTask: await getTaskInfo(
- {
- taskId: nextTaskId,
- returns: ["id", "name", "type"],
- },
- next
- ),
- };
-
- return Object.assign(content, scoped, prolongation, progress);
-}
-
-module.exports = prepareModuleData;
diff --git a/src/processes/prepareData/prepareTaskData/prapareTaskData.js b/src/processes/prepareData/prepareTaskData/prapareTaskData.js
deleted file mode 100644
index 309f9dc..0000000
--- a/src/processes/prepareData/prepareTaskData/prapareTaskData.js
+++ /dev/null
@@ -1,136 +0,0 @@
-const {
- setVisibility,
- getParentContent,
- refAnswerRight,
-} = require("../../updateContent/updateContent");
-const setTaskState = require("../../setTaskState/setTaskState");
-
-/***
- * Normilize State object
- *
- * @param {Object} taskState Task state params
- *
- * @returns {Object} Normilize state object
- */
-function validateTaskState(taskState) {
- return ({
- isChecked = false,
- score = null,
- inProcess = false,
- protest = false,
- isHintActive = false,
- isOurVarActive = false,
- isSolutionActive = false,
- comments = [],
- } = taskState || {});
-}
-
-/***
- * Function prepares task data for response
- *
- * @param {Object} data Throught API obhect
- *
- * @returns {Object} Task object
- */
-async function prepareTaskData(data) {
- const { userId, taskId, task, state } = data;
- const taskState = validateTaskState(state);
- for (const content of task.content) {
- for (const introItem of content.intro) {
- if (introItem.type == "richText") {
- for (const richItem of introItem.value) {
- if (richItem.parentId) {
- const value = await getParentContent(
- userId,
- richItem.parentId,
- lang
- );
-
- richItem.value = value[0];
-
- if (!value[1]) {
- introItem.value = value[0];
- introItem.type = "p";
- break;
- }
- }
- }
- }
-
- if (introItem.parentId) {
- const value = await getParentContent(userId, introItem.parentId, lang);
- introItem.value = value[0];
- }
- }
- for (const question of content.questions || []) {
- if (question?.subtopic) {
- for (let i = 0; i < question?.subtopic.length; i++) {
- if (question?.subtopic[i].parentId) {
- const value = await getParentContent(
- userId,
- question?.subtopic[i].parentId,
- lang
- );
- question.subtopic[i] = value[0];
- }
- }
- }
-
- if (taskState?.data?.[question.id]?.isVisible != undefined) {
- question.isVisible = taskState?.data?.[question.id]?.isVisible;
- } else if (
- question.depends &&
- taskState?.data?.[question.id]?.isVisible == undefined
- ) {
- for (const depend of question.depends) {
- if (depend.type == "visibility") {
- const isVisible = await setVisibility(
- userId,
- depend.parentId,
- question.id
- );
- question.isVisible = isVisible;
- if (!isVisible) {
- break;
- }
- }
- }
- } else {
- const path = "data." + question.id + ".isVisible";
- await setTaskState({
- userId,
- taskId,
- newState: {
- [path]: true,
- },
- });
- question.isVisible = true;
- }
- const questionId = question.id;
- if (question.type === "text" || question.type === "link") {
- question.answer = taskState?.data?.[questionId]?.state || "";
- } else {
- for (const variant of question.variants) {
- if (variant.parentId) {
- const value = await getParentContent(
- userId,
- variant.parentId,
- lang
- );
- variant.label = value[0];
- }
- if (variant.refs) {
- variant.isRight = await refAnswerRight(userId, variant.refs);
- }
- variant.isSelected =
- (taskState?.data?.[questionId]?.state || []).find(
- (item) => item?.id === variant.id
- )?.isSelected || false;
- }
- }
- }
- }
- return task;
-}
-
-module.exports = prepareTaskData;
diff --git a/src/processes/prepareData/prepareUserData/prepareUserData.js b/src/processes/prepareData/prepareUserData/prepareUserData.js
deleted file mode 100644
index 8e2524b..0000000
--- a/src/processes/prepareData/prepareUserData/prepareUserData.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/***
- * Function prepares user data to send to user.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} User content
- */
-function prepareUserData(data) {
- const { user, isAuth } = data;
- user.modules = Object.keys(user.modules || []);
- if (isAuth) {
- delete user.token;
- }
- delete user.pass;
-
- return user;
-}
-
-module.exports = prepareUserData;
diff --git a/src/processes/processes.js b/src/processes/processes.js
deleted file mode 100644
index 252a4c5..0000000
--- a/src/processes/processes.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const getUserInfo = require("./getUserInfo/getUserInfo");
-const checkCredentials = require("./checkCredentials/checkCredentials");
-const checkAccess = require("./checkAccess/checkAccess");
-const checkTransaction = require("./checkTransaction/checkTransaction");
-const checkOTK = require("./checkOTK/checkOTK");
-const authUser = require("./authUser/authUser");
-const updatePass = require("./updatePass/updatePass");
-const getModuleInfo = require("./getModuleInfo/getModuleInfo");
-const getLessonInfo = require("./getLessonInfo/getLessonInfo");
-const getTaskInfo = require("./getTaskInfo/getTaskInfo");
-const getStateInfo = require("./getStateInfo/getStateInfo");
-const getCounselorInfo = require("./getCounselorInfo/getCounselorInfo");
-const prepareData = require("./prepareData/prepareData");
-const updateContent = require("./updateContent/updateContent");
-const setTaskState = require("./setTaskState/setTaskState");
-const pushComment = require("./pushComment/pushComment");
-const setDiploma = require("./setDiploma/setDiploma");
-
-module.exports = {
- getUserInfo,
- checkCredentials,
- ...checkAccess,
- checkTransaction,
- checkOTK,
- authUser,
- updatePass,
- getModuleInfo,
- getLessonInfo,
- getTaskInfo,
- getStateInfo,
- getCounselorInfo,
- ...prepareData,
- ...updateContent,
- setTaskState,
- pushComment,
- setDiploma,
-};
diff --git a/src/processes/pushComment/pushComment.js b/src/processes/pushComment/pushComment.js
deleted file mode 100644
index 84aa366..0000000
--- a/src/processes/pushComment/pushComment.js
+++ /dev/null
@@ -1,37 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function added new comment to the task.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Array} Array of task's comments with the new one
- */
-async function pushComment(data) {
- const { taskId, userId, comment } = data;
-
- const newComment = {
- ts: Date.now(),
- message: comment,
- readedByTeacher: false,
- };
-
- const update = await DB.setOne("state", {
- query: { taskId, userId },
- push: {
- comments: {
- $each: [newComment],
- $position: 0,
- },
- },
- returns: ["comments"],
- });
-
- if (!update) {
- throw new Error(`${taskId}: A problem pushing new comment to DB!`);
- }
-
- return update;
-}
-
-module.exports = pushComment;
diff --git a/src/processes/setDiploma/setDiploma.js b/src/processes/setDiploma/setDiploma.js
deleted file mode 100644
index a093208..0000000
--- a/src/processes/setDiploma/setDiploma.js
+++ /dev/null
@@ -1,24 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function set new sertificate params.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} New sertificate state
- */
-async function setDiploma(data) {
- const { query, params } = data;
- const update = await DB.setOne("certs", {
- query,
- set: params,
- });
-
- if (!update) {
- throw new Error(`${query?.id}: A problem with setting diploma state!`);
- }
-
- return update;
-}
-
-module.exports = setDiploma;
diff --git a/src/processes/setListState/setListState.js b/src/processes/setListState/setListState.js
deleted file mode 100644
index 95015b9..0000000
--- a/src/processes/setListState/setListState.js
+++ /dev/null
@@ -1,61 +0,0 @@
-const getTaskInfo = require("../getTaskInfo/getTaskInfo");
-const { getLessonId } = require("@utils/idExtractor");
-
-/***
- * Function prepares lessons list with current state.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Array} List of lessons
- */
-function setLessonsState(lessons = {}, nextTaskId) {
- const lessonsState = Object.entries(lessons).map(([id, value]) => {
- return {
- id,
- title: value.title,
- description: value.description,
- status: "future",
- };
- });
-
- const currentLessonId = getLessonId(nextTaskId);
-
- const currentLessonIndex = Object.keys(lessons).indexOf(currentLessonId);
-
- lessonsState.forEach((lesson, index) => {
- if (index < currentLessonIndex) {
- lesson.status = "past";
- } else if (index === currentLessonIndex) {
- lesson.status = "current";
- }
- });
-
- return lessonsState;
-}
-
-/***
- * Function prepares lessons list with current state.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Array} List of lessons
- */
-async function setTasksState(tasks = [], state = []) {
- const tasksPromises = tasks.map(async (taskId) => {
- const taskInfo = await getTaskInfo({
- taskId,
- returns: ["id", "name", "type"],
- });
- if (taskInfo.type === "practice") {
- const taskState = state.find((item) => item.taskId === taskId);
- taskInfo.score = taskState?.score || 0;
- taskInfo.isChecked = taskState?.isChecked || false;
- taskInfo.inProcess = taskState?.inProcess || false;
- }
- return taskInfo;
- });
-
- return Promise.all(tasksPromises);
-}
-
-module.exports = { setLessonsState, setTasksState };
diff --git a/src/processes/setTaskState/setTaskState.js b/src/processes/setTaskState/setTaskState.js
deleted file mode 100644
index dba5b50..0000000
--- a/src/processes/setTaskState/setTaskState.js
+++ /dev/null
@@ -1,27 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function set new task state.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} New task state
- */
-async function setTaskState(data) {
- const { taskId, userId, newState } = data;
- const update = await DB.setOne("state", {
- query: { taskId, userId },
- set: newState,
- options: {
- insertNew: true,
- },
- });
-
- if (!update) {
- throw new Error(`${taskId}: A problem with setting new task state!`);
- }
-
- return update;
-}
-
-module.exports = setTaskState;
diff --git a/src/processes/updateContent/updateContent.js b/src/processes/updateContent/updateContent.js
deleted file mode 100644
index 372b8fe..0000000
--- a/src/processes/updateContent/updateContent.js
+++ /dev/null
@@ -1,226 +0,0 @@
-const getPhrase = require("@assets/lang/lang");
-const { getFullTaskId, getFullQuestionId } = require("@utils/idExtractor");
-const DB = require("@mongo/requests");
-
-/***
- * Modify string, if parent task isn't solved
- *
- * @param {String} taskId Task ID
- * @param {String} lang User lang
- *
- * @returns {Array} Modified string and strange bool
- */
-async function getTaskName(taskId, lang) {
- const taskData = await DB.getOne("task", { query: { id: taskId } });
- if (!taskData) {
- throw new Error(`getParentContent: Can't find task woth ID ${taskId}`);
- }
- const taskName = getPhrase(lang, "prevTaskFirst", taskData.name);
- return [taskName, false];
-}
-
-/***
- * Serve all tasks, that will be updated
- *
- * @param {Array} tasks Tasks list
- * @param {String} questionId Reference question ID
- *
- * @returns {Array} Task list to modify
- */
-function getVisibilityUpdateList(tasks, questionId) {
- const list = [];
- for (const task of tasks) {
- for (const contentItem of task?.content || []) {
- for (const question of contentItem?.questions || []) {
- for (const item of question?.depends || []) {
- if (
- item.type === "visibility" &&
- item.parentId.includes(questionId)
- ) {
- switch (item.parentId.length) {
- case 13:
- list.push({
- type: "variant",
- targetTaskId: task.id,
- questionId: question.id,
- variantId: item.parentId,
- });
- break;
- case 11:
- list.push({
- type: "question",
- targetTaskId: task.id,
- questionId: question.id,
- });
- break;
- }
- }
- }
- }
- }
- }
- return list;
-}
-
-/***
- * Update question visibility
- *
- * @param {String} userId User ID
- * @param {String} contentId Question or Variant ID
- * @param {String} childId Question ID to modify
- *
- * @returns {Boolean} New question visibility
- */
-async function setVisibility(userId, contentId, childId) {
- const idLength = id.length;
- const taskId = getFullTaskId(contentId);
- const questionId = getFullQuestionId(contentId);
- const path = "data." + childId + ".isVisible";
- const state = await DB.getOne("state", {
- query: {
- userId,
- taskId,
- },
- });
-
- let isVisible;
- switch (idLength) {
- case 13:
- const answer = (state?.data?.[questionId]?.state || []).find(
- (answer) => answer.id === contentId
- );
- if (answer?.isSelected && state?.data?.[questionId]?.isVisible)
- isVisible = true;
- else isVisible = false;
- break;
- case 11:
- if (state?.data?.[questionId] && state?.data?.[questionId]?.isVisible)
- isVisible = true;
- else isVisible = false;
- break;
- }
- await DB.setOne("state", {
- query: { userId, taskId },
- set: {
- [path]: isVisible,
- },
- });
- return isVisible;
-}
-
-/***
- * Replace question content to previous user's answers
- *
- * @param {String} userId User ID
- * @param {String} contentId Question or Variant ID
- * @param {String} lang User's lang
- *
- * @returns {String} New question content
- */
-async function getParentContent(userId, contentId, lang) {
- const taskId = getFullTaskId(contentId);
- const taskState = await DB.getOne("state", {
- query: {
- userId,
- taskId,
- },
- });
-
- if (taskState?.isChecked) {
- const questionId = getFullQuestionId(contentId);
- const parentContent = taskState.data?.[questionId]?.state;
- if (parentContent?.value) {
- return [parentContent?.value, true];
- } else {
- const selectedAnswers = parentContent
- .filter((item) => item.isSelected)
- .map((item) => item.label);
- return [selectedAnswers.join(", ") || "", true];
- }
- } else return getTaskName(taskId, lang);
-}
-
-/**
- * Switch variant right status
- *
- * @param {String} userId User ID
- * @param {Array} refs List of references
- *
- * @returns {Boolean} Responsive variant status
- */
-async function refAnswerRight(userId, refs = []) {
- for (const ref of refs) {
- for (const id of ref.variantIds) {
- const taskId = getFullTaskId(id);
- const questionId = getFullQuestionId(id);
-
- const state = await DB.getOne("state", {
- query: {
- userId,
- taskId,
- },
- });
- const answer = (state?.data?.[questionId]?.state || []).find(
- (answer) => answer.id == id
- );
- const isRight =
- (answer?.isSelected && ref.type == "isRight") ||
- (!answer?.isSelected && ref.type == "isWrong");
-
- if (!isRight) {
- return false;
- }
- }
- return true;
- }
-}
-
-/**
- * Update all task depends
- *
- * @param {String} userId User ID
- * @param {String} questionId Question ID
- * @param {Array} tasks List of tasks
- * @param {Object} refs Task's state object
- *
- * @returns {undefined}
- */
-async function updateDependenciesTasks(userId, questionId, tasks, state) {
- const questions = getVisibilityUpdateList(tasks, questionId);
- if (questions.length === 0) {
- return;
- }
- for (const question of questions) {
- const targetTask = question.targetTaskId;
- const targetQuestion = question.questionId;
- const path = "data." + targetQuestion + ".isVisible";
- const query = { userId, taskId: targetTask };
- var data = {};
- switch (question.type) {
- case "question":
- data = {
- [path]: state?.data ? true : false,
- };
- break;
- case "variant":
- const targetVariant = question.variantId;
- const variant = (state || []).find((item) => item.id == targetVariant);
- data = {
- [path]: variant?.isSelected ? true : false,
- };
- break;
- }
- await DB.setOne("state", {
- query,
- set: data,
- });
- }
- return;
-}
-
-module.exports = {
- setVisibility,
- getParentContent,
- refAnswerRight,
- updateDependenciesTasks,
-};
diff --git a/src/processes/updatePass/updatePass.js b/src/processes/updatePass/updatePass.js
deleted file mode 100644
index 401ee2d..0000000
--- a/src/processes/updatePass/updatePass.js
+++ /dev/null
@@ -1,26 +0,0 @@
-const DB = require("@mongo/requests");
-
-/***
- * Function set new password for user.
- *
- * @param {Object} data Throught API object
- *
- * @returns {Object} User data
- */
-async function updatePass(data) {
- const { email, pass } = data;
- const user = await DB.setOne("users", {
- query: { email },
- set: { pass },
- });
-
- if (!user) {
- throw new Error(`${email}: User didn't found when pass updating !`);
- }
-
- data.user = user;
-
- return user;
-}
-
-module.exports = updatePass;
diff --git a/src/services/assistant/assistant.js b/src/services/assistant/assistant.js
new file mode 100644
index 0000000..0fd06dd
--- /dev/null
+++ b/src/services/assistant/assistant.js
@@ -0,0 +1,23 @@
+const fetch = require("node-fetch");
+const { log } = require("@logger");
+
+const { ASSISTANT_WEBHOOR_URL, ASSISTANT_ADMIN_TOKEN } = process.env;
+
+async function sendMessage(body) {
+ try {
+ const url = ASSISTANT_WEBHOOR_URL + "/sendMessage"
+ await fetch(url, {
+ method: "POST",
+ body: JSON.stringify(body),
+ headers: {
+ "Content-Type": "application/json",
+ "Authorization": ASSISTANT_ADMIN_TOKEN
+ },
+ })
+ } catch (e) {
+ log.error("sendMessage assistant webhook failed")
+ log.debug(e)
+ }
+}
+
+module.exports = { sendMessage }
\ No newline at end of file
diff --git a/src/services/express/express.js b/src/services/express/express.js
index b9d9e88..4adaad2 100644
--- a/src/services/express/express.js
+++ b/src/services/express/express.js
@@ -2,11 +2,8 @@ const express = require("express");
const cors = require("cors");
const { log } = require("@logger");
-const { PUBLIC } = require("../../modules/apiRequests/apiRequests");
-const { STUDENT } = require("../../API/student/student");
-const { responseHandler, pathHandler } = require("./responses");
-const prepareRequestData = require("./prepareRequestData");
-const { checkAuth } = require("./security");
+const { PUBLIC, TEACHER } = require("../../modules/apiRequests/apiRequests");
+const { checkAdmin } = require("./security");
const { paramsProcessor } = require("../../utils/validate");
const { SERVER_PORT = 8888, ORIGIN = "*" } = process.env;
@@ -23,44 +20,34 @@ app.use(express.json());
app.use(require("body-parser").urlencoded({ extended: false }));
app.use("/diplomas", express.static("diplomas"));
-/*
-app.use((req, res, next) => {
- log.info(req?.query, req?.body, req?.path);
- next();
-});
-*/
// API v.2
-const apiRouter = express.Router();
-app.use("/api/v2", apiRouter);
-apiRouter.use(paramsProcessor);
+const student = express.Router();
+app.use("/student", student);
+student.use(paramsProcessor);
for (const request of PUBLIC) {
const { path, method, exec } = request;
switch (method) {
case "get":
- apiRouter.get(path, exec);
+ student.get(path, exec);
case "post":
- apiRouter.post(path, exec);
+ student.post(path, exec);
}
}
-// API v.3
-const student = express.Router();
-app.use("/v3/student", student);
-
-for (const method of STUDENT) {
- const { name, type, wall, exec } = method;
- switch (type) {
+const oldTeacher = express.Router();
+app.use("/teacher", oldTeacher);
+oldTeacher.use(checkAdmin);
+for (const request of TEACHER) {
+ const { path, method, exec } = request;
+ switch (method) {
case "get":
- student.get("/" + name, checkAuth(wall), prepareRequestData, exec);
+ oldTeacher.get(path, exec);
case "post":
- student.post("/" + name, checkAuth(wall), prepareRequestData, exec);
+ oldTeacher.post(path, exec);
}
}
-app.use(responseHandler);
-app.use(pathHandler);
-
function start() {
return new Promise((resolve, reject) => {
app.listen(SERVER_PORT, (err) => {
diff --git a/src/services/express/security.js b/src/services/express/security.js
index 0d54b79..e387458 100644
--- a/src/services/express/security.js
+++ b/src/services/express/security.js
@@ -1,6 +1,7 @@
const { checkToken } = require("../tokenMachine/tokenMachine");
const trustedMachines = process.env.TRUSTED || [];
+const adminToken = process.env.ADMIN_TOKEN
/***
* Function checks user access token.
@@ -40,4 +41,25 @@ function checkAuth(wall) {
};
}
-module.exports = { checkAuth };
+function checkAdmin(req, res, next) {
+ if (Object.keys(req.body).includes("gumroad_fee")) {
+ next();
+ return;
+ }
+ const token = req?.headers?.accesstoken;
+
+ if (token !== adminToken) {
+ res.status(401);
+ res.send({
+ OK: false,
+ error: "invalid_credentials",
+ error_description: "Invalid access token",
+ error_code: 10003,
+ });
+ return;
+ } else {
+ next();
+ }
+}
+
+module.exports = { checkAuth, checkAdmin };
diff --git a/src/services/fs/fs.js b/src/services/fs/fs.js
new file mode 100644
index 0000000..8607653
--- /dev/null
+++ b/src/services/fs/fs.js
@@ -0,0 +1,36 @@
+const { log } = require("../logger/logger");
+const fs = require("fs")
+const path = require('path');
+
+const projectPath = process.cwd()
+
+function createPath(filePath) {
+ fs.mkdirSync(filePath, { recursive: true }, (err) => {
+ if (err) throw err;
+ });
+}
+
+function readFile(filePath, name) {
+ const fullPath = path.join(projectPath, filePath)
+
+ try {
+ return JSON.parse(fs.readFileSync(fullPath + name))
+ } catch {
+ return
+ }
+}
+
+function writeFile(filePath, name, data) {
+ const fullPath = path.join(projectPath, filePath)
+ if (!fs.existsSync(fullPath)) {
+ createPath(fullPath)
+ }
+
+ try {
+ fs.writeFileSync(fullPath + name, JSON.stringify(data))
+ } catch {
+ throw new Error("Dump file is not wroted")
+ }
+}
+
+module.exports = {readFile, writeFile}
\ No newline at end of file
diff --git a/src/services/mailer/actions.js b/src/services/mailer/actions.js
new file mode 100644
index 0000000..651d4cd
--- /dev/null
+++ b/src/services/mailer/actions.js
@@ -0,0 +1,4 @@
+const sendMail = require("./actions/sendMail");
+const prepareMail = require("./actions/prepareMail");
+
+module.exports = { sendMail, prepareMail };
diff --git a/src/services/mailer/actions/prepareMail.js b/src/services/mailer/actions/prepareMail.js
new file mode 100644
index 0000000..e30d169
--- /dev/null
+++ b/src/services/mailer/actions/prepareMail.js
@@ -0,0 +1,8 @@
+const { applyTemplate } = require("../templates");
+
+function prepareMail(context) {
+ const { params, data } = context;
+ return applyTemplate(params, data);
+}
+
+module.exports = prepareMail;
\ No newline at end of file
diff --git a/src/services/mailer/actions/sendMail.js b/src/services/mailer/actions/sendMail.js
new file mode 100644
index 0000000..af334a9
--- /dev/null
+++ b/src/services/mailer/actions/sendMail.js
@@ -0,0 +1,14 @@
+const { mailer } = require("../mailer");
+
+const { MAIL_FROM } = process.env;
+
+function sendMail(mail, to, subject) {
+ mailer.sendMail({
+ from: MAIL_FROM,
+ to,
+ subject,
+ html: mail,
+ });
+}
+
+module.exports = sendMail;
diff --git a/src/services/mailer/mailer.js b/src/services/mailer/mailer.js
new file mode 100644
index 0000000..9fc53a0
--- /dev/null
+++ b/src/services/mailer/mailer.js
@@ -0,0 +1,18 @@
+const nodemailer = require("nodemailer");
+
+const { MAIL_USER, MAIL_PASS } = process.env;
+
+const options = {
+ pool: true,
+ host: "smtp.gmail.com",
+ port: 465,
+ secure: true,
+ auth: {
+ user: MAIL_USER,
+ pass: MAIL_PASS,
+ },
+};
+
+const mailer = nodemailer.createTransport(options);
+
+module.exports = { mailer };
diff --git a/src/services/mailer/templates.js b/src/services/mailer/templates.js
new file mode 100644
index 0000000..24ed75d
--- /dev/null
+++ b/src/services/mailer/templates.js
@@ -0,0 +1,35 @@
+const fs = require("fs");
+const path = require("path");
+
+const templatePath = path.join(__dirname, "templates");
+
+function getTemplatesList() {
+ return fs.readdirSync(templatePath);
+}
+
+function getTemplate({ lang, status, type, start }) {
+ const nameArray = [lang, status];
+ if (type) {
+ nameArray.push(type);
+ }
+ if (start) {
+ nameArray.push(start);
+ }
+ const name = nameArray.join("_") + ".html";
+ return fs.readFileSync(path.join(templatePath, name)).toString();
+}
+
+function applyTemplate(params, data = {}) {
+ let template = getTemplate(params);
+
+ const prefix = "*|";
+ const suffix = "|*";
+
+ for (const key in data) {
+ template = template.replaceAll(prefix + key + suffix, data[key]);
+ }
+
+ return template;
+}
+
+module.exports = { getTemplatesList, getTemplate, applyTemplate };
diff --git a/src/services/mailer/templates/en_new_buy_now.html b/src/services/mailer/templates/en_new_buy_now.html
new file mode 100644
index 0000000..ae18c55
--- /dev/null
+++ b/src/services/mailer/templates/en_new_buy_now.html
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Welcome!
+
+
+ Now you’ve got your Digital Mentor
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ Hi, *|NAME|*
+
+
+
+ The password was generated automatically ( *|PASSWORD|*), but you can
+ change it.
+ Sign in with your email address.
+
+
+
+ Follow the link below for an explanation of how to work with the Digital Mentor and answers to frequently asked student questions.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_current_buy_date.html b/src/services/mailer/templates/ru_current_buy_date.html
new file mode 100644
index 0000000..1630fb8
--- /dev/null
+++ b/src/services/mailer/templates/ru_current_buy_date.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Вы зачислены
+
+
+ Спасибо за покупку!
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ Привет, *|NAME|*
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_current_buy_now.html b/src/services/mailer/templates/ru_current_buy_now.html
new file mode 100644
index 0000000..2f02180
--- /dev/null
+++ b/src/services/mailer/templates/ru_current_buy_now.html
@@ -0,0 +1,161 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Вы зачислены
+
+
+ Спасибо за покупку!
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ Привет, *|NAME|*
+
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_new_buy_date.html b/src/services/mailer/templates/ru_new_buy_date.html
new file mode 100644
index 0000000..0f2ac5e
--- /dev/null
+++ b/src/services/mailer/templates/ru_new_buy_date.html
@@ -0,0 +1,173 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Вы зачислены
+
+
+ Спасибо за покупку!
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ Привет, *|NAME|*
+
+
+
+ Пароль к задачнику создан автоматически ( *|PASSWORD|*), но вы можете
+ поменять его,
+ если хотите. Логин — ваш е-мейл.
+
+
+
+ По следующей ссылке — объяснение, как работает задачник, и ответы на самые частые студенческие вопросы.
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_new_buy_now.html b/src/services/mailer/templates/ru_new_buy_now.html
new file mode 100644
index 0000000..7266fcb
--- /dev/null
+++ b/src/services/mailer/templates/ru_new_buy_now.html
@@ -0,0 +1,178 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Вы зачислены
+
+
+ Спасибо за покупку!
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ Привет, *|NAME|*
+
+
+
+ Пароль к задачнику создан автоматически ( *|PASSWORD|*), но вы можете
+ поменять его,
+ если хотите. Логин — ваш е-мейл.
+
+
+
+ По следующей ссылке — объяснение, как работает задачник, и ответы на самые частые студенческие вопросы.
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_otp.html b/src/services/mailer/templates/ru_otp.html
new file mode 100644
index 0000000..9fe6701
--- /dev/null
+++ b/src/services/mailer/templates/ru_otp.html
@@ -0,0 +1,169 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Явки-пароли
+
+
+ для входа в задачник
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+ Привет, *|NAME|*
+
+
+ Вы получили это письмо, потому что попросили прислать вам одноразовый код для входа в
+ задачник.
+
+
+ Вот он: *|OTP_CODE|*
+
+
+ Вы можете скопировать код и вставить его на странице входа в личный кабинет или перейти по ссылке ниже, чтобы сразу попасть в задачник:
+
+
+
+ Код и ссылка перестанут работать через час. Не переживайте, вы сможете запросить их повторно.
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mailer/templates/ru_renew.html b/src/services/mailer/templates/ru_renew.html
new file mode 100644
index 0000000..d78180a
--- /dev/null
+++ b/src/services/mailer/templates/ru_renew.html
@@ -0,0 +1,151 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Спасибо!
+
+ Вы купили продление
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+
+
+
+
+ *|NAME|*, здравствуйте
+ Спасибо, что купили продление доступа к дизайн-задачнику «Собаки Павловой».
+ Все в порядке, оплата прошла успешно. Мы сосчитали вас и продлили доступ к модулю
+ *|MODULE|*.
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+
+ |
+
+
+
+ |
+
+
+
+
\ No newline at end of file
diff --git a/src/services/mongo/mongo.js b/src/services/mongo/mongo.js
deleted file mode 100644
index bd5a324..0000000
--- a/src/services/mongo/mongo.js
+++ /dev/null
@@ -1,20 +0,0 @@
-const { MongoClient } = require("mongodb");
-const { log } = require("@logger");
-
-const { DB_URL, DB_NAME } = process.env;
-
-const mongoClient = new MongoClient(DB_URL);
-
-function getCollection(name) {
- return mongoClient.db(DB_NAME).collection(name);
-}
-
-async function start() {
- await mongoClient.connect();
- log.info("Connected to database successfully");
-}
-
-module.exports = {
- start,
- getCollection,
-};
diff --git a/src/services/mongo/requests.js b/src/services/mongo/requests.js
deleted file mode 100644
index 5891db5..0000000
--- a/src/services/mongo/requests.js
+++ /dev/null
@@ -1,68 +0,0 @@
-const { getCollection } = require("./mongo");
-
-function getProjection(returns) {
- const projection = {
- _id: 0,
- };
- for (const param of returns) {
- projection[param] = 1;
- }
- return projection;
-}
-
-function getOptions(returns, options) {
- return {
- projection: getProjection(returns),
- upsert: options.insertNew || false,
- returnDocument: "after",
- returnNewDocument: true,
- };
-}
-
-const DB = {
- count: (collection, data) => {
- const { query } = data;
-
- return getCollection(collection).countDocuments(query) || 0;
- },
- insertOne: (collection, data) => {
- const { query } = data;
-
- return getCollection(collection).insertOne(query);
- },
- getOne: (collection, data) => {
- const { query, returns = [] } = data;
-
- const projection = getProjection(returns);
-
- return getCollection(collection).findOne(query, { projection });
- },
- setOne: async (collection, data) => {
- const { query, set, push, returns = [], options = {} } = data;
-
- const allOptions = getOptions(returns, options);
-
- const response = await getCollection(collection).findOneAndUpdate(
- query,
- (set && { $set: set }) || (push && { $push: push }),
- allOptions
- );
-
- return response?.value || null;
- },
-
- getMany: async (collection, data) => {
- const { query, returns = [] } = data;
-
- const projection = getProjection(returns);
-
- const response = await getCollection(collection)
- .find(query, {
- projection,
- })
- .toArray();
- return response || [];
- },
-};
-
-module.exports = DB;
diff --git a/src/services/tokenMachine/OTK.js b/src/services/tokenMachine/OTK.js
index 313b4e9..55fdae1 100644
--- a/src/services/tokenMachine/OTK.js
+++ b/src/services/tokenMachine/OTK.js
@@ -1,18 +1,57 @@
const fetch = require("node-fetch");
-const server = process.env.REG_OTK_SERVER;
+const { OTK_SERVER, OTK_TOKEN } = process.env;
+
+const bearerToken = "Bearer " + OTK_TOKEN
+
+function getKeyParams(type) {
+ switch (type) {
+ case "oneTimePass":
+ return {
+ type: "digit",
+ length: 4,
+ life: 3600,
+ isReusable: false
+ }
+ case "oneTimeKey":
+ return {
+ type: "string",
+ length: 8,
+ life: 62 * 24 * 60 * 60,
+ isReusable: false
+ }
+ default:
+ return {
+ type: "digit",
+ length: 4,
+ life: 3600,
+ isReusable: false
+ }
+ }
+}
async function checkKey(key) {
- const response = await fetch(`${server}/checkKey?key=${key}`);
+ const response = await fetch(`${OTK_SERVER}/checkKey?key=${key}`, {
+ headers: {
+ "Authorization": bearerToken
+ },
+ });
const data = await response.json();
return data?.OK || false;
}
-async function setKey(user) {
- const response = await fetch(`${server}/setKey`, {
+async function setKey(userId, type) {
+ const body = {
+ userId,
+ ...getKeyParams(type)
+ }
+ const response = await fetch(`${OTK_SERVER}/setKey`, {
method: "POST",
- body: JSON.stringify(user),
- headers: { "Content-Type": "application/json" },
+ body: JSON.stringify(body),
+ headers: {
+ "Content-Type": "application/json",
+ "Authorization": bearerToken
+ },
});
const data = await response.json();
return data?.data?.key || undefined;
diff --git a/src/services/tokenMachine/tokenMachine.js b/src/services/tokenMachine/tokenMachine.js
index bd97ae6..0b4d6ba 100644
--- a/src/services/tokenMachine/tokenMachine.js
+++ b/src/services/tokenMachine/tokenMachine.js
@@ -1,3 +1,5 @@
+const { readFile, writeFile } = require("../../services/fs/fs")
+
function rand() {
return Math.random().toString(36).substring(2);
}
@@ -5,25 +7,31 @@ function rand() {
function getToken() {
const accessToken = rand() + rand();
const refreshToken = rand();
- const expiresIn = Math.floor(Date.now() / 1000 + 7200);
+ const expiresAt = Date.now() + 5 * 24 * 60 * 60 * 1000;
return {
accessToken,
- expiresIn,
+ expiresAt,
refreshToken,
};
}
function tokenMachine() {
- const tokens = {};
+ const tokens = readFile("/files/", "tokens.json",) || {};
function checkToken(token) {
return tokens?.[token];
}
- function setToken(user) {
+ function setToken(user, data = {}) {
const newToken = getToken();
tokens[newToken.accessToken] = {
id: user?.id,
+ expiresAt: newToken.expiresAt,
+ ip: data.ip,
+ ts: Date.now(),
+ userAgent: data.userAgent,
+ geo: data.geo
};
+ writeFile("/files/", "tokens.json", tokens)
return newToken;
}
@@ -37,6 +45,4 @@ function tokenMachine() {
};
}
-const accessTokens = tokenMachine();
-
-module.exports = accessTokens;
+module.exports = tokenMachine();
\ No newline at end of file
diff --git a/src/utils/access.js b/src/utils/access.js
new file mode 100644
index 0000000..6e94680
--- /dev/null
+++ b/src/utils/access.js
@@ -0,0 +1,22 @@
+/**
+ * Calculate deadline for user's module
+ *
+ * @param {String} date Date of start
+ * @param {Number} duration Days number of access
+ * @param {Array} prolongations List of users's prolongations
+ *
+ * @returns {String} Date of deadline
+ */
+function getDeadline({ deadline, prolongations = [] }) {
+ if (prolongations.length === 0) return deadline;
+
+ if (prolongations.length > 1) {
+ prolongations.sort((a, b) => Date.parse(b.until) - Date.parse(a.until));
+ }
+
+ return prolongations[0]?.until > deadline
+ ? prolongations[0]?.until
+ : deadline;
+}
+
+module.exports = { getDeadline };
diff --git a/src/utils/calculators.js b/src/utils/calculators.js
index 3df336a..a5a507c 100644
--- a/src/utils/calculators.js
+++ b/src/utils/calculators.js
@@ -144,20 +144,15 @@ function calculateDefaultScore(content = []) {
*
* @param {String} date Date of start
* @param {Number} duration Days number of access
- * @param {Array} prolongations List of users's prolongations
*
* @returns {String} Date of deadline
*/
-function calculateDeadline({ deadline, prolongations = [] }) {
- if (prolongations.length === 0) return deadline;
-
- if (prolongations.length > 1) {
- prolongations.sort((a, b) => Date.parse(b.until) - Date.parse(a.until));
- }
-
- return prolongations[0]?.until > deadline
- ? prolongations[0]?.until
- : deadline;
+function calculateDeadline(date, duration) {
+ const dateStart = new Date(date);
+ const dateFinish = new Date(
+ dateStart.setDate(dateStart.getDate() + duration)
+ );
+ return dateFinish.toISOString().split("T")[0];
}
/**
diff --git a/src/utils/checkAuth.js b/src/utils/checkAuth.js
index 38ccbdc..535fc41 100644
--- a/src/utils/checkAuth.js
+++ b/src/utils/checkAuth.js
@@ -1,4 +1,4 @@
-const { db } = require("../modules/dbRequests/mongo");
+const { USERS } = require("../modules/dbRequests/mongo");
const accessTokens = require("../services/tokenMachine/tokenMachine");
const { getModuleId } = require("./idExtractor");
const { generateMessage } = require("./messageGenerator");
@@ -16,7 +16,7 @@ function checkAuth(req, res, next) {
const userId = accessTokens.checkList()?.[token]?.id;
if (!userId) {
- const error = generateMessage(10103);
+ const error = generateMessage(10105);
res.status(401).send(error);
return error;
} else {
@@ -61,7 +61,7 @@ function checkModuleAccess(req, res, next) {
req?.body?.moduleId ||
getModuleId(lessonId || taskId || questionId);
- db.USERS.findOne({ id: userId }).then((user) => {
+ USERS.findOne({ id: userId }).then((user) => {
startDate = user?.modules?.[moduleId]?.start;
deadline = user?.modules?.[moduleId]?.deadline;
if (checkDate(startDate, deadline)) {
@@ -88,7 +88,7 @@ function checkCertAccess(req, res, next) {
req?.body?.moduleId ||
getModuleId(lessonId);
- db.USERS.findOne({ id: userId }).then((user) => {
+ USERS.findOne({ id: userId }).then((user) => {
const modules = Object.keys(user?.modules || {});
if (modules.includes(moduleId)) {
next();
diff --git a/src/utils/generateCertId.js b/src/utils/generateCertId.js
index a140d22..1eb2bc4 100644
--- a/src/utils/generateCertId.js
+++ b/src/utils/generateCertId.js
@@ -1,4 +1,5 @@
-const DB = require("@mongo/requests");
+const { CERTS } = require("../modules/dbRequests/mongo");
+const { getDBRequest } = require("../modules/dbRequests/dbRequests");
function padder(number = 0, count = 1) {
return number.toString().padStart(count, "0");
@@ -6,7 +7,7 @@ function padder(number = 0, count = 1) {
async function generateCertId(userId, moduleId, startDate) {
const certsCount =
- (await DB.count("certs", { query: { moduleId, startDate } })) || 0;
+ (await CERTS.count( { moduleId, startDate })) || 0;
const postfix = padder(certsCount + 1, 4);
const date = new Date(Date.parse(startDate));
@@ -16,7 +17,7 @@ async function generateCertId(userId, moduleId, startDate) {
)}`;
const certId = `${moduleId}${datePart}${postfix}`;
- DB.insertOne("certs", {
+ getDBRequest("setUserInfo", {
query: {
id: certId,
userId,
@@ -28,7 +29,10 @@ async function generateCertId(userId, moduleId, startDate) {
const path = `modules.${moduleId}.certId`;
- DB.setOne("users", { query: { id: userId }, set: { [path]: certId } });
+ getDBRequest("setUserInfo", {
+ query: { id: userId },
+ data: { [path]: certId }
+ });
return certId;
}
diff --git a/src/utils/getParentContent.js b/src/utils/getParentContent.js
index 3ca09dd..97587e0 100644
--- a/src/utils/getParentContent.js
+++ b/src/utils/getParentContent.js
@@ -2,10 +2,10 @@
const getPhrase = require("@assets/lang/lang");
const { getFullTaskId, getFullQuestionId } = require("./idExtractor");
-const DB = require("@mongo/requests");
+const { getDBRequest } = require("../modules/dbRequests/dbRequests");
async function getTaskName(taskId, lang) {
- const taskData = await DB.getOne("tasks", { query: { id: taskId } });
+ const taskData = await getDBRequest("getTaskInfo", { query: { id: taskId } });
if (!taskData) {
throw new Error(`getParentContent: Can't find task with ID ${taskId}`);
}
@@ -17,12 +17,9 @@ async function getTaskName(taskId, lang) {
async function getParentContent(userId, contentId, lang, sameTask = false) {
const taskId = getFullTaskId(contentId);
- const taskState = await DB.getOne("state", {
- query: {
- userId,
- taskId,
- },
- });
+ const taskState = await getDBRequest("getStateInfo", {
+ query: { userId, taskId },
+ })
if (taskState?.isChecked || sameTask) {
const questionId = getFullQuestionId(contentId);
diff --git a/src/utils/messageGenerator.js b/src/utils/messageGenerator.js
index 1713730..e8f29fc 100644
--- a/src/utils/messageGenerator.js
+++ b/src/utils/messageGenerator.js
@@ -33,6 +33,11 @@ const ERRORS = [
type: "invalid_credentials",
description: "Payment didn't found",
},
+ {
+ code: 10105,
+ type: "invalid_credentials",
+ description: "Access token is invalid or expired",
+ },
{
code: 10201,
type: "access_denied",
@@ -133,9 +138,19 @@ const ERRORS = [
type: "process_failure",
description: "Error with getting counselor content",
},
+ {
+ code: 20117,
+ type: "process_failure",
+ description: "Error with updating comment status",
+ },
+ {
+ code: 20118,
+ type: "process_failure",
+ description: "Error with resetting user password",
+ },
];
-function generateMessage(code, data = {}) {
+function generateMessage(code, data) {
if (code === 0) {
return { OK: true, data };
} else {
diff --git a/src/utils/validate.js b/src/utils/validate.js
index 677c475..19238b9 100644
--- a/src/utils/validate.js
+++ b/src/utils/validate.js
@@ -6,24 +6,24 @@ const { lang } = require("../../config.json");
const { generateMessage } = require("./messageGenerator");
const requireParams = {
- ["/api/v2/auth"]: ["email", "pass"],
- ["/api/v2/checkPayment"]: ["paymentId"],
- ["/api/v2/createPassword"]: ["email", "pass", "key"],
- ["/api/v2/getDashboard"]: ["accessToken"],
- ["/api/v2/getModuleInfo"]: ["moduleId", "accessToken"],
- ["/api/v2/getTask"]: ["taskId", "accessToken"],
- ["/api/v2/getModuleStart"]: ["moduleId", "accessToken"],
- ["/api/v2/getModuleFinal"]: ["moduleId", "accessToken"],
- ["/api/v2/getLessonStart"]: ["lessonId", "accessToken"],
- ["/api/v2/getLessonFinal"]: ["lessonId", "accessToken"],
- ["/api/v2/getLessonsList"]: ["moduleId", "accessToken"],
- ["/api/v2/getTasksList"]: ["lessonId", "accessToken"],
- ["/api/v2/getDiploma"]: ["moduleId", "accessToken"],
- ["/api/v2/setState"]: ["questionId", "state", "accessToken"],
- ["/api/v2/checkTask"]: ["taskId", "isChecked", "protest", "accessToken"],
- ["/api/v2/setControls"]: ["taskId", "controlsState", "accessToken"],
- ["/api/v2/addComment"]: ["taskId", "comment", "protest", "accessToken"],
- ["/api/v2/getCounselor"]: ["lang", "accessToken"],
+ ["/v2/student/auth"]: ["email", "pass"],
+ ["/v2/student/checkPayment"]: ["paymentId"],
+ ["/v2/student/createPassword"]: ["email", "pass", "key"],
+ ["/v2/student/getDashboard"]: ["accessToken"],
+ ["/v2/student/getModuleInfo"]: ["moduleId", "accessToken"],
+ ["/v2/student/getTask"]: ["taskId", "accessToken"],
+ ["/v2/student/getModuleStart"]: ["moduleId", "accessToken"],
+ ["/v2/student/getModuleFinal"]: ["moduleId", "accessToken"],
+ ["/v2/student/getLessonStart"]: ["lessonId", "accessToken"],
+ ["/v2/student/getLessonFinal"]: ["lessonId", "accessToken"],
+ ["/v2/student/getLessonsList"]: ["moduleId", "accessToken"],
+ ["/v2/student/getTasksList"]: ["lessonId", "accessToken"],
+ ["/v2/student/getDiploma"]: ["moduleId", "accessToken"],
+ ["/v2/student/setState"]: ["questionId", "state", "accessToken"],
+ ["/v2/student/checkTask"]: ["taskId", "isChecked", "protest", "accessToken"],
+ ["/v2/student/setControls"]: ["taskId", "controlsState", "accessToken"],
+ ["/v2/student/addComment"]: ["taskId", "comment", "protest", "accessToken"],
+ ["/v2/student/getCounselor"]: ["lang", "accessToken"],
};
function paramsProcessor(req, res, next) {
diff --git a/src/utils/visibilityControl.js b/src/utils/visibilityControl.js
index 5a1ed2b..0baf34a 100644
--- a/src/utils/visibilityControl.js
+++ b/src/utils/visibilityControl.js
@@ -1,4 +1,4 @@
-const { db } = require("../modules/dbRequests/mongo");
+const { STATE } = require("../modules/dbRequests/mongo");
const { getFullTaskId, getFullQuestionId } = require("./idExtractor");
function checkVisibility(id, taskState) {
@@ -21,11 +21,11 @@ async function setVisibility(userId, dependQuestionId, currentElementId) {
const currentTaskId = getFullTaskId(dependQuestionId);
const path = "data." + currentElementId + ".isVisible";
- const taskState = await db.STATE.findOne({ userId, taskId: dependTaskId });
+ const taskState = await STATE.findOne({ userId, taskId: dependTaskId });
const isVisible = checkVisibility(dependQuestionId, taskState);
- db.STATE.findOneAndUpdate(
+ STATE.findOneAndUpdate(
{ userId, taskId: currentTaskId },
{
$set: {