@kavachos/express 0.0.2 → 0.0.4

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.
@@ -0,0 +1,35 @@
1
+ import { Router } from 'express';
2
+ import { Kavach } from 'kavachos';
3
+ import { McpAuthModule } from 'kavachos/mcp';
4
+
5
+ /**
6
+ * Create an Express Router with all KavachOS REST API routes mounted.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import express from 'express';
11
+ * import { createKavach } from 'kavachos';
12
+ * import { kavachExpress } from '@kavachos/express';
13
+ *
14
+ * const app = express();
15
+ * app.use(express.json());
16
+ * app.use(express.urlencoded({ extended: true }));
17
+ *
18
+ * const kavach = createKavach({ database: { provider: 'sqlite', url: 'kavach.db' } });
19
+ * app.use('/auth', kavachExpress(kavach));
20
+ *
21
+ * app.listen(3000);
22
+ * ```
23
+ *
24
+ * With MCP OAuth 2.1:
25
+ * ```typescript
26
+ * import { createMcpModule } from 'kavachos/mcp';
27
+ * const mcp = createMcpModule({ ... });
28
+ * app.use('/auth', kavachExpress(kavach, { mcp }));
29
+ * ```
30
+ */
31
+ declare function kavachExpress(kavach: Kavach, options?: {
32
+ mcp?: McpAuthModule;
33
+ }): Router;
34
+
35
+ export { kavachExpress };
package/dist/index.js ADDED
@@ -0,0 +1,589 @@
1
+ import { Router } from 'express';
2
+ import { z } from 'zod';
3
+
4
+ // src/adapter.ts
5
+ var PermissionConstraintsSchema = z.object({
6
+ maxCallsPerHour: z.number().int().positive().optional(),
7
+ allowedArgPatterns: z.array(z.string()).optional(),
8
+ requireApproval: z.boolean().optional(),
9
+ timeWindow: z.object({
10
+ start: z.string(),
11
+ end: z.string()
12
+ }).optional(),
13
+ ipAllowlist: z.array(z.string()).optional()
14
+ });
15
+ var PermissionSchema = z.object({
16
+ resource: z.string().min(1),
17
+ actions: z.array(z.string().min(1)).min(1),
18
+ constraints: PermissionConstraintsSchema.optional()
19
+ });
20
+ var CreateAgentSchema = z.object({
21
+ ownerId: z.string().min(1),
22
+ name: z.string().min(1),
23
+ type: z.enum(["autonomous", "delegated", "service"]),
24
+ permissions: z.array(PermissionSchema).min(1),
25
+ expiresAt: z.coerce.date().optional(),
26
+ metadata: z.record(z.unknown()).optional()
27
+ });
28
+ var UpdateAgentSchema = z.object({
29
+ name: z.string().min(1).optional(),
30
+ permissions: z.array(PermissionSchema).optional(),
31
+ expiresAt: z.coerce.date().optional(),
32
+ metadata: z.record(z.unknown()).optional()
33
+ });
34
+ var AuthorizeSchema = z.object({
35
+ agentId: z.string().min(1),
36
+ action: z.string().min(1),
37
+ resource: z.string().min(1),
38
+ arguments: z.record(z.unknown()).optional()
39
+ });
40
+ var AuthorizeByTokenSchema = z.object({
41
+ action: z.string().min(1),
42
+ resource: z.string().min(1),
43
+ arguments: z.record(z.unknown()).optional()
44
+ });
45
+ var DelegateSchema = z.object({
46
+ fromAgent: z.string().min(1),
47
+ toAgent: z.string().min(1),
48
+ permissions: z.array(PermissionSchema).min(1),
49
+ expiresAt: z.coerce.date(),
50
+ maxDepth: z.number().int().positive().optional()
51
+ });
52
+ function sendOk(res, data, status = 200) {
53
+ res.status(status).json({ data });
54
+ }
55
+ function sendCreated(res, data) {
56
+ sendOk(res, data, 201);
57
+ }
58
+ function sendNoContent(res) {
59
+ res.status(204).end();
60
+ }
61
+ function sendError(res, code, message, status) {
62
+ res.status(status).json({ error: { code, message } });
63
+ }
64
+ function sendBadRequest(res, message) {
65
+ sendError(res, "BAD_REQUEST", message, 400);
66
+ }
67
+ function sendUnauthorized(res, message = "Unauthorized") {
68
+ sendError(res, "UNAUTHORIZED", message, 401);
69
+ }
70
+ function sendNotFound(res, message = "Not found") {
71
+ sendError(res, "NOT_FOUND", message, 404);
72
+ }
73
+ function sendInternalError(res, message = "Internal server error") {
74
+ sendError(res, "INTERNAL_ERROR", message, 500);
75
+ }
76
+ function sendValidationError(res, issues) {
77
+ const message = issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ");
78
+ sendBadRequest(res, `Validation failed: ${message}`);
79
+ }
80
+ var MCP_CORS_HEADERS = {
81
+ "Access-Control-Allow-Origin": "*",
82
+ "Access-Control-Allow-Methods": "GET, POST, OPTIONS",
83
+ "Access-Control-Allow-Headers": "Content-Type, Authorization",
84
+ "Access-Control-Max-Age": "86400"
85
+ };
86
+ function setMcpCors(res) {
87
+ for (const [key, value] of Object.entries(MCP_CORS_HEADERS)) {
88
+ res.setHeader(key, value);
89
+ }
90
+ }
91
+ function sendMcpOk(res, data, status = 200) {
92
+ setMcpCors(res);
93
+ res.status(status).json(data);
94
+ }
95
+ function sendMcpError(res, code, message, status) {
96
+ setMcpCors(res);
97
+ res.status(status).json({ error: code, error_description: message });
98
+ }
99
+ function sendMcpNoStore(res, data, status = 200) {
100
+ setMcpCors(res);
101
+ res.setHeader("Cache-Control", "no-store");
102
+ res.setHeader("Pragma", "no-cache");
103
+ res.status(status).json(data);
104
+ }
105
+ function param(req, name) {
106
+ const val = req.params[name];
107
+ return Array.isArray(val) ? val[0] ?? "" : val ?? "";
108
+ }
109
+ function buildWebRequest(req) {
110
+ const protocol = req.protocol ?? "http";
111
+ const host = req.headers.host ?? "localhost";
112
+ const url = `${protocol}://${host}${req.originalUrl ?? req.url}`;
113
+ const headers = new Headers();
114
+ for (const [key, value] of Object.entries(req.headers)) {
115
+ if (value !== void 0) {
116
+ if (Array.isArray(value)) {
117
+ for (const v of value) {
118
+ headers.append(key, v);
119
+ }
120
+ } else {
121
+ headers.set(key, value);
122
+ }
123
+ }
124
+ }
125
+ let body = null;
126
+ if (req.method !== "GET" && req.method !== "HEAD" && req.body !== void 0) {
127
+ const contentType = req.headers["content-type"] ?? "";
128
+ if (contentType.includes("application/x-www-form-urlencoded")) {
129
+ const params = new URLSearchParams();
130
+ for (const [k, v] of Object.entries(req.body)) {
131
+ params.set(k, v);
132
+ }
133
+ body = params.toString();
134
+ } else {
135
+ body = JSON.stringify(req.body);
136
+ }
137
+ }
138
+ return new Request(url, {
139
+ method: req.method,
140
+ headers,
141
+ body: body ?? void 0
142
+ });
143
+ }
144
+ function kavachExpress(kavach, options) {
145
+ const router = Router();
146
+ const mcp = options?.mcp;
147
+ router.post("/agents", (req, res) => {
148
+ const parsed = CreateAgentSchema.safeParse(req.body);
149
+ if (!parsed.success) {
150
+ sendValidationError(res, parsed.error.issues);
151
+ return;
152
+ }
153
+ const input = {
154
+ ...parsed.data,
155
+ permissions: parsed.data.permissions
156
+ };
157
+ kavach.agent.create(input).then((agent) => sendCreated(res, agent)).catch((err) => {
158
+ const message = err instanceof Error ? err.message : "Failed to create agent";
159
+ sendInternalError(res, message);
160
+ });
161
+ });
162
+ router.get("/agents", (req, res) => {
163
+ const filter = {};
164
+ const { userId, status, type } = req.query;
165
+ if (typeof userId === "string") filter.userId = userId;
166
+ if (typeof status === "string" && ["active", "revoked", "expired"].includes(status)) {
167
+ filter.status = status;
168
+ }
169
+ if (typeof type === "string" && ["autonomous", "delegated", "service"].includes(type)) {
170
+ filter.type = type;
171
+ }
172
+ kavach.agent.list(filter).then((agents) => sendOk(res, agents)).catch((err) => {
173
+ const message = err instanceof Error ? err.message : "Failed to list agents";
174
+ sendInternalError(res, message);
175
+ });
176
+ });
177
+ router.get("/agents/:id", (req, res) => {
178
+ const id = param(req, "id");
179
+ kavach.agent.get(id).then((agent) => {
180
+ if (!agent) {
181
+ sendNotFound(res, `Agent "${id}" not found`);
182
+ return;
183
+ }
184
+ sendOk(res, agent);
185
+ }).catch((err) => {
186
+ const message = err instanceof Error ? err.message : "Failed to get agent";
187
+ sendInternalError(res, message);
188
+ });
189
+ });
190
+ router.patch("/agents/:id", (req, res) => {
191
+ const id = param(req, "id");
192
+ const parsed = UpdateAgentSchema.safeParse(req.body);
193
+ if (!parsed.success) {
194
+ sendValidationError(res, parsed.error.issues);
195
+ return;
196
+ }
197
+ const input = {
198
+ ...parsed.data,
199
+ permissions: parsed.data.permissions
200
+ };
201
+ kavach.agent.update(id, input).then((agent) => sendOk(res, agent)).catch((err) => {
202
+ const message = err instanceof Error ? err.message : "Failed to update agent";
203
+ if (message.includes("not found")) {
204
+ sendNotFound(res, message);
205
+ return;
206
+ }
207
+ sendInternalError(res, message);
208
+ });
209
+ });
210
+ router.delete("/agents/:id", (req, res) => {
211
+ const id = param(req, "id");
212
+ kavach.agent.revoke(id).then(() => sendNoContent(res)).catch((err) => {
213
+ const message = err instanceof Error ? err.message : "Failed to revoke agent";
214
+ if (message.includes("not found")) {
215
+ sendNotFound(res, message);
216
+ return;
217
+ }
218
+ sendInternalError(res, message);
219
+ });
220
+ });
221
+ router.post("/agents/:id/rotate", (req, res) => {
222
+ const id = param(req, "id");
223
+ kavach.agent.rotate(id).then((agent) => sendOk(res, agent)).catch((err) => {
224
+ const message = err instanceof Error ? err.message : "Failed to rotate agent token";
225
+ if (message.includes("not found")) {
226
+ sendNotFound(res, message);
227
+ return;
228
+ }
229
+ sendInternalError(res, message);
230
+ });
231
+ });
232
+ router.post("/authorize", (req, res) => {
233
+ const parsed = AuthorizeSchema.safeParse(req.body);
234
+ if (!parsed.success) {
235
+ sendValidationError(res, parsed.error.issues);
236
+ return;
237
+ }
238
+ const xForwardedFor = req.headers["x-forwarded-for"];
239
+ const ip = (Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor?.split(",")[0]?.trim()) ?? req.ip ?? void 0;
240
+ const userAgent = (Array.isArray(req.headers["user-agent"]) ? req.headers["user-agent"][0] : req.headers["user-agent"]) ?? void 0;
241
+ kavach.authorize(
242
+ parsed.data.agentId,
243
+ {
244
+ action: parsed.data.action,
245
+ resource: parsed.data.resource,
246
+ arguments: parsed.data.arguments
247
+ },
248
+ { ip, userAgent }
249
+ ).then((result) => {
250
+ const status = result.allowed ? 200 : 403;
251
+ res.status(status).json({ data: result });
252
+ }).catch((err) => {
253
+ const message = err instanceof Error ? err.message : "Authorization check failed";
254
+ sendInternalError(res, message);
255
+ });
256
+ });
257
+ router.post("/authorize/token", (req, res) => {
258
+ const authHeader = req.headers.authorization;
259
+ if (!authHeader?.startsWith("Bearer ")) {
260
+ sendUnauthorized(res, "Missing or invalid Authorization header");
261
+ return;
262
+ }
263
+ const token = authHeader.slice(7);
264
+ const parsed = AuthorizeByTokenSchema.safeParse(req.body);
265
+ if (!parsed.success) {
266
+ sendValidationError(res, parsed.error.issues);
267
+ return;
268
+ }
269
+ const xForwardedFor = req.headers["x-forwarded-for"];
270
+ const ip = (Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor?.split(",")[0]?.trim()) ?? req.ip ?? void 0;
271
+ const userAgent = (Array.isArray(req.headers["user-agent"]) ? req.headers["user-agent"][0] : req.headers["user-agent"]) ?? void 0;
272
+ kavach.authorizeByToken(
273
+ token,
274
+ {
275
+ action: parsed.data.action,
276
+ resource: parsed.data.resource,
277
+ arguments: parsed.data.arguments
278
+ },
279
+ { ip, userAgent }
280
+ ).then((result) => {
281
+ const status = result.allowed ? 200 : 403;
282
+ res.status(status).json({ data: result });
283
+ }).catch((err) => {
284
+ const message = err instanceof Error ? err.message : "Authorization check failed";
285
+ sendInternalError(res, message);
286
+ });
287
+ });
288
+ router.post("/delegations", (req, res) => {
289
+ const parsed = DelegateSchema.safeParse(req.body);
290
+ if (!parsed.success) {
291
+ sendValidationError(res, parsed.error.issues);
292
+ return;
293
+ }
294
+ const input = {
295
+ ...parsed.data,
296
+ permissions: parsed.data.permissions
297
+ };
298
+ kavach.delegate(input).then((chain) => sendCreated(res, chain)).catch((err) => {
299
+ const message = err instanceof Error ? err.message : "Failed to create delegation";
300
+ if (message.includes("not found")) {
301
+ sendNotFound(res, message);
302
+ return;
303
+ }
304
+ if (message.includes("exceeds") || message.includes("depth")) {
305
+ sendBadRequest(res, message);
306
+ return;
307
+ }
308
+ sendInternalError(res, message);
309
+ });
310
+ });
311
+ router.delete("/delegations/:id", (req, res) => {
312
+ const id = param(req, "id");
313
+ kavach.delegation.revoke(id).then(() => sendNoContent(res)).catch((err) => {
314
+ const message = err instanceof Error ? err.message : "Failed to revoke delegation";
315
+ if (message.includes("not found")) {
316
+ sendNotFound(res, message);
317
+ return;
318
+ }
319
+ sendInternalError(res, message);
320
+ });
321
+ });
322
+ router.get("/delegations/:agentId", (req, res) => {
323
+ const agentId = param(req, "agentId");
324
+ kavach.delegation.listChains(agentId).then((chains) => sendOk(res, chains)).catch((err) => {
325
+ const message = err instanceof Error ? err.message : "Failed to list delegation chains";
326
+ sendInternalError(res, message);
327
+ });
328
+ });
329
+ router.get("/audit", (req, res) => {
330
+ const filter = {};
331
+ const { agentId, userId, since, until, actions, result, limit, offset } = req.query;
332
+ if (typeof agentId === "string") filter.agentId = agentId;
333
+ if (typeof userId === "string") filter.userId = userId;
334
+ if (typeof since === "string") {
335
+ const d = new Date(since);
336
+ if (!Number.isNaN(d.getTime())) filter.since = d;
337
+ }
338
+ if (typeof until === "string") {
339
+ const d = new Date(until);
340
+ if (!Number.isNaN(d.getTime())) filter.until = d;
341
+ }
342
+ if (typeof actions === "string") {
343
+ filter.actions = actions.split(",").map((a) => a.trim());
344
+ }
345
+ if (typeof result === "string" && ["allowed", "denied", "rate_limited"].includes(result)) {
346
+ filter.result = result;
347
+ }
348
+ if (typeof limit === "string") {
349
+ const n = Number.parseInt(limit, 10);
350
+ if (!Number.isNaN(n) && n > 0) filter.limit = n;
351
+ }
352
+ if (typeof offset === "string") {
353
+ const n = Number.parseInt(offset, 10);
354
+ if (!Number.isNaN(n) && n >= 0) filter.offset = n;
355
+ }
356
+ kavach.audit.query(filter).then((entries) => sendOk(res, entries)).catch((err) => {
357
+ const message = err instanceof Error ? err.message : "Failed to query audit logs";
358
+ sendInternalError(res, message);
359
+ });
360
+ });
361
+ router.get("/audit/export", (req, res) => {
362
+ const format = req.query.format ?? "json";
363
+ if (format !== "json" && format !== "csv") {
364
+ sendBadRequest(res, 'format must be "json" or "csv"');
365
+ return;
366
+ }
367
+ const options2 = { format };
368
+ const { since, until } = req.query;
369
+ if (typeof since === "string") {
370
+ const d = new Date(since);
371
+ if (!Number.isNaN(d.getTime())) options2.since = d;
372
+ }
373
+ if (typeof until === "string") {
374
+ const d = new Date(until);
375
+ if (!Number.isNaN(d.getTime())) options2.until = d;
376
+ }
377
+ kavach.audit.export(options2).then((exported) => {
378
+ const contentType = format === "csv" ? "text/csv" : "application/json";
379
+ res.setHeader("Content-Type", contentType);
380
+ res.setHeader("Content-Disposition", `attachment; filename="audit-export.${format}"`);
381
+ res.status(200).send(exported);
382
+ }).catch((err) => {
383
+ const message = err instanceof Error ? err.message : "Failed to export audit logs";
384
+ sendInternalError(res, message);
385
+ });
386
+ });
387
+ router.options("/.well-known/*path", (_req, res) => {
388
+ setMcpCors(res);
389
+ res.status(204).end();
390
+ });
391
+ router.options("/mcp/*path", (_req, res) => {
392
+ setMcpCors(res);
393
+ res.status(204).end();
394
+ });
395
+ router.get("/.well-known/oauth-authorization-server", (_req, res) => {
396
+ if (!mcp) {
397
+ sendNotFound(res, "MCP module not configured");
398
+ return;
399
+ }
400
+ const metadata = mcp.getMetadata();
401
+ sendMcpOk(res, metadata);
402
+ });
403
+ router.get("/.well-known/oauth-protected-resource", (_req, res) => {
404
+ if (!mcp) {
405
+ sendNotFound(res, "MCP module not configured");
406
+ return;
407
+ }
408
+ const metadata = mcp.getProtectedResourceMetadata();
409
+ sendMcpOk(res, metadata);
410
+ });
411
+ router.post("/mcp/register", (req, res) => {
412
+ if (!mcp) {
413
+ sendNotFound(res, "MCP module not configured");
414
+ return;
415
+ }
416
+ mcp.registerClient(req.body).then((result) => {
417
+ if (!result.success) {
418
+ sendMcpError(res, "invalid_client_metadata", result.error.message, 400);
419
+ return;
420
+ }
421
+ sendMcpNoStore(res, result.data, 201);
422
+ }).catch((err) => {
423
+ const message = err instanceof Error ? err.message : "Registration failed";
424
+ sendMcpError(res, "server_error", message, 500);
425
+ });
426
+ });
427
+ router.get("/mcp/authorize", (req, res) => {
428
+ if (!mcp) {
429
+ sendNotFound(res, "MCP module not configured");
430
+ return;
431
+ }
432
+ const webRequest = buildWebRequest(req);
433
+ mcp.authorize(webRequest).then((result) => {
434
+ if (!result.success) {
435
+ if (result.error.code === "LOGIN_REQUIRED") {
436
+ const details = result.error.details;
437
+ if (details?.loginPage) {
438
+ const loginUrl = new URL(details.loginPage);
439
+ if (details.returnTo) {
440
+ loginUrl.searchParams.set("returnTo", details.returnTo);
441
+ }
442
+ res.redirect(302, loginUrl.toString());
443
+ return;
444
+ }
445
+ }
446
+ sendMcpError(res, result.error.code.toLowerCase(), result.error.message, 400);
447
+ return;
448
+ }
449
+ res.redirect(302, result.data.redirectUri);
450
+ }).catch((err) => {
451
+ const message = err instanceof Error ? err.message : "Authorization failed";
452
+ sendMcpError(res, "server_error", message, 500);
453
+ });
454
+ });
455
+ router.post("/mcp/token", (req, res) => {
456
+ if (!mcp) {
457
+ sendNotFound(res, "MCP module not configured");
458
+ return;
459
+ }
460
+ const webRequest = buildWebRequest(req);
461
+ mcp.token(webRequest).then((result) => {
462
+ if (!result.success) {
463
+ const status = result.error.code === "INVALID_CLIENT" ? 401 : 400;
464
+ sendMcpNoStore(
465
+ res,
466
+ {
467
+ error: result.error.code.toLowerCase(),
468
+ error_description: result.error.message
469
+ },
470
+ status
471
+ );
472
+ return;
473
+ }
474
+ sendMcpNoStore(res, result.data);
475
+ }).catch((err) => {
476
+ const message = err instanceof Error ? err.message : "Token exchange failed";
477
+ sendMcpNoStore(res, { error: "server_error", error_description: message }, 500);
478
+ });
479
+ });
480
+ router.get("/dashboard/stats", (_req, res) => {
481
+ Promise.all([
482
+ kavach.agent.list(),
483
+ kavach.audit.query({
484
+ since: new Date(Date.now() - 24 * 60 * 60 * 1e3),
485
+ limit: 1e3
486
+ })
487
+ ]).then(([agents, recentAudit]) => {
488
+ const ownerIds = new Set(agents.map((a) => a.ownerId));
489
+ const activeAgents = agents.filter((a) => a.status === "active");
490
+ const revokedAgents = agents.filter((a) => a.status === "revoked");
491
+ const expiredAgents = agents.filter((a) => a.status === "expired");
492
+ const stats = {
493
+ agents: {
494
+ total: agents.length,
495
+ active: activeAgents.length,
496
+ revoked: revokedAgents.length,
497
+ expired: expiredAgents.length
498
+ },
499
+ users: {
500
+ total: ownerIds.size
501
+ },
502
+ audit: {
503
+ last24h: recentAudit.length,
504
+ allowed: recentAudit.filter((e) => e.result === "allowed").length,
505
+ denied: recentAudit.filter((e) => e.result === "denied").length,
506
+ rateLimited: recentAudit.filter((e) => e.result === "rate_limited").length
507
+ }
508
+ };
509
+ sendOk(res, stats);
510
+ }).catch((err) => {
511
+ const message = err instanceof Error ? err.message : "Failed to fetch dashboard stats";
512
+ sendInternalError(res, message);
513
+ });
514
+ });
515
+ router.get("/dashboard/agents", (req, res) => {
516
+ const filter = {};
517
+ const { userId, status, type } = req.query;
518
+ if (typeof userId === "string") filter.userId = userId;
519
+ if (typeof status === "string" && ["active", "revoked", "expired"].includes(status)) {
520
+ filter.status = status;
521
+ }
522
+ if (typeof type === "string" && ["autonomous", "delegated", "service"].includes(type)) {
523
+ filter.type = type;
524
+ }
525
+ kavach.agent.list(filter).then((agents) => sendOk(res, agents)).catch((err) => {
526
+ const message = err instanceof Error ? err.message : "Failed to list agents";
527
+ sendInternalError(res, message);
528
+ });
529
+ });
530
+ router.get("/dashboard/audit", (req, res) => {
531
+ const filter = {};
532
+ const { agentId, userId, since, until, actions, result, limit, offset } = req.query;
533
+ if (typeof agentId === "string") filter.agentId = agentId;
534
+ if (typeof userId === "string") filter.userId = userId;
535
+ if (typeof since === "string") {
536
+ const d = new Date(since);
537
+ if (!Number.isNaN(d.getTime())) filter.since = d;
538
+ }
539
+ if (typeof until === "string") {
540
+ const d = new Date(until);
541
+ if (!Number.isNaN(d.getTime())) filter.until = d;
542
+ }
543
+ if (typeof actions === "string") {
544
+ filter.actions = actions.split(",").map((a) => a.trim());
545
+ }
546
+ if (typeof result === "string" && ["allowed", "denied", "rate_limited"].includes(result)) {
547
+ filter.result = result;
548
+ }
549
+ if (typeof limit === "string") {
550
+ const n = Number.parseInt(limit, 10);
551
+ if (!Number.isNaN(n) && n > 0) filter.limit = n;
552
+ }
553
+ if (typeof offset === "string") {
554
+ const n = Number.parseInt(offset, 10);
555
+ if (!Number.isNaN(n) && n >= 0) filter.offset = n;
556
+ }
557
+ kavach.audit.query(filter).then((entries) => sendOk(res, entries)).catch((err) => {
558
+ const message = err instanceof Error ? err.message : "Failed to query audit logs";
559
+ sendInternalError(res, message);
560
+ });
561
+ });
562
+ for (const endpoint of kavach.plugins.getEndpoints()) {
563
+ const method = endpoint.method.toLowerCase();
564
+ router[method](endpoint.path, (req, res) => {
565
+ const webReq = buildWebRequest(req);
566
+ kavach.plugins.handleRequest(webReq).then((response) => {
567
+ if (!response) {
568
+ res.status(404).end();
569
+ return;
570
+ }
571
+ res.status(response.status);
572
+ response.headers.forEach((value, key) => {
573
+ res.setHeader(key, value);
574
+ });
575
+ return response.text().then((body) => {
576
+ res.send(body);
577
+ });
578
+ }).catch((err) => {
579
+ const message = err instanceof Error ? err.message : "Plugin endpoint error";
580
+ sendInternalError(res, message);
581
+ });
582
+ });
583
+ }
584
+ return router;
585
+ }
586
+
587
+ export { kavachExpress };
588
+ //# sourceMappingURL=index.js.map
589
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapter.ts"],"names":["options"],"mappings":"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","file":"index.js","sourcesContent":["import type { Request, Response } from \"express\";\nimport { Router } from \"express\";\nimport type {\n\tAgentFilter,\n\tAuditFilter,\n\tCreateAgentInput,\n\tDelegateInput,\n\tKavach,\n\tPermission,\n\tUpdateAgentInput,\n} from \"kavachos\";\nimport type { McpAuthModule } from \"kavachos/mcp\";\nimport { z } from \"zod\";\n\n// ─── Zod Validation Schemas ──────────────────────────────────────────────────\n\nconst PermissionConstraintsSchema = z.object({\n\tmaxCallsPerHour: z.number().int().positive().optional(),\n\tallowedArgPatterns: z.array(z.string()).optional(),\n\trequireApproval: z.boolean().optional(),\n\ttimeWindow: z\n\t\t.object({\n\t\t\tstart: z.string(),\n\t\t\tend: z.string(),\n\t\t})\n\t\t.optional(),\n\tipAllowlist: z.array(z.string()).optional(),\n});\n\nconst PermissionSchema = z.object({\n\tresource: z.string().min(1),\n\tactions: z.array(z.string().min(1)).min(1),\n\tconstraints: PermissionConstraintsSchema.optional(),\n});\n\nconst CreateAgentSchema = z.object({\n\townerId: z.string().min(1),\n\tname: z.string().min(1),\n\ttype: z.enum([\"autonomous\", \"delegated\", \"service\"]),\n\tpermissions: z.array(PermissionSchema).min(1),\n\texpiresAt: z.coerce.date().optional(),\n\tmetadata: z.record(z.unknown()).optional(),\n});\n\nconst UpdateAgentSchema = z.object({\n\tname: z.string().min(1).optional(),\n\tpermissions: z.array(PermissionSchema).optional(),\n\texpiresAt: z.coerce.date().optional(),\n\tmetadata: z.record(z.unknown()).optional(),\n});\n\nconst AuthorizeSchema = z.object({\n\tagentId: z.string().min(1),\n\taction: z.string().min(1),\n\tresource: z.string().min(1),\n\targuments: z.record(z.unknown()).optional(),\n});\n\nconst AuthorizeByTokenSchema = z.object({\n\taction: z.string().min(1),\n\tresource: z.string().min(1),\n\targuments: z.record(z.unknown()).optional(),\n});\n\nconst DelegateSchema = z.object({\n\tfromAgent: z.string().min(1),\n\ttoAgent: z.string().min(1),\n\tpermissions: z.array(PermissionSchema).min(1),\n\texpiresAt: z.coerce.date(),\n\tmaxDepth: z.number().int().positive().optional(),\n});\n\n// ─── Response Helpers ────────────────────────────────────────────────────────\n\nfunction sendOk<T>(res: Response, data: T, status = 200): void {\n\tres.status(status).json({ data });\n}\n\nfunction sendCreated<T>(res: Response, data: T): void {\n\tsendOk(res, data, 201);\n}\n\nfunction sendNoContent(res: Response): void {\n\tres.status(204).end();\n}\n\nfunction sendError(res: Response, code: string, message: string, status: number): void {\n\tres.status(status).json({ error: { code, message } });\n}\n\nfunction sendBadRequest(res: Response, message: string): void {\n\tsendError(res, \"BAD_REQUEST\", message, 400);\n}\n\nfunction sendUnauthorized(res: Response, message = \"Unauthorized\"): void {\n\tsendError(res, \"UNAUTHORIZED\", message, 401);\n}\n\nfunction sendNotFound(res: Response, message = \"Not found\"): void {\n\tsendError(res, \"NOT_FOUND\", message, 404);\n}\n\nfunction sendInternalError(res: Response, message = \"Internal server error\"): void {\n\tsendError(res, \"INTERNAL_ERROR\", message, 500);\n}\n\nfunction sendValidationError(res: Response, issues: z.ZodIssue[]): void {\n\tconst message = issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\", \");\n\tsendBadRequest(res, `Validation failed: ${message}`);\n}\n\n// ─── MCP CORS Headers ────────────────────────────────────────────────────────\n\nconst MCP_CORS_HEADERS: Record<string, string> = {\n\t\"Access-Control-Allow-Origin\": \"*\",\n\t\"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\"Access-Control-Max-Age\": \"86400\",\n};\n\nfunction setMcpCors(res: Response): void {\n\tfor (const [key, value] of Object.entries(MCP_CORS_HEADERS)) {\n\t\tres.setHeader(key, value);\n\t}\n}\n\nfunction sendMcpOk<T>(res: Response, data: T, status = 200): void {\n\tsetMcpCors(res);\n\tres.status(status).json(data);\n}\n\nfunction sendMcpError(res: Response, code: string, message: string, status: number): void {\n\tsetMcpCors(res);\n\tres.status(status).json({ error: code, error_description: message });\n}\n\nfunction sendMcpNoStore<T>(res: Response, data: T, status = 200): void {\n\tsetMcpCors(res);\n\tres.setHeader(\"Cache-Control\", \"no-store\");\n\tres.setHeader(\"Pragma\", \"no-cache\");\n\tres.status(status).json(data);\n}\n\n/** Extract a route param as string (Express 5 params can be string | string[] | undefined) */\nfunction param(req: Request, name: string): string {\n\tconst val = req.params[name];\n\treturn Array.isArray(val) ? (val[0] ?? \"\") : (val ?? \"\");\n}\n\n// ─── Helpers for building a Web-compatible Request from Express ──────────────\n\nfunction buildWebRequest(req: Request): globalThis.Request {\n\tconst protocol = req.protocol ?? \"http\";\n\tconst host = req.headers.host ?? \"localhost\";\n\tconst url = `${protocol}://${host}${req.originalUrl ?? req.url}`;\n\n\tconst headers = new Headers();\n\tfor (const [key, value] of Object.entries(req.headers)) {\n\t\tif (value !== undefined) {\n\t\t\tif (Array.isArray(value)) {\n\t\t\t\tfor (const v of value) {\n\t\t\t\t\theaders.append(key, v);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\theaders.set(key, value);\n\t\t\t}\n\t\t}\n\t}\n\n\t// For POST requests encode body as URL-encoded or JSON\n\tlet body: string | null = null;\n\tif (req.method !== \"GET\" && req.method !== \"HEAD\" && req.body !== undefined) {\n\t\tconst contentType = req.headers[\"content-type\"] ?? \"\";\n\t\tif (contentType.includes(\"application/x-www-form-urlencoded\")) {\n\t\t\tconst params = new URLSearchParams();\n\t\t\tfor (const [k, v] of Object.entries(req.body as Record<string, string>)) {\n\t\t\t\tparams.set(k, v);\n\t\t\t}\n\t\t\tbody = params.toString();\n\t\t} else {\n\t\t\tbody = JSON.stringify(req.body);\n\t\t}\n\t}\n\n\treturn new Request(url, {\n\t\tmethod: req.method,\n\t\theaders,\n\t\tbody: body ?? undefined,\n\t});\n}\n\n// ─── Adapter Factory ─────────────────────────────────────────────────────────\n\n/**\n * Create an Express Router with all KavachOS REST API routes mounted.\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import { createKavach } from 'kavachos';\n * import { kavachExpress } from '@kavachos/express';\n *\n * const app = express();\n * app.use(express.json());\n * app.use(express.urlencoded({ extended: true }));\n *\n * const kavach = createKavach({ database: { provider: 'sqlite', url: 'kavach.db' } });\n * app.use('/auth', kavachExpress(kavach));\n *\n * app.listen(3000);\n * ```\n *\n * With MCP OAuth 2.1:\n * ```typescript\n * import { createMcpModule } from 'kavachos/mcp';\n * const mcp = createMcpModule({ ... });\n * app.use('/auth', kavachExpress(kavach, { mcp }));\n * ```\n */\nexport function kavachExpress(kavach: Kavach, options?: { mcp?: McpAuthModule }): Router {\n\tconst router = Router();\n\tconst mcp = options?.mcp;\n\n\t// ── Agent REST API ──────────────────────────────────────────────\n\n\t// POST /agents - create agent\n\trouter.post(\"/agents\", (req: Request, res: Response) => {\n\t\tconst parsed = CreateAgentSchema.safeParse(req.body);\n\t\tif (!parsed.success) {\n\t\t\tsendValidationError(res, parsed.error.issues);\n\t\t\treturn;\n\t\t}\n\t\tconst input: CreateAgentInput = {\n\t\t\t...parsed.data,\n\t\t\tpermissions: parsed.data.permissions as Permission[],\n\t\t};\n\t\tkavach.agent\n\t\t\t.create(input)\n\t\t\t.then((agent) => sendCreated(res, agent))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to create agent\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /agents - list agents\n\trouter.get(\"/agents\", (req: Request, res: Response) => {\n\t\tconst filter: AgentFilter = {};\n\t\tconst { userId, status, type } = req.query;\n\t\tif (typeof userId === \"string\") filter.userId = userId;\n\t\tif (typeof status === \"string\" && [\"active\", \"revoked\", \"expired\"].includes(status)) {\n\t\t\tfilter.status = status as AgentFilter[\"status\"];\n\t\t}\n\t\tif (typeof type === \"string\" && [\"autonomous\", \"delegated\", \"service\"].includes(type)) {\n\t\t\tfilter.type = type as AgentFilter[\"type\"];\n\t\t}\n\t\tkavach.agent\n\t\t\t.list(filter)\n\t\t\t.then((agents) => sendOk(res, agents))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list agents\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /agents/:id - get agent\n\trouter.get(\"/agents/:id\", (req: Request, res: Response) => {\n\t\tconst id = param(req, \"id\");\n\t\tkavach.agent\n\t\t\t.get(id)\n\t\t\t.then((agent) => {\n\t\t\t\tif (!agent) {\n\t\t\t\t\tsendNotFound(res, `Agent \"${id}\" not found`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendOk(res, agent);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to get agent\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// PATCH /agents/:id - update agent\n\trouter.patch(\"/agents/:id\", (req: Request, res: Response) => {\n\t\tconst id = param(req, \"id\");\n\t\tconst parsed = UpdateAgentSchema.safeParse(req.body);\n\t\tif (!parsed.success) {\n\t\t\tsendValidationError(res, parsed.error.issues);\n\t\t\treturn;\n\t\t}\n\t\tconst input: UpdateAgentInput = {\n\t\t\t...parsed.data,\n\t\t\tpermissions: parsed.data.permissions as Permission[] | undefined,\n\t\t};\n\t\tkavach.agent\n\t\t\t.update(id, input)\n\t\t\t.then((agent) => sendOk(res, agent))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to update agent\";\n\t\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\t\tsendNotFound(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// DELETE /agents/:id - revoke agent\n\trouter.delete(\"/agents/:id\", (req: Request, res: Response) => {\n\t\tconst id = param(req, \"id\");\n\t\tkavach.agent\n\t\t\t.revoke(id)\n\t\t\t.then(() => sendNoContent(res))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to revoke agent\";\n\t\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\t\tsendNotFound(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// POST /agents/:id/rotate - rotate token\n\trouter.post(\"/agents/:id/rotate\", (req: Request, res: Response) => {\n\t\tconst id = param(req, \"id\");\n\t\tkavach.agent\n\t\t\t.rotate(id)\n\t\t\t.then((agent) => sendOk(res, agent))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to rotate agent token\";\n\t\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\t\tsendNotFound(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// ── Authorization ───────────────────────────────────────────────\n\n\t// POST /authorize - authorize action by agentId\n\trouter.post(\"/authorize\", (req: Request, res: Response) => {\n\t\tconst parsed = AuthorizeSchema.safeParse(req.body);\n\t\tif (!parsed.success) {\n\t\t\tsendValidationError(res, parsed.error.issues);\n\t\t\treturn;\n\t\t}\n\t\tconst xForwardedFor = req.headers[\"x-forwarded-for\"];\n\t\tconst ip =\n\t\t\t(Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor?.split(\",\")[0]?.trim()) ??\n\t\t\treq.ip ??\n\t\t\tundefined;\n\t\tconst userAgent =\n\t\t\t(Array.isArray(req.headers[\"user-agent\"])\n\t\t\t\t? req.headers[\"user-agent\"][0]\n\t\t\t\t: req.headers[\"user-agent\"]) ?? undefined;\n\t\tkavach\n\t\t\t.authorize(\n\t\t\t\tparsed.data.agentId,\n\t\t\t\t{\n\t\t\t\t\taction: parsed.data.action,\n\t\t\t\t\tresource: parsed.data.resource,\n\t\t\t\t\targuments: parsed.data.arguments,\n\t\t\t\t},\n\t\t\t\t{ ip, userAgent },\n\t\t\t)\n\t\t\t.then((result) => {\n\t\t\t\tconst status = result.allowed ? 200 : 403;\n\t\t\t\tres.status(status).json({ data: result });\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Authorization check failed\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// POST /authorize/token - authorize by bearer token\n\trouter.post(\"/authorize/token\", (req: Request, res: Response) => {\n\t\tconst authHeader = req.headers.authorization;\n\t\tif (!authHeader?.startsWith(\"Bearer \")) {\n\t\t\tsendUnauthorized(res, \"Missing or invalid Authorization header\");\n\t\t\treturn;\n\t\t}\n\t\tconst token = authHeader.slice(7);\n\n\t\tconst parsed = AuthorizeByTokenSchema.safeParse(req.body);\n\t\tif (!parsed.success) {\n\t\t\tsendValidationError(res, parsed.error.issues);\n\t\t\treturn;\n\t\t}\n\t\tconst xForwardedFor = req.headers[\"x-forwarded-for\"];\n\t\tconst ip =\n\t\t\t(Array.isArray(xForwardedFor) ? xForwardedFor[0] : xForwardedFor?.split(\",\")[0]?.trim()) ??\n\t\t\treq.ip ??\n\t\t\tundefined;\n\t\tconst userAgent =\n\t\t\t(Array.isArray(req.headers[\"user-agent\"])\n\t\t\t\t? req.headers[\"user-agent\"][0]\n\t\t\t\t: req.headers[\"user-agent\"]) ?? undefined;\n\t\tkavach\n\t\t\t.authorizeByToken(\n\t\t\t\ttoken,\n\t\t\t\t{\n\t\t\t\t\taction: parsed.data.action,\n\t\t\t\t\tresource: parsed.data.resource,\n\t\t\t\t\targuments: parsed.data.arguments,\n\t\t\t\t},\n\t\t\t\t{ ip, userAgent },\n\t\t\t)\n\t\t\t.then((result) => {\n\t\t\t\tconst status = result.allowed ? 200 : 403;\n\t\t\t\tres.status(status).json({ data: result });\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Authorization check failed\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// ── Delegation ──────────────────────────────────────────────────\n\n\t// POST /delegations - create delegation\n\trouter.post(\"/delegations\", (req: Request, res: Response) => {\n\t\tconst parsed = DelegateSchema.safeParse(req.body);\n\t\tif (!parsed.success) {\n\t\t\tsendValidationError(res, parsed.error.issues);\n\t\t\treturn;\n\t\t}\n\t\tconst input: DelegateInput = {\n\t\t\t...parsed.data,\n\t\t\tpermissions: parsed.data.permissions as Permission[],\n\t\t};\n\t\tkavach\n\t\t\t.delegate(input)\n\t\t\t.then((chain) => sendCreated(res, chain))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to create delegation\";\n\t\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\t\tsendNotFound(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (message.includes(\"exceeds\") || message.includes(\"depth\")) {\n\t\t\t\t\tsendBadRequest(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// DELETE /delegations/:id - revoke delegation\n\trouter.delete(\"/delegations/:id\", (req: Request, res: Response) => {\n\t\tconst id = param(req, \"id\");\n\t\tkavach.delegation\n\t\t\t.revoke(id)\n\t\t\t.then(() => sendNoContent(res))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to revoke delegation\";\n\t\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\t\tsendNotFound(res, message);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /delegations/:agentId - list chains for agent\n\trouter.get(\"/delegations/:agentId\", (req: Request, res: Response) => {\n\t\tconst agentId = param(req, \"agentId\");\n\t\tkavach.delegation\n\t\t\t.listChains(agentId)\n\t\t\t.then((chains) => sendOk(res, chains))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list delegation chains\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// ── Audit ───────────────────────────────────────────────────────\n\n\t// GET /audit - query audit logs\n\trouter.get(\"/audit\", (req: Request, res: Response) => {\n\t\tconst filter: AuditFilter = {};\n\t\tconst { agentId, userId, since, until, actions, result, limit, offset } = req.query;\n\n\t\tif (typeof agentId === \"string\") filter.agentId = agentId;\n\t\tif (typeof userId === \"string\") filter.userId = userId;\n\t\tif (typeof since === \"string\") {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.since = d;\n\t\t}\n\t\tif (typeof until === \"string\") {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.until = d;\n\t\t}\n\t\tif (typeof actions === \"string\") {\n\t\t\tfilter.actions = actions.split(\",\").map((a) => a.trim());\n\t\t}\n\t\tif (typeof result === \"string\" && [\"allowed\", \"denied\", \"rate_limited\"].includes(result)) {\n\t\t\tfilter.result = result as AuditFilter[\"result\"];\n\t\t}\n\t\tif (typeof limit === \"string\") {\n\t\t\tconst n = Number.parseInt(limit, 10);\n\t\t\tif (!Number.isNaN(n) && n > 0) filter.limit = n;\n\t\t}\n\t\tif (typeof offset === \"string\") {\n\t\t\tconst n = Number.parseInt(offset, 10);\n\t\t\tif (!Number.isNaN(n) && n >= 0) filter.offset = n;\n\t\t}\n\n\t\tkavach.audit\n\t\t\t.query(filter)\n\t\t\t.then((entries) => sendOk(res, entries))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to query audit logs\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /audit/export - export audit logs\n\trouter.get(\"/audit/export\", (req: Request, res: Response) => {\n\t\tconst format = (req.query.format as string | undefined) ?? \"json\";\n\t\tif (format !== \"json\" && format !== \"csv\") {\n\t\t\tsendBadRequest(res, 'format must be \"json\" or \"csv\"');\n\t\t\treturn;\n\t\t}\n\n\t\tconst options: { format: \"json\" | \"csv\"; since?: Date; until?: Date } = { format };\n\t\tconst { since, until } = req.query;\n\t\tif (typeof since === \"string\") {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) options.since = d;\n\t\t}\n\t\tif (typeof until === \"string\") {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) options.until = d;\n\t\t}\n\n\t\tkavach.audit\n\t\t\t.export(options)\n\t\t\t.then((exported) => {\n\t\t\t\tconst contentType = format === \"csv\" ? \"text/csv\" : \"application/json\";\n\t\t\t\tres.setHeader(\"Content-Type\", contentType);\n\t\t\t\tres.setHeader(\"Content-Disposition\", `attachment; filename=\"audit-export.${format}\"`);\n\t\t\t\tres.status(200).send(exported);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to export audit logs\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// ── MCP OAuth 2.1 Endpoints ─────────────────────────────────────\n\n\t// OPTIONS preflight for MCP/well-known routes\n\trouter.options(\"/.well-known/*path\", (_req: Request, res: Response) => {\n\t\tsetMcpCors(res);\n\t\tres.status(204).end();\n\t});\n\n\trouter.options(\"/mcp/*path\", (_req: Request, res: Response) => {\n\t\tsetMcpCors(res);\n\t\tres.status(204).end();\n\t});\n\n\t// GET /.well-known/oauth-authorization-server\n\trouter.get(\"/.well-known/oauth-authorization-server\", (_req: Request, res: Response) => {\n\t\tif (!mcp) {\n\t\t\tsendNotFound(res, \"MCP module not configured\");\n\t\t\treturn;\n\t\t}\n\t\tconst metadata = mcp.getMetadata();\n\t\tsendMcpOk(res, metadata);\n\t});\n\n\t// GET /.well-known/oauth-protected-resource\n\trouter.get(\"/.well-known/oauth-protected-resource\", (_req: Request, res: Response) => {\n\t\tif (!mcp) {\n\t\t\tsendNotFound(res, \"MCP module not configured\");\n\t\t\treturn;\n\t\t}\n\t\tconst metadata = mcp.getProtectedResourceMetadata();\n\t\tsendMcpOk(res, metadata);\n\t});\n\n\t// POST /mcp/register - dynamic client registration\n\trouter.post(\"/mcp/register\", (req: Request, res: Response) => {\n\t\tif (!mcp) {\n\t\t\tsendNotFound(res, \"MCP module not configured\");\n\t\t\treturn;\n\t\t}\n\t\tmcp\n\t\t\t.registerClient(req.body as Parameters<typeof mcp.registerClient>[0])\n\t\t\t.then((result) => {\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tsendMcpError(res, \"invalid_client_metadata\", result.error.message, 400);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendMcpNoStore(res, result.data, 201);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Registration failed\";\n\t\t\t\tsendMcpError(res, \"server_error\", message, 500);\n\t\t\t});\n\t});\n\n\t// GET /mcp/authorize - authorization endpoint\n\trouter.get(\"/mcp/authorize\", (req: Request, res: Response) => {\n\t\tif (!mcp) {\n\t\t\tsendNotFound(res, \"MCP module not configured\");\n\t\t\treturn;\n\t\t}\n\t\tconst webRequest = buildWebRequest(req);\n\t\tmcp\n\t\t\t.authorize(webRequest)\n\t\t\t.then((result) => {\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tif (result.error.code === \"LOGIN_REQUIRED\") {\n\t\t\t\t\t\tconst details = result.error.details as\n\t\t\t\t\t\t\t| { loginPage?: string; returnTo?: string }\n\t\t\t\t\t\t\t| undefined;\n\t\t\t\t\t\tif (details?.loginPage) {\n\t\t\t\t\t\t\tconst loginUrl = new URL(details.loginPage);\n\t\t\t\t\t\t\tif (details.returnTo) {\n\t\t\t\t\t\t\t\tloginUrl.searchParams.set(\"returnTo\", details.returnTo);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tres.redirect(302, loginUrl.toString());\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsendMcpError(res, result.error.code.toLowerCase(), result.error.message, 400);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tres.redirect(302, result.data.redirectUri);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Authorization failed\";\n\t\t\t\tsendMcpError(res, \"server_error\", message, 500);\n\t\t\t});\n\t});\n\n\t// POST /mcp/token - token endpoint\n\trouter.post(\"/mcp/token\", (req: Request, res: Response) => {\n\t\tif (!mcp) {\n\t\t\tsendNotFound(res, \"MCP module not configured\");\n\t\t\treturn;\n\t\t}\n\t\tconst webRequest = buildWebRequest(req);\n\t\tmcp\n\t\t\t.token(webRequest)\n\t\t\t.then((result) => {\n\t\t\t\tif (!result.success) {\n\t\t\t\t\tconst status = result.error.code === \"INVALID_CLIENT\" ? 401 : 400;\n\t\t\t\t\tsendMcpNoStore(\n\t\t\t\t\t\tres,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terror: result.error.code.toLowerCase(),\n\t\t\t\t\t\t\terror_description: result.error.message,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsendMcpNoStore(res, result.data);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Token exchange failed\";\n\t\t\t\tsendMcpNoStore(res, { error: \"server_error\", error_description: message }, 500);\n\t\t\t});\n\t});\n\n\t// ── Dashboard API ───────────────────────────────────────────────\n\n\t// GET /dashboard/stats\n\trouter.get(\"/dashboard/stats\", (_req: Request, res: Response) => {\n\t\tPromise.all([\n\t\t\tkavach.agent.list(),\n\t\t\tkavach.audit.query({\n\t\t\t\tsince: new Date(Date.now() - 24 * 60 * 60 * 1000),\n\t\t\t\tlimit: 1000,\n\t\t\t}),\n\t\t])\n\t\t\t.then(([agents, recentAudit]) => {\n\t\t\t\tconst ownerIds = new Set(agents.map((a) => a.ownerId));\n\t\t\t\tconst activeAgents = agents.filter((a) => a.status === \"active\");\n\t\t\t\tconst revokedAgents = agents.filter((a) => a.status === \"revoked\");\n\t\t\t\tconst expiredAgents = agents.filter((a) => a.status === \"expired\");\n\n\t\t\t\tconst stats = {\n\t\t\t\t\tagents: {\n\t\t\t\t\t\ttotal: agents.length,\n\t\t\t\t\t\tactive: activeAgents.length,\n\t\t\t\t\t\trevoked: revokedAgents.length,\n\t\t\t\t\t\texpired: expiredAgents.length,\n\t\t\t\t\t},\n\t\t\t\t\tusers: {\n\t\t\t\t\t\ttotal: ownerIds.size,\n\t\t\t\t\t},\n\t\t\t\t\taudit: {\n\t\t\t\t\t\tlast24h: recentAudit.length,\n\t\t\t\t\t\tallowed: recentAudit.filter((e) => e.result === \"allowed\").length,\n\t\t\t\t\t\tdenied: recentAudit.filter((e) => e.result === \"denied\").length,\n\t\t\t\t\t\trateLimited: recentAudit.filter((e) => e.result === \"rate_limited\").length,\n\t\t\t\t\t},\n\t\t\t\t};\n\t\t\t\tsendOk(res, stats);\n\t\t\t})\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to fetch dashboard stats\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /dashboard/agents - agents with stats (same as GET /agents)\n\trouter.get(\"/dashboard/agents\", (req: Request, res: Response) => {\n\t\tconst filter: AgentFilter = {};\n\t\tconst { userId, status, type } = req.query;\n\t\tif (typeof userId === \"string\") filter.userId = userId;\n\t\tif (typeof status === \"string\" && [\"active\", \"revoked\", \"expired\"].includes(status)) {\n\t\t\tfilter.status = status as AgentFilter[\"status\"];\n\t\t}\n\t\tif (typeof type === \"string\" && [\"autonomous\", \"delegated\", \"service\"].includes(type)) {\n\t\t\tfilter.type = type as AgentFilter[\"type\"];\n\t\t}\n\t\tkavach.agent\n\t\t\t.list(filter)\n\t\t\t.then((agents) => sendOk(res, agents))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list agents\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// GET /dashboard/audit - same as GET /audit\n\trouter.get(\"/dashboard/audit\", (req: Request, res: Response) => {\n\t\tconst filter: AuditFilter = {};\n\t\tconst { agentId, userId, since, until, actions, result, limit, offset } = req.query;\n\n\t\tif (typeof agentId === \"string\") filter.agentId = agentId;\n\t\tif (typeof userId === \"string\") filter.userId = userId;\n\t\tif (typeof since === \"string\") {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.since = d;\n\t\t}\n\t\tif (typeof until === \"string\") {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.until = d;\n\t\t}\n\t\tif (typeof actions === \"string\") {\n\t\t\tfilter.actions = actions.split(\",\").map((a) => a.trim());\n\t\t}\n\t\tif (typeof result === \"string\" && [\"allowed\", \"denied\", \"rate_limited\"].includes(result)) {\n\t\t\tfilter.result = result as AuditFilter[\"result\"];\n\t\t}\n\t\tif (typeof limit === \"string\") {\n\t\t\tconst n = Number.parseInt(limit, 10);\n\t\t\tif (!Number.isNaN(n) && n > 0) filter.limit = n;\n\t\t}\n\t\tif (typeof offset === \"string\") {\n\t\t\tconst n = Number.parseInt(offset, 10);\n\t\t\tif (!Number.isNaN(n) && n >= 0) filter.offset = n;\n\t\t}\n\n\t\tkavach.audit\n\t\t\t.query(filter)\n\t\t\t.then((entries) => sendOk(res, entries))\n\t\t\t.catch((err: unknown) => {\n\t\t\t\tconst message = err instanceof Error ? err.message : \"Failed to query audit logs\";\n\t\t\t\tsendInternalError(res, message);\n\t\t\t});\n\t});\n\n\t// ── Plugin Endpoints ────────────────────────────────────────────\n\n\tfor (const endpoint of kavach.plugins.getEndpoints()) {\n\t\tconst method = endpoint.method.toLowerCase() as \"get\" | \"post\" | \"put\" | \"patch\" | \"delete\";\n\t\trouter[method](endpoint.path, (req: Request, res: Response) => {\n\t\t\tconst webReq = buildWebRequest(req);\n\t\t\tkavach.plugins\n\t\t\t\t.handleRequest(webReq)\n\t\t\t\t.then((response) => {\n\t\t\t\t\tif (!response) {\n\t\t\t\t\t\tres.status(404).end();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tres.status(response.status);\n\t\t\t\t\tresponse.headers.forEach((value, key) => {\n\t\t\t\t\t\tres.setHeader(key, value);\n\t\t\t\t\t});\n\t\t\t\t\treturn response.text().then((body) => {\n\t\t\t\t\t\tres.send(body);\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.catch((err: unknown) => {\n\t\t\t\t\tconst message = err instanceof Error ? err.message : \"Plugin endpoint error\";\n\t\t\t\t\tsendInternalError(res, message);\n\t\t\t\t});\n\t\t});\n\t}\n\n\treturn router;\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kavachos/express",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "description": "Express adapter for KavachOS - exposes agent auth as HTTP REST endpoints",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "peerDependencies": {
32
32
  "express": ">=4.0.0",
33
33
  "zod": ">=3.0.0",
34
- "kavachos": "0.0.2"
34
+ "kavachos": "0.0.4"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/better-sqlite3": "^7.6.13",
@@ -44,7 +44,7 @@
44
44
  "typescript": "^5.8.0",
45
45
  "vitest": "^3.0.0",
46
46
  "zod": "^3.24.0",
47
- "kavachos": "0.0.2"
47
+ "kavachos": "0.0.4"
48
48
  },
49
49
  "scripts": {
50
50
  "build": "tsup",