@tjamescouch/agentchat 0.22.0 → 0.23.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/Dockerfile +1 -1
- package/dist/bin/agentchat.d.ts +7 -0
- package/dist/bin/agentchat.d.ts.map +1 -0
- package/dist/bin/agentchat.js +1511 -0
- package/dist/bin/agentchat.js.map +1 -0
- package/dist/lib/allowlist.d.ts +77 -0
- package/dist/lib/allowlist.d.ts.map +1 -0
- package/dist/lib/allowlist.js +151 -0
- package/dist/lib/allowlist.js.map +1 -0
- package/dist/lib/client.d.ts +147 -0
- package/dist/lib/client.d.ts.map +1 -0
- package/dist/lib/client.js +704 -0
- package/dist/lib/client.js.map +1 -0
- package/dist/lib/daemon.d.ts +122 -0
- package/dist/lib/daemon.d.ts.map +1 -0
- package/dist/lib/daemon.js +523 -0
- package/dist/lib/daemon.js.map +1 -0
- package/dist/lib/deploy/akash.d.ts +271 -0
- package/dist/lib/deploy/akash.d.ts.map +1 -0
- package/dist/lib/deploy/akash.js +671 -0
- package/dist/lib/deploy/akash.js.map +1 -0
- package/dist/lib/deploy/config.d.ts +62 -0
- package/dist/lib/deploy/config.d.ts.map +1 -0
- package/dist/lib/deploy/config.js +116 -0
- package/dist/lib/deploy/config.js.map +1 -0
- package/dist/lib/deploy/docker.d.ts +37 -0
- package/dist/lib/deploy/docker.d.ts.map +1 -0
- package/dist/lib/deploy/docker.js +122 -0
- package/dist/lib/deploy/docker.js.map +1 -0
- package/dist/lib/deploy/index.d.ts +11 -0
- package/dist/lib/deploy/index.d.ts.map +1 -0
- package/dist/lib/deploy/index.js +11 -0
- package/dist/lib/deploy/index.js.map +1 -0
- package/dist/lib/escrow-hooks.d.ts +199 -0
- package/dist/lib/escrow-hooks.d.ts.map +1 -0
- package/dist/lib/escrow-hooks.js +221 -0
- package/dist/lib/escrow-hooks.js.map +1 -0
- package/dist/lib/identity.d.ts +134 -0
- package/dist/lib/identity.d.ts.map +1 -0
- package/dist/lib/identity.js +334 -0
- package/dist/lib/identity.js.map +1 -0
- package/dist/lib/jitter.d.ts +42 -0
- package/dist/lib/jitter.d.ts.map +1 -0
- package/{lib → dist/lib}/jitter.js +16 -19
- package/dist/lib/jitter.js.map +1 -0
- package/dist/lib/proposals.d.ts +223 -0
- package/dist/lib/proposals.d.ts.map +1 -0
- package/dist/lib/proposals.js +379 -0
- package/dist/lib/proposals.js.map +1 -0
- package/dist/lib/protocol.d.ts +220 -0
- package/dist/lib/protocol.d.ts.map +1 -0
- package/dist/lib/protocol.js +507 -0
- package/dist/lib/protocol.js.map +1 -0
- package/dist/lib/receipts.d.ts +134 -0
- package/dist/lib/receipts.d.ts.map +1 -0
- package/dist/lib/receipts.js +270 -0
- package/dist/lib/receipts.js.map +1 -0
- package/dist/lib/reputation.d.ts +250 -0
- package/dist/lib/reputation.d.ts.map +1 -0
- package/dist/lib/reputation.js +586 -0
- package/dist/lib/reputation.js.map +1 -0
- package/dist/lib/security.d.ts +27 -0
- package/dist/lib/security.d.ts.map +1 -0
- package/dist/lib/security.js +150 -0
- package/dist/lib/security.js.map +1 -0
- package/dist/lib/server/handlers/admin.d.ts +26 -0
- package/dist/lib/server/handlers/admin.d.ts.map +1 -0
- package/dist/lib/server/handlers/admin.js +76 -0
- package/dist/lib/server/handlers/admin.js.map +1 -0
- package/dist/lib/server/handlers/identity.d.ts +36 -0
- package/dist/lib/server/handlers/identity.d.ts.map +1 -0
- package/dist/lib/server/handlers/identity.js +330 -0
- package/dist/lib/server/handlers/identity.js.map +1 -0
- package/dist/lib/server/handlers/index.d.ts +10 -0
- package/dist/lib/server/handlers/index.d.ts.map +1 -0
- package/dist/lib/server/handlers/index.js +15 -0
- package/dist/lib/server/handlers/index.js.map +1 -0
- package/dist/lib/server/handlers/message.d.ts +47 -0
- package/dist/lib/server/handlers/message.d.ts.map +1 -0
- package/dist/lib/server/handlers/message.js +265 -0
- package/dist/lib/server/handlers/message.js.map +1 -0
- package/dist/lib/server/handlers/presence.d.ts +18 -0
- package/dist/lib/server/handlers/presence.d.ts.map +1 -0
- package/dist/lib/server/handlers/presence.js +35 -0
- package/dist/lib/server/handlers/presence.js.map +1 -0
- package/dist/lib/server/handlers/proposal.d.ts +38 -0
- package/dist/lib/server/handlers/proposal.d.ts.map +1 -0
- package/dist/lib/server/handlers/proposal.js +273 -0
- package/dist/lib/server/handlers/proposal.js.map +1 -0
- package/dist/lib/server/handlers/skills.d.ts +22 -0
- package/dist/lib/server/handlers/skills.d.ts.map +1 -0
- package/dist/lib/server/handlers/skills.js +119 -0
- package/dist/lib/server/handlers/skills.js.map +1 -0
- package/dist/lib/server-directory.d.ts +85 -0
- package/dist/lib/server-directory.d.ts.map +1 -0
- package/dist/lib/server-directory.js +177 -0
- package/dist/lib/server-directory.js.map +1 -0
- package/dist/lib/server.d.ts +162 -0
- package/dist/lib/server.d.ts.map +1 -0
- package/dist/lib/server.js +602 -0
- package/dist/lib/server.js.map +1 -0
- package/dist/lib/types.d.ts +461 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +98 -0
- package/dist/lib/types.js.map +1 -0
- package/package.json +22 -13
- package/bin/agentchat.js +0 -1617
- package/lib/chat.py +0 -241
- package/lib/client.js +0 -821
- package/lib/daemon.js +0 -562
- package/lib/deploy/akash.js +0 -811
- package/lib/deploy/config.js +0 -128
- package/lib/deploy/docker.js +0 -132
- package/lib/deploy/index.js +0 -24
- package/lib/elo_swarm.py +0 -569
- package/lib/escrow-hooks.js +0 -237
- package/lib/identity.js +0 -376
- package/lib/proposals.js +0 -426
- package/lib/protocol.js +0 -484
- package/lib/receipts.js +0 -294
- package/lib/reputation.js +0 -664
- package/lib/security.js +0 -183
- package/lib/server/handlers/identity.js +0 -242
- package/lib/server/handlers/index.js +0 -42
- package/lib/server/handlers/message.js +0 -306
- package/lib/server/handlers/presence.js +0 -44
- package/lib/server/handlers/proposal.js +0 -358
- package/lib/server/handlers/skills.js +0 -141
- package/lib/server-directory.js +0 -181
- package/lib/server.js +0 -528
- package/lib/supervisor/USAGE.md +0 -110
- package/lib/supervisor/agent-supervisor.sh +0 -135
- package/lib/supervisor/agentctl.sh +0 -250
- package/lib/supervisor/killswitch.sh +0 -36
- package/lib/supervisor/notify.sh +0 -19
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security utilities for AgentChat
|
|
3
|
+
* Prevents running agents in dangerous directories
|
|
4
|
+
*/
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import os from 'os';
|
|
7
|
+
// Directories that are absolutely forbidden (system roots)
|
|
8
|
+
const FORBIDDEN_DIRECTORIES = new Set([
|
|
9
|
+
'/',
|
|
10
|
+
'/root',
|
|
11
|
+
'/home',
|
|
12
|
+
'/Users',
|
|
13
|
+
'/var',
|
|
14
|
+
'/etc',
|
|
15
|
+
'/usr',
|
|
16
|
+
'/bin',
|
|
17
|
+
'/sbin',
|
|
18
|
+
'/lib',
|
|
19
|
+
'/opt',
|
|
20
|
+
'/tmp',
|
|
21
|
+
'/System',
|
|
22
|
+
'/Applications',
|
|
23
|
+
'/Library',
|
|
24
|
+
'/private',
|
|
25
|
+
'/private/var',
|
|
26
|
+
'/private/tmp',
|
|
27
|
+
'C:\\',
|
|
28
|
+
'C:\\Windows',
|
|
29
|
+
'C:\\Program Files',
|
|
30
|
+
'C:\\Program Files (x86)',
|
|
31
|
+
'C:\\Users',
|
|
32
|
+
]);
|
|
33
|
+
// Minimum depth from root required for a "project" directory
|
|
34
|
+
// e.g., /Users/name/projects/myproject = depth 4 (minimum required)
|
|
35
|
+
const MIN_SAFE_DEPTH = 3;
|
|
36
|
+
/**
|
|
37
|
+
* Get the depth of a path from root
|
|
38
|
+
*/
|
|
39
|
+
function getPathDepth(dirPath) {
|
|
40
|
+
const normalized = path.normalize(dirPath);
|
|
41
|
+
const parts = normalized.split(path.sep).filter(p => p && p !== '.');
|
|
42
|
+
return parts.length;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Check if directory is a user's home directory
|
|
46
|
+
*/
|
|
47
|
+
function isHomeDirectory(dirPath) {
|
|
48
|
+
const normalized = path.normalize(dirPath);
|
|
49
|
+
const homeDir = os.homedir();
|
|
50
|
+
// Check exact match with home directory
|
|
51
|
+
if (normalized === homeDir || normalized === homeDir + path.sep) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
// Check common home directory patterns
|
|
55
|
+
const homePatterns = [
|
|
56
|
+
/^\/Users\/[^/]+$/, // macOS: /Users/username
|
|
57
|
+
/^\/home\/[^/]+$/, // Linux: /home/username
|
|
58
|
+
/^C:\\Users\\[^\\]+$/i, // Windows: C:\Users\username
|
|
59
|
+
];
|
|
60
|
+
return homePatterns.some(pattern => pattern.test(normalized));
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Check if a directory is safe for running agentchat
|
|
64
|
+
*/
|
|
65
|
+
export function checkDirectorySafety(dirPath = process.cwd()) {
|
|
66
|
+
const normalized = path.normalize(path.resolve(dirPath));
|
|
67
|
+
// Check forbidden directories
|
|
68
|
+
if (FORBIDDEN_DIRECTORIES.has(normalized)) {
|
|
69
|
+
return {
|
|
70
|
+
safe: false,
|
|
71
|
+
level: 'error',
|
|
72
|
+
error: `Cannot run agentchat in system directory: ${normalized}\n` +
|
|
73
|
+
`Please run from a project directory instead.`
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
// Check if it's a home directory BEFORE depth check
|
|
77
|
+
// Home directories are allowed but warn (they're at depth 2 which would fail depth check)
|
|
78
|
+
if (isHomeDirectory(normalized)) {
|
|
79
|
+
return {
|
|
80
|
+
safe: true,
|
|
81
|
+
level: 'warning',
|
|
82
|
+
warning: `Running agentchat in home directory: ${normalized}\n` +
|
|
83
|
+
`Consider running from a specific project directory instead.`
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// Check path depth (too shallow = too close to root)
|
|
87
|
+
const depth = getPathDepth(normalized);
|
|
88
|
+
if (depth < MIN_SAFE_DEPTH) {
|
|
89
|
+
return {
|
|
90
|
+
safe: false,
|
|
91
|
+
level: 'error',
|
|
92
|
+
error: `Cannot run agentchat in root-level directory: ${normalized}\n` +
|
|
93
|
+
`This directory is too close to the filesystem root.\n` +
|
|
94
|
+
`Please run from a project directory (at least ${MIN_SAFE_DEPTH} levels deep).`
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// All checks passed
|
|
98
|
+
return {
|
|
99
|
+
safe: true,
|
|
100
|
+
level: 'ok'
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Enforce directory safety check - throws if unsafe
|
|
105
|
+
*/
|
|
106
|
+
export function enforceDirectorySafety(dirPath = process.cwd(), options = {}) {
|
|
107
|
+
const { allowWarnings = true, silent = false } = options;
|
|
108
|
+
const result = checkDirectorySafety(dirPath);
|
|
109
|
+
if (result.level === 'error') {
|
|
110
|
+
throw new Error(result.error);
|
|
111
|
+
}
|
|
112
|
+
if (result.level === 'warning') {
|
|
113
|
+
if (!silent) {
|
|
114
|
+
console.error(`\n⚠️ WARNING: ${result.warning}\n`);
|
|
115
|
+
}
|
|
116
|
+
if (!allowWarnings) {
|
|
117
|
+
throw new Error(result.warning);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return result;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Check if running in a project directory (has common project indicators)
|
|
124
|
+
*/
|
|
125
|
+
export function looksLikeProjectDirectory(dirPath = process.cwd()) {
|
|
126
|
+
const projectIndicators = [
|
|
127
|
+
'package.json',
|
|
128
|
+
'Cargo.toml',
|
|
129
|
+
'go.mod',
|
|
130
|
+
'pyproject.toml',
|
|
131
|
+
'setup.py',
|
|
132
|
+
'requirements.txt',
|
|
133
|
+
'Gemfile',
|
|
134
|
+
'pom.xml',
|
|
135
|
+
'build.gradle',
|
|
136
|
+
'Makefile',
|
|
137
|
+
'CMakeLists.txt',
|
|
138
|
+
'.git',
|
|
139
|
+
'.gitignore',
|
|
140
|
+
'README.md',
|
|
141
|
+
'README',
|
|
142
|
+
];
|
|
143
|
+
// This is a heuristic check - doesn't actually verify files exist
|
|
144
|
+
// Just checks if the path looks reasonable
|
|
145
|
+
const normalized = path.normalize(path.resolve(dirPath));
|
|
146
|
+
const depth = getPathDepth(normalized);
|
|
147
|
+
// If it's deep enough and not a system directory, it probably looks like a project
|
|
148
|
+
return depth >= MIN_SAFE_DEPTH && !FORBIDDEN_DIRECTORIES.has(normalized);
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../lib/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin Handlers
|
|
3
|
+
* Handles allowlist administration commands
|
|
4
|
+
*/
|
|
5
|
+
import type { WebSocket } from 'ws';
|
|
6
|
+
import type { AgentChatServer } from '../../server.js';
|
|
7
|
+
import type { AdminApproveMessage, AdminRevokeMessage, AdminListMessage } from '../../types.js';
|
|
8
|
+
interface ExtendedWebSocket extends WebSocket {
|
|
9
|
+
_connectedAt?: number;
|
|
10
|
+
_realIp?: string;
|
|
11
|
+
_userAgent?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Handle ADMIN_APPROVE command - add a pubkey to the allowlist
|
|
15
|
+
*/
|
|
16
|
+
export declare function handleAdminApprove(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminApproveMessage): void;
|
|
17
|
+
/**
|
|
18
|
+
* Handle ADMIN_REVOKE command - remove a pubkey from the allowlist
|
|
19
|
+
*/
|
|
20
|
+
export declare function handleAdminRevoke(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminRevokeMessage): void;
|
|
21
|
+
/**
|
|
22
|
+
* Handle ADMIN_LIST command - list all approved entries
|
|
23
|
+
*/
|
|
24
|
+
export declare function handleAdminList(server: AgentChatServer, ws: ExtendedWebSocket, msg: AdminListMessage): void;
|
|
25
|
+
export {};
|
|
26
|
+
//# sourceMappingURL=admin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../../../lib/server/handlers/admin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EACV,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EACjB,MAAM,gBAAgB,CAAC;AASxB,UAAU,iBAAkB,SAAQ,SAAS;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,mBAAmB,GAAG,IAAI,CAwBjH;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,kBAAkB,GAAG,IAAI,CAyB/G;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAmB3G"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Admin Handlers
|
|
3
|
+
* Handles allowlist administration commands
|
|
4
|
+
*/
|
|
5
|
+
import { ServerMessageType, ErrorCode, createMessage, createError, } from '../../protocol.js';
|
|
6
|
+
/**
|
|
7
|
+
* Handle ADMIN_APPROVE command - add a pubkey to the allowlist
|
|
8
|
+
*/
|
|
9
|
+
export function handleAdminApprove(server, ws, msg) {
|
|
10
|
+
if (!server.allowlist) {
|
|
11
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (!msg.pubkey) {
|
|
15
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Missing pubkey'));
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const result = server.allowlist.approve(msg.pubkey, msg.admin_key, msg.note || '');
|
|
19
|
+
if (!result.success) {
|
|
20
|
+
server._send(ws, createError(ErrorCode.AUTH_REQUIRED, result.error));
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
server._log('admin_approve', { agentId: result.agentId });
|
|
24
|
+
server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
|
|
25
|
+
action: 'approve',
|
|
26
|
+
success: true,
|
|
27
|
+
agentId: `@${result.agentId}`,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Handle ADMIN_REVOKE command - remove a pubkey from the allowlist
|
|
32
|
+
*/
|
|
33
|
+
export function handleAdminRevoke(server, ws, msg) {
|
|
34
|
+
if (!server.allowlist) {
|
|
35
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const identifier = msg.pubkey || msg.agent_id;
|
|
39
|
+
if (!identifier) {
|
|
40
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Missing pubkey or agent_id'));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const result = server.allowlist.revoke(identifier, msg.admin_key);
|
|
44
|
+
if (!result.success) {
|
|
45
|
+
const code = result.error === 'invalid admin key' ? ErrorCode.AUTH_REQUIRED : ErrorCode.AGENT_NOT_FOUND;
|
|
46
|
+
server._send(ws, createError(code, result.error));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
server._log('admin_revoke', { identifier });
|
|
50
|
+
server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
|
|
51
|
+
action: 'revoke',
|
|
52
|
+
success: true,
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Handle ADMIN_LIST command - list all approved entries
|
|
57
|
+
*/
|
|
58
|
+
export function handleAdminList(server, ws, msg) {
|
|
59
|
+
if (!server.allowlist) {
|
|
60
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Allowlist not configured'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Validate admin key
|
|
64
|
+
if (!server.allowlist._validateAdminKey(msg.admin_key)) {
|
|
65
|
+
server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Invalid admin key'));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const entries = server.allowlist.list();
|
|
69
|
+
server._send(ws, createMessage(ServerMessageType.ADMIN_RESULT, {
|
|
70
|
+
action: 'list',
|
|
71
|
+
entries,
|
|
72
|
+
enabled: server.allowlist.enabled,
|
|
73
|
+
strict: server.allowlist.strict,
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../../../lib/server/handlers/admin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Handlers
|
|
3
|
+
* Handles identify, verification request/response
|
|
4
|
+
*/
|
|
5
|
+
import type { WebSocket } from 'ws';
|
|
6
|
+
import type { AgentChatServer } from '../../server.js';
|
|
7
|
+
import type { IdentifyMessage, VerifyIdentityMessage, VerifyRequestMessage, VerifyResponseMessage } from '../../types.js';
|
|
8
|
+
interface ExtendedWebSocket extends WebSocket {
|
|
9
|
+
_connectedAt?: number;
|
|
10
|
+
_realIp?: string;
|
|
11
|
+
_userAgent?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Handle IDENTIFY command
|
|
15
|
+
*
|
|
16
|
+
* For ephemeral agents (no pubkey): immediately create agent state and send WELCOME.
|
|
17
|
+
* For pubkey agents: send CHALLENGE, wait for VERIFY_IDENTITY before creating state.
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleIdentify(server: AgentChatServer, ws: ExtendedWebSocket, msg: IdentifyMessage): void;
|
|
20
|
+
/**
|
|
21
|
+
* Handle VERIFY_IDENTITY command
|
|
22
|
+
*
|
|
23
|
+
* Verifies the challenge-response signature. On success, creates agent state
|
|
24
|
+
* and sends WELCOME. On failure, sends error.
|
|
25
|
+
*/
|
|
26
|
+
export declare function handleVerifyIdentity(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyIdentityMessage): void;
|
|
27
|
+
/**
|
|
28
|
+
* Handle VERIFY_REQUEST command
|
|
29
|
+
*/
|
|
30
|
+
export declare function handleVerifyRequest(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyRequestMessage): void;
|
|
31
|
+
/**
|
|
32
|
+
* Handle VERIFY_RESPONSE command
|
|
33
|
+
*/
|
|
34
|
+
export declare function handleVerifyResponse(server: AgentChatServer, ws: ExtendedWebSocket, msg: VerifyResponseMessage): void;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../../../lib/server/handlers/identity.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,KAAK,EACV,eAAe,EACf,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,gBAAgB,CAAC;AAgBxB,UAAU,iBAAkB,SAAQ,SAAS;IAC3C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAYD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,eAAe,GAAG,IAAI,CAqGzG;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,qBAAqB,GAAG,IAAI,CAiGrH;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,oBAAoB,GAAG,IAAI,CAsEnH;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,EAAE,iBAAiB,EAAE,GAAG,EAAE,qBAAqB,GAAG,IAAI,CA6ErH"}
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identity Handlers
|
|
3
|
+
* Handles identify, verification request/response
|
|
4
|
+
*/
|
|
5
|
+
import crypto from 'crypto';
|
|
6
|
+
import { ServerMessageType, ErrorCode, createMessage, createError, generateAgentId, generateVerifyId, generateChallengeId, generateNonce, generateAuthSigningContent, pubkeyToAgentId, } from '../../protocol.js';
|
|
7
|
+
import { Identity } from '../../identity.js';
|
|
8
|
+
/**
|
|
9
|
+
* Handle IDENTIFY command
|
|
10
|
+
*
|
|
11
|
+
* For ephemeral agents (no pubkey): immediately create agent state and send WELCOME.
|
|
12
|
+
* For pubkey agents: send CHALLENGE, wait for VERIFY_IDENTITY before creating state.
|
|
13
|
+
*/
|
|
14
|
+
export function handleIdentify(server, ws, msg) {
|
|
15
|
+
// Check if already identified
|
|
16
|
+
if (server.agents.has(ws)) {
|
|
17
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Already identified'));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// Check if this ws already has a pending challenge
|
|
21
|
+
for (const [, challenge] of server.pendingChallenges) {
|
|
22
|
+
if (challenge.ws === ws) {
|
|
23
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Challenge already pending'));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Allowlist check (before any state changes)
|
|
28
|
+
if (server.allowlist && server.allowlist.enabled) {
|
|
29
|
+
const check = server.allowlist.check(msg.pubkey || null);
|
|
30
|
+
if (!check.allowed) {
|
|
31
|
+
server._log('allowlist_rejected', {
|
|
32
|
+
ip: ws._realIp,
|
|
33
|
+
name: msg.name,
|
|
34
|
+
hasPubkey: !!msg.pubkey,
|
|
35
|
+
reason: check.reason
|
|
36
|
+
});
|
|
37
|
+
server._send(ws, createError(ErrorCode.NOT_ALLOWED, check.reason));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (msg.pubkey) {
|
|
42
|
+
// Pubkey agent: send challenge, do NOT create agent state yet
|
|
43
|
+
const challengeId = generateChallengeId();
|
|
44
|
+
const nonce = generateNonce();
|
|
45
|
+
const expiresAt = Date.now() + server.challengeTimeoutMs;
|
|
46
|
+
server.pendingChallenges.set(challengeId, {
|
|
47
|
+
ws,
|
|
48
|
+
name: msg.name,
|
|
49
|
+
pubkey: msg.pubkey,
|
|
50
|
+
nonce,
|
|
51
|
+
challengeId,
|
|
52
|
+
expires: expiresAt
|
|
53
|
+
});
|
|
54
|
+
// Set timeout to clean up expired challenges
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
const challenge = server.pendingChallenges.get(challengeId);
|
|
57
|
+
if (challenge) {
|
|
58
|
+
server.pendingChallenges.delete(challengeId);
|
|
59
|
+
if (challenge.ws.readyState === 1) {
|
|
60
|
+
server._send(challenge.ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge expired'));
|
|
61
|
+
challenge.ws.close(1000, 'Challenge expired');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}, server.challengeTimeoutMs);
|
|
65
|
+
server._log('challenge_sent', {
|
|
66
|
+
challengeId,
|
|
67
|
+
name: msg.name,
|
|
68
|
+
ip: ws._realIp
|
|
69
|
+
});
|
|
70
|
+
server._send(ws, createMessage(ServerMessageType.CHALLENGE, {
|
|
71
|
+
challenge_id: challengeId,
|
|
72
|
+
nonce,
|
|
73
|
+
expires_at: expiresAt
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
// Ephemeral agent: create state immediately
|
|
78
|
+
const id = generateAgentId();
|
|
79
|
+
const agent = {
|
|
80
|
+
id,
|
|
81
|
+
name: msg.name,
|
|
82
|
+
pubkey: null,
|
|
83
|
+
channels: new Set(),
|
|
84
|
+
connectedAt: Date.now(),
|
|
85
|
+
presence: 'online',
|
|
86
|
+
status_text: null,
|
|
87
|
+
verified: false
|
|
88
|
+
};
|
|
89
|
+
server.agents.set(ws, agent);
|
|
90
|
+
server.agentById.set(id, ws);
|
|
91
|
+
server._log('identify', {
|
|
92
|
+
id,
|
|
93
|
+
name: msg.name,
|
|
94
|
+
hasPubkey: false,
|
|
95
|
+
ephemeral: true,
|
|
96
|
+
ip: ws._realIp,
|
|
97
|
+
user_agent: ws._userAgent
|
|
98
|
+
});
|
|
99
|
+
server._send(ws, createMessage(ServerMessageType.WELCOME, {
|
|
100
|
+
agent_id: `@${id}`,
|
|
101
|
+
name: msg.name,
|
|
102
|
+
server: server.serverName
|
|
103
|
+
}));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Handle VERIFY_IDENTITY command
|
|
108
|
+
*
|
|
109
|
+
* Verifies the challenge-response signature. On success, creates agent state
|
|
110
|
+
* and sends WELCOME. On failure, sends error.
|
|
111
|
+
*/
|
|
112
|
+
export function handleVerifyIdentity(server, ws, msg) {
|
|
113
|
+
// Check if already identified
|
|
114
|
+
if (server.agents.has(ws)) {
|
|
115
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Already identified'));
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
// Look up the pending challenge
|
|
119
|
+
const challenge = server.pendingChallenges.get(msg.challenge_id);
|
|
120
|
+
if (!challenge) {
|
|
121
|
+
server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge not found or expired'));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
// Verify this is the same websocket that initiated the challenge
|
|
125
|
+
if (challenge.ws !== ws) {
|
|
126
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Challenge belongs to a different connection'));
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
// Check expiration
|
|
130
|
+
if (Date.now() > challenge.expires) {
|
|
131
|
+
server.pendingChallenges.delete(msg.challenge_id);
|
|
132
|
+
server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Challenge expired'));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
// Verify the signature
|
|
136
|
+
const expectedContent = generateAuthSigningContent(challenge.nonce, msg.challenge_id, msg.timestamp);
|
|
137
|
+
const verified = Identity.verify(expectedContent, msg.signature, challenge.pubkey);
|
|
138
|
+
if (!verified) {
|
|
139
|
+
server.pendingChallenges.delete(msg.challenge_id);
|
|
140
|
+
server._log('challenge_failed', {
|
|
141
|
+
challengeId: msg.challenge_id,
|
|
142
|
+
name: challenge.name,
|
|
143
|
+
ip: ws._realIp
|
|
144
|
+
});
|
|
145
|
+
server._send(ws, createError(ErrorCode.VERIFICATION_FAILED, 'Invalid signature'));
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
// Challenge passed — clean up pending challenge
|
|
149
|
+
server.pendingChallenges.delete(msg.challenge_id);
|
|
150
|
+
// Derive stable agent ID from pubkey
|
|
151
|
+
const existingId = server.pubkeyToId.get(challenge.pubkey);
|
|
152
|
+
let id;
|
|
153
|
+
if (existingId) {
|
|
154
|
+
id = existingId;
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
id = pubkeyToAgentId(challenge.pubkey);
|
|
158
|
+
server.pubkeyToId.set(challenge.pubkey, id);
|
|
159
|
+
}
|
|
160
|
+
// Check if this ID is currently in use by another connection
|
|
161
|
+
if (server.agentById.has(id)) {
|
|
162
|
+
const oldWs = server.agentById.get(id);
|
|
163
|
+
server._log('identity-takeover', { id, reason: 'Verified connection replacing existing' });
|
|
164
|
+
server._send(oldWs, createError(ErrorCode.INVALID_MSG, 'Disconnected: Another connection verified this identity'));
|
|
165
|
+
server._handleDisconnect(oldWs);
|
|
166
|
+
oldWs.close(1000, 'Identity claimed by verified connection');
|
|
167
|
+
}
|
|
168
|
+
// Create agent state with verified = true
|
|
169
|
+
const agent = {
|
|
170
|
+
id,
|
|
171
|
+
name: challenge.name,
|
|
172
|
+
pubkey: challenge.pubkey,
|
|
173
|
+
channels: new Set(),
|
|
174
|
+
connectedAt: Date.now(),
|
|
175
|
+
presence: 'online',
|
|
176
|
+
status_text: null,
|
|
177
|
+
verified: true
|
|
178
|
+
};
|
|
179
|
+
server.agents.set(ws, agent);
|
|
180
|
+
server.agentById.set(id, ws);
|
|
181
|
+
const isReturning = !!existingId;
|
|
182
|
+
server._log('identify', {
|
|
183
|
+
id,
|
|
184
|
+
name: challenge.name,
|
|
185
|
+
hasPubkey: true,
|
|
186
|
+
verified: true,
|
|
187
|
+
returning: isReturning,
|
|
188
|
+
ip: ws._realIp,
|
|
189
|
+
user_agent: ws._userAgent
|
|
190
|
+
});
|
|
191
|
+
server._send(ws, createMessage(ServerMessageType.WELCOME, {
|
|
192
|
+
agent_id: `@${id}`,
|
|
193
|
+
name: challenge.name,
|
|
194
|
+
server: server.serverName,
|
|
195
|
+
verified: true
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Handle VERIFY_REQUEST command
|
|
200
|
+
*/
|
|
201
|
+
export function handleVerifyRequest(server, ws, msg) {
|
|
202
|
+
const agent = server.agents.get(ws);
|
|
203
|
+
if (!agent) {
|
|
204
|
+
server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
// Find target agent
|
|
208
|
+
const targetId = msg.target.slice(1);
|
|
209
|
+
const targetWs = server.agentById.get(targetId);
|
|
210
|
+
if (!targetWs) {
|
|
211
|
+
server._send(ws, createError(ErrorCode.AGENT_NOT_FOUND, `Agent ${msg.target} not found`));
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const targetAgent = server.agents.get(targetWs);
|
|
215
|
+
// Target must have a pubkey for verification
|
|
216
|
+
if (!targetAgent?.pubkey) {
|
|
217
|
+
server._send(ws, createError(ErrorCode.NO_PUBKEY, `Agent ${msg.target} has no persistent identity`));
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
// Create verification request
|
|
221
|
+
const requestId = generateVerifyId();
|
|
222
|
+
const expires = Date.now() + server.verificationTimeoutMs;
|
|
223
|
+
const pendingVerification = {
|
|
224
|
+
from: `@${agent.id}`,
|
|
225
|
+
fromWs: ws,
|
|
226
|
+
target: msg.target,
|
|
227
|
+
targetPubkey: targetAgent.pubkey,
|
|
228
|
+
nonce: msg.nonce,
|
|
229
|
+
expires
|
|
230
|
+
};
|
|
231
|
+
server.pendingVerifications.set(requestId, pendingVerification);
|
|
232
|
+
// Set timeout to clean up expired requests
|
|
233
|
+
setTimeout(() => {
|
|
234
|
+
const request = server.pendingVerifications.get(requestId);
|
|
235
|
+
if (request) {
|
|
236
|
+
server.pendingVerifications.delete(requestId);
|
|
237
|
+
// Notify requester of timeout
|
|
238
|
+
if (request.fromWs.readyState === 1) {
|
|
239
|
+
server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_FAILED, {
|
|
240
|
+
request_id: requestId,
|
|
241
|
+
target: request.target,
|
|
242
|
+
reason: 'Verification timed out'
|
|
243
|
+
}));
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}, server.verificationTimeoutMs);
|
|
247
|
+
server._log('verify_request', { id: requestId, from: agent.id, target: targetId });
|
|
248
|
+
// Forward to target agent
|
|
249
|
+
server._send(targetWs, createMessage(ServerMessageType.VERIFY_REQUEST, {
|
|
250
|
+
request_id: requestId,
|
|
251
|
+
from: `@${agent.id}`,
|
|
252
|
+
nonce: msg.nonce
|
|
253
|
+
}));
|
|
254
|
+
// Acknowledge to requester
|
|
255
|
+
server._send(ws, createMessage(ServerMessageType.VERIFY_REQUEST, {
|
|
256
|
+
request_id: requestId,
|
|
257
|
+
target: msg.target,
|
|
258
|
+
status: 'pending'
|
|
259
|
+
}));
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Handle VERIFY_RESPONSE command
|
|
263
|
+
*/
|
|
264
|
+
export function handleVerifyResponse(server, ws, msg) {
|
|
265
|
+
const agent = server.agents.get(ws);
|
|
266
|
+
if (!agent) {
|
|
267
|
+
server._send(ws, createError(ErrorCode.AUTH_REQUIRED, 'Must IDENTIFY first'));
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// Must have identity to respond to verification
|
|
271
|
+
if (!agent.pubkey) {
|
|
272
|
+
server._send(ws, createError(ErrorCode.SIGNATURE_REQUIRED, 'Responding to verification requires persistent identity'));
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
// Find the pending verification
|
|
276
|
+
const request = server.pendingVerifications.get(msg.request_id);
|
|
277
|
+
if (!request) {
|
|
278
|
+
server._send(ws, createError(ErrorCode.VERIFICATION_EXPIRED, 'Verification request not found or expired'));
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
// Verify the responder is the target
|
|
282
|
+
if (request.target !== `@${agent.id}`) {
|
|
283
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'You are not the target of this verification'));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
// Verify the nonce matches
|
|
287
|
+
if (msg.nonce !== request.nonce) {
|
|
288
|
+
server._send(ws, createError(ErrorCode.INVALID_MSG, 'Nonce mismatch'));
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
// Verify the signature
|
|
292
|
+
let verified = false;
|
|
293
|
+
try {
|
|
294
|
+
const keyObj = crypto.createPublicKey(request.targetPubkey);
|
|
295
|
+
verified = crypto.verify(null, Buffer.from(msg.nonce), keyObj, Buffer.from(msg.sig, 'base64'));
|
|
296
|
+
}
|
|
297
|
+
catch (err) {
|
|
298
|
+
server._log('verify_error', { request_id: msg.request_id, error: err.message });
|
|
299
|
+
}
|
|
300
|
+
// Clean up the pending request
|
|
301
|
+
server.pendingVerifications.delete(msg.request_id);
|
|
302
|
+
server._log('verify_response', {
|
|
303
|
+
request_id: msg.request_id,
|
|
304
|
+
from: agent.id,
|
|
305
|
+
verified
|
|
306
|
+
});
|
|
307
|
+
// Notify the original requester
|
|
308
|
+
if (request.fromWs.readyState === 1) {
|
|
309
|
+
if (verified) {
|
|
310
|
+
server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_SUCCESS, {
|
|
311
|
+
request_id: msg.request_id,
|
|
312
|
+
agent: request.target,
|
|
313
|
+
pubkey: request.targetPubkey
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
316
|
+
else {
|
|
317
|
+
server._send(request.fromWs, createMessage(ServerMessageType.VERIFY_FAILED, {
|
|
318
|
+
request_id: msg.request_id,
|
|
319
|
+
target: request.target,
|
|
320
|
+
reason: 'Signature verification failed'
|
|
321
|
+
}));
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
// Notify the responder
|
|
325
|
+
server._send(ws, createMessage(verified ? ServerMessageType.VERIFY_SUCCESS : ServerMessageType.VERIFY_FAILED, {
|
|
326
|
+
request_id: msg.request_id,
|
|
327
|
+
verified
|
|
328
|
+
}));
|
|
329
|
+
}
|
|
330
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../../../lib/server/handlers/identity.ts"],"names":[],"mappings":"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"}
|