@bridgekitux/agent 0.1.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/README.md +17 -0
- package/dist/src/audit.d.ts +18 -0
- package/dist/src/audit.d.ts.map +1 -0
- package/dist/src/audit.js +30 -0
- package/dist/src/audit.js.map +1 -0
- package/dist/src/cli.d.ts +3 -0
- package/dist/src/cli.d.ts.map +1 -0
- package/dist/src/cli.js +173 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/config.d.ts +24 -0
- package/dist/src/config.d.ts.map +1 -0
- package/dist/src/config.js +66 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/handlers.d.ts +87 -0
- package/dist/src/handlers.d.ts.map +1 -0
- package/dist/src/handlers.js +1143 -0
- package/dist/src/handlers.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +7 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/path-scope.d.ts +2 -0
- package/dist/src/path-scope.d.ts.map +1 -0
- package/dist/src/path-scope.js +12 -0
- package/dist/src/path-scope.js.map +1 -0
- package/dist/src/resources.d.ts +74 -0
- package/dist/src/resources.d.ts.map +1 -0
- package/dist/src/resources.js +92 -0
- package/dist/src/resources.js.map +1 -0
- package/dist/src/server.d.ts +54 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +291 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/state.d.ts +59 -0
- package/dist/src/state.d.ts.map +1 -0
- package/dist/src/state.js +98 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/vault.d.ts +31 -0
- package/dist/src/vault.d.ts.map +1 -0
- package/dist/src/vault.js +69 -0
- package/dist/src/vault.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { createServer as createTcpServer } from 'node:net';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
3
|
+
import { WebSocketServer } from 'ws';
|
|
4
|
+
import { createErrorMessage, createMessage, getManifestRuntime, hasCapability, parseMessage, toBridgeKitError, validateManifest } from '@bridgekitux/protocol';
|
|
5
|
+
import { AuditLog } from './audit.js';
|
|
6
|
+
import { createBridgeKitPaths, ensureBridgeKitHome, JsonFileStore } from './config.js';
|
|
7
|
+
import { ResourceRegistry } from './resources.js';
|
|
8
|
+
import { PairingStore, SessionStore } from './state.js';
|
|
9
|
+
import { createAgentHttpServer, invokeCapability, operationForInvoke, ProcessManager, subscribeCapability } from './handlers.js';
|
|
10
|
+
import { SecretVault } from './vault.js';
|
|
11
|
+
export class BridgeKitAgent {
|
|
12
|
+
options;
|
|
13
|
+
host;
|
|
14
|
+
requestedPort;
|
|
15
|
+
paths;
|
|
16
|
+
registry;
|
|
17
|
+
pairings;
|
|
18
|
+
sessions;
|
|
19
|
+
audit;
|
|
20
|
+
vault;
|
|
21
|
+
processManager = new ProcessManager();
|
|
22
|
+
httpServer;
|
|
23
|
+
wsServer;
|
|
24
|
+
currentPort;
|
|
25
|
+
subscriptions = new Map();
|
|
26
|
+
constructor(options = {}) {
|
|
27
|
+
this.options = options;
|
|
28
|
+
this.host = options.host ?? '127.0.0.1';
|
|
29
|
+
this.requestedPort = options.port ?? 7777;
|
|
30
|
+
this.paths = createBridgeKitPaths(options.home);
|
|
31
|
+
this.registry = new ResourceRegistry(new JsonFileStore(this.paths.resources, { resources: [] }));
|
|
32
|
+
this.pairings = new PairingStore(new JsonFileStore(this.paths.pairings, { pairings: [] }));
|
|
33
|
+
this.sessions = new SessionStore(new JsonFileStore(this.paths.sessions, { sessions: [] }));
|
|
34
|
+
this.audit = new AuditLog(this.paths.auditLog);
|
|
35
|
+
this.vault = new SecretVault(new JsonFileStore(this.paths.vault, { secrets: [] }), this.paths.vaultKey);
|
|
36
|
+
}
|
|
37
|
+
get port() {
|
|
38
|
+
return this.currentPort ?? this.requestedPort;
|
|
39
|
+
}
|
|
40
|
+
get url() {
|
|
41
|
+
return `ws://${this.host}:${this.port}/bridgekit`;
|
|
42
|
+
}
|
|
43
|
+
async start() {
|
|
44
|
+
await ensureBridgeKitHome(this.paths);
|
|
45
|
+
this.httpServer = await createAgentHttpServer(() => ({
|
|
46
|
+
registry: this.registry,
|
|
47
|
+
audit: this.audit,
|
|
48
|
+
vault: this.vault,
|
|
49
|
+
agentHost: this.host,
|
|
50
|
+
agentPort: this.port,
|
|
51
|
+
processManager: this.processManager
|
|
52
|
+
}));
|
|
53
|
+
this.wsServer = new WebSocketServer({ server: this.httpServer, path: '/bridgekit' });
|
|
54
|
+
this.wsServer.on('connection', (socket, request) => {
|
|
55
|
+
const origin = request.headers.origin;
|
|
56
|
+
socket.on('message', (data) => {
|
|
57
|
+
void this.handleRawMessage(socket, data.toString(), typeof origin === 'string' ? origin : undefined);
|
|
58
|
+
});
|
|
59
|
+
socket.on('close', () => this.closeSocketSubscriptions(socket));
|
|
60
|
+
});
|
|
61
|
+
await new Promise((resolve, reject) => {
|
|
62
|
+
this.httpServer.once('error', reject);
|
|
63
|
+
this.httpServer.listen(this.requestedPort, this.host, () => {
|
|
64
|
+
this.currentPort = this.httpServer.address().port;
|
|
65
|
+
this.httpServer.off('error', reject);
|
|
66
|
+
resolve();
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
await this.audit.write({ action: 'agent.start', outcome: 'info', details: { host: this.host, port: this.port } });
|
|
70
|
+
}
|
|
71
|
+
async stop() {
|
|
72
|
+
for (const [subscriptionId, subscription] of this.subscriptions.entries()) {
|
|
73
|
+
subscription.control.close();
|
|
74
|
+
this.subscriptions.delete(subscriptionId);
|
|
75
|
+
}
|
|
76
|
+
await new Promise((resolve) => {
|
|
77
|
+
for (const client of this.wsServer?.clients ?? [])
|
|
78
|
+
client.terminate();
|
|
79
|
+
this.wsServer?.close(() => resolve());
|
|
80
|
+
if (!this.wsServer)
|
|
81
|
+
resolve();
|
|
82
|
+
});
|
|
83
|
+
await new Promise((resolve) => {
|
|
84
|
+
this.httpServer?.close(() => resolve());
|
|
85
|
+
if (!this.httpServer)
|
|
86
|
+
resolve();
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
async handleRawMessage(socket, raw, origin) {
|
|
90
|
+
let message;
|
|
91
|
+
try {
|
|
92
|
+
message = parseMessage(JSON.parse(raw));
|
|
93
|
+
const response = await this.handleMessage(socket, message, origin);
|
|
94
|
+
if (response)
|
|
95
|
+
socket.send(JSON.stringify(response));
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
socket.send(JSON.stringify(createErrorMessage('error', toBridgeKitError(error))));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async handleMessage(socket, message, origin) {
|
|
102
|
+
switch (message.type) {
|
|
103
|
+
case 'hello':
|
|
104
|
+
return this.handleHello(message.payload, message.id, origin);
|
|
105
|
+
case 'pair.request':
|
|
106
|
+
return this.handlePairRequest(message.payload, message.id, origin);
|
|
107
|
+
case 'pair.status':
|
|
108
|
+
return this.handlePairStatus(message.payload, message.id);
|
|
109
|
+
case 'invoke':
|
|
110
|
+
return this.handleInvoke(message.payload, message.id, origin);
|
|
111
|
+
case 'subscribe':
|
|
112
|
+
return this.handleSubscribe(socket, message.payload, message.id, origin);
|
|
113
|
+
case 'stream.send':
|
|
114
|
+
return this.handleStreamSend(message.payload, message.id, origin);
|
|
115
|
+
case 'unsubscribe':
|
|
116
|
+
return this.handleUnsubscribe(message.payload, message.id, origin);
|
|
117
|
+
case 'resources.list':
|
|
118
|
+
return createMessage('resources.list.result', { resources: await this.registry.describe() }, message.id);
|
|
119
|
+
default:
|
|
120
|
+
return createErrorMessage(`${message.type}.error`, { code: 'unknown_message', message: `Unsupported message type: ${message.type}` }, message.id);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async handleHello(payload, id, origin) {
|
|
124
|
+
await this.audit.write({ action: 'client.hello', outcome: 'info', origin, details: payload });
|
|
125
|
+
return createMessage('hello.ok', {
|
|
126
|
+
agentVersion: '0.1.0',
|
|
127
|
+
protocolVersion: '0.1.0',
|
|
128
|
+
bridge: 'direct-websocket'
|
|
129
|
+
}, id);
|
|
130
|
+
}
|
|
131
|
+
async handlePairRequest(payload, id, origin) {
|
|
132
|
+
const manifest = validateManifest(payload.manifest);
|
|
133
|
+
const pairing = await this.pairings.create({
|
|
134
|
+
appName: payload.appName || manifest.name,
|
|
135
|
+
runtime: payload.runtime ?? payload.environment ?? getManifestRuntime(manifest),
|
|
136
|
+
origin: payload.origin ?? origin,
|
|
137
|
+
manifest
|
|
138
|
+
});
|
|
139
|
+
await this.audit.write({ action: 'pair.request', outcome: 'info', pairingId: pairing.id, origin, details: { appName: pairing.appName, runtime: pairing.runtime, requestedCapabilities: pairing.requestedCapabilities } });
|
|
140
|
+
if (this.options.autoApprove) {
|
|
141
|
+
await this.pairings.update(pairing.id, (record) => ({ ...record, status: 'approved', decidedAt: new Date().toISOString() }));
|
|
142
|
+
const approved = await this.issueSession(pairing.id, 'auto-approve');
|
|
143
|
+
return createMessage('pair.approved', approved, id);
|
|
144
|
+
}
|
|
145
|
+
return createMessage('pair.pending', {
|
|
146
|
+
pairingId: pairing.id,
|
|
147
|
+
code: pairing.code,
|
|
148
|
+
approveUrl: `bridgekit://approve/${pairing.code}`,
|
|
149
|
+
requestedCapabilities: pairing.requestedCapabilities,
|
|
150
|
+
status: 'pending'
|
|
151
|
+
}, id);
|
|
152
|
+
}
|
|
153
|
+
async handlePairStatus(payload, id) {
|
|
154
|
+
const key = payload.pairingId ?? payload.code;
|
|
155
|
+
if (!key)
|
|
156
|
+
return createErrorMessage('pair.status.error', { code: 'invalid_request', message: 'pairingId or code is required' }, id);
|
|
157
|
+
const pairing = await this.pairings.find(key);
|
|
158
|
+
if (!pairing)
|
|
159
|
+
return createErrorMessage('pair.status.error', { code: 'pairing_not_found', message: `No pairing found for ${key}` }, id);
|
|
160
|
+
if (pairing.status === 'denied')
|
|
161
|
+
return createErrorMessage('pair.denied', { code: 'permission_denied', message: 'Pairing was denied' }, id);
|
|
162
|
+
if (pairing.status === 'approved')
|
|
163
|
+
return createMessage('pair.approved', await this.issueSession(pairing.id, 'local-user'), id);
|
|
164
|
+
return createMessage('pair.pending', {
|
|
165
|
+
pairingId: pairing.id,
|
|
166
|
+
code: pairing.code,
|
|
167
|
+
approveUrl: `bridgekit://approve/${pairing.code}`,
|
|
168
|
+
requestedCapabilities: pairing.requestedCapabilities,
|
|
169
|
+
status: 'pending'
|
|
170
|
+
}, id);
|
|
171
|
+
}
|
|
172
|
+
async issueSession(pairingId, approvedBy) {
|
|
173
|
+
const pairing = await this.pairings.find(pairingId);
|
|
174
|
+
if (!pairing)
|
|
175
|
+
throw new Error(`Pairing not found: ${pairingId}`);
|
|
176
|
+
const created = await this.sessions.createFromPairing(pairing, approvedBy);
|
|
177
|
+
await this.pairings.update(pairing.id, (record) => ({ ...record, status: 'approved', decidedAt: record.decidedAt ?? new Date().toISOString(), sessionId: created.session.id }));
|
|
178
|
+
await this.audit.write({ action: 'session.create', outcome: 'allowed', pairingId: pairing.id, sessionId: created.session.id, origin: pairing.origin, details: { grants: created.session.grants.length } });
|
|
179
|
+
return { sessionId: created.session.id, sessionToken: created.token, grants: created.session.grants, expiresAt: created.session.expiresAt };
|
|
180
|
+
}
|
|
181
|
+
async handleSubscribe(socket, payload, id, origin) {
|
|
182
|
+
const session = await this.sessions.findByToken(payload.sessionToken);
|
|
183
|
+
if (!session) {
|
|
184
|
+
await this.audit.write({ action: 'subscription.start', outcome: 'denied', capability: payload.capability, resourceId: payload.resourceId, origin, details: { reason: 'invalid_session' } });
|
|
185
|
+
return createErrorMessage('subscribe.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
|
|
186
|
+
}
|
|
187
|
+
const operation = operationForInvoke(payload);
|
|
188
|
+
const allowed = hasCapability(session.grants, payload.capability, payload.resourceId, operation);
|
|
189
|
+
if (!allowed) {
|
|
190
|
+
await this.audit.write({ action: 'subscription.start', outcome: 'denied', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
|
|
191
|
+
return createErrorMessage('subscribe.error', { code: 'permission_denied', message: `${payload.capability} is not approved for ${payload.resourceId}` }, id);
|
|
192
|
+
}
|
|
193
|
+
const subscriptionId = randomUUID();
|
|
194
|
+
try {
|
|
195
|
+
const control = await subscribeCapability({ registry: this.registry, audit: this.audit, vault: this.vault, agentHost: this.host, agentPort: this.port, processManager: this.processManager }, { ...payload, operation }, (event) => {
|
|
196
|
+
const subscription = this.subscriptions.get(subscriptionId);
|
|
197
|
+
if (!subscription || socket.readyState !== 1)
|
|
198
|
+
return;
|
|
199
|
+
subscription.sequence += 1;
|
|
200
|
+
socket.send(JSON.stringify(createMessage('event', {
|
|
201
|
+
...event,
|
|
202
|
+
subscriptionId,
|
|
203
|
+
sequence: subscription.sequence
|
|
204
|
+
})));
|
|
205
|
+
});
|
|
206
|
+
this.subscriptions.set(subscriptionId, { sessionId: session.id, socket, control, sequence: 0 });
|
|
207
|
+
await this.audit.write({ action: 'subscription.start', outcome: 'allowed', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation, subscriptionId } });
|
|
208
|
+
return createMessage('subscribe.result', { subscriptionId }, id);
|
|
209
|
+
}
|
|
210
|
+
catch (error) {
|
|
211
|
+
await this.audit.write({ action: 'subscription.start', outcome: 'error', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: toBridgeKitError(error) });
|
|
212
|
+
return createErrorMessage('subscribe.error', toBridgeKitError(error), id);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
async handleUnsubscribe(payload, id, origin) {
|
|
216
|
+
const session = await this.sessions.findByToken(payload.sessionToken);
|
|
217
|
+
if (!session)
|
|
218
|
+
return createErrorMessage('unsubscribe.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
|
|
219
|
+
const subscription = this.subscriptions.get(payload.subscriptionId);
|
|
220
|
+
if (!subscription || subscription.sessionId !== session.id) {
|
|
221
|
+
return createMessage('unsubscribe.result', { subscriptionId: payload.subscriptionId, closed: false }, id);
|
|
222
|
+
}
|
|
223
|
+
subscription.control.close();
|
|
224
|
+
this.subscriptions.delete(payload.subscriptionId);
|
|
225
|
+
await this.audit.write({ action: 'subscription.stop', outcome: 'allowed', sessionId: session.id, origin, details: { subscriptionId: payload.subscriptionId } });
|
|
226
|
+
return createMessage('unsubscribe.result', { subscriptionId: payload.subscriptionId, closed: true }, id);
|
|
227
|
+
}
|
|
228
|
+
async handleStreamSend(payload, id, origin) {
|
|
229
|
+
const session = await this.sessions.findByToken(payload.sessionToken);
|
|
230
|
+
if (!session) {
|
|
231
|
+
await this.audit.write({ action: 'stream.send', outcome: 'denied', origin, details: { reason: 'invalid_session', subscriptionId: payload.subscriptionId } });
|
|
232
|
+
return createErrorMessage('stream.send.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
|
|
233
|
+
}
|
|
234
|
+
const subscription = this.subscriptions.get(payload.subscriptionId);
|
|
235
|
+
if (!subscription || subscription.sessionId !== session.id) {
|
|
236
|
+
await this.audit.write({ action: 'stream.send', outcome: 'denied', sessionId: session.id, origin, details: { reason: 'subscription_not_found', subscriptionId: payload.subscriptionId } });
|
|
237
|
+
return createErrorMessage('stream.send.error', { code: 'subscription_not_found', message: `No active stream subscription named ${payload.subscriptionId}` }, id);
|
|
238
|
+
}
|
|
239
|
+
if (!subscription.control.send) {
|
|
240
|
+
await this.audit.write({ action: 'stream.send', outcome: 'denied', sessionId: session.id, origin, details: { reason: 'stream_not_writable', subscriptionId: payload.subscriptionId } });
|
|
241
|
+
return createErrorMessage('stream.send.error', { code: 'stream_not_writable', message: `Subscription ${payload.subscriptionId} does not accept outbound data` }, id);
|
|
242
|
+
}
|
|
243
|
+
try {
|
|
244
|
+
const result = await subscription.control.send(payload);
|
|
245
|
+
await this.audit.write({ action: 'stream.send', outcome: 'allowed', sessionId: session.id, origin, details: { subscriptionId: payload.subscriptionId, bytes: result.bytes, ended: result.ended } });
|
|
246
|
+
return createMessage('stream.send.result', { subscriptionId: payload.subscriptionId, ...result }, id);
|
|
247
|
+
}
|
|
248
|
+
catch (error) {
|
|
249
|
+
await this.audit.write({ action: 'stream.send', outcome: 'error', sessionId: session.id, origin, details: toBridgeKitError(error) });
|
|
250
|
+
return createErrorMessage('stream.send.error', toBridgeKitError(error), id);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
closeSocketSubscriptions(socket) {
|
|
254
|
+
for (const [subscriptionId, subscription] of this.subscriptions.entries()) {
|
|
255
|
+
if (subscription.socket !== socket)
|
|
256
|
+
continue;
|
|
257
|
+
subscription.control.close();
|
|
258
|
+
this.subscriptions.delete(subscriptionId);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async handleInvoke(payload, id, origin) {
|
|
262
|
+
const session = await this.sessions.findByToken(payload.sessionToken);
|
|
263
|
+
if (!session) {
|
|
264
|
+
await this.audit.write({ action: 'capability.invoke', outcome: 'denied', capability: payload.capability, resourceId: payload.resourceId, origin, details: { reason: 'invalid_session' } });
|
|
265
|
+
return createErrorMessage('invoke.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
|
|
266
|
+
}
|
|
267
|
+
const operation = operationForInvoke(payload);
|
|
268
|
+
const allowed = hasCapability(session.grants, payload.capability, payload.resourceId ?? '', operation);
|
|
269
|
+
if (!allowed) {
|
|
270
|
+
await this.audit.write({ action: 'capability.invoke', outcome: 'denied', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
|
|
271
|
+
return createErrorMessage('invoke.error', { code: 'permission_denied', message: `${payload.capability} is not approved for ${payload.resourceId ?? 'this session'}` }, id);
|
|
272
|
+
}
|
|
273
|
+
try {
|
|
274
|
+
const result = await invokeCapability({ registry: this.registry, audit: this.audit, vault: this.vault, agentHost: this.host, agentPort: this.port, processManager: this.processManager }, { ...payload, operation });
|
|
275
|
+
await this.audit.write({ action: 'capability.invoke', outcome: 'allowed', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
|
|
276
|
+
return createMessage('invoke.result', { ok: true, result }, id);
|
|
277
|
+
}
|
|
278
|
+
catch (error) {
|
|
279
|
+
await this.audit.write({ action: 'capability.invoke', outcome: 'error', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: toBridgeKitError(error) });
|
|
280
|
+
return createErrorMessage('invoke.error', toBridgeKitError(error), id);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
export async function isPortAvailable(port, host = '127.0.0.1') {
|
|
285
|
+
const server = createTcpServer();
|
|
286
|
+
return new Promise((resolve) => {
|
|
287
|
+
server.once('error', () => resolve(false));
|
|
288
|
+
server.listen(port, host, () => server.close(() => resolve(true)));
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,IAAI,eAAe,EAAe,MAAM,UAAU,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AACrD,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,kBAAkB,EAClB,aAAa,EACb,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAUjB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,aAAa,EAAuB,MAAM,aAAa,CAAC;AAC5G,OAAO,EAAE,gBAAgB,EAAqB,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,YAAY,EAA0D,MAAM,YAAY,CAAC;AAChH,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EAA4B,MAAM,eAAe,CAAC;AAC3J,OAAO,EAAE,WAAW,EAAkB,MAAM,YAAY,CAAC;AAkBzD,MAAM,OAAO,cAAc;IAeI;IAdpB,IAAI,CAAS;IACb,aAAa,CAAS;IACtB,KAAK,CAAiB;IACtB,QAAQ,CAAmB;IAC3B,QAAQ,CAAe;IACvB,QAAQ,CAAe;IACvB,KAAK,CAAW;IAChB,KAAK,CAAc;IACnB,cAAc,GAAG,IAAI,cAAc,EAAE,CAAC;IACvC,UAAU,CAAqD;IAC/D,QAAQ,CAAmB;IAC3B,WAAW,CAAU;IACZ,aAAa,GAAG,IAAI,GAAG,EAAoG,CAAC;IAE7I,YAA6B,UAAiC,EAAE;QAAnC,YAAO,GAAP,OAAO,CAA4B;QAC9D,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC;QACxC,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,GAAG,IAAI,gBAAgB,CAAC,IAAI,aAAa,CAAe,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QAC/G,IAAI,CAAC,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,aAAa,CAAc,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACxG,IAAI,CAAC,QAAQ,GAAG,IAAI,YAAY,CAAC,IAAI,aAAa,CAAc,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;QACxG,IAAI,CAAC,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC/C,IAAI,CAAC,KAAK,GAAG,IAAI,WAAW,CAAC,IAAI,aAAa,CAAY,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IACrH,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,WAAW,IAAI,IAAI,CAAC,aAAa,CAAC;IAChD,CAAC;IAED,IAAI,GAAG;QACL,OAAO,QAAQ,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,YAAY,CAAC;IACpD,CAAC;IAED,KAAK,CAAC,KAAK;QACT,MAAM,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,MAAM,qBAAqB,CAAC,GAAG,EAAE,CAAC,CAAC;YACnD,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,SAAS,EAAE,IAAI,CAAC,IAAI;YACpB,cAAc,EAAE,IAAI,CAAC,cAAc;SACpC,CAAC,CAAC,CAAC;QACJ,IAAI,CAAC,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAC;QACrF,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YACtC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBAC5B,KAAK,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;YACvG,CAAC,CAAC,CAAC;YACH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,CAAC;QAClE,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,CAAC,UAAW,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvC,IAAI,CAAC,UAAW,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,GAAG,EAAE;gBAC1D,IAAI,CAAC,WAAW,GAAI,IAAI,CAAC,UAAW,CAAC,OAAO,EAAkB,CAAC,IAAI,CAAC;gBACpE,IAAI,CAAC,UAAW,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBACtC,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACpH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,KAAK,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1E,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,OAAO,IAAI,EAAE;gBAAE,MAAM,CAAC,SAAS,EAAE,CAAC;YACtE,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,QAAQ;gBAAE,OAAO,EAAE,CAAC;QAChC,CAAC,CAAC,CAAC;QACH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,UAAU;gBAAE,OAAO,EAAE,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,MAAiB,EAAE,GAAW,EAAE,MAAe;QAC5E,IAAI,OAAyB,CAAC;QAC9B,IAAI,CAAC;YACH,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;YACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;YACnE,IAAI,QAAQ;gBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QACtD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACpF,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,aAAa,CAAC,MAAiB,EAAE,OAAyB,EAAE,MAAe;QACvF,QAAQ,OAAO,CAAC,IAAI,EAAE,CAAC;YACrB,KAAK,OAAO;gBACV,OAAO,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAuB,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/E,KAAK,cAAc;gBACjB,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAA6B,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC3F,KAAK,aAAa;gBAChB,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAA4B,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;YACjF,KAAK,QAAQ;gBACX,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAwB,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACjF,KAAK,WAAW;gBACd,OAAO,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,OAA2B,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/F,KAAK,aAAa;gBAChB,OAAO,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,OAA4B,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACzF,KAAK,aAAa;gBAChB,OAAO,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,OAA6B,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC3F,KAAK,gBAAgB;gBACnB,OAAO,aAAa,CAAC,uBAAuB,EAAE,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3G;gBACE,OAAO,kBAAkB,CAAC,GAAG,OAAO,CAAC,IAAI,QAAQ,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,6BAA6B,OAAO,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QACtJ,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,WAAW,CAAC,OAAqB,EAAE,EAAW,EAAE,MAAe;QAC3E,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QAC9F,OAAO,aAAa,CAAC,UAAU,EAAE;YAC/B,YAAY,EAAE,OAAO;YACrB,eAAe,EAAE,OAAO;YACxB,MAAM,EAAE,kBAAkB;SAC3B,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAA2B,EAAE,EAAW,EAAE,MAAe;QACvF,MAAM,QAAQ,GAAG,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACpD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC;YACzC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,IAAI;YACzC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,WAAW,IAAI,kBAAkB,CAAC,QAAQ,CAAC;YAC/E,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,MAAM;YAChC,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,qBAAqB,EAAE,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;QAE1N,IAAI,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC;YAC7H,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACrE,OAAO,aAAa,CAAC,eAAe,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,aAAa,CAAC,cAAc,EAAE;YACnC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,UAAU,EAAE,uBAAuB,OAAO,CAAC,IAAI,EAAE;YACjD,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;YACpD,MAAM,EAAE,SAAS;SAClB,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,OAA0B,EAAE,EAAW;QACpE,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;QAC9C,IAAI,CAAC,GAAG;YAAE,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,+BAA+B,EAAE,EAAE,EAAE,CAAC,CAAC;QACpI,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC9C,IAAI,CAAC,OAAO;YAAE,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,wBAAwB,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACxI,IAAI,OAAO,CAAC,MAAM,KAAK,QAAQ;YAAE,OAAO,kBAAkB,CAAC,aAAa,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,oBAAoB,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5I,IAAI,OAAO,CAAC,MAAM,KAAK,UAAU;YAAE,OAAO,aAAa,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,CAAC,EAAE,EAAE,CAAC,CAAC;QAChI,OAAO,aAAa,CAAC,cAAc,EAAE;YACnC,SAAS,EAAE,OAAO,CAAC,EAAE;YACrB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,UAAU,EAAE,uBAAuB,OAAO,CAAC,IAAI,EAAE;YACjD,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;YACpD,MAAM,EAAE,SAAS;SAClB,EAAE,EAAE,CAAC,CAAC;IACT,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,SAAiB,EAAE,UAAkD;QAC9F,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAA8B,CAAC;QACjF,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QAC3E,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAChL,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,gBAAgB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC3M,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,YAAY,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;IAC9I,CAAC;IAEO,KAAK,CAAC,eAAe,CAAC,MAAiB,EAAE,OAAyB,EAAE,EAAW,EAAE,MAAe;QACtG,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;YAC5L,OAAO,kBAAkB,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,qCAAqC,EAAE,EAAE,EAAE,CAAC,CAAC;QAChI,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAwB,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACjG,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YACnM,OAAO,kBAAkB,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,UAAU,wBAAwB,OAAO,CAAC,UAAU,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9J,CAAC;QAED,MAAM,cAAc,GAAG,UAAU,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE;gBACjO,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAC5D,IAAI,CAAC,YAAY,IAAI,MAAM,CAAC,UAAU,KAAK,CAAC;oBAAE,OAAO;gBACrD,YAAY,CAAC,QAAQ,IAAI,CAAC,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE;oBAChD,GAAG,KAAK;oBACR,cAAc;oBACd,QAAQ,EAAE,YAAY,CAAC,QAAQ;iBAChC,CAAC,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;YACH,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,CAAC;YAChG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,EAAE,CAAC,CAAC;YACpN,OAAO,aAAa,CAAC,kBAAkB,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC5M,OAAO,kBAAkB,CAAC,iBAAiB,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,OAA2B,EAAE,EAAW,EAAE,MAAe;QACvF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO;YAAE,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,qCAAqC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9I,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;YAC3D,OAAO,aAAa,CAAC,oBAAoB,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC5G,CAAC;QACD,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QAChK,OAAO,aAAa,CAAC,oBAAoB,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IAC3G,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,OAA0B,EAAE,EAAW,EAAE,MAAe;QACrF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAC7J,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,qCAAqC,EAAE,EAAE,EAAE,CAAC,CAAC;QAClI,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,EAAE,CAAC;YAC3D,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,wBAAwB,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAC3L,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,wBAAwB,EAAE,OAAO,EAAE,uCAAuC,OAAO,CAAC,cAAc,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACnK,CAAC;QACD,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAC/B,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YACxL,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE,OAAO,EAAE,gBAAgB,OAAO,CAAC,cAAc,gCAAgC,EAAE,EAAE,EAAE,CAAC,CAAC;QACvK,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;YACpM,OAAO,aAAa,CAAC,oBAAoB,EAAE,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QACxG,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACrI,OAAO,kBAAkB,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;IAEO,wBAAwB,CAAC,MAAiB;QAChD,KAAK,MAAM,CAAC,cAAc,EAAE,YAAY,CAAC,IAAI,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,EAAE,CAAC;YAC1E,IAAI,YAAY,CAAC,MAAM,KAAK,MAAM;gBAAE,SAAS;YAC7C,YAAY,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7B,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,OAAsB,EAAE,EAAW,EAAE,MAAe;QAC7E,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QACtE,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,CAAC,CAAC;YAC3L,OAAO,kBAAkB,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,qCAAqC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7H,CAAC;QAED,MAAM,SAAS,GAAG,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC9C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;QACvG,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YAClM,OAAO,kBAAkB,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,UAAU,wBAAwB,OAAO,CAAC,UAAU,IAAI,cAAc,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QAC7K,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,cAAc,EAAE,EAAE,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YACrN,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;YACnM,OAAO,aAAa,CAAC,eAAe,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,mBAAmB,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,UAAU,EAAE,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3M,OAAO,kBAAkB,CAAC,cAAc,EAAE,gBAAgB,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,IAAI,GAAG,WAAW;IACpE,MAAM,MAAM,GAAW,eAAe,EAAE,CAAC;IACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { BridgeKitManifest, CapabilityGrant, CapabilityRequest, RestrictedEnvironment } from '@bridgekitux/protocol';
|
|
2
|
+
import type { JsonFileStore } from './config.js';
|
|
3
|
+
export interface PairingRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
code: string;
|
|
6
|
+
appName: string;
|
|
7
|
+
runtime: RestrictedEnvironment;
|
|
8
|
+
origin?: string;
|
|
9
|
+
manifest: BridgeKitManifest;
|
|
10
|
+
requestedCapabilities: CapabilityRequest[];
|
|
11
|
+
status: 'pending' | 'approved' | 'denied' | 'expired';
|
|
12
|
+
createdAt: string;
|
|
13
|
+
decidedAt?: string;
|
|
14
|
+
sessionId?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface PairingFile {
|
|
17
|
+
pairings: PairingRecord[];
|
|
18
|
+
}
|
|
19
|
+
export interface SessionRecord {
|
|
20
|
+
id: string;
|
|
21
|
+
tokenHash: string;
|
|
22
|
+
appName: string;
|
|
23
|
+
runtime: RestrictedEnvironment;
|
|
24
|
+
origin?: string;
|
|
25
|
+
grants: CapabilityGrant[];
|
|
26
|
+
createdAt: string;
|
|
27
|
+
revokedAt?: string;
|
|
28
|
+
expiresAt?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface SessionFile {
|
|
31
|
+
sessions: SessionRecord[];
|
|
32
|
+
}
|
|
33
|
+
export interface CreatedSession {
|
|
34
|
+
session: SessionRecord;
|
|
35
|
+
token: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function createPairingCode(): string;
|
|
38
|
+
export declare class PairingStore {
|
|
39
|
+
private readonly store;
|
|
40
|
+
constructor(store: JsonFileStore<PairingFile>);
|
|
41
|
+
create(input: {
|
|
42
|
+
appName: string;
|
|
43
|
+
runtime: RestrictedEnvironment;
|
|
44
|
+
origin?: string;
|
|
45
|
+
manifest: BridgeKitManifest;
|
|
46
|
+
}): Promise<PairingRecord>;
|
|
47
|
+
list(): Promise<PairingRecord[]>;
|
|
48
|
+
find(idOrCode: string): Promise<PairingRecord | undefined>;
|
|
49
|
+
update(idOrCode: string, mutator: (pairing: PairingRecord) => PairingRecord): Promise<PairingRecord>;
|
|
50
|
+
}
|
|
51
|
+
export declare class SessionStore {
|
|
52
|
+
private readonly store;
|
|
53
|
+
constructor(store: JsonFileStore<SessionFile>);
|
|
54
|
+
createFromPairing(pairing: PairingRecord, approvedBy: CapabilityGrant['approvedBy']): Promise<CreatedSession>;
|
|
55
|
+
findByToken(token: string): Promise<SessionRecord | undefined>;
|
|
56
|
+
list(): Promise<SessionRecord[]>;
|
|
57
|
+
revoke(id: string): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE1H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,iBAAiB,EAAE,CAAC;IAC3C,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAOD,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAExD,MAAM,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,qBAAqB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBxI,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIhC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAI1D,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAY3G;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAExD,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IA2B7G,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAK9D,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIhC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKxC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { randomBytes, randomUUID } from 'node:crypto';
|
|
2
|
+
import { manifestToCapabilityRequests } from '@bridgekitux/protocol';
|
|
3
|
+
export function createPairingCode() {
|
|
4
|
+
const number = randomBytes(4).readUInt32BE(0) % 1_000_000;
|
|
5
|
+
return number.toString().padStart(6, '0');
|
|
6
|
+
}
|
|
7
|
+
async function sha256(value) {
|
|
8
|
+
const { createHash } = await import('node:crypto');
|
|
9
|
+
return createHash('sha256').update(value).digest('hex');
|
|
10
|
+
}
|
|
11
|
+
export class PairingStore {
|
|
12
|
+
store;
|
|
13
|
+
constructor(store) {
|
|
14
|
+
this.store = store;
|
|
15
|
+
}
|
|
16
|
+
async create(input) {
|
|
17
|
+
const record = {
|
|
18
|
+
id: randomUUID(),
|
|
19
|
+
code: createPairingCode(),
|
|
20
|
+
appName: input.appName,
|
|
21
|
+
runtime: input.runtime,
|
|
22
|
+
origin: input.origin,
|
|
23
|
+
manifest: input.manifest,
|
|
24
|
+
requestedCapabilities: manifestToCapabilityRequests(input.manifest),
|
|
25
|
+
status: 'pending',
|
|
26
|
+
createdAt: new Date().toISOString()
|
|
27
|
+
};
|
|
28
|
+
await this.store.update((file) => {
|
|
29
|
+
file.pairings = [record, ...file.pairings.filter((pairing) => pairing.status === 'pending').slice(0, 99)];
|
|
30
|
+
});
|
|
31
|
+
return record;
|
|
32
|
+
}
|
|
33
|
+
async list() {
|
|
34
|
+
return (await this.store.read()).pairings;
|
|
35
|
+
}
|
|
36
|
+
async find(idOrCode) {
|
|
37
|
+
return (await this.list()).find((pairing) => pairing.id === idOrCode || pairing.code === idOrCode);
|
|
38
|
+
}
|
|
39
|
+
async update(idOrCode, mutator) {
|
|
40
|
+
let updated;
|
|
41
|
+
await this.store.update((file) => {
|
|
42
|
+
file.pairings = file.pairings.map((pairing) => {
|
|
43
|
+
if (pairing.id !== idOrCode && pairing.code !== idOrCode)
|
|
44
|
+
return pairing;
|
|
45
|
+
updated = mutator(pairing);
|
|
46
|
+
return updated;
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
if (!updated)
|
|
50
|
+
throw new Error(`Pairing not found: ${idOrCode}`);
|
|
51
|
+
return updated;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export class SessionStore {
|
|
55
|
+
store;
|
|
56
|
+
constructor(store) {
|
|
57
|
+
this.store = store;
|
|
58
|
+
}
|
|
59
|
+
async createFromPairing(pairing, approvedBy) {
|
|
60
|
+
const token = `bk_${randomBytes(32).toString('base64url')}`;
|
|
61
|
+
const sessionId = randomUUID();
|
|
62
|
+
const now = new Date().toISOString();
|
|
63
|
+
const grants = pairing.requestedCapabilities.map((request) => ({
|
|
64
|
+
...request,
|
|
65
|
+
id: randomUUID(),
|
|
66
|
+
approvedAt: now,
|
|
67
|
+
approvedBy,
|
|
68
|
+
sourceManifest: pairing.manifest.name
|
|
69
|
+
}));
|
|
70
|
+
const session = {
|
|
71
|
+
id: sessionId,
|
|
72
|
+
tokenHash: await sha256(token),
|
|
73
|
+
appName: pairing.appName,
|
|
74
|
+
runtime: pairing.runtime,
|
|
75
|
+
origin: pairing.origin,
|
|
76
|
+
grants,
|
|
77
|
+
createdAt: now
|
|
78
|
+
};
|
|
79
|
+
await this.store.update((file) => {
|
|
80
|
+
file.sessions.unshift(session);
|
|
81
|
+
file.sessions = file.sessions.slice(0, 500);
|
|
82
|
+
});
|
|
83
|
+
return { session, token };
|
|
84
|
+
}
|
|
85
|
+
async findByToken(token) {
|
|
86
|
+
const hash = await sha256(token);
|
|
87
|
+
return (await this.store.read()).sessions.find((session) => session.tokenHash === hash && !session.revokedAt);
|
|
88
|
+
}
|
|
89
|
+
async list() {
|
|
90
|
+
return (await this.store.read()).sessions;
|
|
91
|
+
}
|
|
92
|
+
async revoke(id) {
|
|
93
|
+
await this.store.update((file) => {
|
|
94
|
+
file.sessions = file.sessions.map((session) => session.id === id ? { ...session, revokedAt: new Date().toISOString() } : session);
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AA0CrE,MAAM,UAAU,iBAAiB;IAC/B,MAAM,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC1D,OAAO,MAAM,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC5C,CAAC;AAED,KAAK,UAAU,MAAM,CAAC,KAAa;IACjC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACnD,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,KAAiC;QAAjC,UAAK,GAAL,KAAK,CAA4B;IAAG,CAAC;IAElE,KAAK,CAAC,MAAM,CAAC,KAAwG;QACnH,MAAM,MAAM,GAAkB;YAC5B,EAAE,EAAE,UAAU,EAAE;YAChB,IAAI,EAAE,iBAAiB,EAAE;YACzB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,qBAAqB,EAAE,4BAA4B,CAAC,KAAK,CAAC,QAAQ,CAAC;YACnE,MAAM,EAAE,SAAS;YACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,IAAI,CAAC,QAAQ,GAAG,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAC5G,CAAC,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB;QACzB,OAAO,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC;IACrG,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,QAAgB,EAAE,OAAkD;QAC/E,IAAI,OAAkC,CAAC;QACvC,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;gBAC5C,IAAI,OAAO,CAAC,EAAE,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ;oBAAE,OAAO,OAAO,CAAC;gBACzE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;gBAC3B,OAAO,OAAO,CAAC;YACjB,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,EAAE,CAAC,CAAC;QAChE,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AAED,MAAM,OAAO,YAAY;IACM;IAA7B,YAA6B,KAAiC;QAAjC,UAAK,GAAL,KAAK,CAA4B;IAAG,CAAC;IAElE,KAAK,CAAC,iBAAiB,CAAC,OAAsB,EAAE,UAAyC;QACvF,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5D,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QACrC,MAAM,MAAM,GAAsB,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YAChF,GAAG,OAAO;YACV,EAAE,EAAE,UAAU,EAAE;YAChB,UAAU,EAAE,GAAG;YACf,UAAU;YACV,cAAc,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;SACtC,CAAC,CAAC,CAAC;QACJ,MAAM,OAAO,GAAkB;YAC7B,EAAE,EAAE,SAAS;YACb,SAAS,EAAE,MAAM,MAAM,CAAC,KAAK,CAAC;YAC9B,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM;YACN,SAAS,EAAE,GAAG;SACf,CAAC;QACF,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,KAAa;QAC7B,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC;QACjC,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChH,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;YAC/B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACpI,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { JsonFileStore } from './config.js';
|
|
2
|
+
export interface VaultRecord {
|
|
3
|
+
id: string;
|
|
4
|
+
iv: string;
|
|
5
|
+
tag: string;
|
|
6
|
+
ciphertext: string;
|
|
7
|
+
updatedAt: string;
|
|
8
|
+
}
|
|
9
|
+
export interface VaultFile {
|
|
10
|
+
secrets: VaultRecord[];
|
|
11
|
+
}
|
|
12
|
+
export declare class SecretVault {
|
|
13
|
+
private readonly store;
|
|
14
|
+
private readonly keyPath;
|
|
15
|
+
constructor(store: JsonFileStore<VaultFile>, keyPath: string);
|
|
16
|
+
private key;
|
|
17
|
+
create(id: string, value: string): Promise<{
|
|
18
|
+
id: string;
|
|
19
|
+
updatedAt: string;
|
|
20
|
+
}>;
|
|
21
|
+
resolve(id: string): Promise<string>;
|
|
22
|
+
list(): Promise<Array<{
|
|
23
|
+
id: string;
|
|
24
|
+
updatedAt: string;
|
|
25
|
+
}>>;
|
|
26
|
+
revoke(id: string): Promise<{
|
|
27
|
+
id: string;
|
|
28
|
+
revoked: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=vault.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAWD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,KAAK;IAA4B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAzD,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,EAAmB,OAAO,EAAE,MAAM;YAEhF,GAAG;IAWX,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB7E,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQpC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CASpE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { constants, readFile, writeFile } from 'node:fs/promises';
|
|
2
|
+
import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
|
|
3
|
+
import { access } from 'node:fs/promises';
|
|
4
|
+
import { bridgeKitError } from '@bridgekitux/protocol';
|
|
5
|
+
async function fileExists(path) {
|
|
6
|
+
try {
|
|
7
|
+
await access(path, constants.F_OK);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class SecretVault {
|
|
15
|
+
store;
|
|
16
|
+
keyPath;
|
|
17
|
+
constructor(store, keyPath) {
|
|
18
|
+
this.store = store;
|
|
19
|
+
this.keyPath = keyPath;
|
|
20
|
+
}
|
|
21
|
+
async key() {
|
|
22
|
+
if (!(await fileExists(this.keyPath))) {
|
|
23
|
+
const key = randomBytes(32).toString('base64url');
|
|
24
|
+
await writeFile(this.keyPath, `${key}\n`, { mode: 0o600 });
|
|
25
|
+
}
|
|
26
|
+
const encoded = (await readFile(this.keyPath, 'utf8')).trim();
|
|
27
|
+
const key = Buffer.from(encoded, 'base64url');
|
|
28
|
+
if (key.byteLength !== 32)
|
|
29
|
+
throw bridgeKitError('vault_error', 'BridgeKit vault key is invalid');
|
|
30
|
+
return key;
|
|
31
|
+
}
|
|
32
|
+
async create(id, value) {
|
|
33
|
+
const iv = randomBytes(12);
|
|
34
|
+
const cipher = createCipheriv('aes-256-gcm', await this.key(), iv);
|
|
35
|
+
const ciphertext = Buffer.concat([cipher.update(value, 'utf8'), cipher.final()]);
|
|
36
|
+
const record = {
|
|
37
|
+
id,
|
|
38
|
+
iv: iv.toString('base64url'),
|
|
39
|
+
tag: cipher.getAuthTag().toString('base64url'),
|
|
40
|
+
ciphertext: ciphertext.toString('base64url'),
|
|
41
|
+
updatedAt: new Date().toISOString()
|
|
42
|
+
};
|
|
43
|
+
await this.store.update((file) => {
|
|
44
|
+
file.secrets = [record, ...file.secrets.filter((secret) => secret.id !== id)];
|
|
45
|
+
});
|
|
46
|
+
return { id, updatedAt: record.updatedAt };
|
|
47
|
+
}
|
|
48
|
+
async resolve(id) {
|
|
49
|
+
const record = (await this.store.read()).secrets.find((secret) => secret.id === id);
|
|
50
|
+
if (!record)
|
|
51
|
+
throw bridgeKitError('secret_not_found', `Secret ${id} has not been stored`);
|
|
52
|
+
const decipher = createDecipheriv('aes-256-gcm', await this.key(), Buffer.from(record.iv, 'base64url'));
|
|
53
|
+
decipher.setAuthTag(Buffer.from(record.tag, 'base64url'));
|
|
54
|
+
return Buffer.concat([decipher.update(Buffer.from(record.ciphertext, 'base64url')), decipher.final()]).toString('utf8');
|
|
55
|
+
}
|
|
56
|
+
async list() {
|
|
57
|
+
return (await this.store.read()).secrets.map(({ id, updatedAt }) => ({ id, updatedAt }));
|
|
58
|
+
}
|
|
59
|
+
async revoke(id) {
|
|
60
|
+
let revoked = false;
|
|
61
|
+
await this.store.update((file) => {
|
|
62
|
+
const next = file.secrets.filter((secret) => secret.id !== id);
|
|
63
|
+
revoked = next.length !== file.secrets.length;
|
|
64
|
+
file.secrets = next;
|
|
65
|
+
});
|
|
66
|
+
return { id, revoked };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=vault.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/vault.ts"],"names":[],"mappings":"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"}
|