@adaptivestone/framework 5.0.0-beta.10 → 5.0.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/LICENCE +1 -1
- package/cliCommand.ts +10 -0
- package/dist/Cli.d.ts +7 -0
- package/dist/Cli.js +19 -0
- package/dist/Cli.js.map +1 -0
- package/dist/cluster.d.ts +1 -0
- package/dist/cluster.js +18 -0
- package/dist/cluster.js.map +1 -0
- package/dist/commands/CreateUser.d.ts +32 -0
- package/dist/commands/CreateUser.js +81 -0
- package/dist/commands/CreateUser.js.map +1 -0
- package/dist/commands/Documentation.d.ts +5 -0
- package/dist/commands/Documentation.js +15 -0
- package/dist/commands/Documentation.js.map +1 -0
- package/dist/commands/DropIndex.d.ts +16 -0
- package/dist/commands/DropIndex.js +30 -0
- package/dist/commands/DropIndex.js.map +1 -0
- package/dist/commands/GenerateRandomBytes.d.ts +7 -0
- package/dist/commands/GenerateRandomBytes.js +18 -0
- package/dist/commands/GenerateRandomBytes.js.map +1 -0
- package/dist/commands/GetOpenApiJson.d.ts +17 -0
- package/dist/commands/GetOpenApiJson.js +272 -0
- package/dist/commands/GetOpenApiJson.js.map +1 -0
- package/dist/commands/SyncIndexes.d.ts +6 -0
- package/dist/commands/SyncIndexes.js +32 -0
- package/dist/commands/SyncIndexes.js.map +1 -0
- package/dist/commands/migration/Create.d.ts +18 -0
- package/dist/commands/migration/Create.js +57 -0
- package/dist/commands/migration/Create.js.map +1 -0
- package/dist/commands/migration/Migrate.d.ts +6 -0
- package/dist/commands/migration/Migrate.js +46 -0
- package/dist/commands/migration/Migrate.js.map +1 -0
- package/dist/config/auth.d.ts +6 -0
- package/dist/config/auth.js +7 -0
- package/dist/config/auth.js.map +1 -0
- package/dist/config/http.d.ts +8 -0
- package/dist/config/http.js +10 -0
- package/dist/config/http.js.map +1 -0
- package/dist/config/i18n.d.ts +10 -0
- package/dist/config/i18n.js +13 -0
- package/dist/config/i18n.js.map +1 -0
- package/dist/config/ipDetector.d.ts +5 -0
- package/dist/config/ipDetector.js +15 -0
- package/dist/config/ipDetector.js.map +1 -0
- package/dist/config/log.d.ts +22 -0
- package/dist/config/log.js +23 -0
- package/dist/config/log.js.map +1 -0
- package/dist/config/mongo.d.ts +4 -0
- package/dist/config/mongo.js +4 -0
- package/dist/config/mongo.js.map +1 -0
- package/dist/config/rateLimiter.d.ts +15 -0
- package/dist/config/rateLimiter.js +17 -0
- package/dist/config/rateLimiter.js.map +1 -0
- package/dist/config/redis.d.ts +5 -0
- package/dist/config/redis.js +5 -0
- package/dist/config/redis.js.map +1 -0
- package/dist/config/validate.d.ts +4 -0
- package/dist/config/validate.js +4 -0
- package/dist/config/validate.js.map +1 -0
- package/dist/controllers/Auth.d.ts +74 -0
- package/dist/controllers/Auth.js +181 -0
- package/dist/controllers/Auth.js.map +1 -0
- package/dist/controllers/Home.d.ts +15 -0
- package/dist/controllers/Home.js +24 -0
- package/dist/controllers/Home.js.map +1 -0
- package/dist/controllers/index.d.ts +16 -0
- package/dist/controllers/index.js +59 -0
- package/dist/controllers/index.js.map +1 -0
- package/dist/folderConfig.d.ts +34 -0
- package/dist/folderConfig.js +15 -0
- package/dist/folderConfig.js.map +1 -0
- package/dist/helpers/files.d.ts +16 -0
- package/dist/helpers/files.js +73 -0
- package/dist/helpers/files.js.map +1 -0
- package/dist/helpers/logger.d.ts +4 -0
- package/dist/helpers/logger.js +28 -0
- package/dist/helpers/logger.js.map +1 -0
- package/dist/helpers/redis/clearNamespace.d.ts +3 -0
- package/dist/helpers/redis/clearNamespace.js +15 -0
- package/dist/helpers/redis/clearNamespace.js.map +1 -0
- package/dist/helpers/yup.d.ts +13 -0
- package/{helpers → dist/helpers}/yup.js +8 -9
- package/dist/helpers/yup.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/models/Lock.d.ts +62 -0
- package/dist/models/Lock.js +94 -0
- package/dist/models/Lock.js.map +1 -0
- package/dist/models/Migration.d.ts +11 -0
- package/dist/models/Migration.js +14 -0
- package/dist/models/Migration.js.map +1 -0
- package/dist/models/Sequence.d.ts +16 -0
- package/dist/models/Sequence.js +16 -0
- package/dist/models/Sequence.js.map +1 -0
- package/dist/models/User.d.ts +101 -0
- package/dist/models/User.js +230 -0
- package/dist/models/User.js.map +1 -0
- package/dist/modules/AbstractCommand.d.ts +30 -0
- package/dist/modules/AbstractCommand.js +44 -0
- package/dist/modules/AbstractCommand.js.map +1 -0
- package/dist/modules/AbstractConnector.d.ts +5 -0
- package/dist/modules/AbstractConnector.js +8 -0
- package/dist/modules/AbstractConnector.js.map +1 -0
- package/dist/modules/AbstractController.d.ts +90 -0
- package/dist/modules/AbstractController.js +324 -0
- package/dist/modules/AbstractController.js.map +1 -0
- package/dist/modules/AbstractModel.d.ts +32 -0
- package/dist/modules/AbstractModel.js +73 -0
- package/dist/modules/AbstractModel.js.map +1 -0
- package/dist/modules/Base.d.ts +29 -0
- package/dist/modules/Base.js +54 -0
- package/dist/modules/Base.js.map +1 -0
- package/dist/modules/BaseCli.d.ts +25 -0
- package/dist/modules/BaseCli.js +138 -0
- package/dist/modules/BaseCli.js.map +1 -0
- package/dist/server.d.ts +110 -0
- package/dist/server.js +372 -0
- package/dist/server.js.map +1 -0
- package/dist/services/cache/Cache.d.ts +31 -0
- package/dist/services/cache/Cache.js +115 -0
- package/dist/services/cache/Cache.js.map +1 -0
- package/dist/services/documentation/DocumentationGenerator.d.ts +11 -0
- package/dist/services/documentation/DocumentationGenerator.js +134 -0
- package/dist/services/documentation/DocumentationGenerator.js.map +1 -0
- package/dist/services/http/HttpServer.d.ts +35 -0
- package/dist/services/http/HttpServer.js +71 -0
- package/dist/services/http/HttpServer.js.map +1 -0
- package/dist/services/http/middleware/AbstractMiddleware.d.ts +25 -0
- package/dist/services/http/middleware/AbstractMiddleware.js +43 -0
- package/dist/services/http/middleware/AbstractMiddleware.js.map +1 -0
- package/dist/services/http/middleware/Auth.d.ts +9 -0
- package/dist/services/http/middleware/Auth.js +18 -0
- package/dist/services/http/middleware/Auth.js.map +1 -0
- package/dist/services/http/middleware/Cors.d.ts +10 -0
- package/dist/services/http/middleware/Cors.js +36 -0
- package/dist/services/http/middleware/Cors.js.map +1 -0
- package/dist/services/http/middleware/GetUserByToken.d.ts +19 -0
- package/dist/services/http/middleware/GetUserByToken.js +40 -0
- package/dist/services/http/middleware/GetUserByToken.js.map +1 -0
- package/dist/services/http/middleware/I18n.d.ts +26 -0
- package/dist/services/http/middleware/I18n.js +97 -0
- package/dist/services/http/middleware/I18n.js.map +1 -0
- package/dist/services/http/middleware/IpDetector.d.ts +12 -0
- package/dist/services/http/middleware/IpDetector.js +51 -0
- package/dist/services/http/middleware/IpDetector.js.map +1 -0
- package/dist/services/http/middleware/Pagination.d.ts +27 -0
- package/dist/services/http/middleware/Pagination.js +47 -0
- package/dist/services/http/middleware/Pagination.js.map +1 -0
- package/dist/services/http/middleware/PrepareAppInfo.d.ts +8 -0
- package/dist/services/http/middleware/PrepareAppInfo.js +17 -0
- package/dist/services/http/middleware/PrepareAppInfo.js.map +1 -0
- package/dist/services/http/middleware/RateLimiter.d.ts +18 -0
- package/dist/services/http/middleware/RateLimiter.js +106 -0
- package/dist/services/http/middleware/RateLimiter.js.map +1 -0
- package/dist/services/http/middleware/RequestLogger.d.ts +8 -0
- package/dist/services/http/middleware/RequestLogger.js +18 -0
- package/dist/services/http/middleware/RequestLogger.js.map +1 -0
- package/dist/services/http/middleware/RequestParser.d.ts +8 -0
- package/dist/services/http/middleware/RequestParser.js +35 -0
- package/dist/services/http/middleware/RequestParser.js.map +1 -0
- package/dist/services/http/middleware/Role.d.ts +9 -0
- package/dist/services/http/middleware/Role.js +24 -0
- package/dist/services/http/middleware/Role.js.map +1 -0
- package/dist/services/validate/ValidateService.d.ts +31 -0
- package/dist/services/validate/ValidateService.js +96 -0
- package/dist/services/validate/ValidateService.js.map +1 -0
- package/dist/services/validate/drivers/AbstractValidator.d.ts +14 -0
- package/dist/services/validate/drivers/AbstractValidator.js +32 -0
- package/dist/services/validate/drivers/AbstractValidator.js.map +1 -0
- package/dist/services/validate/drivers/CustomValidator.d.ts +14 -0
- package/dist/services/validate/drivers/CustomValidator.js +48 -0
- package/dist/services/validate/drivers/CustomValidator.js.map +1 -0
- package/dist/services/validate/drivers/YupValidator.d.ts +13 -0
- package/dist/services/validate/drivers/YupValidator.js +86 -0
- package/dist/services/validate/drivers/YupValidator.js.map +1 -0
- package/dist/tests/globalSetupVitest.d.ts +2 -0
- package/dist/tests/globalSetupVitest.js +29 -0
- package/dist/tests/globalSetupVitest.js.map +1 -0
- package/dist/tests/setupVitest.d.ts +1 -0
- package/dist/tests/setupVitest.js +99 -0
- package/dist/tests/setupVitest.js.map +1 -0
- package/package.json +19 -10
- package/Cli.js +0 -21
- package/cluster.js +0 -25
- package/commands/.gitkeep +0 -0
- package/commands/CreateUser.js +0 -106
- package/commands/Documentation.js +0 -17
- package/commands/DropIndex.js +0 -38
- package/commands/GenerateRandomBytes.js +0 -21
- package/commands/GetOpenApiJson.js +0 -336
- package/commands/SyncIndexes.js +0 -40
- package/commands/migration/Create.js +0 -72
- package/commands/migration/Migrate.js +0 -56
- package/config/auth.js +0 -9
- package/config/http.js +0 -9
- package/config/i18n.js +0 -12
- package/config/ipDetector.js +0 -14
- package/config/log.js +0 -22
- package/config/mongo.js +0 -3
- package/config/rateLimiter.js +0 -16
- package/config/redis.js +0 -4
- package/config/validate.js +0 -3
- package/controllers/Auth.js +0 -201
- package/controllers/Home.js +0 -28
- package/controllers/index.js +0 -60
- package/eslint.config.js +0 -68
- package/folderConfig.js +0 -13
- package/helpers/files.js +0 -76
- package/helpers/logger.js +0 -16
- package/helpers/redis/clearNamespace.js +0 -14
- package/index.js +0 -8
- package/jsconfig.json +0 -9
- package/locales/en/translation.json +0 -27
- package/locales/ru/translation.json +0 -27
- package/migrations/.gitkeep +0 -0
- package/models/Lock.js +0 -107
- package/models/Migration.js +0 -15
- package/models/Sequence.js +0 -22
- package/models/User.js +0 -280
- package/modules/AbstractCommand.js +0 -52
- package/modules/AbstractConnector.js +0 -9
- package/modules/AbstractController.js +0 -406
- package/modules/AbstractModel.d.ts +0 -48
- package/modules/AbstractModel.js +0 -92
- package/modules/Base.d.ts +0 -37
- package/modules/Base.js +0 -64
- package/modules/BaseCli.js +0 -157
- package/server.d.ts +0 -100
- package/server.js +0 -439
- package/services/cache/Cache.d.ts +0 -35
- package/services/cache/Cache.js +0 -124
- package/services/documentation/DocumentationGenerator.js +0 -169
- package/services/http/HttpServer.js +0 -89
- package/services/http/middleware/AbstractMiddleware.js +0 -51
- package/services/http/middleware/Auth.js +0 -20
- package/services/http/middleware/Cors.js +0 -46
- package/services/http/middleware/GetUserByToken.js +0 -47
- package/services/http/middleware/I18n.js +0 -117
- package/services/http/middleware/IpDetector.js +0 -59
- package/services/http/middleware/Pagination.js +0 -57
- package/services/http/middleware/PrepareAppInfo.js +0 -18
- package/services/http/middleware/RateLimiter.js +0 -134
- package/services/http/middleware/RequestLogger.js +0 -22
- package/services/http/middleware/RequestParser.js +0 -40
- package/services/http/middleware/Role.js +0 -29
- package/services/messaging/email/resources/.gitkeep +0 -1
- package/services/messaging/email/templates/.gitkeep +0 -0
- package/services/messaging/email/templates/recovery/html.pug +0 -8
- package/services/messaging/email/templates/recovery/subject.pug +0 -2
- package/services/messaging/email/templates/recovery/text.pug +0 -3
- package/services/messaging/email/templates/verification/html.pug +0 -10
- package/services/messaging/email/templates/verification/subject.pug +0 -1
- package/services/messaging/email/templates/verification/text.pug +0 -1
- package/services/validate/ValidateService.js +0 -157
- package/services/validate/drivers/AbstractValidator.js +0 -37
- package/services/validate/drivers/CustomValidator.js +0 -51
- package/services/validate/drivers/YupValidator.js +0 -103
- package/tests/globalSetupVitest.js +0 -35
- package/tests/setup.js +0 -120
- package/tests/setupVitest.js +0 -111
- package/types/Expand.d.ts +0 -11
- package/types/ICommandArguments.d.ts +0 -41
- package/types/TFoldersConfig.d.ts +0 -20
- package/views/404.pug +0 -3
- package/views/home.pug +0 -3
- package/views/layouts/base.pug +0 -39
- package/vitest.config.js +0 -17
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { BlockList } from 'node:net';
|
|
2
|
-
|
|
3
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
4
|
-
|
|
5
|
-
class IpDetector extends AbstractMiddleware {
|
|
6
|
-
static get description() {
|
|
7
|
-
return 'Detect real user IP address. Support proxy and load balancer';
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
constructor(app, params) {
|
|
11
|
-
super(app, params);
|
|
12
|
-
const { trustedProxy } = this.app.getConfig('ipDetector');
|
|
13
|
-
|
|
14
|
-
this.blockList = new BlockList();
|
|
15
|
-
|
|
16
|
-
for (const subnet of trustedProxy) {
|
|
17
|
-
const addressType = subnet.includes(':') ? 'ipv6' : 'ipv4';
|
|
18
|
-
if (subnet.includes('/')) {
|
|
19
|
-
// CIDR
|
|
20
|
-
const [realSubnet, prefixLength] = subnet.split('/');
|
|
21
|
-
this.blockList.addSubnet(
|
|
22
|
-
realSubnet,
|
|
23
|
-
parseInt(prefixLength, 10),
|
|
24
|
-
addressType,
|
|
25
|
-
);
|
|
26
|
-
} else if (subnet.includes('-')) {
|
|
27
|
-
// RANGE
|
|
28
|
-
const [start, end] = subnet.split('-');
|
|
29
|
-
this.blockList.addRange(start, end, addressType);
|
|
30
|
-
} else {
|
|
31
|
-
// just an address
|
|
32
|
-
this.blockList.addAddress(subnet, addressType);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
async middleware(req, res, next) {
|
|
38
|
-
const { headers } = this.app.getConfig('ipDetector');
|
|
39
|
-
const initialIp = req.socket.remoteAddress;
|
|
40
|
-
req.appInfo.ip = initialIp;
|
|
41
|
-
const addressType = initialIp.includes(':') ? 'ipv6' : 'ipv4';
|
|
42
|
-
|
|
43
|
-
if (this.blockList.check(initialIp, addressType)) {
|
|
44
|
-
// we can trust this source
|
|
45
|
-
for (const header of headers) {
|
|
46
|
-
// in a range
|
|
47
|
-
const ipHeader = req.headers[header.toLowerCase()];
|
|
48
|
-
if (ipHeader) {
|
|
49
|
-
const [firstIp] = ipHeader.split(',').map((ip) => ip.trim());
|
|
50
|
-
req.appInfo.ip = firstIp;
|
|
51
|
-
break;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
next();
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export default IpDetector;
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
import { object, number } from 'yup';
|
|
2
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
3
|
-
/**
|
|
4
|
-
* Middleware for reusing pagination
|
|
5
|
-
*/
|
|
6
|
-
class Pagination extends AbstractMiddleware {
|
|
7
|
-
static get description() {
|
|
8
|
-
return 'Pagination middleware. You can use limit=10 and maxLimit=100 parameters';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
// eslint-disable-next-line class-methods-use-this
|
|
12
|
-
get relatedQueryParameters() {
|
|
13
|
-
return object().shape({
|
|
14
|
-
page: number(),
|
|
15
|
-
limit: number(),
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async middleware(req, res, next) {
|
|
20
|
-
let { limit, maxLimit } = this.params;
|
|
21
|
-
|
|
22
|
-
limit = (typeof limit !== 'number' ? parseInt(limit, 10) : limit) || 10;
|
|
23
|
-
maxLimit =
|
|
24
|
-
(typeof maxLimit !== 'number' ? parseInt(maxLimit, 10) : maxLimit) || 100;
|
|
25
|
-
|
|
26
|
-
req.appInfo.pagination = {};
|
|
27
|
-
req.appInfo.pagination.page =
|
|
28
|
-
typeof req?.query?.page === 'string'
|
|
29
|
-
? parseInt(req?.query?.page, 10) || 1
|
|
30
|
-
: 1;
|
|
31
|
-
|
|
32
|
-
req.appInfo.pagination.limit =
|
|
33
|
-
typeof req?.query?.limit === 'string'
|
|
34
|
-
? parseInt(req?.query?.limit, 10) || 0
|
|
35
|
-
: limit;
|
|
36
|
-
|
|
37
|
-
if (req.appInfo.pagination.limit > maxLimit) {
|
|
38
|
-
req.appInfo.pagination.limit = maxLimit;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (req.appInfo.pagination.page < 1) {
|
|
42
|
-
req.appInfo.pagination.page = 1;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
if (req.appInfo.pagination.limit < 0) {
|
|
46
|
-
req.appInfo.pagination.limit = 0;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
req.appInfo.pagination.skip =
|
|
50
|
-
req.appInfo.pagination.page * req.appInfo.pagination.limit -
|
|
51
|
-
req.appInfo.pagination.limit;
|
|
52
|
-
|
|
53
|
-
return next();
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export default Pagination;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
2
|
-
|
|
3
|
-
class PrepareAppInfo extends AbstractMiddleware {
|
|
4
|
-
static get description() {
|
|
5
|
-
return 'Basic middleware that creates "req.appInfo" object';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
async middleware(req, res, next) {
|
|
9
|
-
if (!req.appInfo) {
|
|
10
|
-
req.appInfo = {
|
|
11
|
-
app: this.app,
|
|
12
|
-
};
|
|
13
|
-
}
|
|
14
|
-
next();
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default PrepareAppInfo;
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
RateLimiterMemory,
|
|
3
|
-
RateLimiterRedis,
|
|
4
|
-
RateLimiterMongo,
|
|
5
|
-
} from 'rate-limiter-flexible';
|
|
6
|
-
import merge from 'deepmerge';
|
|
7
|
-
import { createClient } from '@redis/client';
|
|
8
|
-
import mongoose from 'mongoose';
|
|
9
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
10
|
-
|
|
11
|
-
class RateLimiter extends AbstractMiddleware {
|
|
12
|
-
static get description() {
|
|
13
|
-
return 'Rate limiter middleware. Limit amount of request. Please refer to documentation';
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
constructor(app, params) {
|
|
17
|
-
super(app, params);
|
|
18
|
-
const limiterOptions = this.app.getConfig('rateLimiter');
|
|
19
|
-
|
|
20
|
-
this.finalOptions = merge(limiterOptions, params);
|
|
21
|
-
this.limiter = null;
|
|
22
|
-
|
|
23
|
-
switch (this.finalOptions.driver) {
|
|
24
|
-
case 'memory':
|
|
25
|
-
this.limiter = new RateLimiterMemory(this.finalOptions.limiterOptions);
|
|
26
|
-
break;
|
|
27
|
-
|
|
28
|
-
case 'redis':
|
|
29
|
-
this.limiter = this.initRedisLimiter();
|
|
30
|
-
break;
|
|
31
|
-
|
|
32
|
-
case 'mongo':
|
|
33
|
-
this.limiter = new RateLimiterMongo({
|
|
34
|
-
storeClient: mongoose.connection,
|
|
35
|
-
...this.finalOptions.limiterOptions,
|
|
36
|
-
});
|
|
37
|
-
break;
|
|
38
|
-
|
|
39
|
-
default:
|
|
40
|
-
this.logger.error(
|
|
41
|
-
`Unknwon option for driver ${this.finalOptions.driver}`,
|
|
42
|
-
);
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
initRedisLimiter() {
|
|
48
|
-
const redisConfig = this.app.getConfig('redis');
|
|
49
|
-
const redisClient = createClient({
|
|
50
|
-
url: redisConfig.url,
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// TODO: change it
|
|
54
|
-
(async () => {
|
|
55
|
-
await redisClient.connect();
|
|
56
|
-
})();
|
|
57
|
-
|
|
58
|
-
redisClient.on('error', (error, b, c) => {
|
|
59
|
-
this.logger.error(error, b, c);
|
|
60
|
-
});
|
|
61
|
-
redisClient.on('connect', () => {
|
|
62
|
-
this.logger.info('Redis connection success');
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
this.app.events.on('shutdown', async () => {
|
|
66
|
-
await redisClient.disconnect();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
return new RateLimiterRedis({
|
|
70
|
-
storeClient: redisClient,
|
|
71
|
-
useRedisPackage: true,
|
|
72
|
-
...this.finalOptions.limiterOptions,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
gerenateConsumeKey(req) {
|
|
77
|
-
const { ip, route, user, request } = this.finalOptions.consumeKeyComponents;
|
|
78
|
-
|
|
79
|
-
const key = [];
|
|
80
|
-
if (ip) {
|
|
81
|
-
if (!req.appInfo.ip) {
|
|
82
|
-
this.logger.error(
|
|
83
|
-
`RateLimiter: Can't get remote address from request. Please check that you used IpDetecor middleware before RateLimiter`,
|
|
84
|
-
);
|
|
85
|
-
} else {
|
|
86
|
-
key.push(req.appInfo.ip);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (route) {
|
|
90
|
-
key.push(`${req.baseUrl ?? ''}${req.path ?? ''}`); // to avoid quesry params
|
|
91
|
-
}
|
|
92
|
-
if (user && req.appInfo?.user) {
|
|
93
|
-
key.push(req.appInfo?.user.id);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (request && request.length) {
|
|
97
|
-
request.forEach((val) => {
|
|
98
|
-
if (req.body && req.body[val]) {
|
|
99
|
-
key.push(req.body[val]);
|
|
100
|
-
}
|
|
101
|
-
// if (req.appInfo.request && req.appInfo.request[val]) {
|
|
102
|
-
// key.push(req.appInfo.request[val]);
|
|
103
|
-
// }
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return key.join('_');
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
async middleware(req, res, next) {
|
|
111
|
-
if (!this.limiter) {
|
|
112
|
-
this.logger.info(
|
|
113
|
-
`RateLimiter not inited correclty! Please check init logs `,
|
|
114
|
-
);
|
|
115
|
-
return res.status(500).json({ message: 'RateLimiter error' });
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const { namespace } = this.app.getConfig('redis');
|
|
119
|
-
|
|
120
|
-
const consumeKey = `${namespace}-${this.gerenateConsumeKey(req)}`;
|
|
121
|
-
|
|
122
|
-
const consumeResult = await this.limiter
|
|
123
|
-
.consume(consumeKey, this.finalOptions.consumePoints)
|
|
124
|
-
.catch(() => {
|
|
125
|
-
this.logger.warn(`Too many requests. Consume key: ${consumeKey}`);
|
|
126
|
-
});
|
|
127
|
-
if (consumeResult) {
|
|
128
|
-
return next();
|
|
129
|
-
}
|
|
130
|
-
return res.status(429).json({ message: 'Too Many Requests' });
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
export default RateLimiter;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
2
|
-
|
|
3
|
-
class RequestLogger extends AbstractMiddleware {
|
|
4
|
-
static get description() {
|
|
5
|
-
return 'Log info about the request';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
async middleware(req, res, next) {
|
|
9
|
-
const startTime = performance.now();
|
|
10
|
-
const text = `Request is [${req.method}] ${req.url}`;
|
|
11
|
-
this.logger.info(text);
|
|
12
|
-
res.on('finish', () => {
|
|
13
|
-
const end = performance.now();
|
|
14
|
-
this.logger.info(
|
|
15
|
-
`Finished ${text}. Status: ${res.statusCode}. [${(end - startTime).toFixed(2)} ms]`,
|
|
16
|
-
);
|
|
17
|
-
});
|
|
18
|
-
next();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default RequestLogger;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import formidable from 'formidable';
|
|
2
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
3
|
-
|
|
4
|
-
class RequestParser extends AbstractMiddleware {
|
|
5
|
-
static get description() {
|
|
6
|
-
return 'Parses incoming request. Based on Formidable library';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
async middleware(req, res, next) {
|
|
10
|
-
const time = Date.now();
|
|
11
|
-
this.logger.verbose(`Parsing request`);
|
|
12
|
-
// TODO update this to https://github.com/node-formidable/formidable/issues/412#issuecomment-1367914268 in node v20 (in 2023?)
|
|
13
|
-
|
|
14
|
-
const form = formidable(this.params); // not in construstor as reuse formidable affects performance
|
|
15
|
-
let fields;
|
|
16
|
-
let files;
|
|
17
|
-
try {
|
|
18
|
-
[fields, files] = await form.parse(req);
|
|
19
|
-
} catch (err) {
|
|
20
|
-
this.logger.error(`Parsing failed ${err}`);
|
|
21
|
-
return res.status(400).json({
|
|
22
|
-
message: `Error to parse your request. You provided invalid content type or content-length. Please check your request headers and content type.`,
|
|
23
|
-
});
|
|
24
|
-
// return next(err);
|
|
25
|
-
}
|
|
26
|
-
this.logger.verbose(
|
|
27
|
-
`Parsing multipart/formdata request DONE ${Date.now() - time}ms`,
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
req.body = {
|
|
31
|
-
// todo avoid body in next versions
|
|
32
|
-
...(req.body || {}),
|
|
33
|
-
...fields,
|
|
34
|
-
...files,
|
|
35
|
-
};
|
|
36
|
-
return next();
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
export default RequestParser;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import AbstractMiddleware from './AbstractMiddleware.js';
|
|
2
|
-
|
|
3
|
-
class RoleMiddleware extends AbstractMiddleware {
|
|
4
|
-
static get description() {
|
|
5
|
-
return 'Check user role (user.roles property). If the user has no role then stop request and return error. OR logic (any role will pass user)';
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
async middleware(req, res, next) {
|
|
9
|
-
const { user } = req.appInfo;
|
|
10
|
-
|
|
11
|
-
if (!user) {
|
|
12
|
-
return res.status(401).json({ message: 'User should be provided' });
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
let hasRole = false;
|
|
16
|
-
user.roles.forEach((role) => {
|
|
17
|
-
if (this.params.roles.includes(role)) {
|
|
18
|
-
hasRole = true;
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
if (!hasRole) {
|
|
23
|
-
return res.status(403).json({ message: 'You do not have access' });
|
|
24
|
-
}
|
|
25
|
-
return next();
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export default RoleMiddleware;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
This folder for you resources to inline
|
|
File without changes
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
= `Верификаия емейла`
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
= `Добрый день {{username}} Для верификации емейла перейдите по ссылке ${link}`
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import { isSchema } from 'yup';
|
|
2
|
-
import YupValidator from './drivers/YupValidator.js';
|
|
3
|
-
import CustomValidator from './drivers/CustomValidator.js';
|
|
4
|
-
import Base from '../../modules/Base.js';
|
|
5
|
-
|
|
6
|
-
class ValidateService extends Base {
|
|
7
|
-
constructor(app, validator) {
|
|
8
|
-
super(app);
|
|
9
|
-
this.validator = validator
|
|
10
|
-
? ValidateService.getDriverByValidatorBody(app, validator)
|
|
11
|
-
: null;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
static drivers = {
|
|
15
|
-
YupValidator,
|
|
16
|
-
CustomValidator,
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
static isValidatorExists(validator) {
|
|
20
|
-
if (!(validator instanceof Object)) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
return Object.values(this.drivers).some(
|
|
25
|
-
(driver) => validator instanceof driver,
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
static getDriverByValidatorBody(app, body = {}) {
|
|
30
|
-
if (this.isValidatorExists(body)) {
|
|
31
|
-
return body;
|
|
32
|
-
}
|
|
33
|
-
if (isSchema(body)) {
|
|
34
|
-
const yupValidator = new YupValidator(app, body);
|
|
35
|
-
return yupValidator;
|
|
36
|
-
}
|
|
37
|
-
const customValidator = new CustomValidator(app, body);
|
|
38
|
-
return customValidator;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Filter middlewares by route path and select all parameters
|
|
43
|
-
*/
|
|
44
|
-
filterRelatedParametersByRoute(middlewares, method, path) {
|
|
45
|
-
const middlewaresParams = middlewares
|
|
46
|
-
.filter(
|
|
47
|
-
(middleware) =>
|
|
48
|
-
middleware.method.toLowerCase() === method.toLowerCase() &&
|
|
49
|
-
middleware.fullPath.toLowerCase() === path.toLowerCase(),
|
|
50
|
-
)
|
|
51
|
-
?.map((middleware) => {
|
|
52
|
-
const instance = new middleware.MiddlewareFunction(
|
|
53
|
-
this.app,
|
|
54
|
-
middleware.params,
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
return instance.relatedReqParameters;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
return middlewaresParams;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Group all middleware(routes + controller) parameters
|
|
65
|
-
*/
|
|
66
|
-
getMiddlewareParams(controllerMiddlewares, AllrouteMiddlewares, options) {
|
|
67
|
-
const { method, path } = options;
|
|
68
|
-
const routeMiddlewaresParams = this.filterRelatedParametersByRoute(
|
|
69
|
-
AllrouteMiddlewares,
|
|
70
|
-
method,
|
|
71
|
-
path,
|
|
72
|
-
);
|
|
73
|
-
|
|
74
|
-
const controllerMiddlewaresParams = this.filterRelatedParametersByRoute(
|
|
75
|
-
controllerMiddlewares,
|
|
76
|
-
method,
|
|
77
|
-
path,
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
return {
|
|
81
|
-
request: [
|
|
82
|
-
...controllerMiddlewaresParams.map((x) => x.request),
|
|
83
|
-
...routeMiddlewaresParams.map((x) => x.request),
|
|
84
|
-
],
|
|
85
|
-
query: [
|
|
86
|
-
...controllerMiddlewaresParams.map((x) => x.query),
|
|
87
|
-
...routeMiddlewaresParams.map((x) => x.query),
|
|
88
|
-
],
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// eslint-disable-next-line class-methods-use-this
|
|
93
|
-
async validateSchema(req, validator, data) {
|
|
94
|
-
if (!validator) {
|
|
95
|
-
return {};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
await validator.validateFields(data, req);
|
|
99
|
-
|
|
100
|
-
return validator.castFields(data, req);
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
async validateArrayOfSchemas(req, validators, data) {
|
|
104
|
-
const result = [];
|
|
105
|
-
|
|
106
|
-
for (const validator of validators) {
|
|
107
|
-
const formatedValidator = ValidateService.getDriverByValidatorBody(
|
|
108
|
-
this.app,
|
|
109
|
-
validator,
|
|
110
|
-
);
|
|
111
|
-
result.push(this.validateSchema(req, formatedValidator, data));
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
return Promise.all(result);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Validate req data. For example req.body, req.query
|
|
119
|
-
*/
|
|
120
|
-
async validateReqData(req, options) {
|
|
121
|
-
const { selectedReqData, additionalMiddlewareFieldsData } = options;
|
|
122
|
-
const {
|
|
123
|
-
middlewaresInfo,
|
|
124
|
-
routeMiddlewaresReg,
|
|
125
|
-
options: routeOptions,
|
|
126
|
-
} = additionalMiddlewareFieldsData;
|
|
127
|
-
|
|
128
|
-
let validatedFields = await this.validateSchema(
|
|
129
|
-
req,
|
|
130
|
-
this.validator,
|
|
131
|
-
selectedReqData,
|
|
132
|
-
);
|
|
133
|
-
const additionalMiddlewareSchemas = this.getMiddlewareParams(
|
|
134
|
-
middlewaresInfo,
|
|
135
|
-
routeMiddlewaresReg,
|
|
136
|
-
routeOptions,
|
|
137
|
-
)[routeOptions.prefix];
|
|
138
|
-
|
|
139
|
-
if (additionalMiddlewareSchemas.length) {
|
|
140
|
-
const middlewareValidatedFields = await this.validateArrayOfSchemas(
|
|
141
|
-
req,
|
|
142
|
-
additionalMiddlewareSchemas,
|
|
143
|
-
selectedReqData,
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
validatedFields = Object.assign(
|
|
147
|
-
{},
|
|
148
|
-
validatedFields,
|
|
149
|
-
...middlewareValidatedFields,
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
return validatedFields;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
export default ValidateService;
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import Base from '../../../modules/Base.js';
|
|
2
|
-
|
|
3
|
-
class AbstractValidator extends Base {
|
|
4
|
-
constructor(app, body) {
|
|
5
|
-
super(app);
|
|
6
|
-
this.body = body;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// eslint-disable-next-line no-unused-vars
|
|
10
|
-
static convertFieldsToJson(fields) {
|
|
11
|
-
// IMPLENT;
|
|
12
|
-
return {};
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// eslint-disable-next-line class-methods-use-this
|
|
16
|
-
get fieldsInJsonFormat() {
|
|
17
|
-
// IMPLENT;
|
|
18
|
-
return {};
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
// eslint-disable-next-line class-methods-use-this, no-unused-vars
|
|
22
|
-
async validateFields(data, { query, body, appInfo }) {
|
|
23
|
-
// IMPLENT;
|
|
24
|
-
return true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
// eslint-disable-next-line class-methods-use-this
|
|
28
|
-
async castFields() {
|
|
29
|
-
// IMPLENT;
|
|
30
|
-
return true;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static get loggerGroup() {
|
|
34
|
-
return 'AbstractValidator_';
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
export default AbstractValidator;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
import { ValidationError } from 'yup';
|
|
2
|
-
import AbstractValidator from './AbstractValidator.js';
|
|
3
|
-
|
|
4
|
-
class CustomValidator extends AbstractValidator {
|
|
5
|
-
async validateFields(data, { query, body, appInfo }) {
|
|
6
|
-
if (this.body) {
|
|
7
|
-
if (typeof this.body.validate !== 'function') {
|
|
8
|
-
this.logger.error('request.validate should be a function');
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
try {
|
|
12
|
-
await this.body.validate(data, {
|
|
13
|
-
req: {
|
|
14
|
-
query,
|
|
15
|
-
body,
|
|
16
|
-
appInfo,
|
|
17
|
-
},
|
|
18
|
-
});
|
|
19
|
-
} catch (e) {
|
|
20
|
-
this.logger.warn(`CustomValidator validateFields ${e}`);
|
|
21
|
-
if (e.path) {
|
|
22
|
-
throw new ValidationError({
|
|
23
|
-
[e.path]: e.message,
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
throw new Error(e);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
async castFields(data, { query, body, appInfo }) {
|
|
31
|
-
if (this.body) {
|
|
32
|
-
if (typeof this.body.cast !== 'function') {
|
|
33
|
-
this.logger.error('request.validate should be a function');
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return this.body.cast(data, {
|
|
38
|
-
req: {
|
|
39
|
-
query,
|
|
40
|
-
body,
|
|
41
|
-
appInfo,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
static get loggerGroup() {
|
|
47
|
-
return 'CustomValidator_';
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export default CustomValidator;
|