@amtp/protocol 1.0.1
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/LICENSE +21 -0
- package/README.md +386 -0
- package/USAGE_GUIDE.md +722 -0
- package/bin/amtp.ts +387 -0
- package/dist/client/amtp-client.d.ts +164 -0
- package/dist/client/amtp-client.js +460 -0
- package/dist/client/amtp-client.js.map +1 -0
- package/dist/client/examples/basic-client.d.ts +6 -0
- package/dist/client/examples/basic-client.js +35 -0
- package/dist/client/examples/basic-client.js.map +1 -0
- package/dist/crawler/amtp-crawler.d.ts +125 -0
- package/dist/crawler/amtp-crawler.js +359 -0
- package/dist/crawler/amtp-crawler.js.map +1 -0
- package/dist/crawler/examples/basic-crawler.d.ts +6 -0
- package/dist/crawler/examples/basic-crawler.js +28 -0
- package/dist/crawler/examples/basic-crawler.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/server/adapters/fastify-adapter.d.ts +86 -0
- package/dist/server/adapters/fastify-adapter.js +169 -0
- package/dist/server/adapters/fastify-adapter.js.map +1 -0
- package/dist/server/amtp-ql-executor.d.ts +24 -0
- package/dist/server/amtp-ql-executor.js +198 -0
- package/dist/server/amtp-ql-executor.js.map +1 -0
- package/dist/server/amtp-ql-parser.d.ts +30 -0
- package/dist/server/amtp-ql-parser.js +212 -0
- package/dist/server/amtp-ql-parser.js.map +1 -0
- package/dist/server/amtp-server.d.ts +183 -0
- package/dist/server/amtp-server.js +650 -0
- package/dist/server/amtp-server.js.map +1 -0
- package/dist/server/examples/basic-server.d.ts +6 -0
- package/dist/server/examples/basic-server.js +215 -0
- package/dist/server/examples/basic-server.js.map +1 -0
- package/dist/server/examples/saas-dashboard-server.d.ts +44 -0
- package/dist/server/examples/saas-dashboard-server.js +387 -0
- package/dist/server/examples/saas-dashboard-server.js.map +1 -0
- package/dist/server/markdown-parser.d.ts +31 -0
- package/dist/server/markdown-parser.js +463 -0
- package/dist/server/markdown-parser.js.map +1 -0
- package/dist/server/notifications.d.ts +40 -0
- package/dist/server/notifications.js +134 -0
- package/dist/server/notifications.js.map +1 -0
- package/dist/server/permissions.d.ts +40 -0
- package/dist/server/permissions.js +156 -0
- package/dist/server/permissions.js.map +1 -0
- package/dist/server/security.d.ts +127 -0
- package/dist/server/security.js +368 -0
- package/dist/server/security.js.map +1 -0
- package/dist/types/amtp.types.d.ts +720 -0
- package/dist/types/amtp.types.js +224 -0
- package/dist/types/amtp.types.js.map +1 -0
- package/package.json +89 -0
|
@@ -0,0 +1,650 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AMTP Express Middleware & Server Core
|
|
4
|
+
* HTTP server integration for AMTP protocol
|
|
5
|
+
*/
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.AMTPServer = exports.AMTPMiddlewareFactory = exports.ContentNegotiator = exports.SessionManager = exports.AMTPResponseBuilder = exports.AMTPRequestParser = void 0;
|
|
11
|
+
const compression_1 = __importDefault(require("compression"));
|
|
12
|
+
const express_1 = __importDefault(require("express"));
|
|
13
|
+
const amtp_types_1 = require("../types/amtp.types");
|
|
14
|
+
const security_1 = require("./security");
|
|
15
|
+
const amtp_ql_parser_1 = require("./amtp-ql-parser");
|
|
16
|
+
const amtp_ql_executor_1 = require("./amtp-ql-executor");
|
|
17
|
+
/**
|
|
18
|
+
* AMTP Request Parser
|
|
19
|
+
* Converts Express request to AMTP request
|
|
20
|
+
*/
|
|
21
|
+
class AMTPRequestParser {
|
|
22
|
+
parse(req) {
|
|
23
|
+
const headers = {
|
|
24
|
+
accept: req.header("accept"),
|
|
25
|
+
"user-agent": req.header("user-agent"),
|
|
26
|
+
"x-amtp-capabilities": req.header("x-amtp-capabilities"),
|
|
27
|
+
"x-session-id": req.header("x-session-id"),
|
|
28
|
+
"x-agent-identity": req.header("x-agent-identity"),
|
|
29
|
+
authorization: req.header("authorization"),
|
|
30
|
+
};
|
|
31
|
+
// SECURITY: Only accept syntactically valid session IDs from clients
|
|
32
|
+
const rawSessionId = req.header("x-session-id");
|
|
33
|
+
const sessionId = (0, security_1.isValidSessionId)(rawSessionId) ? rawSessionId : undefined;
|
|
34
|
+
const capabilities = this.parseCapabilities(req.header("x-amtp-capabilities") || "");
|
|
35
|
+
// SECURITY: Sanitize error message text before exposing it in downstream text
|
|
36
|
+
const sanitizedPath = req.path.replace(/\r?\n/g, "");
|
|
37
|
+
return {
|
|
38
|
+
path: sanitizedPath,
|
|
39
|
+
headers,
|
|
40
|
+
query: req.query,
|
|
41
|
+
sessionId,
|
|
42
|
+
capabilities,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
parseCapabilities(header) {
|
|
46
|
+
if (!header)
|
|
47
|
+
return [];
|
|
48
|
+
return header
|
|
49
|
+
.split(",")
|
|
50
|
+
.map((c) => c.trim().toLowerCase())
|
|
51
|
+
.filter((c) => Object.values(amtp_types_1.AgentCapability).includes(c));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.AMTPRequestParser = AMTPRequestParser;
|
|
55
|
+
/**
|
|
56
|
+
* AMTP Response Builder
|
|
57
|
+
* Constructs HTTP response from AMTP document
|
|
58
|
+
*/
|
|
59
|
+
class AMTPResponseBuilder {
|
|
60
|
+
build(doc, options) {
|
|
61
|
+
let body;
|
|
62
|
+
if (typeof doc === "string") {
|
|
63
|
+
body = doc;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
body = this.documentToMarkdown(doc);
|
|
67
|
+
}
|
|
68
|
+
const headers = {
|
|
69
|
+
"content-type": amtp_types_1.MIMEType.AMTP_MARKDOWN,
|
|
70
|
+
"x-amtp-version": "1.0",
|
|
71
|
+
...(options?.sessionId && { "x-session-id": options.sessionId }),
|
|
72
|
+
...(options?.cacheControl && {
|
|
73
|
+
"cache-control": options.cacheControl,
|
|
74
|
+
}),
|
|
75
|
+
...(options?.etag && { etag: options.etag }),
|
|
76
|
+
};
|
|
77
|
+
return { headers, body };
|
|
78
|
+
}
|
|
79
|
+
documentToMarkdown(doc) {
|
|
80
|
+
let md = `# ${doc.title}\n\n`;
|
|
81
|
+
// Add nodes
|
|
82
|
+
for (const node of doc.nodes) {
|
|
83
|
+
md += this.nodeToMarkdown(node) + "\n";
|
|
84
|
+
}
|
|
85
|
+
// Add actions section if exists
|
|
86
|
+
if (doc.actions.length > 0) {
|
|
87
|
+
md += "\n## Actions\n\n";
|
|
88
|
+
for (const action of doc.actions) {
|
|
89
|
+
md += `[${action.id.toUpperCase()}]`;
|
|
90
|
+
if (action.description) {
|
|
91
|
+
md += ` — ${action.description}`;
|
|
92
|
+
}
|
|
93
|
+
md += "\n";
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Add structured action definitions (v2.0)
|
|
97
|
+
if (doc.actions.some((a) => a.parameters || a.permissions)) {
|
|
98
|
+
md += "\n```amtp-action\n";
|
|
99
|
+
md += JSON.stringify(doc.actions, null, 2);
|
|
100
|
+
md += "\n```\n";
|
|
101
|
+
}
|
|
102
|
+
// Add permissions (v2.0)
|
|
103
|
+
if (doc.permissions && doc.permissions.length > 0) {
|
|
104
|
+
md += "\n```amtp-permissions\n";
|
|
105
|
+
md += JSON.stringify(doc.permissions, null, 2);
|
|
106
|
+
md += "\n```\n";
|
|
107
|
+
}
|
|
108
|
+
// Add policies (v2.0)
|
|
109
|
+
if (doc.policies && doc.policies.length > 0) {
|
|
110
|
+
md += "\n```amtp-policy\n";
|
|
111
|
+
md += JSON.stringify(doc.policies, null, 2);
|
|
112
|
+
md += "\n```\n";
|
|
113
|
+
}
|
|
114
|
+
// Add skills (v2.0)
|
|
115
|
+
if (doc.skills && doc.skills.length > 0) {
|
|
116
|
+
md += "\n```amtp-skill\n";
|
|
117
|
+
md += JSON.stringify(doc.skills, null, 2);
|
|
118
|
+
md += "\n```\n";
|
|
119
|
+
}
|
|
120
|
+
// Add metadata
|
|
121
|
+
if (Object.keys(doc.metadata).length > 0) {
|
|
122
|
+
md += "\n```amtp-meta\n";
|
|
123
|
+
md += JSON.stringify(doc.metadata, null, 2);
|
|
124
|
+
md += "\n```\n";
|
|
125
|
+
}
|
|
126
|
+
return md;
|
|
127
|
+
}
|
|
128
|
+
nodeToMarkdown(node) {
|
|
129
|
+
switch (node.type) {
|
|
130
|
+
case amtp_types_1.MarkdownNodeType.HEADING: {
|
|
131
|
+
const level = node.metadata?.level || 2;
|
|
132
|
+
return `${"#".repeat(level)} ${node.content || ""}`;
|
|
133
|
+
}
|
|
134
|
+
case amtp_types_1.MarkdownNodeType.PARAGRAPH:
|
|
135
|
+
return node.content || "";
|
|
136
|
+
case amtp_types_1.MarkdownNodeType.IMAGE: {
|
|
137
|
+
const title = node.title ? ` "${node.title}"` : "";
|
|
138
|
+
return ``;
|
|
139
|
+
}
|
|
140
|
+
case amtp_types_1.MarkdownNodeType.CODE_BLOCK:
|
|
141
|
+
return "```\n" + (node.content || "") + "\n```";
|
|
142
|
+
case amtp_types_1.MarkdownNodeType.BLOCKQUOTE:
|
|
143
|
+
return "> " + (node.content || "");
|
|
144
|
+
case amtp_types_1.MarkdownNodeType.LIST:
|
|
145
|
+
return (node.content || "")
|
|
146
|
+
.split("\n")
|
|
147
|
+
.map((l) => "- " + l)
|
|
148
|
+
.join("\n");
|
|
149
|
+
case amtp_types_1.MarkdownNodeType.LIST_ITEM:
|
|
150
|
+
return "- " + (node.content || "");
|
|
151
|
+
case amtp_types_1.MarkdownNodeType.THEMATIC_BREAK:
|
|
152
|
+
return "---";
|
|
153
|
+
case amtp_types_1.MarkdownNodeType.INLINE_CODE:
|
|
154
|
+
return "`" + (node.content || "") + "`";
|
|
155
|
+
default:
|
|
156
|
+
return node.content || "";
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
exports.AMTPResponseBuilder = AMTPResponseBuilder;
|
|
161
|
+
/**
|
|
162
|
+
* Session Manager
|
|
163
|
+
* Handles user sessions and state
|
|
164
|
+
*/
|
|
165
|
+
class SessionManager {
|
|
166
|
+
constructor(absoluteMaxLifetimeMs = security_1.MAX_SESSION_LIFETIME_MS) {
|
|
167
|
+
this.sessions = new Map();
|
|
168
|
+
this.csrfTokens = new Map(); // sessionId -> csrfToken
|
|
169
|
+
this._absoluteMaxLifetimeMs = absoluteMaxLifetimeMs;
|
|
170
|
+
}
|
|
171
|
+
createSession(userId, username, ttlMs) {
|
|
172
|
+
const sessionId = (0, security_1.generateSecureSessionId)();
|
|
173
|
+
const now = new Date();
|
|
174
|
+
const requestedTtl = ttlMs ?? security_1.DEFAULT_SESSION_TIMEOUT_MS;
|
|
175
|
+
const cappedTtl = Math.min(requestedTtl, this._absoluteMaxLifetimeMs);
|
|
176
|
+
const expiresAt = new Date(now.getTime() + cappedTtl);
|
|
177
|
+
const session = {
|
|
178
|
+
sessionId,
|
|
179
|
+
userId,
|
|
180
|
+
username,
|
|
181
|
+
createdAt: now.toISOString(),
|
|
182
|
+
expiresAt: expiresAt.toISOString(),
|
|
183
|
+
lastActivityAt: now.toISOString(),
|
|
184
|
+
capabilities: ["read", "write"],
|
|
185
|
+
permissions: [],
|
|
186
|
+
preferences: {},
|
|
187
|
+
metadata: {},
|
|
188
|
+
};
|
|
189
|
+
this.sessions.set(sessionId, session);
|
|
190
|
+
return session;
|
|
191
|
+
}
|
|
192
|
+
getSession(sessionId) {
|
|
193
|
+
if (!(0, security_1.isValidSessionId)(sessionId)) {
|
|
194
|
+
return null;
|
|
195
|
+
}
|
|
196
|
+
const session = this.sessions.get(sessionId);
|
|
197
|
+
if (!session)
|
|
198
|
+
return null;
|
|
199
|
+
// Check expiration
|
|
200
|
+
if (new Date(session.expiresAt) < new Date()) {
|
|
201
|
+
this.sessions.delete(sessionId);
|
|
202
|
+
this.csrfTokens.delete(sessionId);
|
|
203
|
+
return null;
|
|
204
|
+
}
|
|
205
|
+
// Enforce absolute maximum lifetime regardless of extensions
|
|
206
|
+
const createdAt = new Date(session.createdAt).getTime();
|
|
207
|
+
if (Date.now() - createdAt > this._absoluteMaxLifetimeMs) {
|
|
208
|
+
this.sessions.delete(sessionId);
|
|
209
|
+
this.csrfTokens.delete(sessionId);
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
// Update last activity
|
|
213
|
+
session.lastActivityAt = new Date().toISOString();
|
|
214
|
+
return session;
|
|
215
|
+
}
|
|
216
|
+
deleteSession(sessionId) {
|
|
217
|
+
this.sessions.delete(sessionId);
|
|
218
|
+
this.csrfTokens.delete(sessionId);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Generate and store a CSRF token for the given session.
|
|
222
|
+
*/
|
|
223
|
+
generateCsrfToken(sessionId) {
|
|
224
|
+
const token = (0, security_1.generateCsrfToken)(sessionId);
|
|
225
|
+
this.csrfTokens.set(sessionId, token);
|
|
226
|
+
return token;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Validate a CSRF token against the stored token for a session.
|
|
230
|
+
*/
|
|
231
|
+
validateCsrfToken(sessionId, token) {
|
|
232
|
+
if (!(0, security_1.isValidSessionId)(sessionId) || !(0, security_1.isValidCsrfToken)(token)) {
|
|
233
|
+
return false;
|
|
234
|
+
}
|
|
235
|
+
const stored = this.csrfTokens.get(sessionId);
|
|
236
|
+
if (!stored)
|
|
237
|
+
return false;
|
|
238
|
+
// Constant-time comparison to prevent timing attacks
|
|
239
|
+
if (stored.length !== token.length)
|
|
240
|
+
return false;
|
|
241
|
+
let result = 0;
|
|
242
|
+
for (let i = 0; i < stored.length; i++) {
|
|
243
|
+
result |= stored.charCodeAt(i) ^ token.charCodeAt(i);
|
|
244
|
+
}
|
|
245
|
+
return result === 0;
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Scan for and evict expired sessions. Call periodically.
|
|
249
|
+
*/
|
|
250
|
+
pruneExpired() {
|
|
251
|
+
const now = new Date();
|
|
252
|
+
for (const [id, session] of this.sessions) {
|
|
253
|
+
if (new Date(session.expiresAt) < now) {
|
|
254
|
+
this.sessions.delete(id);
|
|
255
|
+
this.csrfTokens.delete(id);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
exports.SessionManager = SessionManager;
|
|
261
|
+
/**
|
|
262
|
+
* Content Negotiation
|
|
263
|
+
* Determines response format based on Accept header with proper q-value parsing
|
|
264
|
+
*/
|
|
265
|
+
class ContentNegotiator {
|
|
266
|
+
negotiate(acceptHeader, _userAgent) {
|
|
267
|
+
// SECURITY: Never trust user-agent for format decisions;
|
|
268
|
+
// use only the explicit Accept header
|
|
269
|
+
if (!acceptHeader) {
|
|
270
|
+
return amtp_types_1.MIMEType.HTML;
|
|
271
|
+
}
|
|
272
|
+
// Parse Accept header into [{ type, subtype, q }] sorted by quality
|
|
273
|
+
const parsed = acceptHeader
|
|
274
|
+
.split(",")
|
|
275
|
+
.map((part) => {
|
|
276
|
+
const pieces = part.trim().split(";");
|
|
277
|
+
const mediaType = pieces[0].trim().toLowerCase();
|
|
278
|
+
let q = 1.0;
|
|
279
|
+
for (let i = 1; i < pieces.length; i++) {
|
|
280
|
+
const param = pieces[i].trim();
|
|
281
|
+
const m = param.match(/^q\s*=\s*([\d.]+)/);
|
|
282
|
+
if (m) {
|
|
283
|
+
q = parseFloat(m[1]);
|
|
284
|
+
if (isNaN(q))
|
|
285
|
+
q = 1.0;
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return { mediaType, q };
|
|
289
|
+
})
|
|
290
|
+
.sort((a, b) => b.q - a.q);
|
|
291
|
+
for (const entry of parsed) {
|
|
292
|
+
const mt = entry.mediaType;
|
|
293
|
+
if (mt === "text/amtp+markdown" || mt === "application/amtp+markdown") {
|
|
294
|
+
return amtp_types_1.MIMEType.AMTP_MARKDOWN;
|
|
295
|
+
}
|
|
296
|
+
if (mt === "text/markdown") {
|
|
297
|
+
return amtp_types_1.MIMEType.AMTP_MARKDOWN;
|
|
298
|
+
}
|
|
299
|
+
if (mt === "application/json") {
|
|
300
|
+
return amtp_types_1.MIMEType.JSON;
|
|
301
|
+
}
|
|
302
|
+
if (mt === "text/html" || mt === "*/*") {
|
|
303
|
+
return amtp_types_1.MIMEType.HTML;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
// Default to HTML
|
|
307
|
+
return amtp_types_1.MIMEType.HTML;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
exports.ContentNegotiator = ContentNegotiator;
|
|
311
|
+
/**
|
|
312
|
+
* AMTP Middleware Factory
|
|
313
|
+
* Creates express middleware for AMTP protocol
|
|
314
|
+
*/
|
|
315
|
+
class AMTPMiddlewareFactory {
|
|
316
|
+
/**
|
|
317
|
+
* Access the session manager for admin / pruning operations
|
|
318
|
+
*/
|
|
319
|
+
get sessions() {
|
|
320
|
+
return this._sessions;
|
|
321
|
+
}
|
|
322
|
+
constructor() {
|
|
323
|
+
this.parser = new AMTPRequestParser();
|
|
324
|
+
this.builder = new AMTPResponseBuilder();
|
|
325
|
+
this._sessions = new SessionManager();
|
|
326
|
+
this.negotiator = new ContentNegotiator();
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Main AMTP middleware
|
|
330
|
+
*/
|
|
331
|
+
middleware() {
|
|
332
|
+
return (req, res, next) => {
|
|
333
|
+
// Parse AMTP request
|
|
334
|
+
const amtpRequest = this.parser.parse(req);
|
|
335
|
+
// Create AMTP context
|
|
336
|
+
const context = {
|
|
337
|
+
request: amtpRequest,
|
|
338
|
+
response: {
|
|
339
|
+
statusCode: amtp_types_1.StatusCode.OK,
|
|
340
|
+
headers: {
|
|
341
|
+
"content-type": amtp_types_1.MIMEType.AMTP_MARKDOWN,
|
|
342
|
+
"x-amtp-version": "1.0",
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
state: {},
|
|
346
|
+
};
|
|
347
|
+
// Load session if provided
|
|
348
|
+
if (amtpRequest.sessionId) {
|
|
349
|
+
context.session = this._sessions.getSession(amtpRequest.sessionId) || undefined;
|
|
350
|
+
}
|
|
351
|
+
// Attach context to request
|
|
352
|
+
req.amtpContext = context;
|
|
353
|
+
next();
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Response sender middleware
|
|
358
|
+
*/
|
|
359
|
+
responseSender() {
|
|
360
|
+
return (req, res, next) => {
|
|
361
|
+
const context = req.amtpContext;
|
|
362
|
+
if (!context || !context.response.body) {
|
|
363
|
+
return next();
|
|
364
|
+
}
|
|
365
|
+
// Set status code
|
|
366
|
+
res.status(context.response.statusCode);
|
|
367
|
+
// Set headers
|
|
368
|
+
Object.entries(context.response.headers).forEach(([key, value]) => {
|
|
369
|
+
if (value) {
|
|
370
|
+
res.setHeader(key, value);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
// Send body
|
|
374
|
+
res.send(context.response.body);
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* Error handler middleware
|
|
379
|
+
*/
|
|
380
|
+
errorHandler() {
|
|
381
|
+
return (err, req, res, _next) => {
|
|
382
|
+
if (err instanceof amtp_types_1.AMTPError) {
|
|
383
|
+
const safeErr = err;
|
|
384
|
+
return res.status(safeErr.statusCode).json({
|
|
385
|
+
status: "error",
|
|
386
|
+
error: {
|
|
387
|
+
code: safeErr.code,
|
|
388
|
+
message: safeErr.message,
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
if (err instanceof security_1.SecurityError) {
|
|
393
|
+
return res.status(err.statusCode).json({
|
|
394
|
+
status: "error",
|
|
395
|
+
error: {
|
|
396
|
+
code: err.code,
|
|
397
|
+
message: err.message,
|
|
398
|
+
},
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
// SECURITY: HIDE all internal error details for non-safe exceptions
|
|
402
|
+
res.status(amtp_types_1.StatusCode.INTERNAL_ERROR).json({
|
|
403
|
+
status: "error",
|
|
404
|
+
error: {
|
|
405
|
+
code: amtp_types_1.ErrorCode.SERVER_ERROR,
|
|
406
|
+
message: "Internal server error",
|
|
407
|
+
},
|
|
408
|
+
});
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Security headers middleware — adds standard HTTP security headers to all responses
|
|
413
|
+
*/
|
|
414
|
+
securityHeaders() {
|
|
415
|
+
return (_req, res, next) => {
|
|
416
|
+
for (const [key, value] of Object.entries(security_1.AMTP_SECURITY_HEADERS)) {
|
|
417
|
+
res.setHeader(key, value);
|
|
418
|
+
}
|
|
419
|
+
// Content Security Policy — allow self only for AMTP documents
|
|
420
|
+
res.setHeader("Content-Security-Policy", "default-src 'none'; script-src 'none'; object-src 'none'; base-uri 'none';");
|
|
421
|
+
next();
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Rate limiting middleware — rejects requests that exceed the configured window/count
|
|
426
|
+
*/
|
|
427
|
+
rateLimit(windowMs, maxRequests) {
|
|
428
|
+
const limiter = new security_1.InMemoryRateLimiter(windowMs, maxRequests);
|
|
429
|
+
return (req, res, next) => {
|
|
430
|
+
const ip = req.ip || req.socket.remoteAddress || "unknown";
|
|
431
|
+
if (!limiter.check(ip)) {
|
|
432
|
+
res.setHeader("Retry-After", String(limiter.retryAfterSeconds(ip)));
|
|
433
|
+
return res.status(amtp_types_1.StatusCode.TOO_MANY_REQUESTS).json({
|
|
434
|
+
status: "error",
|
|
435
|
+
error: {
|
|
436
|
+
code: amtp_types_1.ErrorCode.RATE_LIMITED,
|
|
437
|
+
message: "Too many requests. Try again later.",
|
|
438
|
+
},
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
next();
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* CSRF guard — rejects state-changing requests that do not carry a valid CSRF token
|
|
446
|
+
* bound to the active session.
|
|
447
|
+
*/
|
|
448
|
+
csrfGuard() {
|
|
449
|
+
return (req, res, next) => {
|
|
450
|
+
const sessionId = req.header("x-session-id");
|
|
451
|
+
if (!sessionId || !(0, security_1.isValidSessionId)(sessionId)) {
|
|
452
|
+
return next(); // no session; nothing to protect
|
|
453
|
+
}
|
|
454
|
+
if (["POST", "PUT", "DELETE", "PATCH"].includes(req.method)) {
|
|
455
|
+
const token = req.header((0, security_1.csrfHeaderName)());
|
|
456
|
+
if (!token || !this._sessions.validateCsrfToken(sessionId, token)) {
|
|
457
|
+
return res.status(amtp_types_1.StatusCode.FORBIDDEN).json({
|
|
458
|
+
status: "error",
|
|
459
|
+
error: {
|
|
460
|
+
code: amtp_types_1.ErrorCode.PERMISSION_DENIED,
|
|
461
|
+
message: token ? "CSRF token invalid" : "CSRF token missing",
|
|
462
|
+
},
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
next();
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
/**
|
|
470
|
+
* Content negotiation middleware — resolves the AMTP mime type the client prefers
|
|
471
|
+
*/
|
|
472
|
+
contentNegotiation() {
|
|
473
|
+
return (req, res, next) => {
|
|
474
|
+
const accept = req.header("accept") || "";
|
|
475
|
+
const userAgent = req.header("user-agent") || undefined;
|
|
476
|
+
const mimeType = this.negotiator.negotiate(accept, userAgent);
|
|
477
|
+
req.preferredMimeType = mimeType;
|
|
478
|
+
next();
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
/**
|
|
482
|
+
* CORS middleware for AMTP
|
|
483
|
+
* `trustedOrigins` is set on the AMTPServer instance and passed here.
|
|
484
|
+
*/
|
|
485
|
+
cors(trustedOrigins) {
|
|
486
|
+
return (req, res, next) => {
|
|
487
|
+
let allowedOrigin = "*";
|
|
488
|
+
if (trustedOrigins && trustedOrigins.length > 0) {
|
|
489
|
+
const requestOrigin = req.header("Origin");
|
|
490
|
+
if (requestOrigin && trustedOrigins.includes(requestOrigin)) {
|
|
491
|
+
allowedOrigin = requestOrigin;
|
|
492
|
+
}
|
|
493
|
+
else {
|
|
494
|
+
return res.status(amtp_types_1.StatusCode.FORBIDDEN).json({
|
|
495
|
+
status: "error",
|
|
496
|
+
error: { code: amtp_types_1.ErrorCode.PERMISSION_DENIED, message: "CORS origin rejected" },
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
res.header("Access-Control-Allow-Origin", allowedOrigin);
|
|
501
|
+
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, X-AMTP-Capabilities, X-Session-ID, X-AMTP-CSRF-Token");
|
|
502
|
+
res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
|
|
503
|
+
res.header("Access-Control-Expose-Headers", "X-Session-ID, X-RateLimit-Remaining, X-RateLimit-Reset");
|
|
504
|
+
res.header("Access-Control-Max-Age", "300"); // 5 min preflight cache
|
|
505
|
+
if (req.method === "OPTIONS") {
|
|
506
|
+
return res.sendStatus(200);
|
|
507
|
+
}
|
|
508
|
+
next();
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
exports.AMTPMiddlewareFactory = AMTPMiddlewareFactory;
|
|
513
|
+
/**
|
|
514
|
+
* AMTP Server
|
|
515
|
+
* Main server class wrapping Express
|
|
516
|
+
*/
|
|
517
|
+
class AMTPServer {
|
|
518
|
+
constructor(config = {}) {
|
|
519
|
+
this.app = (0, express_1.default)();
|
|
520
|
+
this.config = {
|
|
521
|
+
port: 3000,
|
|
522
|
+
host: "localhost",
|
|
523
|
+
sessionTimeout: security_1.DEFAULT_SESSION_TIMEOUT_MS,
|
|
524
|
+
enableCORS: true,
|
|
525
|
+
enableCompression: true,
|
|
526
|
+
enableSecurityHeaders: true,
|
|
527
|
+
enableRateLimit: true,
|
|
528
|
+
csrfProtection: true,
|
|
529
|
+
...config,
|
|
530
|
+
};
|
|
531
|
+
this.middlewareFactory = new AMTPMiddlewareFactory();
|
|
532
|
+
this.router = express_1.default.Router();
|
|
533
|
+
this.setupMiddleware();
|
|
534
|
+
}
|
|
535
|
+
setupMiddleware() {
|
|
536
|
+
// SECURITY: Security headers
|
|
537
|
+
if (this.config.enableSecurityHeaders !== false) {
|
|
538
|
+
this.app.use(this.middlewareFactory.securityHeaders());
|
|
539
|
+
}
|
|
540
|
+
// CORS
|
|
541
|
+
if (this.config.enableCORS) {
|
|
542
|
+
this.app.use(this.middlewareFactory.cors(this.config.trustedOrigins));
|
|
543
|
+
}
|
|
544
|
+
// SECURITY: Request body size limit
|
|
545
|
+
const maxSize = this.config.maxRequestBodySize || security_1.DEFAULT_MAX_BODY_SIZE;
|
|
546
|
+
this.app.use(express_1.default.json({ limit: maxSize }));
|
|
547
|
+
this.app.use(express_1.default.urlencoded({
|
|
548
|
+
extended: true,
|
|
549
|
+
limit: maxSize,
|
|
550
|
+
parameterLimit: 1000,
|
|
551
|
+
}));
|
|
552
|
+
// Compression
|
|
553
|
+
if (this.config.enableCompression) {
|
|
554
|
+
this.app.use((0, compression_1.default)());
|
|
555
|
+
}
|
|
556
|
+
// Content negotiation
|
|
557
|
+
this.app.use(this.middlewareFactory.contentNegotiation());
|
|
558
|
+
// SECURITY: Rate limiting
|
|
559
|
+
if (this.config.enableRateLimit !== false) {
|
|
560
|
+
const rlConfig = this.config.rateLimit || { windowMs: 60000, maxRequests: 60 };
|
|
561
|
+
this.app.use(this.middlewareFactory.rateLimit(rlConfig.windowMs, rlConfig.maxRequests));
|
|
562
|
+
}
|
|
563
|
+
// SECURITY: CSRF protection for mutating methods
|
|
564
|
+
if (this.config.csrfProtection !== false) {
|
|
565
|
+
this.app.use(this.middlewareFactory.csrfGuard());
|
|
566
|
+
}
|
|
567
|
+
// AMTP context
|
|
568
|
+
this.app.use(this.middlewareFactory.middleware());
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Register a route handler
|
|
572
|
+
*/
|
|
573
|
+
register(method, path, handler) {
|
|
574
|
+
this.router[method.toLowerCase()](path, handler);
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* Handle an AMTP-QL query (v2.0).
|
|
578
|
+
* The caller provides a function that returns the AMTPDocument to query.
|
|
579
|
+
* Returns { data } or { errors } per AMTPQLQueryResponse.
|
|
580
|
+
*/
|
|
581
|
+
async handleAMTPQL(body, getDocument) {
|
|
582
|
+
try {
|
|
583
|
+
const doc = await Promise.resolve(getDocument());
|
|
584
|
+
const parsed = (0, amtp_ql_parser_1.parseAMTPQL)(body.query);
|
|
585
|
+
const executor = new amtp_ql_executor_1.AMTPQLExecutor();
|
|
586
|
+
const data = executor.execute(doc, parsed);
|
|
587
|
+
return { data };
|
|
588
|
+
}
|
|
589
|
+
catch (err) {
|
|
590
|
+
if (err instanceof amtp_ql_parser_1.AMTPQLSyntaxError) {
|
|
591
|
+
return {
|
|
592
|
+
errors: [{ message: `Syntax error: ${err.message}`, path: [String(err.position)] }],
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
return {
|
|
596
|
+
errors: [{ message: err.message || "AMTP-QL execution failed" }],
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Return the fully configured Express app with routes and middleware mounted.
|
|
602
|
+
* Does NOT start the HTTP listener — useful for testing with supertest.
|
|
603
|
+
*/
|
|
604
|
+
getConfiguredApp() {
|
|
605
|
+
this.app.use("/", this.router);
|
|
606
|
+
this.app.use(this.middlewareFactory.responseSender());
|
|
607
|
+
this.app.use(this.middlewareFactory.errorHandler());
|
|
608
|
+
return this.app;
|
|
609
|
+
}
|
|
610
|
+
/**
|
|
611
|
+
* Start server
|
|
612
|
+
*/
|
|
613
|
+
async start() {
|
|
614
|
+
this.getConfiguredApp();
|
|
615
|
+
// SECURITY: Periodic session pruning every 5 minutes
|
|
616
|
+
const sessionPruner = () => {
|
|
617
|
+
this.middlewareFactory.sessions.pruneExpired();
|
|
618
|
+
};
|
|
619
|
+
sessionPruner();
|
|
620
|
+
setInterval(sessionPruner, 5 * 60000).unref?.();
|
|
621
|
+
return new Promise((resolve) => {
|
|
622
|
+
this.app.listen(this.config.port, this.config.host, () => {
|
|
623
|
+
console.log(`AMTP Server running on http://${this.config.host}:${this.config.port}`);
|
|
624
|
+
resolve();
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
/**
|
|
629
|
+
* Get Express app instance
|
|
630
|
+
*/
|
|
631
|
+
getApp() {
|
|
632
|
+
return this.app;
|
|
633
|
+
}
|
|
634
|
+
/**
|
|
635
|
+
* Get the internal session manager (useful for tests).
|
|
636
|
+
*/
|
|
637
|
+
getSessionManager() {
|
|
638
|
+
return this.middlewareFactory.sessions;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
exports.AMTPServer = AMTPServer;
|
|
642
|
+
exports.default = {
|
|
643
|
+
AMTPServer,
|
|
644
|
+
AMTPMiddlewareFactory,
|
|
645
|
+
SessionManager,
|
|
646
|
+
ContentNegotiator,
|
|
647
|
+
AMTPRequestParser,
|
|
648
|
+
AMTPResponseBuilder,
|
|
649
|
+
};
|
|
650
|
+
//# sourceMappingURL=amtp-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"amtp-server.js","sourceRoot":"","sources":["../../src/server/amtp-server.ts"],"names":[],"mappings":"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"}
|