@futdevpro/nts-dynamo 1.15.31 → 1.15.34

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.
Files changed (26) hide show
  1. package/build/_modules/rate-limit/_models/rate-limit-config.interface.d.ts +54 -0
  2. package/build/_modules/rate-limit/_models/rate-limit-config.interface.d.ts.map +1 -0
  3. package/build/_modules/rate-limit/_models/rate-limit-config.interface.js +3 -0
  4. package/build/_modules/rate-limit/_models/rate-limit-config.interface.js.map +1 -0
  5. package/build/_modules/rate-limit/_models/rate-limit-policy.interface.d.ts +16 -0
  6. package/build/_modules/rate-limit/_models/rate-limit-policy.interface.d.ts.map +1 -0
  7. package/build/_modules/rate-limit/_models/rate-limit-policy.interface.js +3 -0
  8. package/build/_modules/rate-limit/_models/rate-limit-policy.interface.js.map +1 -0
  9. package/build/_modules/rate-limit/index.d.ts +4 -0
  10. package/build/_modules/rate-limit/index.d.ts.map +1 -0
  11. package/build/_modules/rate-limit/index.js +6 -0
  12. package/build/_modules/rate-limit/index.js.map +1 -0
  13. package/build/_modules/rate-limit/rate-limit.middleware.d.ts +118 -0
  14. package/build/_modules/rate-limit/rate-limit.middleware.d.ts.map +1 -0
  15. package/build/_modules/rate-limit/rate-limit.middleware.js +262 -0
  16. package/build/_modules/rate-limit/rate-limit.middleware.js.map +1 -0
  17. package/build/_modules/server/errors/errors.data-service.d.ts.map +1 -1
  18. package/build/_modules/server/errors/errors.data-service.js +9 -1
  19. package/build/_modules/server/errors/errors.data-service.js.map +1 -1
  20. package/package.json +21 -3
  21. package/src/_modules/rate-limit/_models/rate-limit-config.interface.ts +60 -0
  22. package/src/_modules/rate-limit/_models/rate-limit-policy.interface.ts +16 -0
  23. package/src/_modules/rate-limit/index.ts +3 -0
  24. package/src/_modules/rate-limit/rate-limit.middleware.spec.ts +211 -0
  25. package/src/_modules/rate-limit/rate-limit.middleware.ts +310 -0
  26. package/src/_modules/server/errors/errors.data-service.ts +10 -2
@@ -0,0 +1,54 @@
1
+ import { Request } from 'express';
2
+ import { DyNTS_RateLimit_Policy } from './rate-limit-policy.interface';
3
+ /**
4
+ * Config a `DyNTS_RateLimit_Middleware.configure(...)`-hoz.
5
+ *
6
+ * Minden mezo opcionalis — a default-ok megfelelnek a tipikus API
7
+ * rate-limit-elvarasoknak (100 req/min, sliding window, IP-alapu kulcs,
8
+ * path-alapu endpoint-csoportositas, X-RateLimit-* response header-ek).
9
+ */
10
+ export interface DyNTS_RateLimit_Config {
11
+ /**
12
+ * Default request-limit `windowMs` alatt, ha az adott kulcsra nincs
13
+ * `setPolicyForKey()`-szel beallitott egyedi policy. Default: `100`.
14
+ */
15
+ defaultLimit?: number;
16
+ /**
17
+ * Default sliding-window hossza milliszekundumban. Default: `60000` (1 perc).
18
+ */
19
+ defaultWindowMs?: number;
20
+ /**
21
+ * Rate-limit subject-extractor. Visszater a karakterlanccal, ami azonositja
22
+ * a rate-limit alanyat (pl. IP-cim, API-kulcs ID, account ID).
23
+ *
24
+ * Default: a `req.headers['x-forwarded-for']` (csak az elso IP, ha lista)
25
+ * vagy ha hianyzik akkor `req.ip` vagy `'unknown'`. Ez webszerver elotti
26
+ * proxy/CDN-mentes setup-ra megfelelo; ha az nd-space mar identifikalja az
27
+ * API-kulcsot a `req`-ben, a host adhat sajat extractort ami a key-ID-t
28
+ * adja vissza.
29
+ */
30
+ keyExtractor?: (req: Request) => string;
31
+ /**
32
+ * Endpoint-csoportosito. Visszater a karakterlanccal, ami azonositja az
33
+ * adott endpoint-csoportot. A storage-key `${subject}|${endpoint}` lesz.
34
+ *
35
+ * Default: `req.path` — minden uri-path kulon vodorbe kerul. Csoportositas
36
+ * mas szempontok szerint (pl. "datasets" csoport = `/api/datasets/*`)
37
+ * a hostnal felulirhato.
38
+ */
39
+ endpointGrouper?: (req: Request) => string;
40
+ /**
41
+ * Beallitja-e a `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
42
+ * `X-RateLimit-Reset` (es a 429-re `Retry-After`) response header-eket.
43
+ * Default: `true`.
44
+ *
45
+ * Test/dev kornyezetben opcionalisan kikapcsolhato.
46
+ */
47
+ responseHeaders?: boolean;
48
+ /**
49
+ * Per-policy override-ok az induloskor. A `setPolicyForKey()` runtime-ban is
50
+ * felulhatja ezeket.
51
+ */
52
+ initialKeyPolicies?: Record<string, DyNTS_RateLimit_Policy>;
53
+ }
54
+ //# sourceMappingURL=rate-limit-config.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-config.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/rate-limit/_models/rate-limit-config.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAEvE;;;;;;GAMG;AACH,MAAM,WAAW,sBAAsB;IACrC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAExC;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAE3C;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;CAC7D"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=rate-limit-config.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-config.interface.js","sourceRoot":"","sources":["../../../../src/_modules/rate-limit/_models/rate-limit-config.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Per-kulcs rate-limit policy.
3
+ *
4
+ * A `DyNTS_RateLimit_Middleware.setPolicyForKey(key, policy)` allitja be,
5
+ * vagy a `DyNTS_RateLimit_Config.initialKeyPolicies` map-en at.
6
+ *
7
+ * Tipikus use-case: subscription-tier-up — egy belepett user API-kulcsa
8
+ * magasabb `limit`-et kap, mint a default (anonim/IP-alapu) limit.
9
+ */
10
+ export interface DyNTS_RateLimit_Policy {
11
+ /** Hany request engedelyezett a `windowMs` alatt. */
12
+ limit: number;
13
+ /** A sliding-window hossza milliszekundumban. */
14
+ windowMs: number;
15
+ }
16
+ //# sourceMappingURL=rate-limit-policy.interface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-policy.interface.d.ts","sourceRoot":"","sources":["../../../../src/_modules/rate-limit/_models/rate-limit-policy.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,KAAK,EAAE,MAAM,CAAC;IAEd,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;CAClB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=rate-limit-policy.interface.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit-policy.interface.js","sourceRoot":"","sources":["../../../../src/_modules/rate-limit/_models/rate-limit-policy.interface.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ export { DyNTS_RateLimit_Middleware } from './rate-limit.middleware';
2
+ export { DyNTS_RateLimit_Config } from './_models/rate-limit-config.interface';
3
+ export { DyNTS_RateLimit_Policy } from './_models/rate-limit-policy.interface';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/_modules/rate-limit/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AACrE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_RateLimit_Middleware = void 0;
4
+ var rate_limit_middleware_1 = require("./rate-limit.middleware");
5
+ Object.defineProperty(exports, "DyNTS_RateLimit_Middleware", { enumerable: true, get: function () { return rate_limit_middleware_1.DyNTS_RateLimit_Middleware; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/_modules/rate-limit/index.ts"],"names":[],"mappings":";;;AAAA,iEAAqE;AAA5D,mIAAA,0BAA0B,OAAA"}
@@ -0,0 +1,118 @@
1
+ import { Request, Response } from 'express';
2
+ import { DyNTS_SingletonServiceBase } from '../../_services/base/singleton.service-base';
3
+ import { DyNTS_RateLimit_Config } from './_models/rate-limit-config.interface';
4
+ import { DyNTS_RateLimit_Policy } from './_models/rate-limit-policy.interface';
5
+ /**
6
+ * Sliding-window HTTP rate-limit middleware — opt-in service-szel, a meglevo
7
+ * `DyNTS_Endpoint_Params.preProcesses` mechanizmus mellol mukodik.
8
+ *
9
+ * **Hasznalat (host app):**
10
+ * ```ts
11
+ * const rateLimit = DyNTS_RateLimit_Middleware.getInstance();
12
+ * rateLimit.configure({
13
+ * defaultLimit: 100, // 100 req/perc default
14
+ * defaultWindowMs: 60_000,
15
+ * keyExtractor: (req) => req.headers['x-api-key'] as string || req.ip,
16
+ * });
17
+ *
18
+ * new DyNTS_Endpoint_Params({
19
+ * ...,
20
+ * preProcesses: [rateLimit.check, ...other],
21
+ * });
22
+ *
23
+ * // subscription-tier-up: per-kulcs egyedi limit
24
+ * rateLimit.setPolicyForKey('subscriber-tier-key-123', {
25
+ * limit: 1000,
26
+ * windowMs: 60_000,
27
+ * });
28
+ * ```
29
+ *
30
+ * **Viselkedes:**
31
+ * - Sliding-window algoritmus: minden request egy timestamp; a window-on
32
+ * kivuli timestamp-ek nem szamolnak. Tobb pontos mint a fix-bucket
33
+ * (boundary-burst nincs).
34
+ * - In-memory storage — single-instance MVP-nek megfelelo. Multi-instance
35
+ * prod-hoz Redis-backed extension kell (lasd a kozelebb dokumentumaltot).
36
+ * - Limit lepes: 429 DyFM_Error + `X-RateLimit-*` + `Retry-After` header-ek.
37
+ *
38
+ * **Storage:** `Map<storageKey, timestamps[]>` ahol storageKey = `${subject}|${endpoint}`.
39
+ * Periodikus GC takaritja a inaktiv kulcsokat.
40
+ *
41
+ * **Singleton:** `getInstance()`-szel hivd. A `.check` mezo binding-elve van
42
+ * `this`-re, igy direkt atadhato `preProcesses`-be ujracsomagolas nelkul.
43
+ */
44
+ export declare class DyNTS_RateLimit_Middleware extends DyNTS_SingletonServiceBase {
45
+ static getInstance(): DyNTS_RateLimit_Middleware;
46
+ private defaultLimit;
47
+ private defaultWindowMs;
48
+ private responseHeaders;
49
+ private keyExtractor;
50
+ private endpointGrouper;
51
+ /** request-log: storageKey → timestamp-tomb (Date.now() ms). */
52
+ private requestLog;
53
+ /** Per-kulcs egyedi policy-k. */
54
+ private keyPolicies;
55
+ /** GC timer handle. */
56
+ private gcTimer;
57
+ /**
58
+ * Konfig override. Hianyzo mezok a default-okat orzik. Hivhato barmikor —
59
+ * a `check()` a friss config-ot olvassa.
60
+ */
61
+ configure(config: DyNTS_RateLimit_Config): void;
62
+ /**
63
+ * Aktualis konfig olvasasa (diagnosztika celokra).
64
+ */
65
+ getConfig(): {
66
+ defaultLimit: number;
67
+ defaultWindowMs: number;
68
+ responseHeaders: boolean;
69
+ activeKeyPolicies: number;
70
+ trackedStorageKeys: number;
71
+ };
72
+ /**
73
+ * Per-kulcs egyedi policy beallitas (pl. subscription-tier alapjan).
74
+ * A `key`-nek pontosan azzal a stringgel kell egyeznie, amit a `keyExtractor`
75
+ * visszaad.
76
+ */
77
+ setPolicyForKey(key: string, policy: DyNTS_RateLimit_Policy): void;
78
+ /**
79
+ * Per-kulcs policy torlese (visszaall a default-ra).
80
+ */
81
+ clearPolicyForKey(key: string): void;
82
+ /**
83
+ * Pre-process function — atadhato `DyNTS_Endpoint_Params.preProcesses`-be.
84
+ *
85
+ * Throws:
86
+ * - 429 ha az aktualis request meghaladna a limit-et a sliding window-on
87
+ *
88
+ * Side-effect: ha `responseHeaders === true`, beallitja az `X-RateLimit-Limit`,
89
+ * `X-RateLimit-Remaining`, `X-RateLimit-Reset` header-eket; 429 eseten
90
+ * a `Retry-After` header-t is.
91
+ */
92
+ readonly check: (req: Request, res: Response) => Promise<void>;
93
+ /**
94
+ * Default key-extractor: x-forwarded-for vagy req.ip vagy 'unknown'.
95
+ * Csak akkor hasznalt, ha a host nem allit be sajat extractort a configure-ben.
96
+ */
97
+ private defaultKeyExtractor;
98
+ /**
99
+ * GC timer inditasa (idempotent). Periodikusan eltavolitja az inaktiv
100
+ * storage-key-eket a request-log-bol — memory-leak prevention.
101
+ */
102
+ private startGcTimer;
103
+ /**
104
+ * GC sweep — minden storage-key-rol levagja a regi timestamp-eket, es
105
+ * eltavolitja az ureseket. Hivhato kulonosen test-bol.
106
+ */
107
+ runGc(): void;
108
+ /**
109
+ * GC timer leallitasa (graceful shutdown vagy test-cleanup).
110
+ */
111
+ stopGcTimer(): void;
112
+ /**
113
+ * Test-only: visszaallitja a default config-ot + uriti a state-et, hogy a
114
+ * specfajlok ne szivarogjak at egymas state-jet. Production code NE hivja.
115
+ */
116
+ _resetForTesting(): void;
117
+ }
118
+ //# sourceMappingURL=rate-limit.middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.middleware.d.ts","sourceRoot":"","sources":["../../../src/_modules/rate-limit/rate-limit.middleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI5C,OAAO,EAAE,0BAA0B,EAAE,MAAM,6CAA6C,CAAC;AAGzF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AA2B/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBAAa,0BAA2B,SAAQ,0BAA0B;IAExE,MAAM,CAAC,WAAW,IAAI,0BAA0B;IAIhD,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,eAAe,CAAqC;IAE5D,OAAO,CAAC,YAAY,CACsC;IAC1D,OAAO,CAAC,eAAe,CACc;IAErC,gEAAgE;IAChE,OAAO,CAAC,UAAU,CAAoC;IAEtD,iCAAiC;IACjC,OAAO,CAAC,WAAW,CAAkD;IAErE,uBAAuB;IACvB,OAAO,CAAC,OAAO,CAA+B;IAG9C;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAwB/C;;OAEG;IACH,SAAS,IAAI;QACX,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,eAAe,EAAE,OAAO,CAAC;QACzB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,kBAAkB,EAAE,MAAM,CAAC;KAC5B;IAUD;;;;OAIG;IACH,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,sBAAsB,GAAG,IAAI;IAIlE;;OAEG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAKpC;;;;;;;;;OASG;IACH,QAAQ,CAAC,KAAK,QAAe,OAAO,OAAO,QAAQ,KAAG,OAAO,CAAC,IAAI,CAAC,CAmDjE;IAGF;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;;OAGG;IACH,OAAO,CAAC,YAAY;IAapB;;;OAGG;IACH,KAAK,IAAI,IAAI;IAcb;;OAEG;IACH,WAAW,IAAI,IAAI;IAQnB;;;OAGG;IACH,gBAAgB,IAAI,IAAI;CAUzB"}
@@ -0,0 +1,262 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DyNTS_RateLimit_Middleware = void 0;
4
+ const fsm_dynamo_1 = require("@futdevpro/fsm-dynamo");
5
+ const singleton_service_base_1 = require("../../_services/base/singleton.service-base");
6
+ const global_settings_const_1 = require("../../_collections/global-settings.const");
7
+ /** Default request-limit per default-window. */
8
+ const DEFAULT_LIMIT = 100;
9
+ /** Default sliding-window hossza ms-ben (1 perc). */
10
+ const DEFAULT_WINDOW_MS = 60000;
11
+ /** Default response-header allitas. */
12
+ const DEFAULT_RESPONSE_HEADERS = true;
13
+ /** Periodikus garbage-collection intervallum ms-ben (5 perc).
14
+ * A request-log-bol takaritja a regen inaktiv kulcsokat (memory-leak prevention).
15
+ */
16
+ const GC_INTERVAL_MS = 5 * 60 * 1000;
17
+ /** Service-nev az error-okhoz. */
18
+ const SERVICE_NAME = 'DyNTS_RateLimit_Middleware';
19
+ /** ErrorCode-builder — system shortcode + sajat kod. */
20
+ const buildErrorCode = (subcode) => {
21
+ const sys = global_settings_const_1.DyNTS_global_settings.systemShortCodeName ?? 'DyNTS';
22
+ return `${sys}|DyNTS-RL-${subcode}`;
23
+ };
24
+ /**
25
+ * Sliding-window HTTP rate-limit middleware — opt-in service-szel, a meglevo
26
+ * `DyNTS_Endpoint_Params.preProcesses` mechanizmus mellol mukodik.
27
+ *
28
+ * **Hasznalat (host app):**
29
+ * ```ts
30
+ * const rateLimit = DyNTS_RateLimit_Middleware.getInstance();
31
+ * rateLimit.configure({
32
+ * defaultLimit: 100, // 100 req/perc default
33
+ * defaultWindowMs: 60_000,
34
+ * keyExtractor: (req) => req.headers['x-api-key'] as string || req.ip,
35
+ * });
36
+ *
37
+ * new DyNTS_Endpoint_Params({
38
+ * ...,
39
+ * preProcesses: [rateLimit.check, ...other],
40
+ * });
41
+ *
42
+ * // subscription-tier-up: per-kulcs egyedi limit
43
+ * rateLimit.setPolicyForKey('subscriber-tier-key-123', {
44
+ * limit: 1000,
45
+ * windowMs: 60_000,
46
+ * });
47
+ * ```
48
+ *
49
+ * **Viselkedes:**
50
+ * - Sliding-window algoritmus: minden request egy timestamp; a window-on
51
+ * kivuli timestamp-ek nem szamolnak. Tobb pontos mint a fix-bucket
52
+ * (boundary-burst nincs).
53
+ * - In-memory storage — single-instance MVP-nek megfelelo. Multi-instance
54
+ * prod-hoz Redis-backed extension kell (lasd a kozelebb dokumentumaltot).
55
+ * - Limit lepes: 429 DyFM_Error + `X-RateLimit-*` + `Retry-After` header-ek.
56
+ *
57
+ * **Storage:** `Map<storageKey, timestamps[]>` ahol storageKey = `${subject}|${endpoint}`.
58
+ * Periodikus GC takaritja a inaktiv kulcsokat.
59
+ *
60
+ * **Singleton:** `getInstance()`-szel hivd. A `.check` mezo binding-elve van
61
+ * `this`-re, igy direkt atadhato `preProcesses`-be ujracsomagolas nelkul.
62
+ */
63
+ class DyNTS_RateLimit_Middleware extends singleton_service_base_1.DyNTS_SingletonServiceBase {
64
+ static getInstance() {
65
+ return DyNTS_RateLimit_Middleware.getSingletonInstance();
66
+ }
67
+ defaultLimit = DEFAULT_LIMIT;
68
+ defaultWindowMs = DEFAULT_WINDOW_MS;
69
+ responseHeaders = DEFAULT_RESPONSE_HEADERS;
70
+ keyExtractor = (req) => this.defaultKeyExtractor(req);
71
+ endpointGrouper = (req) => req.path;
72
+ /** request-log: storageKey → timestamp-tomb (Date.now() ms). */
73
+ requestLog = new Map();
74
+ /** Per-kulcs egyedi policy-k. */
75
+ keyPolicies = new Map();
76
+ /** GC timer handle. */
77
+ gcTimer = null;
78
+ /**
79
+ * Konfig override. Hianyzo mezok a default-okat orzik. Hivhato barmikor —
80
+ * a `check()` a friss config-ot olvassa.
81
+ */
82
+ configure(config) {
83
+ if (config.defaultLimit !== undefined) {
84
+ this.defaultLimit = config.defaultLimit;
85
+ }
86
+ if (config.defaultWindowMs !== undefined) {
87
+ this.defaultWindowMs = config.defaultWindowMs;
88
+ }
89
+ if (config.keyExtractor !== undefined) {
90
+ this.keyExtractor = config.keyExtractor;
91
+ }
92
+ if (config.endpointGrouper !== undefined) {
93
+ this.endpointGrouper = config.endpointGrouper;
94
+ }
95
+ if (config.responseHeaders !== undefined) {
96
+ this.responseHeaders = config.responseHeaders;
97
+ }
98
+ if (config.initialKeyPolicies !== undefined) {
99
+ for (const [key, policy] of Object.entries(config.initialKeyPolicies)) {
100
+ this.keyPolicies.set(key, policy);
101
+ }
102
+ }
103
+ this.startGcTimer();
104
+ }
105
+ /**
106
+ * Aktualis konfig olvasasa (diagnosztika celokra).
107
+ */
108
+ getConfig() {
109
+ return {
110
+ defaultLimit: this.defaultLimit,
111
+ defaultWindowMs: this.defaultWindowMs,
112
+ responseHeaders: this.responseHeaders,
113
+ activeKeyPolicies: this.keyPolicies.size,
114
+ trackedStorageKeys: this.requestLog.size,
115
+ };
116
+ }
117
+ /**
118
+ * Per-kulcs egyedi policy beallitas (pl. subscription-tier alapjan).
119
+ * A `key`-nek pontosan azzal a stringgel kell egyeznie, amit a `keyExtractor`
120
+ * visszaad.
121
+ */
122
+ setPolicyForKey(key, policy) {
123
+ this.keyPolicies.set(key, policy);
124
+ }
125
+ /**
126
+ * Per-kulcs policy torlese (visszaall a default-ra).
127
+ */
128
+ clearPolicyForKey(key) {
129
+ this.keyPolicies.delete(key);
130
+ }
131
+ /**
132
+ * Pre-process function — atadhato `DyNTS_Endpoint_Params.preProcesses`-be.
133
+ *
134
+ * Throws:
135
+ * - 429 ha az aktualis request meghaladna a limit-et a sliding window-on
136
+ *
137
+ * Side-effect: ha `responseHeaders === true`, beallitja az `X-RateLimit-Limit`,
138
+ * `X-RateLimit-Remaining`, `X-RateLimit-Reset` header-eket; 429 eseten
139
+ * a `Retry-After` header-t is.
140
+ */
141
+ check = async (req, res) => {
142
+ const subject = this.keyExtractor(req);
143
+ const endpoint = this.endpointGrouper(req);
144
+ const storageKey = `${subject}|${endpoint}`;
145
+ const policy = this.keyPolicies.get(subject) ?? {
146
+ limit: this.defaultLimit,
147
+ windowMs: this.defaultWindowMs,
148
+ };
149
+ const now = Date.now();
150
+ const windowStart = now - policy.windowMs;
151
+ // sliding-window: tartomanyon kivuli timestamp-eket eldobjuk
152
+ const existing = this.requestLog.get(storageKey) ?? [];
153
+ const recent = existing.filter((t) => t > windowStart);
154
+ if (recent.length >= policy.limit) {
155
+ const oldest = recent[0];
156
+ const resetAt = oldest + policy.windowMs;
157
+ const retryAfterSec = Math.max(1, Math.ceil((resetAt - now) / 1000));
158
+ if (this.responseHeaders) {
159
+ res.setHeader('X-RateLimit-Limit', policy.limit.toString());
160
+ res.setHeader('X-RateLimit-Remaining', '0');
161
+ res.setHeader('X-RateLimit-Reset', Math.ceil(resetAt / 1000).toString());
162
+ res.setHeader('Retry-After', retryAfterSec.toString());
163
+ }
164
+ // Frissitjuk a log-ot a kiszurt verzioval (felesleges regi timestamp-eket eldobtuk)
165
+ this.requestLog.set(storageKey, recent);
166
+ throw new fsm_dynamo_1.DyFM_Error({
167
+ status: 429,
168
+ errorCode: buildErrorCode('LIMIT'),
169
+ addECToUserMsg: true,
170
+ message: `Rate limit exceeded: ${policy.limit} req per ${policy.windowMs}ms for ${storageKey}`,
171
+ userMessage: `Too many requests, retry after ${retryAfterSec}s`,
172
+ issuerService: SERVICE_NAME,
173
+ });
174
+ }
175
+ // alatta vagyunk a limit-nek: append the current request
176
+ recent.push(now);
177
+ this.requestLog.set(storageKey, recent);
178
+ if (this.responseHeaders) {
179
+ res.setHeader('X-RateLimit-Limit', policy.limit.toString());
180
+ res.setHeader('X-RateLimit-Remaining', Math.max(0, policy.limit - recent.length).toString());
181
+ res.setHeader('X-RateLimit-Reset', Math.ceil((now + policy.windowMs) / 1000).toString());
182
+ }
183
+ };
184
+ /**
185
+ * Default key-extractor: x-forwarded-for vagy req.ip vagy 'unknown'.
186
+ * Csak akkor hasznalt, ha a host nem allit be sajat extractort a configure-ben.
187
+ */
188
+ defaultKeyExtractor(req) {
189
+ const xff = req.headers['x-forwarded-for'];
190
+ if (typeof xff === 'string' && xff.length > 0) {
191
+ const first = xff.split(',')[0]?.trim() ?? '';
192
+ if (first.length > 0) {
193
+ return first;
194
+ }
195
+ }
196
+ if (Array.isArray(xff) && xff.length > 0) {
197
+ const first = xff[0]?.split(',')[0]?.trim() ?? '';
198
+ if (first.length > 0) {
199
+ return first;
200
+ }
201
+ }
202
+ return req.ip ?? 'unknown';
203
+ }
204
+ /**
205
+ * GC timer inditasa (idempotent). Periodikusan eltavolitja az inaktiv
206
+ * storage-key-eket a request-log-bol — memory-leak prevention.
207
+ */
208
+ startGcTimer() {
209
+ if (this.gcTimer !== null) {
210
+ return;
211
+ }
212
+ this.gcTimer = setInterval(() => {
213
+ this.runGc();
214
+ }, GC_INTERVAL_MS);
215
+ // unref hogy a process ne maradjon eletben a timer miatt
216
+ if (typeof this.gcTimer.unref === 'function') {
217
+ this.gcTimer.unref();
218
+ }
219
+ }
220
+ /**
221
+ * GC sweep — minden storage-key-rol levagja a regi timestamp-eket, es
222
+ * eltavolitja az ureseket. Hivhato kulonosen test-bol.
223
+ */
224
+ runGc() {
225
+ const now = Date.now();
226
+ const horizon = now - this.defaultWindowMs;
227
+ for (const [key, timestamps] of this.requestLog) {
228
+ const recent = timestamps.filter((t) => t > horizon);
229
+ if (recent.length === 0) {
230
+ this.requestLog.delete(key);
231
+ }
232
+ else {
233
+ this.requestLog.set(key, recent);
234
+ }
235
+ }
236
+ }
237
+ /**
238
+ * GC timer leallitasa (graceful shutdown vagy test-cleanup).
239
+ */
240
+ stopGcTimer() {
241
+ if (this.gcTimer !== null) {
242
+ clearInterval(this.gcTimer);
243
+ this.gcTimer = null;
244
+ }
245
+ }
246
+ /**
247
+ * Test-only: visszaallitja a default config-ot + uriti a state-et, hogy a
248
+ * specfajlok ne szivarogjak at egymas state-jet. Production code NE hivja.
249
+ */
250
+ _resetForTesting() {
251
+ this.defaultLimit = DEFAULT_LIMIT;
252
+ this.defaultWindowMs = DEFAULT_WINDOW_MS;
253
+ this.responseHeaders = DEFAULT_RESPONSE_HEADERS;
254
+ this.keyExtractor = (req) => this.defaultKeyExtractor(req);
255
+ this.endpointGrouper = (req) => req.path;
256
+ this.requestLog.clear();
257
+ this.keyPolicies.clear();
258
+ this.stopGcTimer();
259
+ }
260
+ }
261
+ exports.DyNTS_RateLimit_Middleware = DyNTS_RateLimit_Middleware;
262
+ //# sourceMappingURL=rate-limit.middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.middleware.js","sourceRoot":"","sources":["../../../src/_modules/rate-limit/rate-limit.middleware.ts"],"names":[],"mappings":";;;AAEA,sDAAmD;AAEnD,wFAAyF;AACzF,oFAAiF;AAMjF,gDAAgD;AAChD,MAAM,aAAa,GAAW,GAAG,CAAC;AAElC,qDAAqD;AACrD,MAAM,iBAAiB,GAAW,KAAK,CAAC;AAExC,uCAAuC;AACvC,MAAM,wBAAwB,GAAY,IAAI,CAAC;AAE/C;;GAEG;AACH,MAAM,cAAc,GAAW,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7C,kCAAkC;AAClC,MAAM,YAAY,GAAW,4BAA4B,CAAC;AAE1D,wDAAwD;AACxD,MAAM,cAAc,GAAG,CAAC,OAAe,EAAU,EAAE;IACjD,MAAM,GAAG,GAAW,6CAAqB,CAAC,mBAAmB,IAAI,OAAO,CAAC;IACzE,OAAO,GAAG,GAAG,aAAa,OAAO,EAAE,CAAC;AACtC,CAAC,CAAC;AAGF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAa,0BAA2B,SAAQ,mDAA0B;IAExE,MAAM,CAAC,WAAW;QAChB,OAAO,0BAA0B,CAAC,oBAAoB,EAAgC,CAAC;IACzF,CAAC;IAEO,YAAY,GAAW,aAAa,CAAC;IACrC,eAAe,GAAW,iBAAiB,CAAC;IAC5C,eAAe,GAAY,wBAAwB,CAAC;IAEpD,YAAY,GAClB,CAAC,GAAY,EAAU,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;IAClD,eAAe,GACrB,CAAC,GAAY,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;IAErC,gEAAgE;IACxD,UAAU,GAA0B,IAAI,GAAG,EAAE,CAAC;IAEtD,iCAAiC;IACzB,WAAW,GAAwC,IAAI,GAAG,EAAE,CAAC;IAErE,uBAAuB;IACf,OAAO,GAA0B,IAAI,CAAC;IAG9C;;;OAGG;IACH,SAAS,CAAC,MAA8B;QACtC,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAChD,CAAC;QACD,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACtC,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;QAC1C,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAChD,CAAC;QACD,IAAI,MAAM,CAAC,eAAe,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,eAAe,CAAC;QAChD,CAAC;QACD,IAAI,MAAM,CAAC,kBAAkB,KAAK,SAAS,EAAE,CAAC;YAC5C,KAAK,MAAM,CAAE,GAAG,EAAE,MAAM,CAAE,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAAC,EAAE,CAAC;gBACxE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QACD,IAAI,CAAC,YAAY,EAAE,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,SAAS;QAOP,OAAO;YACL,YAAY,EAAS,IAAI,CAAC,YAAY;YACtC,eAAe,EAAM,IAAI,CAAC,eAAe;YACzC,eAAe,EAAM,IAAI,CAAC,eAAe;YACzC,iBAAiB,EAAI,IAAI,CAAC,WAAW,CAAC,IAAI;YAC1C,kBAAkB,EAAG,IAAI,CAAC,UAAU,CAAC,IAAI;SAC1C,CAAC;IACJ,CAAC;IAED;;;;OAIG;IACH,eAAe,CAAC,GAAW,EAAE,MAA8B;QACzD,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,iBAAiB,CAAC,GAAW;QAC3B,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAGD;;;;;;;;;OASG;IACM,KAAK,GAAG,KAAK,EAAE,GAAY,EAAE,GAAa,EAAiB,EAAE;QACpE,MAAM,OAAO,GAAW,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAW,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;QACnD,MAAM,UAAU,GAAW,GAAG,OAAO,IAAI,QAAQ,EAAE,CAAC;QAEpD,MAAM,MAAM,GAA2B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI;YACtE,KAAK,EAAK,IAAI,CAAC,YAAY;YAC3B,QAAQ,EAAE,IAAI,CAAC,eAAe;SAC/B,CAAC;QAEF,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,WAAW,GAAW,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC;QAElD,6DAA6D;QAC7D,MAAM,QAAQ,GAAa,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;QACjE,MAAM,MAAM,GAAa,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAS,EAAW,EAAE,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC;QAElF,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAClC,MAAM,MAAM,GAAW,MAAM,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,OAAO,GAAW,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC;YACjD,MAAM,aAAa,GAAW,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,OAAO,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;YAE7E,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;gBACzB,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5D,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;gBAC5C,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACzE,GAAG,CAAC,SAAS,CAAC,aAAa,EAAE,aAAa,CAAC,QAAQ,EAAE,CAAC,CAAC;YACzD,CAAC;YAED,oFAAoF;YACpF,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;YAExC,MAAM,IAAI,uBAAU,CAAC;gBACnB,MAAM,EAAK,GAAG;gBACd,SAAS,EAAE,cAAc,CAAC,OAAO,CAAC;gBAClC,cAAc,EAAE,IAAI;gBACpB,OAAO,EAAI,wBAAwB,MAAM,CAAC,KAAK,YAAY,MAAM,CAAC,QAAQ,UAAU,UAAU,EAAE;gBAChG,WAAW,EAAE,kCAAkC,aAAa,GAAG;gBAC/D,aAAa,EAAE,YAAY;aAC5B,CAAC,CAAC;QACL,CAAC;QAED,yDAAyD;QACzD,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAExC,IAAI,IAAI,CAAC,eAAe,EAAE,CAAC;YACzB,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC5D,GAAG,CAAC,SAAS,CAAC,uBAAuB,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC7F,GAAG,CAAC,SAAS,CAAC,mBAAmB,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3F,CAAC;IACH,CAAC,CAAC;IAGF;;;OAGG;IACK,mBAAmB,CAAC,GAAY;QACtC,MAAM,GAAG,GAAY,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QACpD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,KAAK,GAAW,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YACtD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzC,MAAM,KAAK,GAAW,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;YAC1D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,OAAO,KAAK,CAAC;YACf,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAC,EAAE,IAAI,SAAS,CAAC;IAC7B,CAAC;IAGD;;;OAGG;IACK,YAAY;QAClB,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,GAAS,EAAE;YACpC,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC,EAAE,cAAc,CAAC,CAAC;QACnB,yDAAyD;QACzD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACvB,CAAC;IACH,CAAC;IAED;;;OAGG;IACH,KAAK;QACH,MAAM,GAAG,GAAW,IAAI,CAAC,GAAG,EAAE,CAAC;QAC/B,MAAM,OAAO,GAAW,GAAG,GAAG,IAAI,CAAC,eAAe,CAAC;QAEnD,KAAK,MAAM,CAAE,GAAG,EAAE,UAAU,CAAE,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClD,MAAM,MAAM,GAAa,UAAU,CAAC,MAAM,CAAC,CAAC,CAAS,EAAW,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC;YAChF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,IAAI,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YAC1B,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC5B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAGD;;;OAGG;IACH,gBAAgB;QACd,IAAI,CAAC,YAAY,GAAO,aAAa,CAAC;QACtC,IAAI,CAAC,eAAe,GAAI,iBAAiB,CAAC;QAC1C,IAAI,CAAC,eAAe,GAAI,wBAAwB,CAAC;QACjD,IAAI,CAAC,YAAY,GAAO,CAAC,GAAY,EAAU,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAChF,IAAI,CAAC,eAAe,GAAI,CAAC,GAAY,EAAU,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACxB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,WAAW,EAAE,CAAC;IACrB,CAAC;CACF;AA3OD,gEA2OC"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.data-service.d.ts","sourceRoot":"","sources":["../../../../src/_modules/server/errors/errors.data-service.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EAEU,UAAU,EAAE,eAAe,EACX,WAAW,EAClD,iBAAiB,EAEjB,UAAU,EAEV,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,qBAAa,wBAAwB,CACnC,OAAO,SAAS,UAAU,EAC1B,cAAc,SAAS,WAAW,CAAC,OAAO,CAAC,CAC3C,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,2BAA2B,CAAC,OAAO,EAAE,cAAc,CAAC;IAEzG,QAAQ,EAAE,OAAO,CAAS;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAuC;IAC/D,kBAAkB,EAAE,MAAM,CAAC;IAgBrB,WAAW,CACf,YAAY,EAAE,cAAc,EAC5B,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;cAiKA,iBAAiB,CAC/B,KAAK,EAAE,aAAa,GAAG,GAAG,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC;IA2CpB,mBAAmB,CACvB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;IAoBV,mBAAmB,CACvB,KAAK,EAAE,aAAa,GAAG,GAAG,EAC1B,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;IAwChB,qCAAqC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc;IA0C/F,4BAA4B,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM;IAwBtD,iBAAiB,CACrB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAqBhC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtE,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAuB/F,cAAc,CAClB,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAuBhC,aAAa,CACjB,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAyBhC,YAAY,CAChB,WAAW,EAAE,gBAAgB,CAAC,cAAc,CAAC,EAC7C,MAAM,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAehD"}
1
+ {"version":3,"file":"errors.data-service.d.ts","sourceRoot":"","sources":["../../../../src/_modules/server/errors/errors.data-service.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,aAAa,EAEU,UAAU,EAAE,eAAe,EACX,WAAW,EAClD,iBAAiB,EAEjB,UAAU,EAEV,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAGvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AAEzE,qBAAa,wBAAwB,CACnC,OAAO,SAAS,UAAU,EAC1B,cAAc,SAAS,WAAW,CAAC,OAAO,CAAC,CAC3C,SAAQ,iBAAiB,CAAC,cAAc,CAAE,YAAW,2BAA2B,CAAC,OAAO,EAAE,cAAc,CAAC;IAEzG,QAAQ,EAAE,OAAO,CAAS;IAC1B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAuC;IAC/D,kBAAkB,EAAE,MAAM,CAAC;IAgBrB,WAAW,CACf,YAAY,EAAE,cAAc,EAC5B,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;cAyKA,iBAAiB,CAC/B,KAAK,EAAE,aAAa,GAAG,GAAG,EAC1B,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,cAAc,CAAC;IA2CpB,mBAAmB,CACvB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;IAoBV,mBAAmB,CACvB,KAAK,EAAE,aAAa,GAAG,GAAG,EAC1B,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,GACrB,OAAO,CAAC,IAAI,CAAC;IAwChB,qCAAqC,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,GAAG,cAAc;IA0C/F,4BAA4B,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM;IAwBtD,iBAAiB,CACrB,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAqBhC,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBnF,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBtE,gBAAgB,CAAC,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAuB/F,cAAc,CAClB,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAuBhC,aAAa,CACjB,KAAK,EAAE,iBAAiB,EACxB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;IAyBhC,YAAY,CAChB,WAAW,EAAE,gBAAgB,CAAC,cAAc,CAAC,EAC7C,MAAM,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;CAehD"}
@@ -124,7 +124,15 @@ class DyNTS_Errors_DataService extends data_service_1.DyNTS_DataService {
124
124
  errorsRecord.versions ??= [];
125
125
  errorsRecord.versions.push(errorVersion);
126
126
  this.duplicationCounter = 1;
127
- await this.saveData();
127
+ // FR-027 (2026-05-24) — Pass `errorsRecord` explicitly. Korabban
128
+ // `saveData()` no-arg fallback `ensureData()`-on keresztul `this.data`-t
129
+ // hasznalt, ami a controller-szinten csak a `{issuer}` constructor
130
+ // wrapper, NEM az actual req.body adat. Eredmenykent minden client-
131
+ // forwarded error EMPTY rekordkent landolt: csak `issuer` mezo,
132
+ // semmilyen message/source/stackTrace/error/level/additionalContent
133
+ // mezo NEM kerult MongoDB-be. (Overseer-en 14454 ilyen empty record
134
+ // halmozodott fel — debug-level details elveszve.)
135
+ await this.saveData(errorsRecord);
128
136
  fsm_dynamo_1.DyFM_Log.warn('error saved');
129
137
  }
130
138
  }
@@ -1 +1 @@
1
- {"version":3,"file":"errors.data-service.js","sourceRoot":"","sources":["../../../../src/_modules/server/errors/errors.data-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.data-service.js","sourceRoot":"","sources":["../../../../src/_modules/server/errors/errors.data-service.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@futdevpro/nts-dynamo",
3
- "version": "01.15.31",
3
+ "version": "01.15.34",
4
4
  "description": "Dynamic NodeTS (NodeJS-Typescript), MongoDB Backend System Framework by Future Development Program Ltd.",
5
5
  "DyBu_settings": {
6
6
  "packageType": "server-package",
@@ -184,12 +184,24 @@
184
184
  "types": "./build/_mock/index.d.ts",
185
185
  "typings": "./build/_mock/index.d.ts"
186
186
  },
187
+ "./admin-auth": {
188
+ "default": "./build/_modules/admin-auth/index.js",
189
+ "module": "./build/_modules/admin-auth/index.js",
190
+ "types": "./build/_modules/admin-auth/index.d.ts",
191
+ "typings": "./build/_modules/admin-auth/index.d.ts"
192
+ },
187
193
  "./oauth2": {
188
194
  "default": "./build/_modules/oauth2/index.js",
189
195
  "module": "./build/_modules/oauth2/index.js",
190
196
  "types": "./build/_modules/oauth2/index.d.ts",
191
197
  "typings": "./build/_modules/oauth2/index.d.ts"
192
198
  },
199
+ "./rate-limit": {
200
+ "default": "./build/_modules/rate-limit/index.js",
201
+ "module": "./build/_modules/rate-limit/index.js",
202
+ "types": "./build/_modules/rate-limit/index.d.ts",
203
+ "typings": "./build/_modules/rate-limit/index.d.ts"
204
+ },
193
205
  "./server": {
194
206
  "default": "./build/_modules/server/index.js",
195
207
  "module": "./build/_modules/server/index.js",
@@ -274,9 +286,15 @@
274
286
  "mock": [
275
287
  "build/_modules/mock/index.d.ts"
276
288
  ],
289
+ "admin-auth": [
290
+ "build/_modules/admin-auth/index.d.ts"
291
+ ],
277
292
  "oauth2": [
278
293
  "build/_modules/oauth2/index.d.ts"
279
294
  ],
295
+ "rate-limit": [
296
+ "build/_modules/rate-limit/index.d.ts"
297
+ ],
280
298
  "server": [
281
299
  "build/_modules/server/index.d.ts"
282
300
  ],
@@ -299,7 +317,7 @@
299
317
  "empty": ""
300
318
  },
301
319
  "peerDependencies": {
302
- "@futdevpro/fsm-dynamo": "1.15.11",
320
+ "@futdevpro/fsm-dynamo": "1.15.13",
303
321
  "@types/express": "4.17.21",
304
322
  "@types/geoip-lite": "~1.4.1",
305
323
  "@types/node": "~24.1.0",
@@ -314,7 +332,7 @@
314
332
  "ts-node": "~10.9.2"
315
333
  },
316
334
  "devDependencies": {
317
- "@futdevpro/dynamo-eslint": "1.15.9",
335
+ "@futdevpro/dynamo-eslint": "1.15.10",
318
336
  "@discordjs/opus": "^0.10.0",
319
337
  "@discordjs/voice": "^0.18.0",
320
338
  "@types/jasmine": "~4.3.5",
@@ -0,0 +1,60 @@
1
+ import { Request } from 'express';
2
+
3
+ import { DyNTS_RateLimit_Policy } from './rate-limit-policy.interface';
4
+
5
+ /**
6
+ * Config a `DyNTS_RateLimit_Middleware.configure(...)`-hoz.
7
+ *
8
+ * Minden mezo opcionalis — a default-ok megfelelnek a tipikus API
9
+ * rate-limit-elvarasoknak (100 req/min, sliding window, IP-alapu kulcs,
10
+ * path-alapu endpoint-csoportositas, X-RateLimit-* response header-ek).
11
+ */
12
+ export interface DyNTS_RateLimit_Config {
13
+ /**
14
+ * Default request-limit `windowMs` alatt, ha az adott kulcsra nincs
15
+ * `setPolicyForKey()`-szel beallitott egyedi policy. Default: `100`.
16
+ */
17
+ defaultLimit?: number;
18
+
19
+ /**
20
+ * Default sliding-window hossza milliszekundumban. Default: `60000` (1 perc).
21
+ */
22
+ defaultWindowMs?: number;
23
+
24
+ /**
25
+ * Rate-limit subject-extractor. Visszater a karakterlanccal, ami azonositja
26
+ * a rate-limit alanyat (pl. IP-cim, API-kulcs ID, account ID).
27
+ *
28
+ * Default: a `req.headers['x-forwarded-for']` (csak az elso IP, ha lista)
29
+ * vagy ha hianyzik akkor `req.ip` vagy `'unknown'`. Ez webszerver elotti
30
+ * proxy/CDN-mentes setup-ra megfelelo; ha az nd-space mar identifikalja az
31
+ * API-kulcsot a `req`-ben, a host adhat sajat extractort ami a key-ID-t
32
+ * adja vissza.
33
+ */
34
+ keyExtractor?: (req: Request) => string;
35
+
36
+ /**
37
+ * Endpoint-csoportosito. Visszater a karakterlanccal, ami azonositja az
38
+ * adott endpoint-csoportot. A storage-key `${subject}|${endpoint}` lesz.
39
+ *
40
+ * Default: `req.path` — minden uri-path kulon vodorbe kerul. Csoportositas
41
+ * mas szempontok szerint (pl. "datasets" csoport = `/api/datasets/*`)
42
+ * a hostnal felulirhato.
43
+ */
44
+ endpointGrouper?: (req: Request) => string;
45
+
46
+ /**
47
+ * Beallitja-e a `X-RateLimit-Limit`, `X-RateLimit-Remaining`,
48
+ * `X-RateLimit-Reset` (es a 429-re `Retry-After`) response header-eket.
49
+ * Default: `true`.
50
+ *
51
+ * Test/dev kornyezetben opcionalisan kikapcsolhato.
52
+ */
53
+ responseHeaders?: boolean;
54
+
55
+ /**
56
+ * Per-policy override-ok az induloskor. A `setPolicyForKey()` runtime-ban is
57
+ * felulhatja ezeket.
58
+ */
59
+ initialKeyPolicies?: Record<string, DyNTS_RateLimit_Policy>;
60
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Per-kulcs rate-limit policy.
3
+ *
4
+ * A `DyNTS_RateLimit_Middleware.setPolicyForKey(key, policy)` allitja be,
5
+ * vagy a `DyNTS_RateLimit_Config.initialKeyPolicies` map-en at.
6
+ *
7
+ * Tipikus use-case: subscription-tier-up — egy belepett user API-kulcsa
8
+ * magasabb `limit`-et kap, mint a default (anonim/IP-alapu) limit.
9
+ */
10
+ export interface DyNTS_RateLimit_Policy {
11
+ /** Hany request engedelyezett a `windowMs` alatt. */
12
+ limit: number;
13
+
14
+ /** A sliding-window hossza milliszekundumban. */
15
+ windowMs: number;
16
+ }
@@ -0,0 +1,3 @@
1
+ export { DyNTS_RateLimit_Middleware } from './rate-limit.middleware';
2
+ export { DyNTS_RateLimit_Config } from './_models/rate-limit-config.interface';
3
+ export { DyNTS_RateLimit_Policy } from './_models/rate-limit-policy.interface';
@@ -0,0 +1,211 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ import { DyFM_Error } from '@futdevpro/fsm-dynamo';
4
+
5
+ import { DyNTS_RateLimit_Middleware } from './rate-limit.middleware';
6
+
7
+
8
+ /** Test-only — minimal Request mock-ot ad vissza. */
9
+ const mockReq = (overrides: Partial<{ ip: string; path: string; headers: Record<string, string> }> = {}): Request => {
10
+ return {
11
+ ip: overrides.ip ?? '127.0.0.1',
12
+ path: overrides.path ?? '/api/test',
13
+ headers: overrides.headers ?? {},
14
+ } as unknown as Request;
15
+ };
16
+
17
+ /** Test-only — Response stub a setHeader-rel. */
18
+ const mockRes = (): Response & { _headers: Record<string, string> } => {
19
+ const headers: Record<string, string> = {};
20
+ return {
21
+ _headers: headers,
22
+ setHeader: function(name: string, value: string): void {
23
+ headers[name] = value;
24
+ },
25
+ } as unknown as Response & { _headers: Record<string, string> };
26
+ };
27
+
28
+
29
+ describe('| DyNTS_RateLimit_Middleware', (): void => {
30
+ let svc: DyNTS_RateLimit_Middleware;
31
+
32
+ beforeEach((): void => {
33
+ svc = DyNTS_RateLimit_Middleware.getInstance();
34
+ svc._resetForTesting();
35
+ });
36
+
37
+ afterEach((): void => {
38
+ svc._resetForTesting();
39
+ });
40
+
41
+
42
+ describe('| singleton', (): void => {
43
+ it('| ugyanazt az instance-t adja vissza', (): void => {
44
+ const a: DyNTS_RateLimit_Middleware = DyNTS_RateLimit_Middleware.getInstance();
45
+ const b: DyNTS_RateLimit_Middleware = DyNTS_RateLimit_Middleware.getInstance();
46
+ expect(a).toBe(b);
47
+ });
48
+ });
49
+
50
+
51
+ describe('| check() — default limit', (): void => {
52
+ it('| atengedi az elso request-et', async (): Promise<void> => {
53
+ let thrown: any = null;
54
+ try { await svc.check(mockReq(), mockRes()); } catch (e) { thrown = e; }
55
+ expect(thrown).toBeNull();
56
+ });
57
+
58
+ it('| 429 amikor a limit-et eleri', async (): Promise<void> => {
59
+ svc.configure({ defaultLimit: 3, defaultWindowMs: 10000 });
60
+
61
+ // 3 sikeres request a limit-en belul
62
+ await svc.check(mockReq(), mockRes());
63
+ await svc.check(mockReq(), mockRes());
64
+ await svc.check(mockReq(), mockRes());
65
+
66
+ // 4. request: 429
67
+ let thrown: any = null;
68
+ try { await svc.check(mockReq(), mockRes()); } catch (e) { thrown = e; }
69
+ expect(thrown).not.toBeNull();
70
+ expect(DyFM_Error.getErrorStatus(thrown)).toBe(429);
71
+ expect(DyFM_Error.getErrorCode(thrown)).toContain('DyNTS-RL-LIMIT');
72
+ });
73
+
74
+ it('| kulonbozo IP-k kulon vodorbe kerulnek', async (): Promise<void> => {
75
+ svc.configure({ defaultLimit: 2, defaultWindowMs: 10000 });
76
+
77
+ await svc.check(mockReq({ ip: '1.1.1.1' }), mockRes());
78
+ await svc.check(mockReq({ ip: '1.1.1.1' }), mockRes());
79
+ // 1.1.1.1 most a limit-en van; 2.2.2.2 meg friss
80
+ let thrown: any = null;
81
+ try { await svc.check(mockReq({ ip: '2.2.2.2' }), mockRes()); } catch (e) { thrown = e; }
82
+ expect(thrown).toBeNull();
83
+ });
84
+
85
+ it('| kulonbozo endpoint-ok kulon vodorbe kerulnek', async (): Promise<void> => {
86
+ svc.configure({ defaultLimit: 2, defaultWindowMs: 10000 });
87
+
88
+ await svc.check(mockReq({ path: '/api/a' }), mockRes());
89
+ await svc.check(mockReq({ path: '/api/a' }), mockRes());
90
+ // /api/a most a limit-en van; /api/b meg friss
91
+ let thrown: any = null;
92
+ try { await svc.check(mockReq({ path: '/api/b' }), mockRes()); } catch (e) { thrown = e; }
93
+ expect(thrown).toBeNull();
94
+ });
95
+ });
96
+
97
+
98
+ describe('| response headers', (): void => {
99
+ it('| beallitja az X-RateLimit-* header-eket sikeres request-nel', async (): Promise<void> => {
100
+ svc.configure({ defaultLimit: 10, defaultWindowMs: 60000 });
101
+ const res = mockRes();
102
+ await svc.check(mockReq(), res);
103
+ expect(res._headers['X-RateLimit-Limit']).toBe('10');
104
+ expect(res._headers['X-RateLimit-Remaining']).toBe('9');
105
+ expect(res._headers['X-RateLimit-Reset']).toBeDefined();
106
+ });
107
+
108
+ it('| beallitja a Retry-After header-t 429-nel', async (): Promise<void> => {
109
+ svc.configure({ defaultLimit: 1, defaultWindowMs: 10000 });
110
+ await svc.check(mockReq(), mockRes());
111
+
112
+ const res = mockRes();
113
+ let thrown: any = null;
114
+ try { await svc.check(mockReq(), res); } catch (e) { thrown = e; }
115
+ expect(thrown).not.toBeNull();
116
+ expect(res._headers['Retry-After']).toBeDefined();
117
+ expect(res._headers['X-RateLimit-Remaining']).toBe('0');
118
+ });
119
+
120
+ it('| nem allit be header-t ha responseHeaders=false', async (): Promise<void> => {
121
+ svc.configure({ defaultLimit: 10, defaultWindowMs: 60000, responseHeaders: false });
122
+ const res = mockRes();
123
+ await svc.check(mockReq(), res);
124
+ expect(res._headers['X-RateLimit-Limit']).toBeUndefined();
125
+ });
126
+ });
127
+
128
+
129
+ describe('| setPolicyForKey() — subscription-tier-up', (): void => {
130
+ it('| egyedi limit a kulcsra felulhatja a default-ot', async (): Promise<void> => {
131
+ svc.configure({
132
+ defaultLimit: 2,
133
+ defaultWindowMs: 10000,
134
+ keyExtractor: (req: Request): string => (req.headers['x-api-key'] as string) ?? req.ip ?? 'anon',
135
+ });
136
+ svc.setPolicyForKey('premium-key', { limit: 10, windowMs: 10000 });
137
+
138
+ // premium-key 10-et kap
139
+ for (let i: number = 0; i < 10; i++) {
140
+ await svc.check(mockReq({ headers: { 'x-api-key': 'premium-key' } }), mockRes());
141
+ }
142
+ let thrown: any = null;
143
+ try { await svc.check(mockReq({ headers: { 'x-api-key': 'premium-key' } }), mockRes()); } catch (e) { thrown = e; }
144
+ expect(thrown).not.toBeNull();
145
+ expect(DyFM_Error.getErrorStatus(thrown)).toBe(429);
146
+ });
147
+
148
+ it('| clearPolicyForKey visszaallit a default-ra', async (): Promise<void> => {
149
+ svc.configure({
150
+ defaultLimit: 1,
151
+ defaultWindowMs: 10000,
152
+ keyExtractor: (req: Request): string => (req.headers['x-api-key'] as string) ?? 'anon',
153
+ });
154
+ svc.setPolicyForKey('k1', { limit: 5, windowMs: 10000 });
155
+ svc.clearPolicyForKey('k1');
156
+
157
+ // most a default 1-es limit ervenyes
158
+ await svc.check(mockReq({ headers: { 'x-api-key': 'k1' } }), mockRes());
159
+ let thrown: any = null;
160
+ try { await svc.check(mockReq({ headers: { 'x-api-key': 'k1' } }), mockRes()); } catch (e) { thrown = e; }
161
+ expect(thrown).not.toBeNull();
162
+ });
163
+ });
164
+
165
+
166
+ describe('| keyExtractor override', (): void => {
167
+ it('| custom keyExtractor felulhatja a default IP-alapu-t', async (): Promise<void> => {
168
+ svc.configure({
169
+ defaultLimit: 1,
170
+ defaultWindowMs: 10000,
171
+ keyExtractor: (req: Request): string => (req.headers['x-api-key'] as string) ?? 'anon',
172
+ });
173
+ // ugyanaz a IP, kulonbozo api-key — kulon limit
174
+ await svc.check(mockReq({ ip: '1.1.1.1', headers: { 'x-api-key': 'k1' } }), mockRes());
175
+ await svc.check(mockReq({ ip: '1.1.1.1', headers: { 'x-api-key': 'k2' } }), mockRes());
176
+ // k1 most a limit-en, k2 meg friss; ujabb k1 → 429
177
+ let thrown: any = null;
178
+ try { await svc.check(mockReq({ ip: '1.1.1.1', headers: { 'x-api-key': 'k1' } }), mockRes()); } catch (e) { thrown = e; }
179
+ expect(thrown).not.toBeNull();
180
+ });
181
+ });
182
+
183
+
184
+ describe('| GC', (): void => {
185
+ it('| runGc eltavolitja az ures kulcsokat', async (): Promise<void> => {
186
+ svc.configure({ defaultLimit: 10, defaultWindowMs: 10 }); // 10ms-os window
187
+ await svc.check(mockReq(), mockRes());
188
+ expect(svc.getConfig().trackedStorageKeys).toBe(1);
189
+
190
+ // varjunk meg amig a window lejar
191
+ await new Promise<void>((resolve: () => void): void => { setTimeout(resolve, 50); });
192
+
193
+ svc.runGc();
194
+ expect(svc.getConfig().trackedStorageKeys).toBe(0);
195
+ });
196
+ });
197
+
198
+
199
+ describe('| getConfig() diagnosztika', (): void => {
200
+ it('| visszaadja az aktualis allapotot', (): void => {
201
+ svc.configure({ defaultLimit: 50, defaultWindowMs: 30000 });
202
+ svc.setPolicyForKey('a', { limit: 100, windowMs: 60000 });
203
+ svc.setPolicyForKey('b', { limit: 200, windowMs: 60000 });
204
+
205
+ const cfg = svc.getConfig();
206
+ expect(cfg.defaultLimit).toBe(50);
207
+ expect(cfg.defaultWindowMs).toBe(30000);
208
+ expect(cfg.activeKeyPolicies).toBe(2);
209
+ });
210
+ });
211
+ });
@@ -0,0 +1,310 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ import { DyFM_Error } from '@futdevpro/fsm-dynamo';
4
+
5
+ import { DyNTS_SingletonServiceBase } from '../../_services/base/singleton.service-base';
6
+ import { DyNTS_global_settings } from '../../_collections/global-settings.const';
7
+
8
+ import { DyNTS_RateLimit_Config } from './_models/rate-limit-config.interface';
9
+ import { DyNTS_RateLimit_Policy } from './_models/rate-limit-policy.interface';
10
+
11
+
12
+ /** Default request-limit per default-window. */
13
+ const DEFAULT_LIMIT: number = 100;
14
+
15
+ /** Default sliding-window hossza ms-ben (1 perc). */
16
+ const DEFAULT_WINDOW_MS: number = 60000;
17
+
18
+ /** Default response-header allitas. */
19
+ const DEFAULT_RESPONSE_HEADERS: boolean = true;
20
+
21
+ /** Periodikus garbage-collection intervallum ms-ben (5 perc).
22
+ * A request-log-bol takaritja a regen inaktiv kulcsokat (memory-leak prevention).
23
+ */
24
+ const GC_INTERVAL_MS: number = 5 * 60 * 1000;
25
+
26
+ /** Service-nev az error-okhoz. */
27
+ const SERVICE_NAME: string = 'DyNTS_RateLimit_Middleware';
28
+
29
+ /** ErrorCode-builder — system shortcode + sajat kod. */
30
+ const buildErrorCode = (subcode: string): string => {
31
+ const sys: string = DyNTS_global_settings.systemShortCodeName ?? 'DyNTS';
32
+ return `${sys}|DyNTS-RL-${subcode}`;
33
+ };
34
+
35
+
36
+ /**
37
+ * Sliding-window HTTP rate-limit middleware — opt-in service-szel, a meglevo
38
+ * `DyNTS_Endpoint_Params.preProcesses` mechanizmus mellol mukodik.
39
+ *
40
+ * **Hasznalat (host app):**
41
+ * ```ts
42
+ * const rateLimit = DyNTS_RateLimit_Middleware.getInstance();
43
+ * rateLimit.configure({
44
+ * defaultLimit: 100, // 100 req/perc default
45
+ * defaultWindowMs: 60_000,
46
+ * keyExtractor: (req) => req.headers['x-api-key'] as string || req.ip,
47
+ * });
48
+ *
49
+ * new DyNTS_Endpoint_Params({
50
+ * ...,
51
+ * preProcesses: [rateLimit.check, ...other],
52
+ * });
53
+ *
54
+ * // subscription-tier-up: per-kulcs egyedi limit
55
+ * rateLimit.setPolicyForKey('subscriber-tier-key-123', {
56
+ * limit: 1000,
57
+ * windowMs: 60_000,
58
+ * });
59
+ * ```
60
+ *
61
+ * **Viselkedes:**
62
+ * - Sliding-window algoritmus: minden request egy timestamp; a window-on
63
+ * kivuli timestamp-ek nem szamolnak. Tobb pontos mint a fix-bucket
64
+ * (boundary-burst nincs).
65
+ * - In-memory storage — single-instance MVP-nek megfelelo. Multi-instance
66
+ * prod-hoz Redis-backed extension kell (lasd a kozelebb dokumentumaltot).
67
+ * - Limit lepes: 429 DyFM_Error + `X-RateLimit-*` + `Retry-After` header-ek.
68
+ *
69
+ * **Storage:** `Map<storageKey, timestamps[]>` ahol storageKey = `${subject}|${endpoint}`.
70
+ * Periodikus GC takaritja a inaktiv kulcsokat.
71
+ *
72
+ * **Singleton:** `getInstance()`-szel hivd. A `.check` mezo binding-elve van
73
+ * `this`-re, igy direkt atadhato `preProcesses`-be ujracsomagolas nelkul.
74
+ */
75
+ export class DyNTS_RateLimit_Middleware extends DyNTS_SingletonServiceBase {
76
+
77
+ static getInstance(): DyNTS_RateLimit_Middleware {
78
+ return DyNTS_RateLimit_Middleware.getSingletonInstance() as DyNTS_RateLimit_Middleware;
79
+ }
80
+
81
+ private defaultLimit: number = DEFAULT_LIMIT;
82
+ private defaultWindowMs: number = DEFAULT_WINDOW_MS;
83
+ private responseHeaders: boolean = DEFAULT_RESPONSE_HEADERS;
84
+
85
+ private keyExtractor: (req: Request) => string =
86
+ (req: Request): string => this.defaultKeyExtractor(req);
87
+ private endpointGrouper: (req: Request) => string =
88
+ (req: Request): string => req.path;
89
+
90
+ /** request-log: storageKey → timestamp-tomb (Date.now() ms). */
91
+ private requestLog: Map<string, number[]> = new Map();
92
+
93
+ /** Per-kulcs egyedi policy-k. */
94
+ private keyPolicies: Map<string, DyNTS_RateLimit_Policy> = new Map();
95
+
96
+ /** GC timer handle. */
97
+ private gcTimer: NodeJS.Timeout | null = null;
98
+
99
+
100
+ /**
101
+ * Konfig override. Hianyzo mezok a default-okat orzik. Hivhato barmikor —
102
+ * a `check()` a friss config-ot olvassa.
103
+ */
104
+ configure(config: DyNTS_RateLimit_Config): void {
105
+ if (config.defaultLimit !== undefined) {
106
+ this.defaultLimit = config.defaultLimit;
107
+ }
108
+ if (config.defaultWindowMs !== undefined) {
109
+ this.defaultWindowMs = config.defaultWindowMs;
110
+ }
111
+ if (config.keyExtractor !== undefined) {
112
+ this.keyExtractor = config.keyExtractor;
113
+ }
114
+ if (config.endpointGrouper !== undefined) {
115
+ this.endpointGrouper = config.endpointGrouper;
116
+ }
117
+ if (config.responseHeaders !== undefined) {
118
+ this.responseHeaders = config.responseHeaders;
119
+ }
120
+ if (config.initialKeyPolicies !== undefined) {
121
+ for (const [ key, policy ] of Object.entries(config.initialKeyPolicies)) {
122
+ this.keyPolicies.set(key, policy);
123
+ }
124
+ }
125
+ this.startGcTimer();
126
+ }
127
+
128
+ /**
129
+ * Aktualis konfig olvasasa (diagnosztika celokra).
130
+ */
131
+ getConfig(): {
132
+ defaultLimit: number;
133
+ defaultWindowMs: number;
134
+ responseHeaders: boolean;
135
+ activeKeyPolicies: number;
136
+ trackedStorageKeys: number;
137
+ } {
138
+ return {
139
+ defaultLimit: this.defaultLimit,
140
+ defaultWindowMs: this.defaultWindowMs,
141
+ responseHeaders: this.responseHeaders,
142
+ activeKeyPolicies: this.keyPolicies.size,
143
+ trackedStorageKeys: this.requestLog.size,
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Per-kulcs egyedi policy beallitas (pl. subscription-tier alapjan).
149
+ * A `key`-nek pontosan azzal a stringgel kell egyeznie, amit a `keyExtractor`
150
+ * visszaad.
151
+ */
152
+ setPolicyForKey(key: string, policy: DyNTS_RateLimit_Policy): void {
153
+ this.keyPolicies.set(key, policy);
154
+ }
155
+
156
+ /**
157
+ * Per-kulcs policy torlese (visszaall a default-ra).
158
+ */
159
+ clearPolicyForKey(key: string): void {
160
+ this.keyPolicies.delete(key);
161
+ }
162
+
163
+
164
+ /**
165
+ * Pre-process function — atadhato `DyNTS_Endpoint_Params.preProcesses`-be.
166
+ *
167
+ * Throws:
168
+ * - 429 ha az aktualis request meghaladna a limit-et a sliding window-on
169
+ *
170
+ * Side-effect: ha `responseHeaders === true`, beallitja az `X-RateLimit-Limit`,
171
+ * `X-RateLimit-Remaining`, `X-RateLimit-Reset` header-eket; 429 eseten
172
+ * a `Retry-After` header-t is.
173
+ */
174
+ readonly check = async (req: Request, res: Response): Promise<void> => {
175
+ const subject: string = this.keyExtractor(req);
176
+ const endpoint: string = this.endpointGrouper(req);
177
+ const storageKey: string = `${subject}|${endpoint}`;
178
+
179
+ const policy: DyNTS_RateLimit_Policy = this.keyPolicies.get(subject) ?? {
180
+ limit: this.defaultLimit,
181
+ windowMs: this.defaultWindowMs,
182
+ };
183
+
184
+ const now: number = Date.now();
185
+ const windowStart: number = now - policy.windowMs;
186
+
187
+ // sliding-window: tartomanyon kivuli timestamp-eket eldobjuk
188
+ const existing: number[] = this.requestLog.get(storageKey) ?? [];
189
+ const recent: number[] = existing.filter((t: number): boolean => t > windowStart);
190
+
191
+ if (recent.length >= policy.limit) {
192
+ const oldest: number = recent[0];
193
+ const resetAt: number = oldest + policy.windowMs;
194
+ const retryAfterSec: number = Math.max(1, Math.ceil((resetAt - now) / 1000));
195
+
196
+ if (this.responseHeaders) {
197
+ res.setHeader('X-RateLimit-Limit', policy.limit.toString());
198
+ res.setHeader('X-RateLimit-Remaining', '0');
199
+ res.setHeader('X-RateLimit-Reset', Math.ceil(resetAt / 1000).toString());
200
+ res.setHeader('Retry-After', retryAfterSec.toString());
201
+ }
202
+
203
+ // Frissitjuk a log-ot a kiszurt verzioval (felesleges regi timestamp-eket eldobtuk)
204
+ this.requestLog.set(storageKey, recent);
205
+
206
+ throw new DyFM_Error({
207
+ status: 429,
208
+ errorCode: buildErrorCode('LIMIT'),
209
+ addECToUserMsg: true,
210
+ message: `Rate limit exceeded: ${policy.limit} req per ${policy.windowMs}ms for ${storageKey}`,
211
+ userMessage: `Too many requests, retry after ${retryAfterSec}s`,
212
+ issuerService: SERVICE_NAME,
213
+ });
214
+ }
215
+
216
+ // alatta vagyunk a limit-nek: append the current request
217
+ recent.push(now);
218
+ this.requestLog.set(storageKey, recent);
219
+
220
+ if (this.responseHeaders) {
221
+ res.setHeader('X-RateLimit-Limit', policy.limit.toString());
222
+ res.setHeader('X-RateLimit-Remaining', Math.max(0, policy.limit - recent.length).toString());
223
+ res.setHeader('X-RateLimit-Reset', Math.ceil((now + policy.windowMs) / 1000).toString());
224
+ }
225
+ };
226
+
227
+
228
+ /**
229
+ * Default key-extractor: x-forwarded-for vagy req.ip vagy 'unknown'.
230
+ * Csak akkor hasznalt, ha a host nem allit be sajat extractort a configure-ben.
231
+ */
232
+ private defaultKeyExtractor(req: Request): string {
233
+ const xff: unknown = req.headers['x-forwarded-for'];
234
+ if (typeof xff === 'string' && xff.length > 0) {
235
+ const first: string = xff.split(',')[0]?.trim() ?? '';
236
+ if (first.length > 0) {
237
+ return first;
238
+ }
239
+ }
240
+ if (Array.isArray(xff) && xff.length > 0) {
241
+ const first: string = xff[0]?.split(',')[0]?.trim() ?? '';
242
+ if (first.length > 0) {
243
+ return first;
244
+ }
245
+ }
246
+ return req.ip ?? 'unknown';
247
+ }
248
+
249
+
250
+ /**
251
+ * GC timer inditasa (idempotent). Periodikusan eltavolitja az inaktiv
252
+ * storage-key-eket a request-log-bol — memory-leak prevention.
253
+ */
254
+ private startGcTimer(): void {
255
+ if (this.gcTimer !== null) {
256
+ return;
257
+ }
258
+ this.gcTimer = setInterval((): void => {
259
+ this.runGc();
260
+ }, GC_INTERVAL_MS);
261
+ // unref hogy a process ne maradjon eletben a timer miatt
262
+ if (typeof this.gcTimer.unref === 'function') {
263
+ this.gcTimer.unref();
264
+ }
265
+ }
266
+
267
+ /**
268
+ * GC sweep — minden storage-key-rol levagja a regi timestamp-eket, es
269
+ * eltavolitja az ureseket. Hivhato kulonosen test-bol.
270
+ */
271
+ runGc(): void {
272
+ const now: number = Date.now();
273
+ const horizon: number = now - this.defaultWindowMs;
274
+
275
+ for (const [ key, timestamps ] of this.requestLog) {
276
+ const recent: number[] = timestamps.filter((t: number): boolean => t > horizon);
277
+ if (recent.length === 0) {
278
+ this.requestLog.delete(key);
279
+ } else {
280
+ this.requestLog.set(key, recent);
281
+ }
282
+ }
283
+ }
284
+
285
+ /**
286
+ * GC timer leallitasa (graceful shutdown vagy test-cleanup).
287
+ */
288
+ stopGcTimer(): void {
289
+ if (this.gcTimer !== null) {
290
+ clearInterval(this.gcTimer);
291
+ this.gcTimer = null;
292
+ }
293
+ }
294
+
295
+
296
+ /**
297
+ * Test-only: visszaallitja a default config-ot + uriti a state-et, hogy a
298
+ * specfajlok ne szivarogjak at egymas state-jet. Production code NE hivja.
299
+ */
300
+ _resetForTesting(): void {
301
+ this.defaultLimit = DEFAULT_LIMIT;
302
+ this.defaultWindowMs = DEFAULT_WINDOW_MS;
303
+ this.responseHeaders = DEFAULT_RESPONSE_HEADERS;
304
+ this.keyExtractor = (req: Request): string => this.defaultKeyExtractor(req);
305
+ this.endpointGrouper = (req: Request): string => req.path;
306
+ this.requestLog.clear();
307
+ this.keyPolicies.clear();
308
+ this.stopGcTimer();
309
+ }
310
+ }
@@ -178,7 +178,7 @@ export class DyNTS_Errors_DataService<
178
178
  if (this.debugLog) DyFM_Log.error('Error:', errorsRecord);
179
179
 
180
180
  errorsRecord.priority = this.getPriorityMultiplierByLevel(errorsRecord?.level);
181
-
181
+
182
182
  errorsRecord.duplications ??= [];
183
183
  errorsRecord.duplications.push(DyFM_Object.clone(errorsRecord));
184
184
 
@@ -187,7 +187,15 @@ export class DyNTS_Errors_DataService<
187
187
 
188
188
  this.duplicationCounter = 1;
189
189
 
190
- await this.saveData();
190
+ // FR-027 (2026-05-24) — Pass `errorsRecord` explicitly. Korabban
191
+ // `saveData()` no-arg fallback `ensureData()`-on keresztul `this.data`-t
192
+ // hasznalt, ami a controller-szinten csak a `{issuer}` constructor
193
+ // wrapper, NEM az actual req.body adat. Eredmenykent minden client-
194
+ // forwarded error EMPTY rekordkent landolt: csak `issuer` mezo,
195
+ // semmilyen message/source/stackTrace/error/level/additionalContent
196
+ // mezo NEM kerult MongoDB-be. (Overseer-en 14454 ilyen empty record
197
+ // halmozodott fel — debug-level details elveszve.)
198
+ await this.saveData(errorsRecord);
191
199
  DyFM_Log.warn('error saved');
192
200
  }
193
201
  } catch (error) {