@j3r3mcdev/oast-server 1.1.6 → 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 (97) 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/dist/index.d.ts +1 -0
  7. package/dist/index.js +16 -1
  8. package/jest.config.js +14 -14
  9. package/package.json +45 -45
  10. package/sadmin list shadows +9 -9
  11. package/src/api/controllers/__tests__/tasks.controller.test.ts +74 -74
  12. package/src/api/controllers/events.controller.ts +10 -10
  13. package/src/api/controllers/health.controller.ts +7 -7
  14. package/src/api/controllers/tasks.controller.ts +41 -41
  15. package/src/api/dto/__tests__/create-task.dto.test.ts +41 -41
  16. package/src/api/dto/__tests__/filter-tasks.dto.test.ts +35 -35
  17. package/src/api/dto/create-task.dto.ts +33 -33
  18. package/src/api/dto/filter-tasks.dto.ts +33 -33
  19. package/src/api/services/__tests__/events.service.test.ts +41 -41
  20. package/src/api/services/__tests__/tasks.service.test.ts +41 -41
  21. package/src/api/services/events.service.ts +17 -17
  22. package/src/api/services/tasks.service.ts +79 -79
  23. package/src/api/sse/events.stream.ts +90 -90
  24. package/src/bootstrap.ts +89 -89
  25. package/src/core/__tests__/core-router.test.ts +30 -30
  26. package/src/core/__tests__/core-server.test.ts +44 -44
  27. package/src/core/__tests__/event.normalizer.test.ts +56 -56
  28. package/src/core/__tests__/event.router.test.ts +89 -89
  29. package/src/core/__tests__/logger.test.ts +32 -32
  30. package/src/core/__tests__/storage-manager.test.ts +74 -74
  31. package/src/core/event.normalizer.ts +147 -147
  32. package/src/core/event.router.ts +13 -13
  33. package/src/core/http/__tests__/adapter-node.test.ts +52 -52
  34. package/src/core/http/__tests__/body-parser-multipart.test.ts +41 -41
  35. package/src/core/http/__tests__/body-parser-raw.test.ts +28 -28
  36. package/src/core/http/__tests__/body-parser-text.test.ts +28 -28
  37. package/src/core/http/__tests__/compile-path.test.ts +39 -39
  38. package/src/core/http/__tests__/middleware-pipeline.test.ts +51 -51
  39. package/src/core/http/__tests__/request.test.ts +34 -34
  40. package/src/core/http/__tests__/response.test.ts +35 -35
  41. package/src/core/http/__tests__/router-match.test.ts +171 -171
  42. package/src/core/http/adapter-node.ts +51 -51
  43. package/src/core/http/buildRequest.ts +18 -18
  44. package/src/core/http/compile-path.ts +32 -32
  45. package/src/core/http/errors.ts +37 -37
  46. package/src/core/http/http-server.ts +52 -52
  47. package/src/core/http/middleware.ts +160 -160
  48. package/src/core/http/request.ts +55 -55
  49. package/src/core/http/response.ts +93 -93
  50. package/src/core/http/router.ts +138 -138
  51. package/src/core/id-generator.ts +8 -8
  52. package/src/core/logger.ts +113 -113
  53. package/src/core/router.ts +44 -44
  54. package/src/core/server.ts +85 -85
  55. package/src/core/storage.ts +64 -64
  56. package/src/index.ts +14 -14
  57. package/src/listeners/api/__tests__/api.controller.test.ts +116 -116
  58. package/src/listeners/api/__tests__/api.extractor.test.ts +46 -46
  59. package/src/listeners/api/__tests__/api.listener.test.ts +82 -82
  60. package/src/listeners/api/__tests__/api.routes.test.ts +155 -155
  61. package/src/listeners/api/__tests__/api.sse.test.ts +105 -105
  62. package/src/listeners/api/api.controllers.ts +67 -67
  63. package/src/listeners/api/api.extractor.ts +43 -43
  64. package/src/listeners/api/api.listener.ts +50 -50
  65. package/src/listeners/api/api.routes.ts +76 -76
  66. package/src/listeners/api/api.sse.ts +38 -38
  67. package/src/listeners/dns/__tests__/dns.test.ts +118 -118
  68. package/src/listeners/dns/dns.extractor.ts +14 -14
  69. package/src/listeners/dns/dns.listener.ts +61 -61
  70. package/src/listeners/http/__tests__/http.extractor.test.ts +59 -59
  71. package/src/listeners/http/__tests__/http.listener.test.ts +133 -133
  72. package/src/listeners/http/http.extractor.ts +15 -15
  73. package/src/listeners/http/http.listener.ts +110 -110
  74. package/src/listeners/listener.interface.ts +4 -4
  75. package/src/listeners/smtp/__tests__/smtp.extractor.test.ts +69 -69
  76. package/src/listeners/smtp/__tests__/smtp.listener.test.ts +150 -150
  77. package/src/listeners/smtp/smtp.extractor.ts +18 -18
  78. package/src/listeners/smtp/smtp.listener.ts +60 -60
  79. package/src/listeners/ssrf/__tests__/ssrf.extractor.test.ts +41 -41
  80. package/src/listeners/ssrf/__tests__/ssrf.listener.test.ts +87 -87
  81. package/src/listeners/ssrf/ssrf.extractor.ts +14 -14
  82. package/src/listeners/ssrf/ssrf.listener.ts +37 -37
  83. package/src/listeners/tcp/tcp.extractor.ts +16 -16
  84. package/src/listeners/tcp/tcp.listener.ts +61 -61
  85. package/src/listeners/webhook/__tests__/webhook.extractor.test.ts +35 -35
  86. package/src/listeners/webhook/__tests__/webhook.listener.test.ts +122 -122
  87. package/src/listeners/webhook/webhook.extractor.ts +12 -12
  88. package/src/listeners/webhook/webhook.listener.ts +58 -58
  89. package/src/listeners/websocket/__tests__/websocket.extractor.test.ts +33 -33
  90. package/src/listeners/websocket/__tests__/websocket.listener.test.ts +90 -90
  91. package/src/listeners/websocket/websocket.extractor.ts +11 -11
  92. package/src/listeners/websocket/websocket.listener.ts +40 -40
  93. package/src/storage-adapters/adapters/__tests__/memory.storage.test.ts +75 -75
  94. package/src/storage-adapters/adapters/memory.storage.ts +64 -64
  95. package/src/storage-adapters/storage.interface.ts +26 -26
  96. package/src/types/event.types.ts +147 -147
  97. package/tsconfig.json +20 -21
@@ -1,93 +1,93 @@
1
- // src/http/response.ts
2
-
3
- export class Response {
4
- private _status = 200;
5
- private _headers: Record<string, string> = {};
6
- private _sent = false;
7
- private _raw: any; // Node ServerResponse ou autre selon l'adaptateur
8
-
9
- constructor(raw: any) {
10
- this._raw = raw;
11
- }
12
-
13
- status(code: number): this {
14
- this._status = code;
15
- return this;
16
- }
17
-
18
- header(name: string, value: string): this {
19
- this._headers[name.toLowerCase()] = value;
20
- return this;
21
- }
22
-
23
- json(data: any): void {
24
- this.ensureNotSent();
25
- this.header("content-type", "application/json");
26
- this.send(JSON.stringify(data));
27
- }
28
-
29
- text(data: string): void {
30
- this.ensureNotSent();
31
- this.header("content-type", "text/plain");
32
- this.send(data);
33
- }
34
-
35
- send(data: any): void {
36
- this.ensureNotSent();
37
-
38
- for (const [name, value] of Object.entries(this._headers)) {
39
- this._raw.setHeader(name, value);
40
- }
41
-
42
- this._raw.statusCode = this._status;
43
- this._raw.end(data);
44
-
45
- this._sent = true;
46
- }
47
-
48
- stream(readable: NodeJS.ReadableStream): void {
49
- this.ensureNotSent();
50
-
51
- for (const [name, value] of Object.entries(this._headers)) {
52
- this._raw.setHeader(name, value);
53
- }
54
-
55
- this._raw.statusCode = this._status;
56
- readable.pipe(this._raw);
57
-
58
- this._sent = true;
59
- }
60
-
61
- sse(): void {
62
- this.ensureNotSent();
63
-
64
- this.header("content-type", "text/event-stream");
65
- this.header("cache-control", "no-cache");
66
- this.header("connection", "keep-alive");
67
-
68
- for (const [name, value] of Object.entries(this._headers)) {
69
- this._raw.setHeader(name, value);
70
- }
71
-
72
- this._raw.flushHeaders?.();
73
-
74
- this._sent = false; // SSE reste ouvert
75
- }
76
-
77
- write(data: string): void {
78
- this._raw.write(data);
79
- }
80
-
81
- end(): void {
82
- if (!this._sent) {
83
- this._raw.end();
84
- this._sent = true;
85
- }
86
- }
87
-
88
- private ensureNotSent() {
89
- if (this._sent) {
90
- throw new Error("Response already sent");
91
- }
92
- }
93
- }
1
+ // src/http/response.ts
2
+
3
+ export class Response {
4
+ private _status = 200;
5
+ private _headers: Record<string, string> = {};
6
+ private _sent = false;
7
+ private _raw: any; // Node ServerResponse ou autre selon l'adaptateur
8
+
9
+ constructor(raw: any) {
10
+ this._raw = raw;
11
+ }
12
+
13
+ status(code: number): this {
14
+ this._status = code;
15
+ return this;
16
+ }
17
+
18
+ header(name: string, value: string): this {
19
+ this._headers[name.toLowerCase()] = value;
20
+ return this;
21
+ }
22
+
23
+ json(data: any): void {
24
+ this.ensureNotSent();
25
+ this.header("content-type", "application/json");
26
+ this.send(JSON.stringify(data));
27
+ }
28
+
29
+ text(data: string): void {
30
+ this.ensureNotSent();
31
+ this.header("content-type", "text/plain");
32
+ this.send(data);
33
+ }
34
+
35
+ send(data: any): void {
36
+ this.ensureNotSent();
37
+
38
+ for (const [name, value] of Object.entries(this._headers)) {
39
+ this._raw.setHeader(name, value);
40
+ }
41
+
42
+ this._raw.statusCode = this._status;
43
+ this._raw.end(data);
44
+
45
+ this._sent = true;
46
+ }
47
+
48
+ stream(readable: NodeJS.ReadableStream): void {
49
+ this.ensureNotSent();
50
+
51
+ for (const [name, value] of Object.entries(this._headers)) {
52
+ this._raw.setHeader(name, value);
53
+ }
54
+
55
+ this._raw.statusCode = this._status;
56
+ readable.pipe(this._raw);
57
+
58
+ this._sent = true;
59
+ }
60
+
61
+ sse(): void {
62
+ this.ensureNotSent();
63
+
64
+ this.header("content-type", "text/event-stream");
65
+ this.header("cache-control", "no-cache");
66
+ this.header("connection", "keep-alive");
67
+
68
+ for (const [name, value] of Object.entries(this._headers)) {
69
+ this._raw.setHeader(name, value);
70
+ }
71
+
72
+ this._raw.flushHeaders?.();
73
+
74
+ this._sent = false; // SSE reste ouvert
75
+ }
76
+
77
+ write(data: string): void {
78
+ this._raw.write(data);
79
+ }
80
+
81
+ end(): void {
82
+ if (!this._sent) {
83
+ this._raw.end();
84
+ this._sent = true;
85
+ }
86
+ }
87
+
88
+ private ensureNotSent() {
89
+ if (this._sent) {
90
+ throw new Error("Response already sent");
91
+ }
92
+ }
93
+ }
@@ -1,138 +1,138 @@
1
- // src/http/router.ts
2
-
3
- import { compilePath } from "./compile-path";
4
- import { Middleware } from "./middleware";
5
-
6
- export class Router {
7
- private routes: Array<{
8
- method: string;
9
- path: string;
10
- compiled: any[];
11
- middlewares: Middleware[];
12
- handler: Function;
13
- }> = [];
14
-
15
- /**
16
- * Enregistre une route avec middlewares optionnels :
17
- * router.get("/x", mw1, mw2, handler)
18
- */
19
- register(method: string, path: string, ...middlewaresAndHandler: any[]) {
20
- const compiled = compilePath(path);
21
-
22
- const handler = middlewaresAndHandler.pop();
23
- const middlewares = middlewaresAndHandler as Middleware[];
24
-
25
- this.routes.push({
26
- method,
27
- path,
28
- compiled,
29
- middlewares,
30
- handler,
31
- });
32
- }
33
-
34
- /**
35
- * Trouve la route et extrait les params
36
- */
37
- match(method: string, urlPath: string) {
38
- const urlSegments = urlPath.replace(/^\//, "").split("/");
39
-
40
- for (const route of this.routes) {
41
- if (route.method !== method) continue;
42
-
43
- const params: Record<string, string> = {};
44
- const compiled = route.compiled;
45
-
46
- if (this.matchSegments(compiled, urlSegments, params)) {
47
- return {
48
- handler: route.handler,
49
- middlewares: route.middlewares,
50
- params,
51
- };
52
- }
53
- }
54
-
55
- return null;
56
- }
57
-
58
- /**
59
- * Ton moteur de matching existant — inchangé
60
- */
61
- private matchSegments(
62
- compiled: any[],
63
- urlSegments: string[],
64
- params: Record<string, string>,
65
- ) {
66
- let i = 0;
67
-
68
- for (let j = 0; j < compiled.length; j++) {
69
- const segment = compiled[j];
70
- const part = urlSegments[i];
71
-
72
- if (!part && segment.type !== "wildcard") {
73
- return false;
74
- }
75
-
76
- if (segment.type === "static") {
77
- if (segment.value !== part) return false;
78
- i++;
79
- continue;
80
- }
81
-
82
- if (segment.type === "param") {
83
- if (!part) return false;
84
- params[segment.name] = part;
85
- i++;
86
- continue;
87
- }
88
-
89
- if (segment.type === "wildcard") {
90
- if (!part) return false;
91
-
92
- const next = compiled[j + 1];
93
- if (!next) return true;
94
-
95
- while (i < urlSegments.length) {
96
- if (next.type === "static" && urlSegments[i] === next.value) {
97
- break;
98
- }
99
- i++;
100
- }
101
-
102
- if (i >= urlSegments.length) return false;
103
-
104
- continue;
105
- }
106
- }
107
-
108
- return i === urlSegments.length;
109
- }
110
-
111
- get(path: string, ...middlewaresAndHandler: any[]) {
112
- this.register("GET", path, ...middlewaresAndHandler);
113
- }
114
-
115
- post(path: string, ...middlewaresAndHandler: any[]) {
116
- this.register("POST", path, ...middlewaresAndHandler);
117
- }
118
-
119
- put(path: string, ...middlewaresAndHandler: any[]) {
120
- this.register("PUT", path, ...middlewaresAndHandler);
121
- }
122
-
123
- delete(path: string, ...middlewaresAndHandler: any[]) {
124
- this.register("DELETE", path, ...middlewaresAndHandler);
125
- }
126
-
127
- patch(path: string, ...middlewaresAndHandler: any[]) {
128
- this.register("PATCH", path, ...middlewaresAndHandler);
129
- }
130
-
131
- options(path: string, ...middlewaresAndHandler: any[]) {
132
- this.register("OPTIONS", path, ...middlewaresAndHandler);
133
- }
134
-
135
- head(path: string, ...middlewaresAndHandler: any[]) {
136
- this.register("HEAD", path, ...middlewaresAndHandler);
137
- }
138
- }
1
+ // src/http/router.ts
2
+
3
+ import { compilePath } from "./compile-path";
4
+ import { Middleware } from "./middleware";
5
+
6
+ export class Router {
7
+ private routes: Array<{
8
+ method: string;
9
+ path: string;
10
+ compiled: any[];
11
+ middlewares: Middleware[];
12
+ handler: Function;
13
+ }> = [];
14
+
15
+ /**
16
+ * Enregistre une route avec middlewares optionnels :
17
+ * router.get("/x", mw1, mw2, handler)
18
+ */
19
+ register(method: string, path: string, ...middlewaresAndHandler: any[]) {
20
+ const compiled = compilePath(path);
21
+
22
+ const handler = middlewaresAndHandler.pop();
23
+ const middlewares = middlewaresAndHandler as Middleware[];
24
+
25
+ this.routes.push({
26
+ method,
27
+ path,
28
+ compiled,
29
+ middlewares,
30
+ handler,
31
+ });
32
+ }
33
+
34
+ /**
35
+ * Trouve la route et extrait les params
36
+ */
37
+ match(method: string, urlPath: string) {
38
+ const urlSegments = urlPath.replace(/^\//, "").split("/");
39
+
40
+ for (const route of this.routes) {
41
+ if (route.method !== method) continue;
42
+
43
+ const params: Record<string, string> = {};
44
+ const compiled = route.compiled;
45
+
46
+ if (this.matchSegments(compiled, urlSegments, params)) {
47
+ return {
48
+ handler: route.handler,
49
+ middlewares: route.middlewares,
50
+ params,
51
+ };
52
+ }
53
+ }
54
+
55
+ return null;
56
+ }
57
+
58
+ /**
59
+ * Ton moteur de matching existant — inchangé
60
+ */
61
+ private matchSegments(
62
+ compiled: any[],
63
+ urlSegments: string[],
64
+ params: Record<string, string>,
65
+ ) {
66
+ let i = 0;
67
+
68
+ for (let j = 0; j < compiled.length; j++) {
69
+ const segment = compiled[j];
70
+ const part = urlSegments[i];
71
+
72
+ if (!part && segment.type !== "wildcard") {
73
+ return false;
74
+ }
75
+
76
+ if (segment.type === "static") {
77
+ if (segment.value !== part) return false;
78
+ i++;
79
+ continue;
80
+ }
81
+
82
+ if (segment.type === "param") {
83
+ if (!part) return false;
84
+ params[segment.name] = part;
85
+ i++;
86
+ continue;
87
+ }
88
+
89
+ if (segment.type === "wildcard") {
90
+ if (!part) return false;
91
+
92
+ const next = compiled[j + 1];
93
+ if (!next) return true;
94
+
95
+ while (i < urlSegments.length) {
96
+ if (next.type === "static" && urlSegments[i] === next.value) {
97
+ break;
98
+ }
99
+ i++;
100
+ }
101
+
102
+ if (i >= urlSegments.length) return false;
103
+
104
+ continue;
105
+ }
106
+ }
107
+
108
+ return i === urlSegments.length;
109
+ }
110
+
111
+ get(path: string, ...middlewaresAndHandler: any[]) {
112
+ this.register("GET", path, ...middlewaresAndHandler);
113
+ }
114
+
115
+ post(path: string, ...middlewaresAndHandler: any[]) {
116
+ this.register("POST", path, ...middlewaresAndHandler);
117
+ }
118
+
119
+ put(path: string, ...middlewaresAndHandler: any[]) {
120
+ this.register("PUT", path, ...middlewaresAndHandler);
121
+ }
122
+
123
+ delete(path: string, ...middlewaresAndHandler: any[]) {
124
+ this.register("DELETE", path, ...middlewaresAndHandler);
125
+ }
126
+
127
+ patch(path: string, ...middlewaresAndHandler: any[]) {
128
+ this.register("PATCH", path, ...middlewaresAndHandler);
129
+ }
130
+
131
+ options(path: string, ...middlewaresAndHandler: any[]) {
132
+ this.register("OPTIONS", path, ...middlewaresAndHandler);
133
+ }
134
+
135
+ head(path: string, ...middlewaresAndHandler: any[]) {
136
+ this.register("HEAD", path, ...middlewaresAndHandler);
137
+ }
138
+ }
@@ -1,8 +1,8 @@
1
- import crypto from "crypto";
2
-
3
- export class IdGenerator {
4
- static generate(): string {
5
- // Token long, alphanumérique, très difficile à deviner
6
- return crypto.randomBytes(16).toString("hex");
7
- }
8
- }
1
+ import crypto from "crypto";
2
+
3
+ export class IdGenerator {
4
+ static generate(): string {
5
+ // Token long, alphanumérique, très difficile à deviner
6
+ return crypto.randomBytes(16).toString("hex");
7
+ }
8
+ }