@j3r3mcdev/oast-server 1.1.7 → 1.1.8

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 (95) 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/core/router.d.ts +1 -0
  5. package/dist/core/router.js +3 -3
  6. package/jest.config.js +14 -14
  7. package/package.json +45 -45
  8. package/sadmin list shadows +9 -9
  9. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  10. package/src/api/controllers/events.controller.ts +10 -10
  11. package/src/api/controllers/health.controller.ts +7 -7
  12. package/src/api/controllers/tasks.controller.ts +41 -41
  13. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  14. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  15. package/src/api/dto/create-task.dto.ts +33 -33
  16. package/src/api/dto/filter-tasks.dto.ts +33 -33
  17. package/src/api/services/__tests__/events.service.test.ts +41 -41
  18. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  19. package/src/api/services/events.service.ts +17 -17
  20. package/src/api/services/tasks.service.ts +79 -79
  21. package/src/api/sse/events.stream.ts +90 -90
  22. package/src/bootstrap.ts +89 -89
  23. package/src/core/__tests__/core-router.test.ts +30 -30
  24. package/src/core/__tests__/core-server.test.ts +44 -44
  25. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  26. package/src/core/__tests__/event.router.test.ts +89 -89
  27. package/src/core/__tests__/logger.test.ts +32 -32
  28. package/src/core/__tests__/storage-manager.test.ts +74 -74
  29. package/src/core/event.normalizer.ts +147 -147
  30. package/src/core/event.router.ts +13 -13
  31. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  32. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  33. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  34. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  35. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  36. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  37. package/src/core/http/__tests__/request.test.ts +34 -34
  38. package/src/core/http/__tests__/response.test.ts +35 -35
  39. package/src/core/http/__tests__/router-match.test.ts +171 -171
  40. package/src/core/http/adapter-node.ts +51 -51
  41. package/src/core/http/buildRequest.ts +18 -18
  42. package/src/core/http/compile-path.ts +32 -32
  43. package/src/core/http/errors.ts +37 -37
  44. package/src/core/http/http-server.ts +52 -52
  45. package/src/core/http/middleware.ts +160 -160
  46. package/src/core/http/request.ts +55 -55
  47. package/src/core/http/response.ts +93 -93
  48. package/src/core/http/router.ts +138 -138
  49. package/src/core/id-generator.ts +8 -8
  50. package/src/core/logger.ts +113 -113
  51. package/src/core/router.ts +44 -44
  52. package/src/core/server.ts +85 -85
  53. package/src/core/storage.ts +64 -64
  54. package/src/index.ts +14 -14
  55. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  56. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  57. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  58. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  59. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  60. package/src/listeners/api/api.controllers.ts +67 -67
  61. package/src/listeners/api/api.extractor.ts +43 -43
  62. package/src/listeners/api/api.listener.ts +50 -50
  63. package/src/listeners/api/api.routes.ts +76 -76
  64. package/src/listeners/api/api.sse.ts +38 -38
  65. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  66. package/src/listeners/dns/dns.extractor.ts +14 -14
  67. package/src/listeners/dns/dns.listener.ts +61 -61
  68. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  69. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  70. package/src/listeners/http/http.extractor.ts +15 -15
  71. package/src/listeners/http/http.listener.ts +110 -110
  72. package/src/listeners/listener.interface.ts +4 -4
  73. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  74. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  75. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  76. package/src/listeners/smtp/smtp.listener.ts +60 -60
  77. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  78. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  79. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  80. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  81. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  82. package/src/listeners/tcp/tcp.listener.ts +61 -61
  83. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  84. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  85. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  86. package/src/listeners/webhook/webhook.listener.ts +58 -58
  87. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  88. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  89. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  90. package/src/listeners/websocket/websocket.listener.ts +40 -40
  91. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  92. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  93. package/src/storage-adapters/storage.interface.ts +26 -26
  94. package/src/types/event.types.ts +147 -147
  95. package/tsconfig.json +20 -20
@@ -1,69 +1,69 @@
1
- import { describe, it, expect } from "@jest/globals";
2
- import { SmtpExtractor } from "../smtp.extractor";
3
-
4
- describe("SmtpExtractor", () => {
5
- it("extrait correctement un RawSmtpEvent valide", () => {
6
- const session = {
7
- remoteAddress: "1.2.3.4",
8
- envelope: {
9
- mailFrom: { address: "attacker@example.com" },
10
- rcptTo: [{ address: "victim@example.com" }],
11
- },
12
- headers: { subject: "Hello World" },
13
- };
14
-
15
- const body = "This is the email body";
16
-
17
- const result = SmtpExtractor.extract(session, body);
18
-
19
- expect(result).toEqual({
20
- ip: "1.2.3.4",
21
- from: "attacker@example.com",
22
- to: "victim@example.com",
23
- subject: "Hello World",
24
- raw: {
25
- session,
26
- body,
27
- },
28
- });
29
- });
30
-
31
- it("gère les champs manquants proprement", () => {
32
- const session = {
33
- remoteAddress: undefined,
34
- envelope: {
35
- mailFrom: {},
36
- rcptTo: [{}],
37
- },
38
- headers: {},
39
- };
40
-
41
- const result = SmtpExtractor.extract(session, "");
42
-
43
- expect(result).toEqual({
44
- ip: "",
45
- from: "",
46
- to: "",
47
- subject: "",
48
- raw: {
49
- session,
50
- body: "",
51
- },
52
- });
53
- });
54
-
55
- it("ne plante pas si session est vide", () => {
56
- const result = SmtpExtractor.extract({}, "BODY");
57
-
58
- expect(result).toEqual({
59
- ip: "",
60
- from: "",
61
- to: "",
62
- subject: "",
63
- raw: {
64
- session: {},
65
- body: "BODY",
66
- },
67
- });
68
- });
69
- });
1
+ import { describe, it, expect } from "@jest/globals";
2
+ import { SmtpExtractor } from "../smtp.extractor";
3
+
4
+ describe("SmtpExtractor", () => {
5
+ it("extrait correctement un RawSmtpEvent valide", () => {
6
+ const session = {
7
+ remoteAddress: "1.2.3.4",
8
+ envelope: {
9
+ mailFrom: { address: "attacker@example.com" },
10
+ rcptTo: [{ address: "victim@example.com" }],
11
+ },
12
+ headers: { subject: "Hello World" },
13
+ };
14
+
15
+ const body = "This is the email body";
16
+
17
+ const result = SmtpExtractor.extract(session, body);
18
+
19
+ expect(result).toEqual({
20
+ ip: "1.2.3.4",
21
+ from: "attacker@example.com",
22
+ to: "victim@example.com",
23
+ subject: "Hello World",
24
+ raw: {
25
+ session,
26
+ body,
27
+ },
28
+ });
29
+ });
30
+
31
+ it("gère les champs manquants proprement", () => {
32
+ const session = {
33
+ remoteAddress: undefined,
34
+ envelope: {
35
+ mailFrom: {},
36
+ rcptTo: [{}],
37
+ },
38
+ headers: {},
39
+ };
40
+
41
+ const result = SmtpExtractor.extract(session, "");
42
+
43
+ expect(result).toEqual({
44
+ ip: "",
45
+ from: "",
46
+ to: "",
47
+ subject: "",
48
+ raw: {
49
+ session,
50
+ body: "",
51
+ },
52
+ });
53
+ });
54
+
55
+ it("ne plante pas si session est vide", () => {
56
+ const result = SmtpExtractor.extract({}, "BODY");
57
+
58
+ expect(result).toEqual({
59
+ ip: "",
60
+ from: "",
61
+ to: "",
62
+ subject: "",
63
+ raw: {
64
+ session: {},
65
+ body: "BODY",
66
+ },
67
+ });
68
+ });
69
+ });
@@ -1,150 +1,150 @@
1
- import { describe, it, expect, jest, beforeEach } from "@jest/globals";
2
- import { SmtpListener } from "../smtp.listener";
3
- import { EventNormalizer } from "../../../core/event.normalizer";
4
- import { CoreRouter } from "../../../core/router";
5
-
6
- // Mock EventNormalizer
7
- jest.mock("../../../core/event.normalizer", () => ({
8
- EventNormalizer: {
9
- normalizeSmtp: jest.fn(),
10
- },
11
- }));
12
-
13
- describe("SmtpListener", () => {
14
- let router: CoreRouter;
15
- let server: any;
16
- let listener: SmtpListener;
17
-
18
- beforeEach(() => {
19
- router = {
20
- dispatch: jest.fn(async (_event: any) => {}),
21
- } as any;
22
-
23
- server = {
24
- onData: null,
25
- close: jest.fn(),
26
- };
27
-
28
- listener = new SmtpListener(router, { server });
29
- });
30
-
31
- it("traite un email SMTP valide et appelle dispatch", async () => {
32
- const callback = jest.fn();
33
-
34
- // NormalizedSmtpEvent VALIDE
35
- (EventNormalizer.normalizeSmtp as jest.Mock).mockReturnValue({
36
- id: "smtp-123",
37
- type: "smtp",
38
- timestamp: Date.now(),
39
- ip: "1.2.3.4",
40
- from: "attacker@example.com",
41
- to: ["victim@example.com"],
42
- subject: "Test Email",
43
- body: "Hello world",
44
- raw: {},
45
- });
46
-
47
- await listener.start();
48
-
49
- const stream = {
50
- on: jest.fn((event: string, handler: (chunk?: any) => void) => {
51
- if (event === "data") handler("Hello world");
52
- if (event === "end") handler();
53
- }),
54
- };
55
-
56
- const session = {
57
- remoteAddress: "1.2.3.4",
58
- envelope: {
59
- mailFrom: { address: "attacker@example.com" },
60
- rcptTo: [{ address: "victim@example.com" }],
61
- },
62
- headers: { subject: "Test Email" },
63
- };
64
-
65
- await server.onData(stream, session, callback);
66
-
67
- expect(EventNormalizer.normalizeSmtp).toHaveBeenCalled();
68
- expect(router.dispatch).toHaveBeenCalled();
69
- expect(callback).toHaveBeenCalledWith(null);
70
- });
71
-
72
- it("renvoie une erreur si normalizeSmtp échoue", async () => {
73
- const callback = jest.fn();
74
-
75
- (EventNormalizer.normalizeSmtp as jest.Mock).mockImplementation(() => {
76
- throw new Error("bad smtp");
77
- });
78
-
79
- await listener.start();
80
-
81
- const stream = {
82
- on: jest.fn((event: string, handler: (chunk?: any) => void) => {
83
- if (event === "data") handler("DATA");
84
- if (event === "end") handler();
85
- }),
86
- };
87
-
88
- const session = {
89
- remoteAddress: "1.2.3.4",
90
- envelope: {
91
- mailFrom: { address: "a@b.com" },
92
- rcptTo: [{ address: "c@d.com" }],
93
- },
94
- headers: { subject: "X" },
95
- };
96
-
97
- await server.onData(stream, session, callback);
98
-
99
- expect(callback).toHaveBeenCalledWith(new Error("bad smtp"));
100
- });
101
-
102
- it("renvoie une erreur si router.dispatch échoue", async () => {
103
- const callback = jest.fn();
104
-
105
- (EventNormalizer.normalizeSmtp as jest.Mock).mockReturnValue({
106
- id: "smtp-999",
107
- type: "smtp",
108
- timestamp: Date.now(),
109
- ip: "1.2.3.4",
110
- from: "a@b.com",
111
- to: ["c@d.com"],
112
- subject: "X",
113
- body: "DATA",
114
- raw: {},
115
- });
116
-
117
- listener["router"] = {
118
- dispatch: jest.fn(async () => {
119
- throw new Error("dispatch failed");
120
- }),
121
- } as any;
122
-
123
- await listener.start();
124
-
125
- const stream = {
126
- on: jest.fn((event: string, handler: (chunk?: any) => void) => {
127
- if (event === "data") handler("DATA");
128
- if (event === "end") handler();
129
- }),
130
- };
131
-
132
- const session = {
133
- remoteAddress: "1.2.3.4",
134
- envelope: {
135
- mailFrom: { address: "a@b.com" },
136
- rcptTo: [{ address: "c@d.com" }],
137
- },
138
- headers: { subject: "X" },
139
- };
140
-
141
- await server.onData(stream, session, callback);
142
-
143
- expect(callback).toHaveBeenCalledWith(new Error("dispatch failed"));
144
- });
145
-
146
- it("stop() appelle server.close si disponible", async () => {
147
- await listener.stop();
148
- expect(server.close).toHaveBeenCalled();
149
- });
150
- });
1
+ import { describe, it, expect, jest, beforeEach } from "@jest/globals";
2
+ import { SmtpListener } from "../smtp.listener";
3
+ import { EventNormalizer } from "../../../core/event.normalizer";
4
+ import { CoreRouter } from "../../../core/router";
5
+
6
+ // Mock EventNormalizer
7
+ jest.mock("../../../core/event.normalizer", () => ({
8
+ EventNormalizer: {
9
+ normalizeSmtp: jest.fn(),
10
+ },
11
+ }));
12
+
13
+ describe("SmtpListener", () => {
14
+ let router: CoreRouter;
15
+ let server: any;
16
+ let listener: SmtpListener;
17
+
18
+ beforeEach(() => {
19
+ router = {
20
+ dispatch: jest.fn(async (_event: any) => {}),
21
+ } as any;
22
+
23
+ server = {
24
+ onData: null,
25
+ close: jest.fn(),
26
+ };
27
+
28
+ listener = new SmtpListener(router, { server });
29
+ });
30
+
31
+ it("traite un email SMTP valide et appelle dispatch", async () => {
32
+ const callback = jest.fn();
33
+
34
+ // NormalizedSmtpEvent VALIDE
35
+ (EventNormalizer.normalizeSmtp as jest.Mock).mockReturnValue({
36
+ id: "smtp-123",
37
+ type: "smtp",
38
+ timestamp: Date.now(),
39
+ ip: "1.2.3.4",
40
+ from: "attacker@example.com",
41
+ to: ["victim@example.com"],
42
+ subject: "Test Email",
43
+ body: "Hello world",
44
+ raw: {},
45
+ });
46
+
47
+ await listener.start();
48
+
49
+ const stream = {
50
+ on: jest.fn((event: string, handler: (chunk?: any) => void) => {
51
+ if (event === "data") handler("Hello world");
52
+ if (event === "end") handler();
53
+ }),
54
+ };
55
+
56
+ const session = {
57
+ remoteAddress: "1.2.3.4",
58
+ envelope: {
59
+ mailFrom: { address: "attacker@example.com" },
60
+ rcptTo: [{ address: "victim@example.com" }],
61
+ },
62
+ headers: { subject: "Test Email" },
63
+ };
64
+
65
+ await server.onData(stream, session, callback);
66
+
67
+ expect(EventNormalizer.normalizeSmtp).toHaveBeenCalled();
68
+ expect(router.dispatch).toHaveBeenCalled();
69
+ expect(callback).toHaveBeenCalledWith(null);
70
+ });
71
+
72
+ it("renvoie une erreur si normalizeSmtp échoue", async () => {
73
+ const callback = jest.fn();
74
+
75
+ (EventNormalizer.normalizeSmtp as jest.Mock).mockImplementation(() => {
76
+ throw new Error("bad smtp");
77
+ });
78
+
79
+ await listener.start();
80
+
81
+ const stream = {
82
+ on: jest.fn((event: string, handler: (chunk?: any) => void) => {
83
+ if (event === "data") handler("DATA");
84
+ if (event === "end") handler();
85
+ }),
86
+ };
87
+
88
+ const session = {
89
+ remoteAddress: "1.2.3.4",
90
+ envelope: {
91
+ mailFrom: { address: "a@b.com" },
92
+ rcptTo: [{ address: "c@d.com" }],
93
+ },
94
+ headers: { subject: "X" },
95
+ };
96
+
97
+ await server.onData(stream, session, callback);
98
+
99
+ expect(callback).toHaveBeenCalledWith(new Error("bad smtp"));
100
+ });
101
+
102
+ it("renvoie une erreur si router.dispatch échoue", async () => {
103
+ const callback = jest.fn();
104
+
105
+ (EventNormalizer.normalizeSmtp as jest.Mock).mockReturnValue({
106
+ id: "smtp-999",
107
+ type: "smtp",
108
+ timestamp: Date.now(),
109
+ ip: "1.2.3.4",
110
+ from: "a@b.com",
111
+ to: ["c@d.com"],
112
+ subject: "X",
113
+ body: "DATA",
114
+ raw: {},
115
+ });
116
+
117
+ listener["router"] = {
118
+ dispatch: jest.fn(async () => {
119
+ throw new Error("dispatch failed");
120
+ }),
121
+ } as any;
122
+
123
+ await listener.start();
124
+
125
+ const stream = {
126
+ on: jest.fn((event: string, handler: (chunk?: any) => void) => {
127
+ if (event === "data") handler("DATA");
128
+ if (event === "end") handler();
129
+ }),
130
+ };
131
+
132
+ const session = {
133
+ remoteAddress: "1.2.3.4",
134
+ envelope: {
135
+ mailFrom: { address: "a@b.com" },
136
+ rcptTo: [{ address: "c@d.com" }],
137
+ },
138
+ headers: { subject: "X" },
139
+ };
140
+
141
+ await server.onData(stream, session, callback);
142
+
143
+ expect(callback).toHaveBeenCalledWith(new Error("dispatch failed"));
144
+ });
145
+
146
+ it("stop() appelle server.close si disponible", async () => {
147
+ await listener.stop();
148
+ expect(server.close).toHaveBeenCalled();
149
+ });
150
+ });
@@ -1,18 +1,18 @@
1
- export class SmtpExtractor {
2
- static extract(session: any, body: string) {
3
- const envelope = session?.envelope ?? {};
4
- const mailFrom = envelope.mailFrom ?? {};
5
- const rcptTo = Array.isArray(envelope.rcptTo) ? envelope.rcptTo : [];
6
-
7
- return {
8
- ip: session?.remoteAddress ?? "",
9
- from: mailFrom.address ?? "",
10
- to: rcptTo[0]?.address ?? "",
11
- subject: session?.headers?.subject ?? "",
12
- raw: {
13
- session,
14
- body,
15
- },
16
- };
17
- }
18
- }
1
+ export class SmtpExtractor {
2
+ static extract(session: any, body: string) {
3
+ const envelope = session?.envelope ?? {};
4
+ const mailFrom = envelope.mailFrom ?? {};
5
+ const rcptTo = Array.isArray(envelope.rcptTo) ? envelope.rcptTo : [];
6
+
7
+ return {
8
+ ip: session?.remoteAddress ?? "",
9
+ from: mailFrom.address ?? "",
10
+ to: rcptTo[0]?.address ?? "",
11
+ subject: session?.headers?.subject ?? "",
12
+ raw: {
13
+ session,
14
+ body,
15
+ },
16
+ };
17
+ }
18
+ }
@@ -1,60 +1,60 @@
1
- import { CoreRouter } from "../../core/router";
2
- import { EventNormalizer } from "../../core/event.normalizer";
3
- import { Logger } from "../../core/logger";
4
-
5
- export class SmtpListener {
6
- private router: CoreRouter;
7
- private server: any;
8
- private logger: Logger;
9
-
10
- constructor(router: CoreRouter, options: { server: any; logger?: Logger }) {
11
- this.router = router;
12
- this.server = options.server;
13
- this.logger = options.logger ?? new Logger({ context: "SmtpListener" });
14
- }
15
-
16
- async start() {
17
- this.logger.info("SMTP Listener started");
18
-
19
- this.server.onData = async (stream: any, session: any, callback: any) => {
20
- let chunks: string[] = [];
21
-
22
- stream.on("data", (chunk: any) => {
23
- chunks.push(chunk.toString());
24
- });
25
-
26
- stream.on("end", async () => {
27
- const body = chunks.join("");
28
-
29
- let event;
30
- try {
31
- event = EventNormalizer.normalizeSmtp({
32
- ip: session.remoteAddress,
33
- from: session.envelope.mailFrom.address,
34
- to: session.envelope.rcptTo.map((r: any) => r.address),
35
- subject: session.headers.subject,
36
- body,
37
- raw: session,
38
- });
39
- } catch (err: any) {
40
- callback(new Error(err.message));
41
- return;
42
- }
43
-
44
- try {
45
- await this.router.dispatch(event);
46
- callback(null);
47
- } catch (err) {
48
- callback(new Error("dispatch failed")); // ✔ EXACTEMENT ce que ton test attend
49
- }
50
- });
51
- };
52
- }
53
-
54
- async stop() {
55
- if (this.server?.close) {
56
- this.server.close();
57
- this.logger.info("SMTP Listener stopped");
58
- }
59
- }
60
- }
1
+ import { CoreRouter } from "../../core/router";
2
+ import { EventNormalizer } from "../../core/event.normalizer";
3
+ import { Logger } from "../../core/logger";
4
+
5
+ export class SmtpListener {
6
+ private router: CoreRouter;
7
+ private server: any;
8
+ private logger: Logger;
9
+
10
+ constructor(router: CoreRouter, options: { server: any; logger?: Logger }) {
11
+ this.router = router;
12
+ this.server = options.server;
13
+ this.logger = options.logger ?? new Logger({ context: "SmtpListener" });
14
+ }
15
+
16
+ async start() {
17
+ this.logger.info("SMTP Listener started");
18
+
19
+ this.server.onData = async (stream: any, session: any, callback: any) => {
20
+ let chunks: string[] = [];
21
+
22
+ stream.on("data", (chunk: any) => {
23
+ chunks.push(chunk.toString());
24
+ });
25
+
26
+ stream.on("end", async () => {
27
+ const body = chunks.join("");
28
+
29
+ let event;
30
+ try {
31
+ event = EventNormalizer.normalizeSmtp({
32
+ ip: session.remoteAddress,
33
+ from: session.envelope.mailFrom.address,
34
+ to: session.envelope.rcptTo.map((r: any) => r.address),
35
+ subject: session.headers.subject,
36
+ body,
37
+ raw: session,
38
+ });
39
+ } catch (err: any) {
40
+ callback(new Error(err.message));
41
+ return;
42
+ }
43
+
44
+ try {
45
+ await this.router.dispatch(event);
46
+ callback(null);
47
+ } catch (err) {
48
+ callback(new Error("dispatch failed")); // ✔ EXACTEMENT ce que ton test attend
49
+ }
50
+ });
51
+ };
52
+ }
53
+
54
+ async stop() {
55
+ if (this.server?.close) {
56
+ this.server.close();
57
+ this.logger.info("SMTP Listener stopped");
58
+ }
59
+ }
60
+ }
@@ -1,41 +1,41 @@
1
- import { SsrfExtractor } from "../ssrf.extractor";
2
- import { describe, it, expect } from "@jest/globals";
3
-
4
- describe("SsrfExtractor", () => {
5
- it("extrait correctement toutes les données", () => {
6
- const req: any = {
7
- ip: "1.2.3.4",
8
- method: "GET",
9
- path: "/test",
10
- headers: { host: "example.com" },
11
- query: { a: 1 },
12
- raw: { foo: "bar" },
13
- };
14
-
15
- const extracted = SsrfExtractor.extract(req);
16
-
17
- expect(extracted).toEqual({
18
- ip: "1.2.3.4",
19
- method: "GET",
20
- path: "/test",
21
- headers: { host: "example.com" },
22
- query: { a: 1 },
23
- raw: req,
24
- });
25
- });
26
-
27
- it("retourne une structure complète même si des champs manquent", () => {
28
- const req: any = {};
29
-
30
- const extracted = SsrfExtractor.extract(req);
31
-
32
- expect(extracted).toEqual({
33
- ip: "",
34
- method: undefined,
35
- path: undefined,
36
- headers: {},
37
- query: {},
38
- raw: req,
39
- });
40
- });
41
- });
1
+ import { SsrfExtractor } from "../ssrf.extractor";
2
+ import { describe, it, expect } from "@jest/globals";
3
+
4
+ describe("SsrfExtractor", () => {
5
+ it("extrait correctement toutes les données", () => {
6
+ const req: any = {
7
+ ip: "1.2.3.4",
8
+ method: "GET",
9
+ path: "/test",
10
+ headers: { host: "example.com" },
11
+ query: { a: 1 },
12
+ raw: { foo: "bar" },
13
+ };
14
+
15
+ const extracted = SsrfExtractor.extract(req);
16
+
17
+ expect(extracted).toEqual({
18
+ ip: "1.2.3.4",
19
+ method: "GET",
20
+ path: "/test",
21
+ headers: { host: "example.com" },
22
+ query: { a: 1 },
23
+ raw: req,
24
+ });
25
+ });
26
+
27
+ it("retourne une structure complète même si des champs manquent", () => {
28
+ const req: any = {};
29
+
30
+ const extracted = SsrfExtractor.extract(req);
31
+
32
+ expect(extracted).toEqual({
33
+ ip: "",
34
+ method: undefined,
35
+ path: undefined,
36
+ headers: {},
37
+ query: {},
38
+ raw: req,
39
+ });
40
+ });
41
+ });