@j3r3mcdev/oast-server 1.1.11 → 1.1.13

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.
@@ -1,4 +1,4 @@
1
- import { RawEvent, RawDnsEvent, RawSmtpEvent, RawTcpEvent, RawSsrfEvent, NormalizedHttpEvent, NormalizedDnsEvent, NormalizedSmtpEvent, NormalizedTcpEvent, NormalizedSsrfEvent, NormalizedWebhookEvent, RawWebhookEvent, NormalizedWebSocketEvent, RawWebSocketEvent } from "../types/event.types";
1
+ import { RawEvent, RawDnsEvent, RawSmtpEvent, RawTcpEvent, RawSsrfEvent, RawWebhookEvent, RawWebSocketEvent, RawApiEvent, NormalizedHttpEvent, NormalizedDnsEvent, NormalizedSmtpEvent, NormalizedTcpEvent, NormalizedSsrfEvent, NormalizedWebhookEvent, NormalizedWebSocketEvent, NormalizedApiEvent } from "../types/event.types";
2
2
  export declare class EventNormalizer {
3
3
  static normalizeDns(event: RawDnsEvent): NormalizedDnsEvent;
4
4
  static normalizeHttp(event: RawEvent): NormalizedHttpEvent;
@@ -7,4 +7,5 @@ export declare class EventNormalizer {
7
7
  static normalizeSsrf(raw: RawSsrfEvent): NormalizedSsrfEvent;
8
8
  static normalizeWebhook(raw: RawWebhookEvent): NormalizedWebhookEvent;
9
9
  static normalizeWebSocket(raw: RawWebSocketEvent): NormalizedWebSocketEvent;
10
+ static normalizeApi(raw: RawApiEvent): NormalizedApiEvent;
10
11
  }
@@ -95,7 +95,7 @@ class EventNormalizer {
95
95
  }
96
96
  //
97
97
  // -------------------------
98
- // webhook
98
+ // WEBHOOK
99
99
  // -------------------------
100
100
  //
101
101
  static normalizeWebhook(raw) {
@@ -110,7 +110,7 @@ class EventNormalizer {
110
110
  }
111
111
  //
112
112
  // -------------------------
113
- // websocket
113
+ // WEBSOCKET
114
114
  // -------------------------
115
115
  //
116
116
  static normalizeWebSocket(raw) {
@@ -122,5 +122,22 @@ class EventNormalizer {
122
122
  message: raw.message,
123
123
  };
124
124
  }
125
+ //
126
+ // -------------------------
127
+ // API (NOUVEAU)
128
+ // -------------------------
129
+ //
130
+ static normalizeApi(raw) {
131
+ return {
132
+ id: id_generator_1.IdGenerator.generate(),
133
+ type: "api",
134
+ timestamp: Date.now(),
135
+ sourceIp: raw.ip,
136
+ request: {
137
+ body: raw.body,
138
+ },
139
+ raw: raw.raw,
140
+ };
141
+ }
125
142
  }
126
143
  exports.EventNormalizer = EventNormalizer;
@@ -2,11 +2,41 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.handleApiRequest = handleApiRequest;
4
4
  const api_controllers_1 = require("./api.controllers");
5
+ const event_normalizer_1 = require("../../core/event.normalizer");
5
6
  async function handleApiRequest(req, res, storage, sse, logger) {
6
7
  try {
7
8
  const url = new URL(req.url ?? "", `http://${req.headers.host}`);
8
9
  const path = url.pathname;
9
10
  const method = req.method ?? "GET";
11
+ //
12
+ // ---------------------------
13
+ // POST / (API EVENT)
14
+ // ---------------------------
15
+ //
16
+ if (method === "POST" && path === "/") {
17
+ let body = "";
18
+ req.on("data", (chunk) => (body += chunk));
19
+ req.on("end", async () => {
20
+ try {
21
+ const parsed = JSON.parse(body);
22
+ const normalized = event_normalizer_1.EventNormalizer.normalizeApi({
23
+ ip: req.socket.remoteAddress ?? "",
24
+ body: parsed,
25
+ raw: parsed,
26
+ });
27
+ await storage.save(normalized);
28
+ res.writeHead(200, { "Content-Type": "application/json" });
29
+ res.end(JSON.stringify({ success: true }));
30
+ }
31
+ catch (err) {
32
+ logger.error("API POST error", err);
33
+ res.writeHead(400, { "Content-Type": "application/json" });
34
+ res.end(JSON.stringify({ success: false, error: err.message }));
35
+ }
36
+ });
37
+ return;
38
+ }
39
+ //
10
40
  // ---------------------------
11
41
  // SSE STREAM
12
42
  // ---------------------------
@@ -14,32 +44,28 @@ async function handleApiRequest(req, res, storage, sse, logger) {
14
44
  await sse.handle(res);
15
45
  return;
16
46
  }
47
+ //
17
48
  // ---------------------------
18
49
  // ROUTES REST
19
50
  // ---------------------------
20
- // GET /events
21
51
  if (method === "GET" && path === "/events") {
22
52
  await api_controllers_1.ApiController.listEvents(url, res, storage);
23
53
  return;
24
54
  }
25
- // GET /events/:id
26
55
  if (method === "GET" && path.startsWith("/events/")) {
27
56
  const id = path.split("/")[2];
28
57
  await api_controllers_1.ApiController.getEvent(id, res, storage);
29
58
  return;
30
59
  }
31
- // DELETE /events
32
60
  if (method === "DELETE" && path === "/events") {
33
61
  await api_controllers_1.ApiController.deleteAll(res, storage);
34
62
  return;
35
63
  }
36
- // DELETE /events/:id
37
64
  if (method === "DELETE" && path.startsWith("/events/")) {
38
65
  const id = path.split("/")[2];
39
66
  await api_controllers_1.ApiController.deleteOne(id, res, storage);
40
67
  return;
41
68
  }
42
- // GET /stats
43
69
  if (method === "GET" && path === "/stats") {
44
70
  await api_controllers_1.ApiController.stats(res, storage);
45
71
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j3r3mcdev/oast-server",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "description": "Modular OAST callback server for security auditing",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -4,15 +4,17 @@ import {
4
4
  RawSmtpEvent,
5
5
  RawTcpEvent,
6
6
  RawSsrfEvent,
7
+ RawWebhookEvent,
8
+ RawWebSocketEvent,
9
+ RawApiEvent,
7
10
  NormalizedHttpEvent,
8
11
  NormalizedDnsEvent,
9
12
  NormalizedSmtpEvent,
10
13
  NormalizedTcpEvent,
11
14
  NormalizedSsrfEvent,
12
15
  NormalizedWebhookEvent,
13
- RawWebhookEvent,
14
16
  NormalizedWebSocketEvent,
15
- RawWebSocketEvent,
17
+ NormalizedApiEvent,
16
18
  } from "../types/event.types";
17
19
 
18
20
  import { IdGenerator } from "./id-generator";
@@ -116,7 +118,7 @@ export class EventNormalizer {
116
118
 
117
119
  //
118
120
  // -------------------------
119
- // webhook
121
+ // WEBHOOK
120
122
  // -------------------------
121
123
  //
122
124
  static normalizeWebhook(raw: RawWebhookEvent): NormalizedWebhookEvent {
@@ -132,7 +134,7 @@ export class EventNormalizer {
132
134
 
133
135
  //
134
136
  // -------------------------
135
- // websocket
137
+ // WEBSOCKET
136
138
  // -------------------------
137
139
  //
138
140
  static normalizeWebSocket(raw: RawWebSocketEvent): NormalizedWebSocketEvent {
@@ -144,4 +146,22 @@ export class EventNormalizer {
144
146
  message: raw.message,
145
147
  };
146
148
  }
149
+
150
+ //
151
+ // -------------------------
152
+ // API (NOUVEAU)
153
+ // -------------------------
154
+ //
155
+ static normalizeApi(raw: RawApiEvent): NormalizedApiEvent {
156
+ return {
157
+ id: IdGenerator.generate(),
158
+ type: "api",
159
+ timestamp: Date.now(),
160
+ sourceIp: raw.ip,
161
+ request: {
162
+ body: raw.body,
163
+ },
164
+ raw: raw.raw,
165
+ };
166
+ }
147
167
  }
@@ -3,6 +3,7 @@ import { Logger } from "../../core/logger";
3
3
  import { StorageManager } from "../../core/storage";
4
4
  import { ApiSse } from "./api.sse";
5
5
  import { ApiController } from "./api.controllers";
6
+ import { EventNormalizer } from "../../core/event.normalizer";
6
7
 
7
8
  export async function handleApiRequest(
8
9
  req: IncomingMessage,
@@ -16,6 +17,38 @@ export async function handleApiRequest(
16
17
  const path = url.pathname;
17
18
  const method = req.method ?? "GET";
18
19
 
20
+ //
21
+ // ---------------------------
22
+ // POST / (API EVENT)
23
+ // ---------------------------
24
+ //
25
+ if (method === "POST" && path === "/") {
26
+ let body = "";
27
+ req.on("data", (chunk) => (body += chunk));
28
+ req.on("end", async () => {
29
+ try {
30
+ const parsed = JSON.parse(body);
31
+
32
+ const normalized = EventNormalizer.normalizeApi({
33
+ ip: req.socket.remoteAddress ?? "",
34
+ body: parsed,
35
+ raw: parsed,
36
+ });
37
+
38
+ await storage.save(normalized);
39
+
40
+ res.writeHead(200, { "Content-Type": "application/json" });
41
+ res.end(JSON.stringify({ success: true }));
42
+ } catch (err: any) {
43
+ logger.error("API POST error", err);
44
+ res.writeHead(400, { "Content-Type": "application/json" });
45
+ res.end(JSON.stringify({ success: false, error: err.message }));
46
+ }
47
+ });
48
+ return;
49
+ }
50
+
51
+ //
19
52
  // ---------------------------
20
53
  // SSE STREAM
21
54
  // ---------------------------
@@ -24,37 +57,32 @@ export async function handleApiRequest(
24
57
  return;
25
58
  }
26
59
 
60
+ //
27
61
  // ---------------------------
28
62
  // ROUTES REST
29
63
  // ---------------------------
30
-
31
- // GET /events
32
64
  if (method === "GET" && path === "/events") {
33
65
  await ApiController.listEvents(url, res, storage);
34
66
  return;
35
67
  }
36
68
 
37
- // GET /events/:id
38
69
  if (method === "GET" && path.startsWith("/events/")) {
39
70
  const id = path.split("/")[2];
40
71
  await ApiController.getEvent(id, res, storage);
41
72
  return;
42
73
  }
43
74
 
44
- // DELETE /events
45
75
  if (method === "DELETE" && path === "/events") {
46
76
  await ApiController.deleteAll(res, storage);
47
77
  return;
48
78
  }
49
79
 
50
- // DELETE /events/:id
51
80
  if (method === "DELETE" && path.startsWith("/events/")) {
52
81
  const id = path.split("/")[2];
53
82
  await ApiController.deleteOne(id, res, storage);
54
83
  return;
55
84
  }
56
85
 
57
- // GET /stats
58
86
  if (method === "GET" && path === "/stats") {
59
87
  await ApiController.stats(res, storage);
60
88
  return;