@j3r3mcdev/oast-server 1.1.1 → 1.1.3

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 (191) hide show
  1. package/.github/workflows/ci.yml +29 -29
  2. package/.github/workflows/publish.yml +31 -31
  3. package/README.md +192 -192
  4. package/dist/api/controllers/__tests__/tasks.controller.test.d.ts +1 -0
  5. package/dist/api/controllers/events.controller.d.ts +6 -0
  6. package/dist/api/controllers/health.controller.d.ts +4 -0
  7. package/dist/api/controllers/index.d.ts +0 -0
  8. package/dist/api/controllers/tasks.controller.d.ts +40 -0
  9. package/dist/api/dto/__tests__/create-task.dto.test.d.ts +1 -0
  10. package/dist/api/dto/__tests__/filter-tasks.dto.test.d.ts +1 -0
  11. package/dist/api/dto/create-task.dto.d.ts +9 -0
  12. package/dist/api/dto/filter-tasks.dto.d.ts +8 -0
  13. package/dist/api/services/__tests__/events.service.test.d.ts +1 -0
  14. package/dist/api/services/__tests__/tasks.service.test.d.ts +1 -0
  15. package/dist/api/services/events.service.d.ts +8 -0
  16. package/dist/api/services/tasks.service.d.ts +22 -0
  17. package/dist/api/sse/events.stream.d.ts +25 -0
  18. package/dist/bootstrap.d.ts +1 -0
  19. package/dist/bootstrap.js +76 -0
  20. package/dist/config/constants.d.ts +0 -0
  21. package/dist/config/env.d.ts +0 -0
  22. package/dist/core/__tests__/core-router.test.d.ts +1 -0
  23. package/dist/core/__tests__/core-server.test.d.ts +1 -0
  24. package/dist/core/__tests__/event.normalizer.test.d.ts +1 -0
  25. package/dist/core/__tests__/event.router.test.d.ts +1 -0
  26. package/dist/core/__tests__/logger.test.d.ts +1 -0
  27. package/dist/core/__tests__/storage-manager.test.d.ts +1 -0
  28. package/dist/core/event.normalizer.d.ts +10 -0
  29. package/dist/core/event.router.d.ts +7 -0
  30. package/dist/core/http/__tests__/adapter-node.test.d.ts +1 -0
  31. package/dist/core/http/__tests__/body-parser-multipart.test.d.ts +1 -0
  32. package/dist/core/http/__tests__/body-parser-raw.test.d.ts +1 -0
  33. package/dist/core/http/__tests__/body-parser-text.test.d.ts +1 -0
  34. package/dist/core/http/__tests__/compile-path.test.d.ts +1 -0
  35. package/dist/core/http/__tests__/middleware-pipeline.test.d.ts +1 -0
  36. package/dist/core/http/__tests__/request.test.d.ts +1 -0
  37. package/dist/core/http/__tests__/response.test.d.ts +1 -0
  38. package/dist/core/http/__tests__/router-match.test.d.ts +1 -0
  39. package/dist/core/http/adapter-node.d.ts +8 -0
  40. package/dist/core/http/buildRequest.d.ts +2 -0
  41. package/dist/core/http/compile-path.d.ts +13 -0
  42. package/dist/core/http/errors.d.ts +9 -0
  43. package/dist/core/http/http-server.d.ts +7 -0
  44. package/dist/core/http/index.d.ts +0 -0
  45. package/dist/core/http/main.d.ts +0 -0
  46. package/dist/core/http/middleware.d.ts +12 -0
  47. package/dist/core/http/request.d.ts +35 -0
  48. package/dist/core/http/response.d.ts +17 -0
  49. package/dist/core/http/router.d.ts +28 -0
  50. package/dist/core/http/utils.d.ts +0 -0
  51. package/dist/core/id-generator.d.ts +3 -0
  52. package/dist/core/logger.d.ts +29 -0
  53. package/dist/core/router.d.ts +16 -0
  54. package/dist/core/server.d.ts +25 -0
  55. package/dist/core/storage.d.ts +24 -0
  56. package/dist/index.d.ts +9 -0
  57. package/dist/index.js +19 -74
  58. package/dist/listeners/api/__tests__/api.controller.test.d.ts +1 -0
  59. package/dist/listeners/api/__tests__/api.extractor.test.d.ts +1 -0
  60. package/dist/listeners/api/__tests__/api.listener.test.d.ts +1 -0
  61. package/dist/listeners/api/__tests__/api.routes.test.d.ts +1 -0
  62. package/dist/listeners/api/__tests__/api.sse.test.d.ts +1 -0
  63. package/dist/listeners/api/api.controllers.d.ts +9 -0
  64. package/dist/listeners/api/api.extractor.d.ts +5 -0
  65. package/dist/listeners/api/api.listener.d.ts +17 -0
  66. package/dist/listeners/api/api.routes.d.ts +5 -0
  67. package/dist/listeners/api/api.sse.d.ts +10 -0
  68. package/dist/listeners/dns/__tests__/dns.test.d.ts +1 -0
  69. package/dist/listeners/dns/dns.extractor.d.ts +8 -0
  70. package/dist/listeners/dns/dns.listener.d.ts +15 -0
  71. package/dist/listeners/http/__tests__/http.extractor.test.d.ts +1 -0
  72. package/dist/listeners/http/__tests__/http.listener.test.d.ts +1 -0
  73. package/dist/listeners/http/http.extractor.d.ts +11 -0
  74. package/dist/listeners/http/http.listener.d.ts +17 -0
  75. package/dist/listeners/listener.interface.d.ts +4 -0
  76. package/dist/listeners/smtp/__tests__/smtp.extractor.test.d.ts +1 -0
  77. package/dist/listeners/smtp/__tests__/smtp.listener.test.d.ts +1 -0
  78. package/dist/listeners/smtp/smtp.extractor.d.ts +12 -0
  79. package/dist/listeners/smtp/smtp.listener.d.ts +13 -0
  80. package/dist/listeners/ssrf/__tests__/ssrf.extractor.test.d.ts +1 -0
  81. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.d.ts +1 -0
  82. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.js +4 -16
  83. package/dist/listeners/ssrf/ssrf.extractor.d.ts +10 -0
  84. package/dist/listeners/ssrf/ssrf.listener.d.ts +8 -0
  85. package/dist/listeners/tcp/tcp.extractor.d.ts +4 -0
  86. package/dist/listeners/tcp/tcp.listener.d.ts +18 -0
  87. package/dist/listeners/webhook/__tests__/webhook.extractor.test.d.ts +1 -0
  88. package/dist/listeners/webhook/__tests__/webhook.listener.test.d.ts +1 -0
  89. package/dist/listeners/webhook/webhook.extractor.d.ts +8 -0
  90. package/dist/listeners/webhook/webhook.listener.d.ts +8 -0
  91. package/dist/listeners/websocket/__tests__/websocket.extractor.test.d.ts +1 -0
  92. package/dist/listeners/websocket/__tests__/websocket.listener.test.d.ts +1 -0
  93. package/dist/listeners/websocket/websocket.extractor.d.ts +10 -0
  94. package/dist/listeners/websocket/websocket.listener.d.ts +8 -0
  95. package/dist/storage-adapters/adapters/__tests__/memory.storage.test.d.ts +1 -0
  96. package/dist/storage-adapters/adapters/memory.storage.d.ts +21 -0
  97. package/dist/storage-adapters/adapters/redis.storage.d.ts +0 -0
  98. package/dist/storage-adapters/adapters/sqlite.storage.d.ts +0 -0
  99. package/dist/storage-adapters/storage.interface.d.ts +18 -0
  100. package/dist/types/event.types.d.ts +118 -0
  101. package/dist/utils/token.d.ts +0 -0
  102. package/jest.config.js +14 -14
  103. package/package.json +45 -45
  104. package/sadmin list shadows +9 -9
  105. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  106. package/src/api/controllers/events.controller.ts +10 -10
  107. package/src/api/controllers/health.controller.ts +7 -7
  108. package/src/api/controllers/tasks.controller.ts +41 -41
  109. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  110. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  111. package/src/api/dto/create-task.dto.ts +33 -33
  112. package/src/api/dto/filter-tasks.dto.ts +33 -33
  113. package/src/api/services/__tests__/events.service.test.ts +41 -41
  114. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  115. package/src/api/services/events.service.ts +17 -17
  116. package/src/api/services/tasks.service.ts +79 -79
  117. package/src/api/sse/events.stream.ts +90 -90
  118. package/src/bootstrap.ts +89 -0
  119. package/src/core/__tests__/core-router.test.ts +30 -30
  120. package/src/core/__tests__/core-server.test.ts +44 -44
  121. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  122. package/src/core/__tests__/event.router.test.ts +89 -89
  123. package/src/core/__tests__/logger.test.ts +32 -32
  124. package/src/core/__tests__/storage-manager.test.ts +74 -74
  125. package/src/core/event.normalizer.ts +147 -147
  126. package/src/core/event.router.ts +13 -13
  127. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  128. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  129. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  130. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  131. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  132. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  133. package/src/core/http/__tests__/request.test.ts +34 -34
  134. package/src/core/http/__tests__/response.test.ts +35 -35
  135. package/src/core/http/__tests__/router-match.test.ts +171 -171
  136. package/src/core/http/adapter-node.ts +51 -51
  137. package/src/core/http/buildRequest.ts +18 -18
  138. package/src/core/http/compile-path.ts +32 -32
  139. package/src/core/http/errors.ts +37 -37
  140. package/src/core/http/http-server.ts +52 -52
  141. package/src/core/http/middleware.ts +160 -160
  142. package/src/core/http/request.ts +55 -55
  143. package/src/core/http/response.ts +93 -93
  144. package/src/core/http/router.ts +138 -138
  145. package/src/core/id-generator.ts +8 -8
  146. package/src/core/logger.ts +113 -113
  147. package/src/core/router.ts +44 -44
  148. package/src/core/server.ts +85 -85
  149. package/src/core/storage.ts +64 -64
  150. package/src/index.ts +10 -89
  151. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  152. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  153. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  154. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  155. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  156. package/src/listeners/api/api.controllers.ts +67 -67
  157. package/src/listeners/api/api.extractor.ts +43 -43
  158. package/src/listeners/api/api.listener.ts +50 -50
  159. package/src/listeners/api/api.routes.ts +76 -76
  160. package/src/listeners/api/api.sse.ts +38 -38
  161. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  162. package/src/listeners/dns/dns.extractor.ts +14 -14
  163. package/src/listeners/dns/dns.listener.ts +61 -61
  164. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  165. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  166. package/src/listeners/http/http.extractor.ts +15 -15
  167. package/src/listeners/http/http.listener.ts +110 -110
  168. package/src/listeners/listener.interface.ts +4 -4
  169. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  170. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  171. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  172. package/src/listeners/smtp/smtp.listener.ts +60 -60
  173. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  174. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  175. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  176. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  177. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  178. package/src/listeners/tcp/tcp.listener.ts +61 -61
  179. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  180. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  181. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  182. package/src/listeners/webhook/webhook.listener.ts +58 -58
  183. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  184. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  185. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  186. package/src/listeners/websocket/websocket.listener.ts +40 -40
  187. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  188. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  189. package/src/storage-adapters/storage.interface.ts +26 -26
  190. package/src/types/event.types.ts +147 -147
  191. package/tsconfig.json +21 -21
@@ -1,44 +1,44 @@
1
- import { CoreServer } from "../../core/server";
2
- import { StorageManager } from "../../core/storage";
3
- import { Logger } from "../../core/logger";
4
- import { describe, it, expect } from "@jest/globals";
5
-
6
- class FakeListener {
7
- started = false;
8
- stopped = false;
9
-
10
- async start() {
11
- this.started = true;
12
- }
13
-
14
- async stop() {
15
- this.stopped = true;
16
- }
17
- }
18
-
19
- describe("CoreServer", () => {
20
- it("démarre et arrête les listeners", async () => {
21
- const listener = new FakeListener();
22
-
23
- const server = new CoreServer({
24
- storage: new StorageManager(),
25
- logger: new Logger({ enabled: false }),
26
- listeners: [listener],
27
- });
28
-
29
- await server.start();
30
- expect(listener.started).toBe(true);
31
-
32
- await server.stop();
33
- expect(listener.stopped).toBe(true);
34
- });
35
-
36
- it("expose le router", () => {
37
- const server = new CoreServer({
38
- storage: new StorageManager(),
39
- });
40
-
41
- const router = server.getRouter();
42
- expect(router).toBeDefined();
43
- });
44
- });
1
+ import { CoreServer } from "../../core/server";
2
+ import { StorageManager } from "../../core/storage";
3
+ import { Logger } from "../../core/logger";
4
+ import { describe, it, expect } from "@jest/globals";
5
+
6
+ class FakeListener {
7
+ started = false;
8
+ stopped = false;
9
+
10
+ async start() {
11
+ this.started = true;
12
+ }
13
+
14
+ async stop() {
15
+ this.stopped = true;
16
+ }
17
+ }
18
+
19
+ describe("CoreServer", () => {
20
+ it("démarre et arrête les listeners", async () => {
21
+ const listener = new FakeListener();
22
+
23
+ const server = new CoreServer({
24
+ storage: new StorageManager(),
25
+ logger: new Logger({ enabled: false }),
26
+ listeners: [listener],
27
+ });
28
+
29
+ await server.start();
30
+ expect(listener.started).toBe(true);
31
+
32
+ await server.stop();
33
+ expect(listener.stopped).toBe(true);
34
+ });
35
+
36
+ it("expose le router", () => {
37
+ const server = new CoreServer({
38
+ storage: new StorageManager(),
39
+ });
40
+
41
+ const router = server.getRouter();
42
+ expect(router).toBeDefined();
43
+ });
44
+ });
@@ -1,56 +1,56 @@
1
- import { EventNormalizer } from "../event.normalizer";
2
- import { describe, it, expect, jest } from "@jest/globals";
3
- import { IdGenerator } from "../id-generator";
4
-
5
- describe("EventNormalizer.normalizeHttp", () => {
6
- it("normalise correctement une requête HTTP", () => {
7
- // Mock du timestamp
8
- const fakeNow = 1234567890;
9
- jest.spyOn(Date, "now").mockReturnValue(fakeNow);
10
-
11
- // Mock de l'ID
12
- jest.spyOn(IdGenerator, "generate").mockReturnValue("uuid-test");
13
-
14
- const req = {
15
- ip: "9.9.9.9",
16
- method: "POST",
17
- path: "/test",
18
- headers: { "x-forwarded-for": "9.9.9.9" },
19
- query: { a: "1" },
20
- body: { hello: "world" },
21
- raw: {}, // obligatoire
22
- };
23
-
24
- const event = EventNormalizer.normalizeHttp(req);
25
-
26
- expect(event).toEqual({
27
- id: "uuid-test",
28
- type: "http",
29
- timestamp: fakeNow,
30
- sourceIp: "9.9.9.9",
31
- request: {
32
- method: "POST",
33
- path: "/test",
34
- headers: { "x-forwarded-for": "9.9.9.9" },
35
- query: { a: "1" },
36
- body: { hello: "world" },
37
- },
38
- });
39
- });
40
-
41
- it("retourne 'unknown' si aucune IP n'est trouvée", () => {
42
- const req = {
43
- ip: "",
44
- method: "GET",
45
- path: "/",
46
- headers: {},
47
- query: {},
48
- body: {},
49
- raw: {},
50
- };
51
-
52
- const event = EventNormalizer.normalizeHttp(req);
53
-
54
- expect(event.sourceIp).toBe("unknown");
55
- });
56
- });
1
+ import { EventNormalizer } from "../event.normalizer";
2
+ import { describe, it, expect, jest } from "@jest/globals";
3
+ import { IdGenerator } from "../id-generator";
4
+
5
+ describe("EventNormalizer.normalizeHttp", () => {
6
+ it("normalise correctement une requête HTTP", () => {
7
+ // Mock du timestamp
8
+ const fakeNow = 1234567890;
9
+ jest.spyOn(Date, "now").mockReturnValue(fakeNow);
10
+
11
+ // Mock de l'ID
12
+ jest.spyOn(IdGenerator, "generate").mockReturnValue("uuid-test");
13
+
14
+ const req = {
15
+ ip: "9.9.9.9",
16
+ method: "POST",
17
+ path: "/test",
18
+ headers: { "x-forwarded-for": "9.9.9.9" },
19
+ query: { a: "1" },
20
+ body: { hello: "world" },
21
+ raw: {}, // obligatoire
22
+ };
23
+
24
+ const event = EventNormalizer.normalizeHttp(req);
25
+
26
+ expect(event).toEqual({
27
+ id: "uuid-test",
28
+ type: "http",
29
+ timestamp: fakeNow,
30
+ sourceIp: "9.9.9.9",
31
+ request: {
32
+ method: "POST",
33
+ path: "/test",
34
+ headers: { "x-forwarded-for": "9.9.9.9" },
35
+ query: { a: "1" },
36
+ body: { hello: "world" },
37
+ },
38
+ });
39
+ });
40
+
41
+ it("retourne 'unknown' si aucune IP n'est trouvée", () => {
42
+ const req = {
43
+ ip: "",
44
+ method: "GET",
45
+ path: "/",
46
+ headers: {},
47
+ query: {},
48
+ body: {},
49
+ raw: {},
50
+ };
51
+
52
+ const event = EventNormalizer.normalizeHttp(req);
53
+
54
+ expect(event.sourceIp).toBe("unknown");
55
+ });
56
+ });
@@ -1,89 +1,89 @@
1
- import {
2
- AnyNormalizedEvent,
3
- NormalizedHttpEvent,
4
- } from "../../types/event.types";
5
- import {
6
- StorageListParams,
7
- Storage,
8
- } from "../../storage-adapters/storage.interface";
9
- import { EventRouter } from "../event.router";
10
- import { EventNormalizer } from "../event.normalizer";
11
- import { describe, it, expect, jest } from "@jest/globals";
12
-
13
- class MockStorage implements Storage {
14
- save = jest.fn<(event: AnyNormalizedEvent) => Promise<void>>();
15
- getEvent = jest.fn<(id: string) => Promise<AnyNormalizedEvent | null>>();
16
- listEvents =
17
- jest.fn<(params: StorageListParams) => Promise<AnyNormalizedEvent[]>>();
18
- deleteEvent = jest.fn<(id: string) => Promise<boolean>>();
19
- clearEvents = jest.fn<() => Promise<void>>();
20
- getStats =
21
- jest.fn<() => Promise<{ total: number; byType: Record<string, number> }>>();
22
- getAll = jest.fn<() => Promise<AnyNormalizedEvent[]>>();
23
- }
24
-
25
- describe("EventRouter", () => {
26
- it("enregistre un événement HTTP normalisé", async () => {
27
- const mockStorage = new MockStorage();
28
-
29
- const fakeEvent: NormalizedHttpEvent = {
30
- id: "123",
31
- type: "http",
32
- timestamp: 111,
33
- sourceIp: "1.1.1.1",
34
- request: {
35
- method: "GET",
36
- path: "/",
37
- headers: {},
38
- query: {},
39
- body: {},
40
- },
41
- };
42
-
43
- jest.spyOn(EventNormalizer, "normalizeHttp").mockReturnValue(fakeEvent);
44
-
45
- const router = new EventRouter(mockStorage);
46
-
47
- const req = {
48
- ip: "1.1.1.1",
49
- method: "GET",
50
- path: "/",
51
- headers: {},
52
- query: {},
53
- body: {},
54
- raw: {},
55
- };
56
-
57
- const result = await router.handleHttp(req);
58
-
59
- expect(EventNormalizer.normalizeHttp).toHaveBeenCalledWith(req);
60
- expect(mockStorage.save).toHaveBeenCalledWith(fakeEvent);
61
- expect(result).toEqual(fakeEvent);
62
- });
63
-
64
- it("propagate une erreur si normalizeHttp throw", async () => {
65
- const mockStorage = new MockStorage();
66
-
67
- jest.spyOn(EventNormalizer, "normalizeHttp").mockImplementation(() => {
68
- throw new Error("Boom");
69
- });
70
-
71
- const router = new EventRouter(mockStorage);
72
-
73
- await expect(router.handleHttp({} as any)).rejects.toThrow("Boom");
74
- expect(mockStorage.save).not.toHaveBeenCalled();
75
- });
76
-
77
- it("propagate une erreur si storage.save throw", async () => {
78
- const mockStorage = new MockStorage();
79
-
80
- const fakeEvent = { id: "x", type: "http" } as any;
81
-
82
- jest.spyOn(EventNormalizer, "normalizeHttp").mockReturnValue(fakeEvent);
83
- mockStorage.save.mockRejectedValue(new Error("DB error"));
84
-
85
- const router = new EventRouter(mockStorage);
86
-
87
- await expect(router.handleHttp({} as any)).rejects.toThrow("DB error");
88
- });
89
- });
1
+ import {
2
+ AnyNormalizedEvent,
3
+ NormalizedHttpEvent,
4
+ } from "../../types/event.types";
5
+ import {
6
+ StorageListParams,
7
+ Storage,
8
+ } from "../../storage-adapters/storage.interface";
9
+ import { EventRouter } from "../event.router";
10
+ import { EventNormalizer } from "../event.normalizer";
11
+ import { describe, it, expect, jest } from "@jest/globals";
12
+
13
+ class MockStorage implements Storage {
14
+ save = jest.fn<(event: AnyNormalizedEvent) => Promise<void>>();
15
+ getEvent = jest.fn<(id: string) => Promise<AnyNormalizedEvent | null>>();
16
+ listEvents =
17
+ jest.fn<(params: StorageListParams) => Promise<AnyNormalizedEvent[]>>();
18
+ deleteEvent = jest.fn<(id: string) => Promise<boolean>>();
19
+ clearEvents = jest.fn<() => Promise<void>>();
20
+ getStats =
21
+ jest.fn<() => Promise<{ total: number; byType: Record<string, number> }>>();
22
+ getAll = jest.fn<() => Promise<AnyNormalizedEvent[]>>();
23
+ }
24
+
25
+ describe("EventRouter", () => {
26
+ it("enregistre un événement HTTP normalisé", async () => {
27
+ const mockStorage = new MockStorage();
28
+
29
+ const fakeEvent: NormalizedHttpEvent = {
30
+ id: "123",
31
+ type: "http",
32
+ timestamp: 111,
33
+ sourceIp: "1.1.1.1",
34
+ request: {
35
+ method: "GET",
36
+ path: "/",
37
+ headers: {},
38
+ query: {},
39
+ body: {},
40
+ },
41
+ };
42
+
43
+ jest.spyOn(EventNormalizer, "normalizeHttp").mockReturnValue(fakeEvent);
44
+
45
+ const router = new EventRouter(mockStorage);
46
+
47
+ const req = {
48
+ ip: "1.1.1.1",
49
+ method: "GET",
50
+ path: "/",
51
+ headers: {},
52
+ query: {},
53
+ body: {},
54
+ raw: {},
55
+ };
56
+
57
+ const result = await router.handleHttp(req);
58
+
59
+ expect(EventNormalizer.normalizeHttp).toHaveBeenCalledWith(req);
60
+ expect(mockStorage.save).toHaveBeenCalledWith(fakeEvent);
61
+ expect(result).toEqual(fakeEvent);
62
+ });
63
+
64
+ it("propagate une erreur si normalizeHttp throw", async () => {
65
+ const mockStorage = new MockStorage();
66
+
67
+ jest.spyOn(EventNormalizer, "normalizeHttp").mockImplementation(() => {
68
+ throw new Error("Boom");
69
+ });
70
+
71
+ const router = new EventRouter(mockStorage);
72
+
73
+ await expect(router.handleHttp({} as any)).rejects.toThrow("Boom");
74
+ expect(mockStorage.save).not.toHaveBeenCalled();
75
+ });
76
+
77
+ it("propagate une erreur si storage.save throw", async () => {
78
+ const mockStorage = new MockStorage();
79
+
80
+ const fakeEvent = { id: "x", type: "http" } as any;
81
+
82
+ jest.spyOn(EventNormalizer, "normalizeHttp").mockReturnValue(fakeEvent);
83
+ mockStorage.save.mockRejectedValue(new Error("DB error"));
84
+
85
+ const router = new EventRouter(mockStorage);
86
+
87
+ await expect(router.handleHttp({} as any)).rejects.toThrow("DB error");
88
+ });
89
+ });
@@ -1,32 +1,32 @@
1
- import { Logger, LogEntry } from "../../core/logger";
2
- import { describe, it, expect, jest } from "@jest/globals";
3
-
4
- describe("Logger", () => {
5
- it("appelle les hooks", () => {
6
- const hook = jest.fn<(entry: LogEntry) => void>();
7
- const logger = new Logger({ hooks: [hook], enabled: true });
8
-
9
- logger.info("hello");
10
-
11
- expect(hook).toHaveBeenCalled();
12
- expect(hook.mock.calls[0][0].message).toBe("hello");
13
- });
14
-
15
- it("respecte le niveau de logs", () => {
16
- const hook = jest.fn<(entry: LogEntry) => void>();
17
- const logger = new Logger({ level: "warn", hooks: [hook] });
18
-
19
- logger.info("should not log");
20
- logger.error("should log");
21
-
22
- expect(hook).toHaveBeenCalledTimes(1);
23
- expect(hook.mock.calls[0][0].level).toBe("error");
24
- });
25
-
26
- it("crée un logger enfant avec contexte", () => {
27
- const logger = new Logger({ context: "root" });
28
- const child = logger.withContext("child");
29
-
30
- expect(child).not.toBe(logger);
31
- });
32
- });
1
+ import { Logger, LogEntry } from "../../core/logger";
2
+ import { describe, it, expect, jest } from "@jest/globals";
3
+
4
+ describe("Logger", () => {
5
+ it("appelle les hooks", () => {
6
+ const hook = jest.fn<(entry: LogEntry) => void>();
7
+ const logger = new Logger({ hooks: [hook], enabled: true });
8
+
9
+ logger.info("hello");
10
+
11
+ expect(hook).toHaveBeenCalled();
12
+ expect(hook.mock.calls[0][0].message).toBe("hello");
13
+ });
14
+
15
+ it("respecte le niveau de logs", () => {
16
+ const hook = jest.fn<(entry: LogEntry) => void>();
17
+ const logger = new Logger({ level: "warn", hooks: [hook] });
18
+
19
+ logger.info("should not log");
20
+ logger.error("should log");
21
+
22
+ expect(hook).toHaveBeenCalledTimes(1);
23
+ expect(hook.mock.calls[0][0].level).toBe("error");
24
+ });
25
+
26
+ it("crée un logger enfant avec contexte", () => {
27
+ const logger = new Logger({ context: "root" });
28
+ const child = logger.withContext("child");
29
+
30
+ expect(child).not.toBe(logger);
31
+ });
32
+ });
@@ -1,74 +1,74 @@
1
- import { describe, test, expect } from "@jest/globals";
2
- import { StorageManager } from "../storage"; // si ton fichier s'appelle storage-manager.ts
3
- import { NormalizedHttpEvent } from "../../types/event.types";
4
-
5
- function makeHttpEvent(id: string): NormalizedHttpEvent {
6
- return {
7
- id,
8
- type: "http",
9
- timestamp: Date.now(),
10
- sourceIp: "127.0.0.1",
11
- request: {
12
- method: "GET",
13
- path: "/",
14
- headers: {},
15
- query: {},
16
- body: "",
17
- },
18
- };
19
- }
20
-
21
- describe("StorageManager", () => {
22
- test("save + getEvent", async () => {
23
- const storage = new StorageManager();
24
-
25
- const event = makeHttpEvent("1");
26
- await storage.save(event);
27
-
28
- const found = await storage.getEvent("1");
29
- expect(found).not.toBeNull();
30
- expect(found?.id).toBe("1");
31
- });
32
-
33
- test("listEvents returns events", async () => {
34
- const storage = new StorageManager();
35
-
36
- await storage.save(makeHttpEvent("1"));
37
-
38
- const list = await storage.listEvents({});
39
- expect(list.length).toBe(1);
40
- });
41
-
42
- test("deleteEvent removes event", async () => {
43
- const storage = new StorageManager();
44
-
45
- await storage.save(makeHttpEvent("1"));
46
-
47
- let list = await storage.listEvents({});
48
- expect(list.length).toBe(1);
49
-
50
- await storage.deleteEvent("1");
51
-
52
- list = await storage.listEvents({});
53
- expect(list.length).toBe(0);
54
- });
55
-
56
- test("clearEvents empties storage", async () => {
57
- const storage = new StorageManager();
58
-
59
- await storage.save(makeHttpEvent("1"));
60
- await storage.clearEvents();
61
-
62
- const list = await storage.listEvents({});
63
- expect(list.length).toBe(0);
64
- });
65
-
66
- test("getStats returns correct structure", async () => {
67
- const storage = new StorageManager();
68
-
69
- const stats = await storage.getStats();
70
-
71
- expect(stats.total).toBe(0);
72
- expect(stats.byType).toEqual({});
73
- });
74
- });
1
+ import { describe, test, expect } from "@jest/globals";
2
+ import { StorageManager } from "../storage"; // si ton fichier s'appelle storage-manager.ts
3
+ import { NormalizedHttpEvent } from "../../types/event.types";
4
+
5
+ function makeHttpEvent(id: string): NormalizedHttpEvent {
6
+ return {
7
+ id,
8
+ type: "http",
9
+ timestamp: Date.now(),
10
+ sourceIp: "127.0.0.1",
11
+ request: {
12
+ method: "GET",
13
+ path: "/",
14
+ headers: {},
15
+ query: {},
16
+ body: "",
17
+ },
18
+ };
19
+ }
20
+
21
+ describe("StorageManager", () => {
22
+ test("save + getEvent", async () => {
23
+ const storage = new StorageManager();
24
+
25
+ const event = makeHttpEvent("1");
26
+ await storage.save(event);
27
+
28
+ const found = await storage.getEvent("1");
29
+ expect(found).not.toBeNull();
30
+ expect(found?.id).toBe("1");
31
+ });
32
+
33
+ test("listEvents returns events", async () => {
34
+ const storage = new StorageManager();
35
+
36
+ await storage.save(makeHttpEvent("1"));
37
+
38
+ const list = await storage.listEvents({});
39
+ expect(list.length).toBe(1);
40
+ });
41
+
42
+ test("deleteEvent removes event", async () => {
43
+ const storage = new StorageManager();
44
+
45
+ await storage.save(makeHttpEvent("1"));
46
+
47
+ let list = await storage.listEvents({});
48
+ expect(list.length).toBe(1);
49
+
50
+ await storage.deleteEvent("1");
51
+
52
+ list = await storage.listEvents({});
53
+ expect(list.length).toBe(0);
54
+ });
55
+
56
+ test("clearEvents empties storage", async () => {
57
+ const storage = new StorageManager();
58
+
59
+ await storage.save(makeHttpEvent("1"));
60
+ await storage.clearEvents();
61
+
62
+ const list = await storage.listEvents({});
63
+ expect(list.length).toBe(0);
64
+ });
65
+
66
+ test("getStats returns correct structure", async () => {
67
+ const storage = new StorageManager();
68
+
69
+ const stats = await storage.getStats();
70
+
71
+ expect(stats.total).toBe(0);
72
+ expect(stats.byType).toEqual({});
73
+ });
74
+ });