@guardcore/express 1.0.0
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.
- package/dist/index.cjs +298 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +51 -0
- package/dist/index.d.ts +51 -0
- package/dist/index.js +262 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
BaseSecurityDecorator: () => import_core2.BaseSecurityDecorator,
|
|
34
|
+
BehaviorRule: () => import_core2.BehaviorRule,
|
|
35
|
+
ExpressGuardRequest: () => ExpressGuardRequest,
|
|
36
|
+
ExpressGuardResponse: () => ExpressGuardResponse,
|
|
37
|
+
ExpressResponseFactory: () => ExpressResponseFactory,
|
|
38
|
+
RouteConfig: () => import_core2.RouteConfig,
|
|
39
|
+
SecurityConfigSchema: () => import_core2.SecurityConfigSchema,
|
|
40
|
+
SecurityDecorator: () => import_core2.SecurityDecorator,
|
|
41
|
+
configureCors: () => configureCors,
|
|
42
|
+
createSecurityMiddleware: () => createSecurityMiddleware,
|
|
43
|
+
defaultLogger: () => import_core2.defaultLogger,
|
|
44
|
+
guardBodyParser: () => guardBodyParser,
|
|
45
|
+
guardUrlEncodedParser: () => guardUrlEncodedParser,
|
|
46
|
+
sendGuardResponse: () => sendGuardResponse
|
|
47
|
+
});
|
|
48
|
+
module.exports = __toCommonJS(index_exports);
|
|
49
|
+
|
|
50
|
+
// src/middleware.ts
|
|
51
|
+
var import_core = require("@guardcore/core");
|
|
52
|
+
|
|
53
|
+
// src/adapters.ts
|
|
54
|
+
var ExpressGuardRequest = class {
|
|
55
|
+
constructor(req) {
|
|
56
|
+
this.req = req;
|
|
57
|
+
const raw = req["rawBody"];
|
|
58
|
+
if (raw instanceof Uint8Array) {
|
|
59
|
+
this.rawBody = raw;
|
|
60
|
+
} else if (raw instanceof Buffer) {
|
|
61
|
+
this.rawBody = new Uint8Array(raw);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
_state = {};
|
|
65
|
+
rawBody = null;
|
|
66
|
+
get urlPath() {
|
|
67
|
+
return this.req.path;
|
|
68
|
+
}
|
|
69
|
+
get urlScheme() {
|
|
70
|
+
return this.req.protocol;
|
|
71
|
+
}
|
|
72
|
+
get urlFull() {
|
|
73
|
+
return `${this.req.protocol}://${this.req.get("host")}${this.req.originalUrl}`;
|
|
74
|
+
}
|
|
75
|
+
urlReplaceScheme(scheme) {
|
|
76
|
+
return this.urlFull.replace(/^https?/, scheme);
|
|
77
|
+
}
|
|
78
|
+
get method() {
|
|
79
|
+
return this.req.method;
|
|
80
|
+
}
|
|
81
|
+
get clientHost() {
|
|
82
|
+
return this.req.socket.remoteAddress ?? null;
|
|
83
|
+
}
|
|
84
|
+
get headers() {
|
|
85
|
+
return this.req.headers;
|
|
86
|
+
}
|
|
87
|
+
get queryParams() {
|
|
88
|
+
return this.req.query;
|
|
89
|
+
}
|
|
90
|
+
async body() {
|
|
91
|
+
return this.rawBody ?? new Uint8Array(0);
|
|
92
|
+
}
|
|
93
|
+
get state() {
|
|
94
|
+
return this._state;
|
|
95
|
+
}
|
|
96
|
+
get scope() {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var ExpressGuardResponse = class {
|
|
101
|
+
constructor(statusCode, content) {
|
|
102
|
+
this.statusCode = statusCode;
|
|
103
|
+
this._body = new TextEncoder().encode(content);
|
|
104
|
+
this._headers["content-type"] = "application/json";
|
|
105
|
+
}
|
|
106
|
+
_headers = {};
|
|
107
|
+
_body;
|
|
108
|
+
get headers() {
|
|
109
|
+
return this._headers;
|
|
110
|
+
}
|
|
111
|
+
setHeader(name, value) {
|
|
112
|
+
this._headers[name] = value;
|
|
113
|
+
}
|
|
114
|
+
get body() {
|
|
115
|
+
return this._body;
|
|
116
|
+
}
|
|
117
|
+
get bodyText() {
|
|
118
|
+
return this._body ? new TextDecoder().decode(this._body) : null;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
var ExpressResponseFactory = class {
|
|
122
|
+
createResponse(content, statusCode) {
|
|
123
|
+
return new ExpressGuardResponse(statusCode, JSON.stringify({ detail: content }));
|
|
124
|
+
}
|
|
125
|
+
createRedirectResponse(url, statusCode) {
|
|
126
|
+
const resp = new ExpressGuardResponse(statusCode, "");
|
|
127
|
+
resp.setHeader("location", url);
|
|
128
|
+
return resp;
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
function sendGuardResponse(res, guardResponse) {
|
|
132
|
+
for (const [name, value] of Object.entries(guardResponse.headers)) {
|
|
133
|
+
res.setHeader(name, value);
|
|
134
|
+
}
|
|
135
|
+
if (guardResponse.headers["location"]) {
|
|
136
|
+
res.redirect(guardResponse.statusCode, guardResponse.headers["location"]);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
res.status(guardResponse.statusCode);
|
|
140
|
+
if (guardResponse.body) {
|
|
141
|
+
res.send(Buffer.from(guardResponse.body));
|
|
142
|
+
} else {
|
|
143
|
+
res.end();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// src/middleware.ts
|
|
148
|
+
function createSecurityMiddleware(options) {
|
|
149
|
+
const resolved = import_core.SecurityConfigSchema.parse(options.config);
|
|
150
|
+
const logger = resolved.logger ?? import_core.defaultLogger;
|
|
151
|
+
const responseFactory = new ExpressResponseFactory();
|
|
152
|
+
let initialized = false;
|
|
153
|
+
let components;
|
|
154
|
+
async function initialize() {
|
|
155
|
+
if (initialized) return;
|
|
156
|
+
components = await (0, import_core.initializeSecurityMiddleware)(
|
|
157
|
+
resolved,
|
|
158
|
+
logger,
|
|
159
|
+
responseFactory,
|
|
160
|
+
options.agentHandler,
|
|
161
|
+
options.geoIpHandler,
|
|
162
|
+
options.guardDecorator
|
|
163
|
+
);
|
|
164
|
+
initialized = true;
|
|
165
|
+
logger.info("Guard security middleware initialized");
|
|
166
|
+
}
|
|
167
|
+
return async function guardMiddleware(req, res, next) {
|
|
168
|
+
await initialize();
|
|
169
|
+
const startTime = performance.now();
|
|
170
|
+
const guardReq = new ExpressGuardRequest(req);
|
|
171
|
+
const passthrough = await components.bypassHandler.handlePassthrough(
|
|
172
|
+
guardReq,
|
|
173
|
+
async () => createPassthroughResponse()
|
|
174
|
+
);
|
|
175
|
+
if (passthrough) {
|
|
176
|
+
sendGuardResponse(res, passthrough);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const routeConfig = components.routeResolver.getRouteConfig(guardReq);
|
|
180
|
+
const bypass = await components.bypassHandler.handleSecurityBypass(
|
|
181
|
+
guardReq,
|
|
182
|
+
async () => createPassthroughResponse(),
|
|
183
|
+
routeConfig
|
|
184
|
+
);
|
|
185
|
+
if (bypass) {
|
|
186
|
+
sendGuardResponse(res, bypass);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const blockResponse = await components.pipeline.execute(guardReq);
|
|
190
|
+
if (blockResponse) {
|
|
191
|
+
sendGuardResponse(res, blockResponse);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (routeConfig && routeConfig.behaviorRules.length > 0) {
|
|
195
|
+
const clientIp = guardReq.clientHost ?? "unknown";
|
|
196
|
+
await components.behavioralProcessor.processUsageRules(guardReq, clientIp, routeConfig);
|
|
197
|
+
}
|
|
198
|
+
const originalEnd = res.end;
|
|
199
|
+
const chunks = [];
|
|
200
|
+
res.end = function(chunk, ...args) {
|
|
201
|
+
if (chunk) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
202
|
+
const responseTime = (performance.now() - startTime) / 1e3;
|
|
203
|
+
const body = Buffer.concat(chunks);
|
|
204
|
+
const capturedResponse = {
|
|
205
|
+
statusCode: res.statusCode,
|
|
206
|
+
headers: Object.fromEntries(
|
|
207
|
+
Object.entries(res.getHeaders()).map(([k, v]) => [k, String(v)])
|
|
208
|
+
),
|
|
209
|
+
setHeader(name, value) {
|
|
210
|
+
res.setHeader(name, value);
|
|
211
|
+
},
|
|
212
|
+
body: new Uint8Array(body),
|
|
213
|
+
bodyText: body.toString("utf-8")
|
|
214
|
+
};
|
|
215
|
+
components.errorResponseFactory.processResponse(
|
|
216
|
+
guardReq,
|
|
217
|
+
capturedResponse,
|
|
218
|
+
responseTime,
|
|
219
|
+
routeConfig ?? null,
|
|
220
|
+
routeConfig ? async (request, response, clientIp, rc) => {
|
|
221
|
+
await components.behavioralProcessor.processReturnRules(request, response, clientIp, rc);
|
|
222
|
+
} : void 0
|
|
223
|
+
).catch(() => {
|
|
224
|
+
});
|
|
225
|
+
return originalEnd.apply(res, [chunk, ...args]);
|
|
226
|
+
};
|
|
227
|
+
next();
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
function createPassthroughResponse() {
|
|
231
|
+
return {
|
|
232
|
+
statusCode: 200,
|
|
233
|
+
headers: {},
|
|
234
|
+
setHeader() {
|
|
235
|
+
},
|
|
236
|
+
body: null,
|
|
237
|
+
bodyText: null
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// src/cors.ts
|
|
242
|
+
function configureCors(app, config) {
|
|
243
|
+
if (!config.enableCors) return;
|
|
244
|
+
try {
|
|
245
|
+
const corsMiddleware = require("cors");
|
|
246
|
+
app.use(corsMiddleware({
|
|
247
|
+
origin: config.corsAllowOrigins,
|
|
248
|
+
methods: config.corsAllowMethods,
|
|
249
|
+
allowedHeaders: config.corsAllowHeaders,
|
|
250
|
+
credentials: config.corsAllowCredentials,
|
|
251
|
+
exposedHeaders: config.corsExposeHeaders,
|
|
252
|
+
maxAge: config.corsMaxAge
|
|
253
|
+
}));
|
|
254
|
+
} catch {
|
|
255
|
+
throw new Error(
|
|
256
|
+
'@guardcore/express: CORS is enabled but the "cors" package is not installed. Run: pnpm add cors'
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// src/body-parser.ts
|
|
262
|
+
var import_express = __toESM(require("express"), 1);
|
|
263
|
+
function guardBodyParser() {
|
|
264
|
+
return import_express.default.json({
|
|
265
|
+
verify: (req, _res, buf, _encoding) => {
|
|
266
|
+
req["rawBody"] = buf;
|
|
267
|
+
}
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function guardUrlEncodedParser() {
|
|
271
|
+
return import_express.default.urlencoded({
|
|
272
|
+
extended: true,
|
|
273
|
+
verify: (req, _res, buf, _encoding) => {
|
|
274
|
+
req["rawBody"] = buf;
|
|
275
|
+
}
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// src/index.ts
|
|
280
|
+
var import_core2 = require("@guardcore/core");
|
|
281
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
282
|
+
0 && (module.exports = {
|
|
283
|
+
BaseSecurityDecorator,
|
|
284
|
+
BehaviorRule,
|
|
285
|
+
ExpressGuardRequest,
|
|
286
|
+
ExpressGuardResponse,
|
|
287
|
+
ExpressResponseFactory,
|
|
288
|
+
RouteConfig,
|
|
289
|
+
SecurityConfigSchema,
|
|
290
|
+
SecurityDecorator,
|
|
291
|
+
configureCors,
|
|
292
|
+
createSecurityMiddleware,
|
|
293
|
+
defaultLogger,
|
|
294
|
+
guardBodyParser,
|
|
295
|
+
guardUrlEncodedParser,
|
|
296
|
+
sendGuardResponse
|
|
297
|
+
});
|
|
298
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/middleware.ts","../src/adapters.ts","../src/cors.ts","../src/body-parser.ts"],"sourcesContent":["export { createSecurityMiddleware } from './middleware.js';\nexport type { SecurityMiddlewareOptions } from './middleware.js';\nexport { configureCors } from './cors.js';\nexport { guardBodyParser, guardUrlEncodedParser } from './body-parser.js';\nexport { ExpressGuardRequest, ExpressGuardResponse, ExpressResponseFactory, sendGuardResponse } from './adapters.js';\n\nexport {\n SecurityConfigSchema,\n BaseSecurityDecorator,\n SecurityDecorator,\n RouteConfig,\n BehaviorRule,\n defaultLogger,\n} from '@guardcore/core';\n\nexport type {\n SecurityConfig,\n ResolvedSecurityConfig,\n GuardRequest,\n GuardResponse,\n Logger,\n SecurityMiddlewareComponents,\n HandlerRegistry,\n} from '@guardcore/core';\n","import type { Request, Response, NextFunction } from 'express';\nimport type {\n SecurityConfig,\n GuardRequest,\n GuardResponse,\n Logger,\n AgentHandlerProtocol,\n GeoIPHandler,\n SecurityMiddlewareComponents,\n RouteConfig,\n} from '@guardcore/core';\nimport { SecurityConfigSchema, defaultLogger, initializeSecurityMiddleware } from '@guardcore/core';\nimport { ExpressGuardRequest, ExpressResponseFactory, sendGuardResponse } from './adapters.js';\n\nexport interface SecurityMiddlewareOptions {\n config: SecurityConfig;\n agentHandler?: AgentHandlerProtocol;\n geoIpHandler?: GeoIPHandler;\n guardDecorator?: unknown;\n}\n\nexport function createSecurityMiddleware(options: SecurityMiddlewareOptions) {\n const resolved = SecurityConfigSchema.parse(options.config);\n const logger: Logger = resolved.logger ?? defaultLogger;\n const responseFactory = new ExpressResponseFactory();\n\n let initialized = false;\n let components: SecurityMiddlewareComponents;\n\n async function initialize(): Promise<void> {\n if (initialized) return;\n components = await initializeSecurityMiddleware(\n resolved, logger, responseFactory,\n options.agentHandler, options.geoIpHandler, options.guardDecorator,\n );\n initialized = true;\n logger.info('Guard security middleware initialized');\n }\n\n return async function guardMiddleware(req: Request, res: Response, next: NextFunction): Promise<void> {\n await initialize();\n\n const startTime = performance.now();\n const guardReq = new ExpressGuardRequest(req);\n\n const passthrough = await components.bypassHandler.handlePassthrough(\n guardReq,\n async () => createPassthroughResponse(),\n );\n if (passthrough) {\n sendGuardResponse(res, passthrough);\n return;\n }\n\n const routeConfig = components.routeResolver.getRouteConfig(guardReq);\n\n const bypass = await components.bypassHandler.handleSecurityBypass(\n guardReq,\n async () => createPassthroughResponse(),\n routeConfig,\n );\n if (bypass) {\n sendGuardResponse(res, bypass);\n return;\n }\n\n const blockResponse = await components.pipeline.execute(guardReq);\n if (blockResponse) {\n sendGuardResponse(res, blockResponse);\n return;\n }\n\n if (routeConfig && routeConfig.behaviorRules.length > 0) {\n const clientIp = guardReq.clientHost ?? 'unknown';\n await components.behavioralProcessor.processUsageRules(guardReq, clientIp, routeConfig);\n }\n\n const originalEnd = res.end;\n const chunks: Buffer[] = [];\n\n res.end = function (chunk: unknown, ...args: unknown[]): Response {\n if (chunk) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n\n const responseTime = (performance.now() - startTime) / 1000;\n const body = Buffer.concat(chunks);\n const capturedResponse: GuardResponse = {\n statusCode: res.statusCode,\n headers: Object.fromEntries(\n Object.entries(res.getHeaders()).map(([k, v]) => [k, String(v)]),\n ),\n setHeader(name: string, value: string) { res.setHeader(name, value); },\n body: new Uint8Array(body),\n bodyText: body.toString('utf-8'),\n };\n\n components.errorResponseFactory.processResponse(\n guardReq, capturedResponse, responseTime, routeConfig ?? null,\n routeConfig ? async (request: GuardRequest, response: GuardResponse, clientIp: string, rc: RouteConfig) => {\n await components.behavioralProcessor.processReturnRules(request, response, clientIp, rc);\n } : undefined,\n ).catch(() => {});\n\n return originalEnd.apply(res, [chunk, ...args] as Parameters<typeof originalEnd>);\n };\n\n next();\n };\n}\n\nfunction createPassthroughResponse(): GuardResponse {\n return {\n statusCode: 200,\n headers: {},\n setHeader() {},\n body: null,\n bodyText: null,\n };\n}\n","import type { Request, Response } from 'express';\nimport type { GuardRequest, GuardRequestState, GuardResponse, GuardResponseFactory } from '@guardcore/core';\n\nexport class ExpressGuardRequest implements GuardRequest {\n private _state: GuardRequestState = {};\n private rawBody: Uint8Array | null = null;\n\n constructor(private readonly req: Request) {\n const raw = (req as unknown as Record<string, unknown>)['rawBody'];\n if (raw instanceof Uint8Array) {\n this.rawBody = raw;\n } else if (raw instanceof Buffer) {\n this.rawBody = new Uint8Array(raw);\n }\n }\n\n get urlPath(): string { return this.req.path; }\n get urlScheme(): string { return this.req.protocol; }\n get urlFull(): string { return `${this.req.protocol}://${this.req.get('host')}${this.req.originalUrl}`; }\n urlReplaceScheme(scheme: string): string { return this.urlFull.replace(/^https?/, scheme); }\n get method(): string { return this.req.method; }\n get clientHost(): string | null { return this.req.socket.remoteAddress ?? null; }\n get headers(): Readonly<Record<string, string>> { return this.req.headers as Record<string, string>; }\n get queryParams(): Readonly<Record<string, string>> { return this.req.query as Record<string, string>; }\n async body(): Promise<Uint8Array> { return this.rawBody ?? new Uint8Array(0); }\n get state(): GuardRequestState { return this._state; }\n get scope(): Readonly<Record<string, unknown>> { return {}; }\n}\n\nexport class ExpressGuardResponse implements GuardResponse {\n private _headers: Record<string, string> = {};\n private _body: Uint8Array | null;\n\n constructor(\n readonly statusCode: number,\n content: string,\n ) {\n this._body = new TextEncoder().encode(content);\n this._headers['content-type'] = 'application/json';\n }\n\n get headers(): Record<string, string> { return this._headers; }\n setHeader(name: string, value: string): void { this._headers[name] = value; }\n get body(): Uint8Array | null { return this._body; }\n get bodyText(): string | null {\n return this._body ? new TextDecoder().decode(this._body) : null;\n }\n}\n\nexport class ExpressResponseFactory implements GuardResponseFactory {\n createResponse(content: string, statusCode: number): GuardResponse {\n return new ExpressGuardResponse(statusCode, JSON.stringify({ detail: content }));\n }\n\n createRedirectResponse(url: string, statusCode: number): GuardResponse {\n const resp = new ExpressGuardResponse(statusCode, '');\n resp.setHeader('location', url);\n return resp;\n }\n}\n\nexport function sendGuardResponse(res: Response, guardResponse: GuardResponse): void {\n for (const [name, value] of Object.entries(guardResponse.headers)) {\n res.setHeader(name, value);\n }\n\n if (guardResponse.headers['location']) {\n res.redirect(guardResponse.statusCode, guardResponse.headers['location']);\n return;\n }\n\n res.status(guardResponse.statusCode);\n if (guardResponse.body) {\n res.send(Buffer.from(guardResponse.body));\n } else {\n res.end();\n }\n}\n","import type { Express } from 'express';\nimport type { ResolvedSecurityConfig } from '@guardcore/core';\n\nexport function configureCors(app: Express, config: ResolvedSecurityConfig): void {\n if (!config.enableCors) return;\n\n try {\n const corsMiddleware = require('cors');\n app.use(corsMiddleware({\n origin: config.corsAllowOrigins,\n methods: config.corsAllowMethods,\n allowedHeaders: config.corsAllowHeaders,\n credentials: config.corsAllowCredentials,\n exposedHeaders: config.corsExposeHeaders,\n maxAge: config.corsMaxAge,\n }));\n } catch {\n throw new Error(\n '@guardcore/express: CORS is enabled but the \"cors\" package is not installed. ' +\n 'Run: pnpm add cors',\n );\n }\n}\n","import type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport express from 'express';\n\nexport function guardBodyParser(): RequestHandler {\n return express.json({\n verify: (req: Request, _res: Response, buf: Buffer, _encoding: string) => {\n (req as unknown as Record<string, unknown>)['rawBody'] = buf;\n },\n });\n}\n\nexport function guardUrlEncodedParser(): RequestHandler {\n return express.urlencoded({\n extended: true,\n verify: (req: Request, _res: Response, buf: Buffer, _encoding: string) => {\n (req as unknown as Record<string, unknown>)['rawBody'] = buf;\n },\n });\n}\n"],"mappings":"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","names":["express","import_core"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Request, Response, NextFunction, Express, RequestHandler } from 'express';
|
|
2
|
+
import { SecurityConfig, AgentHandlerProtocol, GeoIPHandler, ResolvedSecurityConfig, GuardRequest, GuardRequestState, GuardResponse, GuardResponseFactory } from '@guardcore/core';
|
|
3
|
+
export { BaseSecurityDecorator, BehaviorRule, GuardRequest, GuardResponse, HandlerRegistry, Logger, ResolvedSecurityConfig, RouteConfig, SecurityConfig, SecurityConfigSchema, SecurityDecorator, SecurityMiddlewareComponents, defaultLogger } from '@guardcore/core';
|
|
4
|
+
|
|
5
|
+
interface SecurityMiddlewareOptions {
|
|
6
|
+
config: SecurityConfig;
|
|
7
|
+
agentHandler?: AgentHandlerProtocol;
|
|
8
|
+
geoIpHandler?: GeoIPHandler;
|
|
9
|
+
guardDecorator?: unknown;
|
|
10
|
+
}
|
|
11
|
+
declare function createSecurityMiddleware(options: SecurityMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12
|
+
|
|
13
|
+
declare function configureCors(app: Express, config: ResolvedSecurityConfig): void;
|
|
14
|
+
|
|
15
|
+
declare function guardBodyParser(): RequestHandler;
|
|
16
|
+
declare function guardUrlEncodedParser(): RequestHandler;
|
|
17
|
+
|
|
18
|
+
declare class ExpressGuardRequest implements GuardRequest {
|
|
19
|
+
private readonly req;
|
|
20
|
+
private _state;
|
|
21
|
+
private rawBody;
|
|
22
|
+
constructor(req: Request);
|
|
23
|
+
get urlPath(): string;
|
|
24
|
+
get urlScheme(): string;
|
|
25
|
+
get urlFull(): string;
|
|
26
|
+
urlReplaceScheme(scheme: string): string;
|
|
27
|
+
get method(): string;
|
|
28
|
+
get clientHost(): string | null;
|
|
29
|
+
get headers(): Readonly<Record<string, string>>;
|
|
30
|
+
get queryParams(): Readonly<Record<string, string>>;
|
|
31
|
+
body(): Promise<Uint8Array>;
|
|
32
|
+
get state(): GuardRequestState;
|
|
33
|
+
get scope(): Readonly<Record<string, unknown>>;
|
|
34
|
+
}
|
|
35
|
+
declare class ExpressGuardResponse implements GuardResponse {
|
|
36
|
+
readonly statusCode: number;
|
|
37
|
+
private _headers;
|
|
38
|
+
private _body;
|
|
39
|
+
constructor(statusCode: number, content: string);
|
|
40
|
+
get headers(): Record<string, string>;
|
|
41
|
+
setHeader(name: string, value: string): void;
|
|
42
|
+
get body(): Uint8Array | null;
|
|
43
|
+
get bodyText(): string | null;
|
|
44
|
+
}
|
|
45
|
+
declare class ExpressResponseFactory implements GuardResponseFactory {
|
|
46
|
+
createResponse(content: string, statusCode: number): GuardResponse;
|
|
47
|
+
createRedirectResponse(url: string, statusCode: number): GuardResponse;
|
|
48
|
+
}
|
|
49
|
+
declare function sendGuardResponse(res: Response, guardResponse: GuardResponse): void;
|
|
50
|
+
|
|
51
|
+
export { ExpressGuardRequest, ExpressGuardResponse, ExpressResponseFactory, type SecurityMiddlewareOptions, configureCors, createSecurityMiddleware, guardBodyParser, guardUrlEncodedParser, sendGuardResponse };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Request, Response, NextFunction, Express, RequestHandler } from 'express';
|
|
2
|
+
import { SecurityConfig, AgentHandlerProtocol, GeoIPHandler, ResolvedSecurityConfig, GuardRequest, GuardRequestState, GuardResponse, GuardResponseFactory } from '@guardcore/core';
|
|
3
|
+
export { BaseSecurityDecorator, BehaviorRule, GuardRequest, GuardResponse, HandlerRegistry, Logger, ResolvedSecurityConfig, RouteConfig, SecurityConfig, SecurityConfigSchema, SecurityDecorator, SecurityMiddlewareComponents, defaultLogger } from '@guardcore/core';
|
|
4
|
+
|
|
5
|
+
interface SecurityMiddlewareOptions {
|
|
6
|
+
config: SecurityConfig;
|
|
7
|
+
agentHandler?: AgentHandlerProtocol;
|
|
8
|
+
geoIpHandler?: GeoIPHandler;
|
|
9
|
+
guardDecorator?: unknown;
|
|
10
|
+
}
|
|
11
|
+
declare function createSecurityMiddleware(options: SecurityMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => Promise<void>;
|
|
12
|
+
|
|
13
|
+
declare function configureCors(app: Express, config: ResolvedSecurityConfig): void;
|
|
14
|
+
|
|
15
|
+
declare function guardBodyParser(): RequestHandler;
|
|
16
|
+
declare function guardUrlEncodedParser(): RequestHandler;
|
|
17
|
+
|
|
18
|
+
declare class ExpressGuardRequest implements GuardRequest {
|
|
19
|
+
private readonly req;
|
|
20
|
+
private _state;
|
|
21
|
+
private rawBody;
|
|
22
|
+
constructor(req: Request);
|
|
23
|
+
get urlPath(): string;
|
|
24
|
+
get urlScheme(): string;
|
|
25
|
+
get urlFull(): string;
|
|
26
|
+
urlReplaceScheme(scheme: string): string;
|
|
27
|
+
get method(): string;
|
|
28
|
+
get clientHost(): string | null;
|
|
29
|
+
get headers(): Readonly<Record<string, string>>;
|
|
30
|
+
get queryParams(): Readonly<Record<string, string>>;
|
|
31
|
+
body(): Promise<Uint8Array>;
|
|
32
|
+
get state(): GuardRequestState;
|
|
33
|
+
get scope(): Readonly<Record<string, unknown>>;
|
|
34
|
+
}
|
|
35
|
+
declare class ExpressGuardResponse implements GuardResponse {
|
|
36
|
+
readonly statusCode: number;
|
|
37
|
+
private _headers;
|
|
38
|
+
private _body;
|
|
39
|
+
constructor(statusCode: number, content: string);
|
|
40
|
+
get headers(): Record<string, string>;
|
|
41
|
+
setHeader(name: string, value: string): void;
|
|
42
|
+
get body(): Uint8Array | null;
|
|
43
|
+
get bodyText(): string | null;
|
|
44
|
+
}
|
|
45
|
+
declare class ExpressResponseFactory implements GuardResponseFactory {
|
|
46
|
+
createResponse(content: string, statusCode: number): GuardResponse;
|
|
47
|
+
createRedirectResponse(url: string, statusCode: number): GuardResponse;
|
|
48
|
+
}
|
|
49
|
+
declare function sendGuardResponse(res: Response, guardResponse: GuardResponse): void;
|
|
50
|
+
|
|
51
|
+
export { ExpressGuardRequest, ExpressGuardResponse, ExpressResponseFactory, type SecurityMiddlewareOptions, configureCors, createSecurityMiddleware, guardBodyParser, guardUrlEncodedParser, sendGuardResponse };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
|
|
2
|
+
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
|
|
3
|
+
}) : x)(function(x) {
|
|
4
|
+
if (typeof require !== "undefined") return require.apply(this, arguments);
|
|
5
|
+
throw Error('Dynamic require of "' + x + '" is not supported');
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
// src/middleware.ts
|
|
9
|
+
import { SecurityConfigSchema, defaultLogger, initializeSecurityMiddleware } from "@guardcore/core";
|
|
10
|
+
|
|
11
|
+
// src/adapters.ts
|
|
12
|
+
var ExpressGuardRequest = class {
|
|
13
|
+
constructor(req) {
|
|
14
|
+
this.req = req;
|
|
15
|
+
const raw = req["rawBody"];
|
|
16
|
+
if (raw instanceof Uint8Array) {
|
|
17
|
+
this.rawBody = raw;
|
|
18
|
+
} else if (raw instanceof Buffer) {
|
|
19
|
+
this.rawBody = new Uint8Array(raw);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
_state = {};
|
|
23
|
+
rawBody = null;
|
|
24
|
+
get urlPath() {
|
|
25
|
+
return this.req.path;
|
|
26
|
+
}
|
|
27
|
+
get urlScheme() {
|
|
28
|
+
return this.req.protocol;
|
|
29
|
+
}
|
|
30
|
+
get urlFull() {
|
|
31
|
+
return `${this.req.protocol}://${this.req.get("host")}${this.req.originalUrl}`;
|
|
32
|
+
}
|
|
33
|
+
urlReplaceScheme(scheme) {
|
|
34
|
+
return this.urlFull.replace(/^https?/, scheme);
|
|
35
|
+
}
|
|
36
|
+
get method() {
|
|
37
|
+
return this.req.method;
|
|
38
|
+
}
|
|
39
|
+
get clientHost() {
|
|
40
|
+
return this.req.socket.remoteAddress ?? null;
|
|
41
|
+
}
|
|
42
|
+
get headers() {
|
|
43
|
+
return this.req.headers;
|
|
44
|
+
}
|
|
45
|
+
get queryParams() {
|
|
46
|
+
return this.req.query;
|
|
47
|
+
}
|
|
48
|
+
async body() {
|
|
49
|
+
return this.rawBody ?? new Uint8Array(0);
|
|
50
|
+
}
|
|
51
|
+
get state() {
|
|
52
|
+
return this._state;
|
|
53
|
+
}
|
|
54
|
+
get scope() {
|
|
55
|
+
return {};
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
var ExpressGuardResponse = class {
|
|
59
|
+
constructor(statusCode, content) {
|
|
60
|
+
this.statusCode = statusCode;
|
|
61
|
+
this._body = new TextEncoder().encode(content);
|
|
62
|
+
this._headers["content-type"] = "application/json";
|
|
63
|
+
}
|
|
64
|
+
_headers = {};
|
|
65
|
+
_body;
|
|
66
|
+
get headers() {
|
|
67
|
+
return this._headers;
|
|
68
|
+
}
|
|
69
|
+
setHeader(name, value) {
|
|
70
|
+
this._headers[name] = value;
|
|
71
|
+
}
|
|
72
|
+
get body() {
|
|
73
|
+
return this._body;
|
|
74
|
+
}
|
|
75
|
+
get bodyText() {
|
|
76
|
+
return this._body ? new TextDecoder().decode(this._body) : null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
var ExpressResponseFactory = class {
|
|
80
|
+
createResponse(content, statusCode) {
|
|
81
|
+
return new ExpressGuardResponse(statusCode, JSON.stringify({ detail: content }));
|
|
82
|
+
}
|
|
83
|
+
createRedirectResponse(url, statusCode) {
|
|
84
|
+
const resp = new ExpressGuardResponse(statusCode, "");
|
|
85
|
+
resp.setHeader("location", url);
|
|
86
|
+
return resp;
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
function sendGuardResponse(res, guardResponse) {
|
|
90
|
+
for (const [name, value] of Object.entries(guardResponse.headers)) {
|
|
91
|
+
res.setHeader(name, value);
|
|
92
|
+
}
|
|
93
|
+
if (guardResponse.headers["location"]) {
|
|
94
|
+
res.redirect(guardResponse.statusCode, guardResponse.headers["location"]);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
res.status(guardResponse.statusCode);
|
|
98
|
+
if (guardResponse.body) {
|
|
99
|
+
res.send(Buffer.from(guardResponse.body));
|
|
100
|
+
} else {
|
|
101
|
+
res.end();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// src/middleware.ts
|
|
106
|
+
function createSecurityMiddleware(options) {
|
|
107
|
+
const resolved = SecurityConfigSchema.parse(options.config);
|
|
108
|
+
const logger = resolved.logger ?? defaultLogger;
|
|
109
|
+
const responseFactory = new ExpressResponseFactory();
|
|
110
|
+
let initialized = false;
|
|
111
|
+
let components;
|
|
112
|
+
async function initialize() {
|
|
113
|
+
if (initialized) return;
|
|
114
|
+
components = await initializeSecurityMiddleware(
|
|
115
|
+
resolved,
|
|
116
|
+
logger,
|
|
117
|
+
responseFactory,
|
|
118
|
+
options.agentHandler,
|
|
119
|
+
options.geoIpHandler,
|
|
120
|
+
options.guardDecorator
|
|
121
|
+
);
|
|
122
|
+
initialized = true;
|
|
123
|
+
logger.info("Guard security middleware initialized");
|
|
124
|
+
}
|
|
125
|
+
return async function guardMiddleware(req, res, next) {
|
|
126
|
+
await initialize();
|
|
127
|
+
const startTime = performance.now();
|
|
128
|
+
const guardReq = new ExpressGuardRequest(req);
|
|
129
|
+
const passthrough = await components.bypassHandler.handlePassthrough(
|
|
130
|
+
guardReq,
|
|
131
|
+
async () => createPassthroughResponse()
|
|
132
|
+
);
|
|
133
|
+
if (passthrough) {
|
|
134
|
+
sendGuardResponse(res, passthrough);
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
const routeConfig = components.routeResolver.getRouteConfig(guardReq);
|
|
138
|
+
const bypass = await components.bypassHandler.handleSecurityBypass(
|
|
139
|
+
guardReq,
|
|
140
|
+
async () => createPassthroughResponse(),
|
|
141
|
+
routeConfig
|
|
142
|
+
);
|
|
143
|
+
if (bypass) {
|
|
144
|
+
sendGuardResponse(res, bypass);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const blockResponse = await components.pipeline.execute(guardReq);
|
|
148
|
+
if (blockResponse) {
|
|
149
|
+
sendGuardResponse(res, blockResponse);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
if (routeConfig && routeConfig.behaviorRules.length > 0) {
|
|
153
|
+
const clientIp = guardReq.clientHost ?? "unknown";
|
|
154
|
+
await components.behavioralProcessor.processUsageRules(guardReq, clientIp, routeConfig);
|
|
155
|
+
}
|
|
156
|
+
const originalEnd = res.end;
|
|
157
|
+
const chunks = [];
|
|
158
|
+
res.end = function(chunk, ...args) {
|
|
159
|
+
if (chunk) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
160
|
+
const responseTime = (performance.now() - startTime) / 1e3;
|
|
161
|
+
const body = Buffer.concat(chunks);
|
|
162
|
+
const capturedResponse = {
|
|
163
|
+
statusCode: res.statusCode,
|
|
164
|
+
headers: Object.fromEntries(
|
|
165
|
+
Object.entries(res.getHeaders()).map(([k, v]) => [k, String(v)])
|
|
166
|
+
),
|
|
167
|
+
setHeader(name, value) {
|
|
168
|
+
res.setHeader(name, value);
|
|
169
|
+
},
|
|
170
|
+
body: new Uint8Array(body),
|
|
171
|
+
bodyText: body.toString("utf-8")
|
|
172
|
+
};
|
|
173
|
+
components.errorResponseFactory.processResponse(
|
|
174
|
+
guardReq,
|
|
175
|
+
capturedResponse,
|
|
176
|
+
responseTime,
|
|
177
|
+
routeConfig ?? null,
|
|
178
|
+
routeConfig ? async (request, response, clientIp, rc) => {
|
|
179
|
+
await components.behavioralProcessor.processReturnRules(request, response, clientIp, rc);
|
|
180
|
+
} : void 0
|
|
181
|
+
).catch(() => {
|
|
182
|
+
});
|
|
183
|
+
return originalEnd.apply(res, [chunk, ...args]);
|
|
184
|
+
};
|
|
185
|
+
next();
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
function createPassthroughResponse() {
|
|
189
|
+
return {
|
|
190
|
+
statusCode: 200,
|
|
191
|
+
headers: {},
|
|
192
|
+
setHeader() {
|
|
193
|
+
},
|
|
194
|
+
body: null,
|
|
195
|
+
bodyText: null
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// src/cors.ts
|
|
200
|
+
function configureCors(app, config) {
|
|
201
|
+
if (!config.enableCors) return;
|
|
202
|
+
try {
|
|
203
|
+
const corsMiddleware = __require("cors");
|
|
204
|
+
app.use(corsMiddleware({
|
|
205
|
+
origin: config.corsAllowOrigins,
|
|
206
|
+
methods: config.corsAllowMethods,
|
|
207
|
+
allowedHeaders: config.corsAllowHeaders,
|
|
208
|
+
credentials: config.corsAllowCredentials,
|
|
209
|
+
exposedHeaders: config.corsExposeHeaders,
|
|
210
|
+
maxAge: config.corsMaxAge
|
|
211
|
+
}));
|
|
212
|
+
} catch {
|
|
213
|
+
throw new Error(
|
|
214
|
+
'@guardcore/express: CORS is enabled but the "cors" package is not installed. Run: pnpm add cors'
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// src/body-parser.ts
|
|
220
|
+
import express from "express";
|
|
221
|
+
function guardBodyParser() {
|
|
222
|
+
return express.json({
|
|
223
|
+
verify: (req, _res, buf, _encoding) => {
|
|
224
|
+
req["rawBody"] = buf;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
function guardUrlEncodedParser() {
|
|
229
|
+
return express.urlencoded({
|
|
230
|
+
extended: true,
|
|
231
|
+
verify: (req, _res, buf, _encoding) => {
|
|
232
|
+
req["rawBody"] = buf;
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// src/index.ts
|
|
238
|
+
import {
|
|
239
|
+
SecurityConfigSchema as SecurityConfigSchema2,
|
|
240
|
+
BaseSecurityDecorator,
|
|
241
|
+
SecurityDecorator,
|
|
242
|
+
RouteConfig,
|
|
243
|
+
BehaviorRule,
|
|
244
|
+
defaultLogger as defaultLogger2
|
|
245
|
+
} from "@guardcore/core";
|
|
246
|
+
export {
|
|
247
|
+
BaseSecurityDecorator,
|
|
248
|
+
BehaviorRule,
|
|
249
|
+
ExpressGuardRequest,
|
|
250
|
+
ExpressGuardResponse,
|
|
251
|
+
ExpressResponseFactory,
|
|
252
|
+
RouteConfig,
|
|
253
|
+
SecurityConfigSchema2 as SecurityConfigSchema,
|
|
254
|
+
SecurityDecorator,
|
|
255
|
+
configureCors,
|
|
256
|
+
createSecurityMiddleware,
|
|
257
|
+
defaultLogger2 as defaultLogger,
|
|
258
|
+
guardBodyParser,
|
|
259
|
+
guardUrlEncodedParser,
|
|
260
|
+
sendGuardResponse
|
|
261
|
+
};
|
|
262
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/middleware.ts","../src/adapters.ts","../src/cors.ts","../src/body-parser.ts","../src/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction } from 'express';\nimport type {\n SecurityConfig,\n GuardRequest,\n GuardResponse,\n Logger,\n AgentHandlerProtocol,\n GeoIPHandler,\n SecurityMiddlewareComponents,\n RouteConfig,\n} from '@guardcore/core';\nimport { SecurityConfigSchema, defaultLogger, initializeSecurityMiddleware } from '@guardcore/core';\nimport { ExpressGuardRequest, ExpressResponseFactory, sendGuardResponse } from './adapters.js';\n\nexport interface SecurityMiddlewareOptions {\n config: SecurityConfig;\n agentHandler?: AgentHandlerProtocol;\n geoIpHandler?: GeoIPHandler;\n guardDecorator?: unknown;\n}\n\nexport function createSecurityMiddleware(options: SecurityMiddlewareOptions) {\n const resolved = SecurityConfigSchema.parse(options.config);\n const logger: Logger = resolved.logger ?? defaultLogger;\n const responseFactory = new ExpressResponseFactory();\n\n let initialized = false;\n let components: SecurityMiddlewareComponents;\n\n async function initialize(): Promise<void> {\n if (initialized) return;\n components = await initializeSecurityMiddleware(\n resolved, logger, responseFactory,\n options.agentHandler, options.geoIpHandler, options.guardDecorator,\n );\n initialized = true;\n logger.info('Guard security middleware initialized');\n }\n\n return async function guardMiddleware(req: Request, res: Response, next: NextFunction): Promise<void> {\n await initialize();\n\n const startTime = performance.now();\n const guardReq = new ExpressGuardRequest(req);\n\n const passthrough = await components.bypassHandler.handlePassthrough(\n guardReq,\n async () => createPassthroughResponse(),\n );\n if (passthrough) {\n sendGuardResponse(res, passthrough);\n return;\n }\n\n const routeConfig = components.routeResolver.getRouteConfig(guardReq);\n\n const bypass = await components.bypassHandler.handleSecurityBypass(\n guardReq,\n async () => createPassthroughResponse(),\n routeConfig,\n );\n if (bypass) {\n sendGuardResponse(res, bypass);\n return;\n }\n\n const blockResponse = await components.pipeline.execute(guardReq);\n if (blockResponse) {\n sendGuardResponse(res, blockResponse);\n return;\n }\n\n if (routeConfig && routeConfig.behaviorRules.length > 0) {\n const clientIp = guardReq.clientHost ?? 'unknown';\n await components.behavioralProcessor.processUsageRules(guardReq, clientIp, routeConfig);\n }\n\n const originalEnd = res.end;\n const chunks: Buffer[] = [];\n\n res.end = function (chunk: unknown, ...args: unknown[]): Response {\n if (chunk) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));\n\n const responseTime = (performance.now() - startTime) / 1000;\n const body = Buffer.concat(chunks);\n const capturedResponse: GuardResponse = {\n statusCode: res.statusCode,\n headers: Object.fromEntries(\n Object.entries(res.getHeaders()).map(([k, v]) => [k, String(v)]),\n ),\n setHeader(name: string, value: string) { res.setHeader(name, value); },\n body: new Uint8Array(body),\n bodyText: body.toString('utf-8'),\n };\n\n components.errorResponseFactory.processResponse(\n guardReq, capturedResponse, responseTime, routeConfig ?? null,\n routeConfig ? async (request: GuardRequest, response: GuardResponse, clientIp: string, rc: RouteConfig) => {\n await components.behavioralProcessor.processReturnRules(request, response, clientIp, rc);\n } : undefined,\n ).catch(() => {});\n\n return originalEnd.apply(res, [chunk, ...args] as Parameters<typeof originalEnd>);\n };\n\n next();\n };\n}\n\nfunction createPassthroughResponse(): GuardResponse {\n return {\n statusCode: 200,\n headers: {},\n setHeader() {},\n body: null,\n bodyText: null,\n };\n}\n","import type { Request, Response } from 'express';\nimport type { GuardRequest, GuardRequestState, GuardResponse, GuardResponseFactory } from '@guardcore/core';\n\nexport class ExpressGuardRequest implements GuardRequest {\n private _state: GuardRequestState = {};\n private rawBody: Uint8Array | null = null;\n\n constructor(private readonly req: Request) {\n const raw = (req as unknown as Record<string, unknown>)['rawBody'];\n if (raw instanceof Uint8Array) {\n this.rawBody = raw;\n } else if (raw instanceof Buffer) {\n this.rawBody = new Uint8Array(raw);\n }\n }\n\n get urlPath(): string { return this.req.path; }\n get urlScheme(): string { return this.req.protocol; }\n get urlFull(): string { return `${this.req.protocol}://${this.req.get('host')}${this.req.originalUrl}`; }\n urlReplaceScheme(scheme: string): string { return this.urlFull.replace(/^https?/, scheme); }\n get method(): string { return this.req.method; }\n get clientHost(): string | null { return this.req.socket.remoteAddress ?? null; }\n get headers(): Readonly<Record<string, string>> { return this.req.headers as Record<string, string>; }\n get queryParams(): Readonly<Record<string, string>> { return this.req.query as Record<string, string>; }\n async body(): Promise<Uint8Array> { return this.rawBody ?? new Uint8Array(0); }\n get state(): GuardRequestState { return this._state; }\n get scope(): Readonly<Record<string, unknown>> { return {}; }\n}\n\nexport class ExpressGuardResponse implements GuardResponse {\n private _headers: Record<string, string> = {};\n private _body: Uint8Array | null;\n\n constructor(\n readonly statusCode: number,\n content: string,\n ) {\n this._body = new TextEncoder().encode(content);\n this._headers['content-type'] = 'application/json';\n }\n\n get headers(): Record<string, string> { return this._headers; }\n setHeader(name: string, value: string): void { this._headers[name] = value; }\n get body(): Uint8Array | null { return this._body; }\n get bodyText(): string | null {\n return this._body ? new TextDecoder().decode(this._body) : null;\n }\n}\n\nexport class ExpressResponseFactory implements GuardResponseFactory {\n createResponse(content: string, statusCode: number): GuardResponse {\n return new ExpressGuardResponse(statusCode, JSON.stringify({ detail: content }));\n }\n\n createRedirectResponse(url: string, statusCode: number): GuardResponse {\n const resp = new ExpressGuardResponse(statusCode, '');\n resp.setHeader('location', url);\n return resp;\n }\n}\n\nexport function sendGuardResponse(res: Response, guardResponse: GuardResponse): void {\n for (const [name, value] of Object.entries(guardResponse.headers)) {\n res.setHeader(name, value);\n }\n\n if (guardResponse.headers['location']) {\n res.redirect(guardResponse.statusCode, guardResponse.headers['location']);\n return;\n }\n\n res.status(guardResponse.statusCode);\n if (guardResponse.body) {\n res.send(Buffer.from(guardResponse.body));\n } else {\n res.end();\n }\n}\n","import type { Express } from 'express';\nimport type { ResolvedSecurityConfig } from '@guardcore/core';\n\nexport function configureCors(app: Express, config: ResolvedSecurityConfig): void {\n if (!config.enableCors) return;\n\n try {\n const corsMiddleware = require('cors');\n app.use(corsMiddleware({\n origin: config.corsAllowOrigins,\n methods: config.corsAllowMethods,\n allowedHeaders: config.corsAllowHeaders,\n credentials: config.corsAllowCredentials,\n exposedHeaders: config.corsExposeHeaders,\n maxAge: config.corsMaxAge,\n }));\n } catch {\n throw new Error(\n '@guardcore/express: CORS is enabled but the \"cors\" package is not installed. ' +\n 'Run: pnpm add cors',\n );\n }\n}\n","import type { Request, Response, NextFunction, RequestHandler } from 'express';\nimport express from 'express';\n\nexport function guardBodyParser(): RequestHandler {\n return express.json({\n verify: (req: Request, _res: Response, buf: Buffer, _encoding: string) => {\n (req as unknown as Record<string, unknown>)['rawBody'] = buf;\n },\n });\n}\n\nexport function guardUrlEncodedParser(): RequestHandler {\n return express.urlencoded({\n extended: true,\n verify: (req: Request, _res: Response, buf: Buffer, _encoding: string) => {\n (req as unknown as Record<string, unknown>)['rawBody'] = buf;\n },\n });\n}\n","export { createSecurityMiddleware } from './middleware.js';\nexport type { SecurityMiddlewareOptions } from './middleware.js';\nexport { configureCors } from './cors.js';\nexport { guardBodyParser, guardUrlEncodedParser } from './body-parser.js';\nexport { ExpressGuardRequest, ExpressGuardResponse, ExpressResponseFactory, sendGuardResponse } from './adapters.js';\n\nexport {\n SecurityConfigSchema,\n BaseSecurityDecorator,\n SecurityDecorator,\n RouteConfig,\n BehaviorRule,\n defaultLogger,\n} from '@guardcore/core';\n\nexport type {\n SecurityConfig,\n ResolvedSecurityConfig,\n GuardRequest,\n GuardResponse,\n Logger,\n SecurityMiddlewareComponents,\n HandlerRegistry,\n} from '@guardcore/core';\n"],"mappings":"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","names":["SecurityConfigSchema","defaultLogger"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@guardcore/express",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Express adapter for @guardcore/core security middleware",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup",
|
|
21
|
+
"test": "vitest run",
|
|
22
|
+
"lint": "tsc --noEmit",
|
|
23
|
+
"clean": "rm -rf dist"
|
|
24
|
+
},
|
|
25
|
+
"dependencies": {
|
|
26
|
+
"@guardcore/core": "workspace:*"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"tsup": "^8",
|
|
30
|
+
"vitest": "^4",
|
|
31
|
+
"typescript": "~5.9",
|
|
32
|
+
"@types/express": "^5"
|
|
33
|
+
},
|
|
34
|
+
"peerDependencies": {
|
|
35
|
+
"express": "^4 || ^5",
|
|
36
|
+
"cors": "^2"
|
|
37
|
+
},
|
|
38
|
+
"peerDependenciesMeta": {
|
|
39
|
+
"cors": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"license": "MIT",
|
|
44
|
+
"engines": {
|
|
45
|
+
"node": ">=18"
|
|
46
|
+
},
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/rennf93/guard-core-ts.git",
|
|
50
|
+
"directory": "packages/express"
|
|
51
|
+
},
|
|
52
|
+
"publishConfig": {
|
|
53
|
+
"access": "public"
|
|
54
|
+
}
|
|
55
|
+
}
|