@j3r3mcdev/oast-server 1.1.0 → 1.1.1

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 (187) 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/listeners/ssrf/__tests__/ssrf.listener.test.js +16 -4
  5. package/jest.config.js +14 -14
  6. package/package.json +45 -45
  7. package/sadmin list shadows +9 -9
  8. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  9. package/src/api/controllers/events.controller.ts +10 -10
  10. package/src/api/controllers/health.controller.ts +7 -7
  11. package/src/api/controllers/tasks.controller.ts +41 -41
  12. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  13. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  14. package/src/api/dto/create-task.dto.ts +33 -33
  15. package/src/api/dto/filter-tasks.dto.ts +33 -33
  16. package/src/api/services/__tests__/events.service.test.ts +41 -41
  17. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  18. package/src/api/services/events.service.ts +17 -17
  19. package/src/api/services/tasks.service.ts +79 -79
  20. package/src/api/sse/events.stream.ts +90 -90
  21. package/src/core/__tests__/core-router.test.ts +30 -30
  22. package/src/core/__tests__/core-server.test.ts +44 -44
  23. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  24. package/src/core/__tests__/event.router.test.ts +89 -89
  25. package/src/core/__tests__/logger.test.ts +32 -32
  26. package/src/core/__tests__/storage-manager.test.ts +74 -74
  27. package/src/core/event.normalizer.ts +147 -147
  28. package/src/core/event.router.ts +13 -13
  29. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  30. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  31. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  32. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  33. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  34. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  35. package/src/core/http/__tests__/request.test.ts +34 -34
  36. package/src/core/http/__tests__/response.test.ts +35 -35
  37. package/src/core/http/__tests__/router-match.test.ts +171 -171
  38. package/src/core/http/adapter-node.ts +51 -51
  39. package/src/core/http/buildRequest.ts +18 -18
  40. package/src/core/http/compile-path.ts +32 -32
  41. package/src/core/http/errors.ts +37 -37
  42. package/src/core/http/http-server.ts +52 -52
  43. package/src/core/http/middleware.ts +160 -160
  44. package/src/core/http/request.ts +55 -55
  45. package/src/core/http/response.ts +93 -93
  46. package/src/core/http/router.ts +138 -138
  47. package/src/core/id-generator.ts +8 -8
  48. package/src/core/logger.ts +113 -113
  49. package/src/core/router.ts +44 -44
  50. package/src/core/server.ts +85 -85
  51. package/src/core/storage.ts +64 -64
  52. package/src/index.ts +89 -89
  53. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  54. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  55. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  56. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  57. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  58. package/src/listeners/api/api.controllers.ts +67 -67
  59. package/src/listeners/api/api.extractor.ts +43 -43
  60. package/src/listeners/api/api.listener.ts +50 -50
  61. package/src/listeners/api/api.routes.ts +76 -76
  62. package/src/listeners/api/api.sse.ts +38 -38
  63. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  64. package/src/listeners/dns/dns.extractor.ts +14 -14
  65. package/src/listeners/dns/dns.listener.ts +61 -61
  66. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  67. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  68. package/src/listeners/http/http.extractor.ts +15 -15
  69. package/src/listeners/http/http.listener.ts +110 -110
  70. package/src/listeners/listener.interface.ts +4 -4
  71. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  72. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  73. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  74. package/src/listeners/smtp/smtp.listener.ts +60 -60
  75. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  76. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  77. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  78. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  79. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  80. package/src/listeners/tcp/tcp.listener.ts +61 -61
  81. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  82. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  83. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  84. package/src/listeners/webhook/webhook.listener.ts +58 -58
  85. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  86. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  87. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  88. package/src/listeners/websocket/websocket.listener.ts +40 -40
  89. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  90. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  91. package/src/storage-adapters/storage.interface.ts +26 -26
  92. package/src/types/event.types.ts +147 -147
  93. package/tsconfig.json +21 -21
  94. package/dist/api/controllers/__tests__/tasks.controller.test.d.ts +0 -1
  95. package/dist/api/controllers/events.controller.d.ts +0 -6
  96. package/dist/api/controllers/health.controller.d.ts +0 -4
  97. package/dist/api/controllers/index.d.ts +0 -0
  98. package/dist/api/controllers/tasks.controller.d.ts +0 -40
  99. package/dist/api/dto/__tests__/create-task.dto.test.d.ts +0 -1
  100. package/dist/api/dto/__tests__/filter-tasks.dto.test.d.ts +0 -1
  101. package/dist/api/dto/create-task.dto.d.ts +0 -9
  102. package/dist/api/dto/filter-tasks.dto.d.ts +0 -8
  103. package/dist/api/services/__tests__/events.service.test.d.ts +0 -1
  104. package/dist/api/services/__tests__/tasks.service.test.d.ts +0 -1
  105. package/dist/api/services/events.service.d.ts +0 -8
  106. package/dist/api/services/tasks.service.d.ts +0 -22
  107. package/dist/api/sse/events.stream.d.ts +0 -25
  108. package/dist/config/constants.d.ts +0 -0
  109. package/dist/config/env.d.ts +0 -0
  110. package/dist/core/__tests__/core-router.test.d.ts +0 -1
  111. package/dist/core/__tests__/core-server.test.d.ts +0 -1
  112. package/dist/core/__tests__/event.normalizer.test.d.ts +0 -1
  113. package/dist/core/__tests__/event.router.test.d.ts +0 -1
  114. package/dist/core/__tests__/logger.test.d.ts +0 -1
  115. package/dist/core/__tests__/storage-manager.test.d.ts +0 -1
  116. package/dist/core/event.normalizer.d.ts +0 -10
  117. package/dist/core/event.router.d.ts +0 -7
  118. package/dist/core/http/__tests__/adapter-node.test.d.ts +0 -1
  119. package/dist/core/http/__tests__/body-parser-multipart.test.d.ts +0 -1
  120. package/dist/core/http/__tests__/body-parser-raw.test.d.ts +0 -1
  121. package/dist/core/http/__tests__/body-parser-text.test.d.ts +0 -1
  122. package/dist/core/http/__tests__/compile-path.test.d.ts +0 -1
  123. package/dist/core/http/__tests__/middleware-pipeline.test.d.ts +0 -1
  124. package/dist/core/http/__tests__/request.test.d.ts +0 -1
  125. package/dist/core/http/__tests__/response.test.d.ts +0 -1
  126. package/dist/core/http/__tests__/router-match.test.d.ts +0 -1
  127. package/dist/core/http/adapter-node.d.ts +0 -8
  128. package/dist/core/http/buildRequest.d.ts +0 -2
  129. package/dist/core/http/compile-path.d.ts +0 -13
  130. package/dist/core/http/errors.d.ts +0 -9
  131. package/dist/core/http/http-server.d.ts +0 -7
  132. package/dist/core/http/index.d.ts +0 -0
  133. package/dist/core/http/main.d.ts +0 -0
  134. package/dist/core/http/middleware.d.ts +0 -12
  135. package/dist/core/http/request.d.ts +0 -35
  136. package/dist/core/http/response.d.ts +0 -17
  137. package/dist/core/http/router.d.ts +0 -28
  138. package/dist/core/http/utils.d.ts +0 -0
  139. package/dist/core/id-generator.d.ts +0 -3
  140. package/dist/core/logger.d.ts +0 -29
  141. package/dist/core/router.d.ts +0 -16
  142. package/dist/core/server.d.ts +0 -25
  143. package/dist/core/storage.d.ts +0 -24
  144. package/dist/index.d.ts +0 -1
  145. package/dist/listeners/api/__tests__/api.controller.test.d.ts +0 -1
  146. package/dist/listeners/api/__tests__/api.extractor.test.d.ts +0 -1
  147. package/dist/listeners/api/__tests__/api.listener.test.d.ts +0 -1
  148. package/dist/listeners/api/__tests__/api.routes.test.d.ts +0 -1
  149. package/dist/listeners/api/__tests__/api.sse.test.d.ts +0 -1
  150. package/dist/listeners/api/api.controllers.d.ts +0 -9
  151. package/dist/listeners/api/api.extractor.d.ts +0 -5
  152. package/dist/listeners/api/api.listener.d.ts +0 -17
  153. package/dist/listeners/api/api.routes.d.ts +0 -5
  154. package/dist/listeners/api/api.sse.d.ts +0 -10
  155. package/dist/listeners/dns/__tests__/dns.test.d.ts +0 -1
  156. package/dist/listeners/dns/dns.extractor.d.ts +0 -8
  157. package/dist/listeners/dns/dns.listener.d.ts +0 -15
  158. package/dist/listeners/http/__tests__/http.extractor.test.d.ts +0 -1
  159. package/dist/listeners/http/__tests__/http.listener.test.d.ts +0 -1
  160. package/dist/listeners/http/http.extractor.d.ts +0 -11
  161. package/dist/listeners/http/http.listener.d.ts +0 -17
  162. package/dist/listeners/listener.interface.d.ts +0 -4
  163. package/dist/listeners/smtp/__tests__/smtp.extractor.test.d.ts +0 -1
  164. package/dist/listeners/smtp/__tests__/smtp.listener.test.d.ts +0 -1
  165. package/dist/listeners/smtp/smtp.extractor.d.ts +0 -12
  166. package/dist/listeners/smtp/smtp.listener.d.ts +0 -13
  167. package/dist/listeners/ssrf/__tests__/ssrf.extractor.test.d.ts +0 -1
  168. package/dist/listeners/ssrf/__tests__/ssrf.listener.test.d.ts +0 -1
  169. package/dist/listeners/ssrf/ssrf.extractor.d.ts +0 -10
  170. package/dist/listeners/ssrf/ssrf.listener.d.ts +0 -8
  171. package/dist/listeners/tcp/tcp.extractor.d.ts +0 -4
  172. package/dist/listeners/tcp/tcp.listener.d.ts +0 -18
  173. package/dist/listeners/webhook/__tests__/webhook.extractor.test.d.ts +0 -1
  174. package/dist/listeners/webhook/__tests__/webhook.listener.test.d.ts +0 -1
  175. package/dist/listeners/webhook/webhook.extractor.d.ts +0 -8
  176. package/dist/listeners/webhook/webhook.listener.d.ts +0 -8
  177. package/dist/listeners/websocket/__tests__/websocket.extractor.test.d.ts +0 -1
  178. package/dist/listeners/websocket/__tests__/websocket.listener.test.d.ts +0 -1
  179. package/dist/listeners/websocket/websocket.extractor.d.ts +0 -10
  180. package/dist/listeners/websocket/websocket.listener.d.ts +0 -8
  181. package/dist/storage-adapters/adapters/__tests__/memory.storage.test.d.ts +0 -1
  182. package/dist/storage-adapters/adapters/memory.storage.d.ts +0 -21
  183. package/dist/storage-adapters/adapters/redis.storage.d.ts +0 -0
  184. package/dist/storage-adapters/adapters/sqlite.storage.d.ts +0 -0
  185. package/dist/storage-adapters/storage.interface.d.ts +0 -18
  186. package/dist/types/event.types.d.ts +0 -118
  187. package/dist/utils/token.d.ts +0 -0
@@ -1,35 +1,35 @@
1
- import { describe, it, expect } from "@jest/globals";
2
- import { WebhookExtractor } from "../webhook.extractor";
3
-
4
- describe("WebhookExtractor", () => {
5
- it("extrait correctement toutes les données", () => {
6
- const req: any = {
7
- ip: "1.2.3.4",
8
- headers: { "x-test": "ok" },
9
- };
10
-
11
- const body = { hello: "world" };
12
-
13
- const extracted = WebhookExtractor.extract(req, body);
14
-
15
- expect(extracted).toEqual({
16
- ip: "1.2.3.4",
17
- headers: { "x-test": "ok" },
18
- body,
19
- raw: req,
20
- });
21
- });
22
-
23
- it("retourne une structure complète même si des champs manquent", () => {
24
- const req: any = {};
25
-
26
- const extracted = WebhookExtractor.extract(req, null);
27
-
28
- expect(extracted).toEqual({
29
- ip: "",
30
- headers: {},
31
- body: null,
32
- raw: req,
33
- });
34
- });
35
- });
1
+ import { describe, it, expect } from "@jest/globals";
2
+ import { WebhookExtractor } from "../webhook.extractor";
3
+
4
+ describe("WebhookExtractor", () => {
5
+ it("extrait correctement toutes les données", () => {
6
+ const req: any = {
7
+ ip: "1.2.3.4",
8
+ headers: { "x-test": "ok" },
9
+ };
10
+
11
+ const body = { hello: "world" };
12
+
13
+ const extracted = WebhookExtractor.extract(req, body);
14
+
15
+ expect(extracted).toEqual({
16
+ ip: "1.2.3.4",
17
+ headers: { "x-test": "ok" },
18
+ body,
19
+ raw: req,
20
+ });
21
+ });
22
+
23
+ it("retourne une structure complète même si des champs manquent", () => {
24
+ const req: any = {};
25
+
26
+ const extracted = WebhookExtractor.extract(req, null);
27
+
28
+ expect(extracted).toEqual({
29
+ ip: "",
30
+ headers: {},
31
+ body: null,
32
+ raw: req,
33
+ });
34
+ });
35
+ });
@@ -1,122 +1,122 @@
1
- import {
2
- describe,
3
- it,
4
- expect,
5
- jest,
6
- beforeEach,
7
- afterEach,
8
- } from "@jest/globals";
9
-
10
- import http from "http";
11
- import { WebhookListener } from "../webhook.listener";
12
- import { WebhookExtractor } from "../webhook.extractor";
13
- import { EventNormalizer } from "../../../core/event.normalizer";
14
-
15
- jest.mock("../webhook.extractor");
16
- jest.mock("../../../core/event.normalizer");
17
-
18
- describe("WebhookListener", () => {
19
- let router: any;
20
- let port: number;
21
- let listener: WebhookListener;
22
-
23
- beforeEach(() => {
24
- router = {
25
- dispatch: jest.fn(),
26
- };
27
-
28
- port = 13000 + Math.floor(Math.random() * 2000);
29
-
30
- (WebhookExtractor.extract as jest.Mock).mockReturnValue({
31
- ip: "1.2.3.4",
32
- headers: { "x-test": "ok" },
33
- body: { hello: "world" },
34
- raw: {},
35
- });
36
-
37
- (EventNormalizer.normalizeWebhook as jest.Mock).mockReturnValue({
38
- id: "abc",
39
- type: "webhook",
40
- timestamp: 111,
41
- sourceIp: "1.2.3.4",
42
- headers: { "x-test": "ok" },
43
- body: { hello: "world" },
44
- });
45
-
46
- listener = new WebhookListener(router, port);
47
- });
48
-
49
- afterEach(() => {
50
- listener.stop();
51
- });
52
-
53
- it("appelle router.dispatch avec l'événement normalisé", async () => {
54
- await new Promise<void>((resolve) => {
55
- const req = http.request(
56
- {
57
- hostname: "localhost",
58
- port,
59
- path: "/",
60
- method: "POST",
61
- headers: { "content-type": "application/json" },
62
- },
63
- (res) => {
64
- expect(res.statusCode).toBe(200);
65
- expect(router.dispatch).toHaveBeenCalledTimes(1);
66
- expect(router.dispatch).toHaveBeenCalledWith({
67
- id: "abc",
68
- type: "webhook",
69
- timestamp: 111,
70
- sourceIp: "1.2.3.4",
71
- headers: { "x-test": "ok" },
72
- body: { hello: "world" },
73
- });
74
- resolve();
75
- },
76
- );
77
-
78
- req.write(JSON.stringify({ hello: "world" }));
79
- req.end();
80
- });
81
- });
82
-
83
- it("retourne 500 si router.dispatch échoue", async () => {
84
- router.dispatch.mockRejectedValue(new Error("fail"));
85
-
86
- await new Promise<void>((resolve) => {
87
- const req = http.request(
88
- {
89
- hostname: "localhost",
90
- port,
91
- path: "/",
92
- method: "POST",
93
- },
94
- (res) => {
95
- expect(res.statusCode).toBe(500);
96
- resolve();
97
- },
98
- );
99
-
100
- req.write("{}");
101
- req.end();
102
- });
103
- });
104
-
105
- it("retourne 405 si la méthode n'est pas POST", async () => {
106
- await new Promise<void>((resolve) => {
107
- const req = http.request(
108
- {
109
- hostname: "localhost",
110
- port,
111
- path: "/",
112
- method: "GET",
113
- },
114
- (res) => {
115
- expect(res.statusCode).toBe(405);
116
- resolve();
117
- },
118
- );
119
- req.end();
120
- });
121
- });
122
- });
1
+ import {
2
+ describe,
3
+ it,
4
+ expect,
5
+ jest,
6
+ beforeEach,
7
+ afterEach,
8
+ } from "@jest/globals";
9
+
10
+ import http from "http";
11
+ import { WebhookListener } from "../webhook.listener";
12
+ import { WebhookExtractor } from "../webhook.extractor";
13
+ import { EventNormalizer } from "../../../core/event.normalizer";
14
+
15
+ jest.mock("../webhook.extractor");
16
+ jest.mock("../../../core/event.normalizer");
17
+
18
+ describe("WebhookListener", () => {
19
+ let router: any;
20
+ let port: number;
21
+ let listener: WebhookListener;
22
+
23
+ beforeEach(() => {
24
+ router = {
25
+ dispatch: jest.fn(),
26
+ };
27
+
28
+ port = 13000 + Math.floor(Math.random() * 2000);
29
+
30
+ (WebhookExtractor.extract as jest.Mock).mockReturnValue({
31
+ ip: "1.2.3.4",
32
+ headers: { "x-test": "ok" },
33
+ body: { hello: "world" },
34
+ raw: {},
35
+ });
36
+
37
+ (EventNormalizer.normalizeWebhook as jest.Mock).mockReturnValue({
38
+ id: "abc",
39
+ type: "webhook",
40
+ timestamp: 111,
41
+ sourceIp: "1.2.3.4",
42
+ headers: { "x-test": "ok" },
43
+ body: { hello: "world" },
44
+ });
45
+
46
+ listener = new WebhookListener(router, port);
47
+ });
48
+
49
+ afterEach(() => {
50
+ listener.stop();
51
+ });
52
+
53
+ it("appelle router.dispatch avec l'événement normalisé", async () => {
54
+ await new Promise<void>((resolve) => {
55
+ const req = http.request(
56
+ {
57
+ hostname: "localhost",
58
+ port,
59
+ path: "/",
60
+ method: "POST",
61
+ headers: { "content-type": "application/json" },
62
+ },
63
+ (res) => {
64
+ expect(res.statusCode).toBe(200);
65
+ expect(router.dispatch).toHaveBeenCalledTimes(1);
66
+ expect(router.dispatch).toHaveBeenCalledWith({
67
+ id: "abc",
68
+ type: "webhook",
69
+ timestamp: 111,
70
+ sourceIp: "1.2.3.4",
71
+ headers: { "x-test": "ok" },
72
+ body: { hello: "world" },
73
+ });
74
+ resolve();
75
+ },
76
+ );
77
+
78
+ req.write(JSON.stringify({ hello: "world" }));
79
+ req.end();
80
+ });
81
+ });
82
+
83
+ it("retourne 500 si router.dispatch échoue", async () => {
84
+ router.dispatch.mockRejectedValue(new Error("fail"));
85
+
86
+ await new Promise<void>((resolve) => {
87
+ const req = http.request(
88
+ {
89
+ hostname: "localhost",
90
+ port,
91
+ path: "/",
92
+ method: "POST",
93
+ },
94
+ (res) => {
95
+ expect(res.statusCode).toBe(500);
96
+ resolve();
97
+ },
98
+ );
99
+
100
+ req.write("{}");
101
+ req.end();
102
+ });
103
+ });
104
+
105
+ it("retourne 405 si la méthode n'est pas POST", async () => {
106
+ await new Promise<void>((resolve) => {
107
+ const req = http.request(
108
+ {
109
+ hostname: "localhost",
110
+ port,
111
+ path: "/",
112
+ method: "GET",
113
+ },
114
+ (res) => {
115
+ expect(res.statusCode).toBe(405);
116
+ resolve();
117
+ },
118
+ );
119
+ req.end();
120
+ });
121
+ });
122
+ });
@@ -1,12 +1,12 @@
1
- export class WebhookExtractor {
2
- static extract(req: any, body: any) {
3
- const headers = req.headers ?? {};
4
-
5
- return {
6
- ip: req.ip ?? headers["x-forwarded-for"] ?? "",
7
- headers,
8
- body,
9
- raw: req,
10
- };
11
- }
12
- }
1
+ export class WebhookExtractor {
2
+ static extract(req: any, body: any) {
3
+ const headers = req.headers ?? {};
4
+
5
+ return {
6
+ ip: req.ip ?? headers["x-forwarded-for"] ?? "",
7
+ headers,
8
+ body,
9
+ raw: req,
10
+ };
11
+ }
12
+ }
@@ -1,58 +1,58 @@
1
- import http from "http";
2
- import { CoreRouter } from "../../core/router";
3
- import { WebhookExtractor } from "./webhook.extractor";
4
- import { EventNormalizer } from "../../core/event.normalizer";
5
- import { Logger } from "../../core/logger";
6
-
7
- export class WebhookListener {
8
- private router: CoreRouter;
9
- private server: http.Server;
10
- private logger: Logger;
11
-
12
- constructor(router: CoreRouter, port: number) {
13
- this.router = router;
14
- this.logger = new Logger({ context: "WebhookListener" });
15
-
16
- this.server = http.createServer(async (req, res) => {
17
- if (req.method !== "POST") {
18
- res.writeHead(405);
19
- return res.end("Method Not Allowed");
20
- }
21
-
22
- let chunks: Buffer[] = [];
23
-
24
- req.on("data", (chunk) => chunks.push(chunk));
25
-
26
- req.on("end", async () => {
27
- try {
28
- const bodyRaw = Buffer.concat(chunks).toString();
29
- let body: any = null;
30
-
31
- try {
32
- body = JSON.parse(bodyRaw);
33
- } catch {
34
- body = bodyRaw;
35
- }
36
-
37
- const extracted = WebhookExtractor.extract(req, body);
38
- const event = EventNormalizer.normalizeWebhook(extracted);
39
-
40
- await this.router.dispatch(event);
41
-
42
- res.writeHead(200);
43
- res.end("OK");
44
- } catch (err) {
45
- res.writeHead(500);
46
- res.end("ERROR");
47
- }
48
- });
49
- });
50
-
51
- this.server.listen(port);
52
- }
53
-
54
- stop() {
55
- this.server.close();
56
- this.logger.info("Webhook Listener stopped");
57
- }
58
- }
1
+ import http from "http";
2
+ import { CoreRouter } from "../../core/router";
3
+ import { WebhookExtractor } from "./webhook.extractor";
4
+ import { EventNormalizer } from "../../core/event.normalizer";
5
+ import { Logger } from "../../core/logger";
6
+
7
+ export class WebhookListener {
8
+ private router: CoreRouter;
9
+ private server: http.Server;
10
+ private logger: Logger;
11
+
12
+ constructor(router: CoreRouter, port: number) {
13
+ this.router = router;
14
+ this.logger = new Logger({ context: "WebhookListener" });
15
+
16
+ this.server = http.createServer(async (req, res) => {
17
+ if (req.method !== "POST") {
18
+ res.writeHead(405);
19
+ return res.end("Method Not Allowed");
20
+ }
21
+
22
+ let chunks: Buffer[] = [];
23
+
24
+ req.on("data", (chunk) => chunks.push(chunk));
25
+
26
+ req.on("end", async () => {
27
+ try {
28
+ const bodyRaw = Buffer.concat(chunks).toString();
29
+ let body: any = null;
30
+
31
+ try {
32
+ body = JSON.parse(bodyRaw);
33
+ } catch {
34
+ body = bodyRaw;
35
+ }
36
+
37
+ const extracted = WebhookExtractor.extract(req, body);
38
+ const event = EventNormalizer.normalizeWebhook(extracted);
39
+
40
+ await this.router.dispatch(event);
41
+
42
+ res.writeHead(200);
43
+ res.end("OK");
44
+ } catch (err) {
45
+ res.writeHead(500);
46
+ res.end("ERROR");
47
+ }
48
+ });
49
+ });
50
+
51
+ this.server.listen(port);
52
+ }
53
+
54
+ stop() {
55
+ this.server.close();
56
+ this.logger.info("Webhook Listener stopped");
57
+ }
58
+ }
@@ -1,33 +1,33 @@
1
- import { describe, it, expect } from "@jest/globals";
2
- import { WebSocketExtractor } from "../websocket.extractor";
3
-
4
- describe("WebSocketExtractor", () => {
5
- it("extrait correctement les données", () => {
6
- const ws: any = {};
7
- const req: any = {
8
- socket: { remoteAddress: "1.2.3.4" },
9
- headers: { host: "example.com" },
10
- };
11
-
12
- const extracted = WebSocketExtractor.extract(ws, req, "hello");
13
-
14
- expect(extracted).toEqual({
15
- ip: "1.2.3.4",
16
- message: "hello",
17
- raw: { ws, req },
18
- });
19
- });
20
-
21
- it("retourne une structure complète même si des champs manquent", () => {
22
- const ws: any = {};
23
- const req: any = {};
24
-
25
- const extracted = WebSocketExtractor.extract(ws, req, "test");
26
-
27
- expect(extracted).toEqual({
28
- ip: "",
29
- message: "test",
30
- raw: { ws, req },
31
- });
32
- });
33
- });
1
+ import { describe, it, expect } from "@jest/globals";
2
+ import { WebSocketExtractor } from "../websocket.extractor";
3
+
4
+ describe("WebSocketExtractor", () => {
5
+ it("extrait correctement les données", () => {
6
+ const ws: any = {};
7
+ const req: any = {
8
+ socket: { remoteAddress: "1.2.3.4" },
9
+ headers: { host: "example.com" },
10
+ };
11
+
12
+ const extracted = WebSocketExtractor.extract(ws, req, "hello");
13
+
14
+ expect(extracted).toEqual({
15
+ ip: "1.2.3.4",
16
+ message: "hello",
17
+ raw: { ws, req },
18
+ });
19
+ });
20
+
21
+ it("retourne une structure complète même si des champs manquent", () => {
22
+ const ws: any = {};
23
+ const req: any = {};
24
+
25
+ const extracted = WebSocketExtractor.extract(ws, req, "test");
26
+
27
+ expect(extracted).toEqual({
28
+ ip: "",
29
+ message: "test",
30
+ raw: { ws, req },
31
+ });
32
+ });
33
+ });