@positronic/cloudflare 0.0.56 → 0.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/api/auth-middleware.js +466 -0
- package/dist/src/api/brains.js +160 -0
- package/dist/src/api/index.js +22 -1
- package/dist/src/api/users.js +582 -0
- package/dist/src/api/webhooks/coordination.js +43 -8
- package/dist/src/api/webhooks/index.js +2 -2
- package/dist/src/api/webhooks/system.js +2 -2
- package/dist/src/auth-do.js +455 -0
- package/dist/src/brain-runner-do.js +255 -97
- package/dist/src/event-loader.js +301 -0
- package/dist/src/index.js +1 -0
- package/dist/src/monitor-do.js +39 -19
- package/dist/src/signal-provider.js +179 -0
- package/dist/src/sqlite-adapter.js +196 -13
- package/dist/types/api/auth-middleware.d.ts +19 -0
- package/dist/types/api/auth-middleware.d.ts.map +1 -0
- package/dist/types/api/brains.d.ts.map +1 -1
- package/dist/types/api/index.d.ts.map +1 -1
- package/dist/types/api/types.d.ts +3 -0
- package/dist/types/api/types.d.ts.map +1 -1
- package/dist/types/api/users.d.ts +7 -0
- package/dist/types/api/users.d.ts.map +1 -0
- package/dist/types/api/webhooks/coordination.d.ts +7 -3
- package/dist/types/api/webhooks/coordination.d.ts.map +1 -1
- package/dist/types/auth-do.d.ts +37 -0
- package/dist/types/auth-do.d.ts.map +1 -0
- package/dist/types/brain-runner-do.d.ts +29 -2
- package/dist/types/brain-runner-do.d.ts.map +1 -1
- package/dist/types/event-loader.d.ts +25 -0
- package/dist/types/event-loader.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/monitor-do.d.ts +1 -0
- package/dist/types/monitor-do.d.ts.map +1 -1
- package/dist/types/signal-provider.d.ts +11 -0
- package/dist/types/signal-provider.d.ts.map +1 -0
- package/dist/types/sqlite-adapter.d.ts +6 -3
- package/dist/types/sqlite-adapter.d.ts.map +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
|
|
2
|
+
try {
|
|
3
|
+
var info = gen[key](arg);
|
|
4
|
+
var value = info.value;
|
|
5
|
+
} catch (error) {
|
|
6
|
+
reject(error);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
if (info.done) {
|
|
10
|
+
resolve(value);
|
|
11
|
+
} else {
|
|
12
|
+
Promise.resolve(value).then(_next, _throw);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function _async_to_generator(fn) {
|
|
16
|
+
return function() {
|
|
17
|
+
var self = this, args = arguments;
|
|
18
|
+
return new Promise(function(resolve, reject) {
|
|
19
|
+
var gen = fn.apply(self, args);
|
|
20
|
+
function _next(value) {
|
|
21
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
|
|
22
|
+
}
|
|
23
|
+
function _throw(err) {
|
|
24
|
+
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
|
|
25
|
+
}
|
|
26
|
+
_next(undefined);
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
function _type_of(obj) {
|
|
31
|
+
"@swc/helpers - typeof";
|
|
32
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
33
|
+
}
|
|
34
|
+
function _ts_generator(thisArg, body) {
|
|
35
|
+
var f, y, t, _ = {
|
|
36
|
+
label: 0,
|
|
37
|
+
sent: function() {
|
|
38
|
+
if (t[0] & 1) throw t[1];
|
|
39
|
+
return t[1];
|
|
40
|
+
},
|
|
41
|
+
trys: [],
|
|
42
|
+
ops: []
|
|
43
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
44
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() {
|
|
45
|
+
return this;
|
|
46
|
+
}), g;
|
|
47
|
+
function verb(n) {
|
|
48
|
+
return function(v) {
|
|
49
|
+
return step([
|
|
50
|
+
n,
|
|
51
|
+
v
|
|
52
|
+
]);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
function step(op) {
|
|
56
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
57
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
58
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
59
|
+
if (y = 0, t) op = [
|
|
60
|
+
op[0] & 2,
|
|
61
|
+
t.value
|
|
62
|
+
];
|
|
63
|
+
switch(op[0]){
|
|
64
|
+
case 0:
|
|
65
|
+
case 1:
|
|
66
|
+
t = op;
|
|
67
|
+
break;
|
|
68
|
+
case 4:
|
|
69
|
+
_.label++;
|
|
70
|
+
return {
|
|
71
|
+
value: op[1],
|
|
72
|
+
done: false
|
|
73
|
+
};
|
|
74
|
+
case 5:
|
|
75
|
+
_.label++;
|
|
76
|
+
y = op[1];
|
|
77
|
+
op = [
|
|
78
|
+
0
|
|
79
|
+
];
|
|
80
|
+
continue;
|
|
81
|
+
case 7:
|
|
82
|
+
op = _.ops.pop();
|
|
83
|
+
_.trys.pop();
|
|
84
|
+
continue;
|
|
85
|
+
default:
|
|
86
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
87
|
+
_ = 0;
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
91
|
+
_.label = op[1];
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
95
|
+
_.label = t[1];
|
|
96
|
+
t = op;
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
if (t && _.label < t[2]) {
|
|
100
|
+
_.label = t[2];
|
|
101
|
+
_.ops.push(op);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
if (t[2]) _.ops.pop();
|
|
105
|
+
_.trys.pop();
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
op = body.call(thisArg, _);
|
|
109
|
+
} catch (e) {
|
|
110
|
+
op = [
|
|
111
|
+
6,
|
|
112
|
+
e
|
|
113
|
+
];
|
|
114
|
+
y = 0;
|
|
115
|
+
} finally{
|
|
116
|
+
f = t = 0;
|
|
117
|
+
}
|
|
118
|
+
if (op[0] & 5) throw op[1];
|
|
119
|
+
return {
|
|
120
|
+
value: op[0] ? op[1] : void 0,
|
|
121
|
+
done: true
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
import { Hono } from 'hono';
|
|
126
|
+
var app = new Hono();
|
|
127
|
+
// Validation constants
|
|
128
|
+
var MAX_USERNAME_LENGTH = 64;
|
|
129
|
+
var USERNAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
130
|
+
/**
|
|
131
|
+
* Validate a username
|
|
132
|
+
* @returns null if valid, error message if invalid
|
|
133
|
+
*/ function validateUsername(name) {
|
|
134
|
+
if (!name || typeof name !== 'string') {
|
|
135
|
+
return 'Name is required';
|
|
136
|
+
}
|
|
137
|
+
if (name.length === 0) {
|
|
138
|
+
return 'Name cannot be empty';
|
|
139
|
+
}
|
|
140
|
+
if (name.length > MAX_USERNAME_LENGTH) {
|
|
141
|
+
return "Name cannot exceed ".concat(MAX_USERNAME_LENGTH, " characters");
|
|
142
|
+
}
|
|
143
|
+
if (!USERNAME_PATTERN.test(name)) {
|
|
144
|
+
return 'Name can only contain letters, numbers, hyphens, and underscores';
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
// POST /users - Create a new user
|
|
149
|
+
app.post('/', function(c) {
|
|
150
|
+
return _async_to_generator(function() {
|
|
151
|
+
var body, validationError, authDoId, authDo, existing, user, error;
|
|
152
|
+
return _ts_generator(this, function(_state) {
|
|
153
|
+
switch(_state.label){
|
|
154
|
+
case 0:
|
|
155
|
+
_state.trys.push([
|
|
156
|
+
0,
|
|
157
|
+
4,
|
|
158
|
+
,
|
|
159
|
+
5
|
|
160
|
+
]);
|
|
161
|
+
return [
|
|
162
|
+
4,
|
|
163
|
+
c.req.json()
|
|
164
|
+
];
|
|
165
|
+
case 1:
|
|
166
|
+
body = _state.sent();
|
|
167
|
+
validationError = validateUsername(body.name);
|
|
168
|
+
if (validationError) {
|
|
169
|
+
return [
|
|
170
|
+
2,
|
|
171
|
+
c.json({
|
|
172
|
+
error: validationError
|
|
173
|
+
}, 400)
|
|
174
|
+
];
|
|
175
|
+
}
|
|
176
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
177
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
178
|
+
return [
|
|
179
|
+
4,
|
|
180
|
+
authDo.getUserByName(body.name)
|
|
181
|
+
];
|
|
182
|
+
case 2:
|
|
183
|
+
existing = _state.sent();
|
|
184
|
+
if (existing) {
|
|
185
|
+
return [
|
|
186
|
+
2,
|
|
187
|
+
c.json({
|
|
188
|
+
error: "User '".concat(body.name, "' already exists")
|
|
189
|
+
}, 409)
|
|
190
|
+
];
|
|
191
|
+
}
|
|
192
|
+
return [
|
|
193
|
+
4,
|
|
194
|
+
authDo.createUser(body.name)
|
|
195
|
+
];
|
|
196
|
+
case 3:
|
|
197
|
+
user = _state.sent();
|
|
198
|
+
return [
|
|
199
|
+
2,
|
|
200
|
+
c.json(user, 201)
|
|
201
|
+
];
|
|
202
|
+
case 4:
|
|
203
|
+
error = _state.sent();
|
|
204
|
+
console.error('Error creating user:', error);
|
|
205
|
+
return [
|
|
206
|
+
2,
|
|
207
|
+
c.json({
|
|
208
|
+
error: 'Failed to create user'
|
|
209
|
+
}, 500)
|
|
210
|
+
];
|
|
211
|
+
case 5:
|
|
212
|
+
return [
|
|
213
|
+
2
|
|
214
|
+
];
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
})();
|
|
218
|
+
});
|
|
219
|
+
// GET /users - List all users
|
|
220
|
+
app.get('/', function(c) {
|
|
221
|
+
return _async_to_generator(function() {
|
|
222
|
+
var authDoId, authDo, result, error;
|
|
223
|
+
return _ts_generator(this, function(_state) {
|
|
224
|
+
switch(_state.label){
|
|
225
|
+
case 0:
|
|
226
|
+
_state.trys.push([
|
|
227
|
+
0,
|
|
228
|
+
2,
|
|
229
|
+
,
|
|
230
|
+
3
|
|
231
|
+
]);
|
|
232
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
233
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
234
|
+
return [
|
|
235
|
+
4,
|
|
236
|
+
authDo.listUsers()
|
|
237
|
+
];
|
|
238
|
+
case 1:
|
|
239
|
+
result = _state.sent();
|
|
240
|
+
return [
|
|
241
|
+
2,
|
|
242
|
+
c.json(result)
|
|
243
|
+
];
|
|
244
|
+
case 2:
|
|
245
|
+
error = _state.sent();
|
|
246
|
+
console.error('Error listing users:', error);
|
|
247
|
+
return [
|
|
248
|
+
2,
|
|
249
|
+
c.json({
|
|
250
|
+
error: 'Failed to list users'
|
|
251
|
+
}, 500)
|
|
252
|
+
];
|
|
253
|
+
case 3:
|
|
254
|
+
return [
|
|
255
|
+
2
|
|
256
|
+
];
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
})();
|
|
260
|
+
});
|
|
261
|
+
// GET /users/:id - Get a specific user
|
|
262
|
+
app.get('/:id', function(c) {
|
|
263
|
+
return _async_to_generator(function() {
|
|
264
|
+
var userId, authDoId, authDo, user, error;
|
|
265
|
+
return _ts_generator(this, function(_state) {
|
|
266
|
+
switch(_state.label){
|
|
267
|
+
case 0:
|
|
268
|
+
_state.trys.push([
|
|
269
|
+
0,
|
|
270
|
+
2,
|
|
271
|
+
,
|
|
272
|
+
3
|
|
273
|
+
]);
|
|
274
|
+
userId = c.req.param('id');
|
|
275
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
276
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
277
|
+
return [
|
|
278
|
+
4,
|
|
279
|
+
authDo.getUser(userId)
|
|
280
|
+
];
|
|
281
|
+
case 1:
|
|
282
|
+
user = _state.sent();
|
|
283
|
+
if (!user) {
|
|
284
|
+
return [
|
|
285
|
+
2,
|
|
286
|
+
c.json({
|
|
287
|
+
error: "User '".concat(userId, "' not found")
|
|
288
|
+
}, 404)
|
|
289
|
+
];
|
|
290
|
+
}
|
|
291
|
+
return [
|
|
292
|
+
2,
|
|
293
|
+
c.json(user)
|
|
294
|
+
];
|
|
295
|
+
case 2:
|
|
296
|
+
error = _state.sent();
|
|
297
|
+
console.error('Error getting user:', error);
|
|
298
|
+
return [
|
|
299
|
+
2,
|
|
300
|
+
c.json({
|
|
301
|
+
error: 'Failed to get user'
|
|
302
|
+
}, 500)
|
|
303
|
+
];
|
|
304
|
+
case 3:
|
|
305
|
+
return [
|
|
306
|
+
2
|
|
307
|
+
];
|
|
308
|
+
}
|
|
309
|
+
});
|
|
310
|
+
})();
|
|
311
|
+
});
|
|
312
|
+
// DELETE /users/:id - Delete a user
|
|
313
|
+
app.delete('/:id', function(c) {
|
|
314
|
+
return _async_to_generator(function() {
|
|
315
|
+
var userId, authDoId, authDo, deleted, error;
|
|
316
|
+
return _ts_generator(this, function(_state) {
|
|
317
|
+
switch(_state.label){
|
|
318
|
+
case 0:
|
|
319
|
+
_state.trys.push([
|
|
320
|
+
0,
|
|
321
|
+
2,
|
|
322
|
+
,
|
|
323
|
+
3
|
|
324
|
+
]);
|
|
325
|
+
userId = c.req.param('id');
|
|
326
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
327
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
328
|
+
return [
|
|
329
|
+
4,
|
|
330
|
+
authDo.deleteUser(userId)
|
|
331
|
+
];
|
|
332
|
+
case 1:
|
|
333
|
+
deleted = _state.sent();
|
|
334
|
+
if (!deleted) {
|
|
335
|
+
return [
|
|
336
|
+
2,
|
|
337
|
+
c.json({
|
|
338
|
+
error: "User '".concat(userId, "' not found")
|
|
339
|
+
}, 404)
|
|
340
|
+
];
|
|
341
|
+
}
|
|
342
|
+
return [
|
|
343
|
+
2,
|
|
344
|
+
c.body(null, 204)
|
|
345
|
+
];
|
|
346
|
+
case 2:
|
|
347
|
+
error = _state.sent();
|
|
348
|
+
console.error('Error deleting user:', error);
|
|
349
|
+
return [
|
|
350
|
+
2,
|
|
351
|
+
c.json({
|
|
352
|
+
error: 'Failed to delete user'
|
|
353
|
+
}, 500)
|
|
354
|
+
];
|
|
355
|
+
case 3:
|
|
356
|
+
return [
|
|
357
|
+
2
|
|
358
|
+
];
|
|
359
|
+
}
|
|
360
|
+
});
|
|
361
|
+
})();
|
|
362
|
+
});
|
|
363
|
+
// POST /users/:id/keys - Add a key to a user
|
|
364
|
+
app.post('/:id/keys', function(c) {
|
|
365
|
+
return _async_to_generator(function() {
|
|
366
|
+
var userId, body, authDoId, authDo, user, existingKey, key, error;
|
|
367
|
+
return _ts_generator(this, function(_state) {
|
|
368
|
+
switch(_state.label){
|
|
369
|
+
case 0:
|
|
370
|
+
_state.trys.push([
|
|
371
|
+
0,
|
|
372
|
+
5,
|
|
373
|
+
,
|
|
374
|
+
6
|
|
375
|
+
]);
|
|
376
|
+
userId = c.req.param('id');
|
|
377
|
+
return [
|
|
378
|
+
4,
|
|
379
|
+
c.req.json()
|
|
380
|
+
];
|
|
381
|
+
case 1:
|
|
382
|
+
body = _state.sent();
|
|
383
|
+
if (!body.jwk || _type_of(body.jwk) !== 'object') {
|
|
384
|
+
return [
|
|
385
|
+
2,
|
|
386
|
+
c.json({
|
|
387
|
+
error: 'JWK is required'
|
|
388
|
+
}, 400)
|
|
389
|
+
];
|
|
390
|
+
}
|
|
391
|
+
if (!body.fingerprint || typeof body.fingerprint !== 'string') {
|
|
392
|
+
return [
|
|
393
|
+
2,
|
|
394
|
+
c.json({
|
|
395
|
+
error: 'Fingerprint is required'
|
|
396
|
+
}, 400)
|
|
397
|
+
];
|
|
398
|
+
}
|
|
399
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
400
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
401
|
+
return [
|
|
402
|
+
4,
|
|
403
|
+
authDo.getUser(userId)
|
|
404
|
+
];
|
|
405
|
+
case 2:
|
|
406
|
+
user = _state.sent();
|
|
407
|
+
if (!user) {
|
|
408
|
+
return [
|
|
409
|
+
2,
|
|
410
|
+
c.json({
|
|
411
|
+
error: "User '".concat(userId, "' not found")
|
|
412
|
+
}, 404)
|
|
413
|
+
];
|
|
414
|
+
}
|
|
415
|
+
return [
|
|
416
|
+
4,
|
|
417
|
+
authDo.getKeyByFingerprint(body.fingerprint)
|
|
418
|
+
];
|
|
419
|
+
case 3:
|
|
420
|
+
existingKey = _state.sent();
|
|
421
|
+
if (existingKey) {
|
|
422
|
+
return [
|
|
423
|
+
2,
|
|
424
|
+
c.json({
|
|
425
|
+
error: 'Key already exists'
|
|
426
|
+
}, 409)
|
|
427
|
+
];
|
|
428
|
+
}
|
|
429
|
+
return [
|
|
430
|
+
4,
|
|
431
|
+
authDo.addKey(userId, body.fingerprint, JSON.stringify(body.jwk), body.label || '')
|
|
432
|
+
];
|
|
433
|
+
case 4:
|
|
434
|
+
key = _state.sent();
|
|
435
|
+
// Return key without the jwk for security
|
|
436
|
+
return [
|
|
437
|
+
2,
|
|
438
|
+
c.json({
|
|
439
|
+
fingerprint: key.fingerprint,
|
|
440
|
+
userId: key.userId,
|
|
441
|
+
label: key.label,
|
|
442
|
+
addedAt: key.addedAt
|
|
443
|
+
}, 201)
|
|
444
|
+
];
|
|
445
|
+
case 5:
|
|
446
|
+
error = _state.sent();
|
|
447
|
+
console.error('Error adding key:', error);
|
|
448
|
+
return [
|
|
449
|
+
2,
|
|
450
|
+
c.json({
|
|
451
|
+
error: 'Failed to add key'
|
|
452
|
+
}, 500)
|
|
453
|
+
];
|
|
454
|
+
case 6:
|
|
455
|
+
return [
|
|
456
|
+
2
|
|
457
|
+
];
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
})();
|
|
461
|
+
});
|
|
462
|
+
// GET /users/:id/keys - List keys for a user
|
|
463
|
+
app.get('/:id/keys', function(c) {
|
|
464
|
+
return _async_to_generator(function() {
|
|
465
|
+
var userId, authDoId, authDo, user, result, error;
|
|
466
|
+
return _ts_generator(this, function(_state) {
|
|
467
|
+
switch(_state.label){
|
|
468
|
+
case 0:
|
|
469
|
+
_state.trys.push([
|
|
470
|
+
0,
|
|
471
|
+
3,
|
|
472
|
+
,
|
|
473
|
+
4
|
|
474
|
+
]);
|
|
475
|
+
userId = c.req.param('id');
|
|
476
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
477
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
478
|
+
return [
|
|
479
|
+
4,
|
|
480
|
+
authDo.getUser(userId)
|
|
481
|
+
];
|
|
482
|
+
case 1:
|
|
483
|
+
user = _state.sent();
|
|
484
|
+
if (!user) {
|
|
485
|
+
return [
|
|
486
|
+
2,
|
|
487
|
+
c.json({
|
|
488
|
+
error: "User '".concat(userId, "' not found")
|
|
489
|
+
}, 404)
|
|
490
|
+
];
|
|
491
|
+
}
|
|
492
|
+
return [
|
|
493
|
+
4,
|
|
494
|
+
authDo.listKeys(userId)
|
|
495
|
+
];
|
|
496
|
+
case 2:
|
|
497
|
+
result = _state.sent();
|
|
498
|
+
// Return keys without the jwk for security
|
|
499
|
+
return [
|
|
500
|
+
2,
|
|
501
|
+
c.json({
|
|
502
|
+
keys: result.keys.map(function(key) {
|
|
503
|
+
return {
|
|
504
|
+
fingerprint: key.fingerprint,
|
|
505
|
+
userId: key.userId,
|
|
506
|
+
label: key.label,
|
|
507
|
+
addedAt: key.addedAt
|
|
508
|
+
};
|
|
509
|
+
}),
|
|
510
|
+
count: result.count
|
|
511
|
+
})
|
|
512
|
+
];
|
|
513
|
+
case 3:
|
|
514
|
+
error = _state.sent();
|
|
515
|
+
console.error('Error listing keys:', error);
|
|
516
|
+
return [
|
|
517
|
+
2,
|
|
518
|
+
c.json({
|
|
519
|
+
error: 'Failed to list keys'
|
|
520
|
+
}, 500)
|
|
521
|
+
];
|
|
522
|
+
case 4:
|
|
523
|
+
return [
|
|
524
|
+
2
|
|
525
|
+
];
|
|
526
|
+
}
|
|
527
|
+
});
|
|
528
|
+
})();
|
|
529
|
+
});
|
|
530
|
+
// DELETE /users/:id/keys/:fingerprint - Remove a key from a user
|
|
531
|
+
app.delete('/:id/keys/:fingerprint', function(c) {
|
|
532
|
+
return _async_to_generator(function() {
|
|
533
|
+
var userId, fingerprint, authDoId, authDo, deleted, error;
|
|
534
|
+
return _ts_generator(this, function(_state) {
|
|
535
|
+
switch(_state.label){
|
|
536
|
+
case 0:
|
|
537
|
+
_state.trys.push([
|
|
538
|
+
0,
|
|
539
|
+
2,
|
|
540
|
+
,
|
|
541
|
+
3
|
|
542
|
+
]);
|
|
543
|
+
userId = c.req.param('id');
|
|
544
|
+
fingerprint = decodeURIComponent(c.req.param('fingerprint'));
|
|
545
|
+
authDoId = c.env.AUTH_DO.idFromName('auth');
|
|
546
|
+
authDo = c.env.AUTH_DO.get(authDoId);
|
|
547
|
+
return [
|
|
548
|
+
4,
|
|
549
|
+
authDo.removeKey(userId, fingerprint)
|
|
550
|
+
];
|
|
551
|
+
case 1:
|
|
552
|
+
deleted = _state.sent();
|
|
553
|
+
if (!deleted) {
|
|
554
|
+
return [
|
|
555
|
+
2,
|
|
556
|
+
c.json({
|
|
557
|
+
error: "Key not found"
|
|
558
|
+
}, 404)
|
|
559
|
+
];
|
|
560
|
+
}
|
|
561
|
+
return [
|
|
562
|
+
2,
|
|
563
|
+
c.body(null, 204)
|
|
564
|
+
];
|
|
565
|
+
case 2:
|
|
566
|
+
error = _state.sent();
|
|
567
|
+
console.error('Error removing key:', error);
|
|
568
|
+
return [
|
|
569
|
+
2,
|
|
570
|
+
c.json({
|
|
571
|
+
error: 'Failed to remove key'
|
|
572
|
+
}, 500)
|
|
573
|
+
];
|
|
574
|
+
case 3:
|
|
575
|
+
return [
|
|
576
|
+
2
|
|
577
|
+
];
|
|
578
|
+
}
|
|
579
|
+
});
|
|
580
|
+
})();
|
|
581
|
+
});
|
|
582
|
+
export default app;
|
|
@@ -164,12 +164,16 @@ function _ts_generator(thisArg, body) {
|
|
|
164
164
|
};
|
|
165
165
|
}
|
|
166
166
|
}
|
|
167
|
+
import { isSignalValid, brainMachineDefinition } from '@positronic/core';
|
|
167
168
|
/**
|
|
168
|
-
* Find a brain waiting for a webhook and
|
|
169
|
+
* Find a brain waiting for a webhook, queue the WEBHOOK_RESPONSE signal, and wake it up.
|
|
169
170
|
* Returns a JSON response object suitable for returning from a webhook endpoint.
|
|
170
|
-
|
|
171
|
+
*
|
|
172
|
+
* This is the signal-based approach: webhook response data flows through the signal queue
|
|
173
|
+
* rather than being passed directly to the resume method.
|
|
174
|
+
*/ export function queueWebhookAndWakeUp(context, slug, identifier, response) {
|
|
171
175
|
return _async_to_generator(function() {
|
|
172
|
-
var monitorId, monitorStub, brainRunId, namespace, doId, stub;
|
|
176
|
+
var monitorId, monitorStub, brainRunId, run, validation, namespace, doId, stub;
|
|
173
177
|
return _ts_generator(this, function(_state) {
|
|
174
178
|
switch(_state.label){
|
|
175
179
|
case 0:
|
|
@@ -183,17 +187,48 @@ function _ts_generator(thisArg, body) {
|
|
|
183
187
|
brainRunId = _state.sent();
|
|
184
188
|
if (!brainRunId) return [
|
|
185
189
|
3,
|
|
186
|
-
|
|
190
|
+
5
|
|
187
191
|
];
|
|
188
|
-
|
|
192
|
+
return [
|
|
193
|
+
4,
|
|
194
|
+
monitorStub.getRun(brainRunId)
|
|
195
|
+
];
|
|
196
|
+
case 2:
|
|
197
|
+
run = _state.sent();
|
|
198
|
+
if (run) {
|
|
199
|
+
validation = isSignalValid(brainMachineDefinition, run.status, 'WEBHOOK_RESPONSE');
|
|
200
|
+
if (!validation.valid) {
|
|
201
|
+
return [
|
|
202
|
+
2,
|
|
203
|
+
{
|
|
204
|
+
received: true,
|
|
205
|
+
action: 'ignored',
|
|
206
|
+
identifier: identifier,
|
|
207
|
+
brainRunId: brainRunId,
|
|
208
|
+
reason: validation.reason
|
|
209
|
+
}
|
|
210
|
+
];
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Queue WEBHOOK_RESPONSE signal and wake up the brain
|
|
189
214
|
namespace = context.env.BRAIN_RUNNER_DO;
|
|
190
215
|
doId = namespace.idFromName(brainRunId);
|
|
191
216
|
stub = namespace.get(doId);
|
|
217
|
+
// Queue the signal first, then wake up the brain
|
|
192
218
|
return [
|
|
193
219
|
4,
|
|
194
|
-
stub.
|
|
220
|
+
stub.queueSignal({
|
|
221
|
+
type: 'WEBHOOK_RESPONSE',
|
|
222
|
+
response: response
|
|
223
|
+
})
|
|
195
224
|
];
|
|
196
|
-
case
|
|
225
|
+
case 3:
|
|
226
|
+
_state.sent();
|
|
227
|
+
return [
|
|
228
|
+
4,
|
|
229
|
+
stub.wakeUp(brainRunId)
|
|
230
|
+
];
|
|
231
|
+
case 4:
|
|
197
232
|
_state.sent();
|
|
198
233
|
return [
|
|
199
234
|
2,
|
|
@@ -204,7 +239,7 @@ function _ts_generator(thisArg, body) {
|
|
|
204
239
|
brainRunId: brainRunId
|
|
205
240
|
}
|
|
206
241
|
];
|
|
207
|
-
case
|
|
242
|
+
case 5:
|
|
208
243
|
// No brain waiting for this webhook
|
|
209
244
|
return [
|
|
210
245
|
2,
|
|
@@ -166,7 +166,7 @@ function _ts_generator(thisArg, body) {
|
|
|
166
166
|
}
|
|
167
167
|
import { Hono } from 'hono';
|
|
168
168
|
import { getWebhookManifest } from '../../brain-runner-do.js';
|
|
169
|
-
import {
|
|
169
|
+
import { queueWebhookAndWakeUp } from './coordination.js';
|
|
170
170
|
import system from './system.js';
|
|
171
171
|
var webhooks = new Hono();
|
|
172
172
|
// Mount system webhooks at /webhooks/system/*
|
|
@@ -237,7 +237,7 @@ webhooks.post('/:slug', function(context) {
|
|
|
237
237
|
}
|
|
238
238
|
return [
|
|
239
239
|
4,
|
|
240
|
-
|
|
240
|
+
queueWebhookAndWakeUp(context, slug, handlerResult.identifier, handlerResult.response)
|
|
241
241
|
];
|
|
242
242
|
case 3:
|
|
243
243
|
result = _state.sent();
|
|
@@ -171,7 +171,7 @@ function _ts_generator(thisArg, body) {
|
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
173
|
import { Hono } from 'hono';
|
|
174
|
-
import {
|
|
174
|
+
import { queueWebhookAndWakeUp, parseFormData } from './coordination.js';
|
|
175
175
|
var system = new Hono();
|
|
176
176
|
/**
|
|
177
177
|
* Built-in webhook for UI form submissions.
|
|
@@ -211,7 +211,7 @@ var system = new Hono();
|
|
|
211
211
|
response = parseFormData(formData);
|
|
212
212
|
return [
|
|
213
213
|
4,
|
|
214
|
-
|
|
214
|
+
queueWebhookAndWakeUp(context, 'ui-form', identifier, response)
|
|
215
215
|
];
|
|
216
216
|
case 3:
|
|
217
217
|
result = _state.sent();
|