sello 0.1.4 → 0.1.5
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/cli/sello.js +65 -10
- package/package.json +1 -1
- package/src/cli/sello.ts +65 -10
package/dist/cli/sello.js
CHANGED
|
@@ -44,6 +44,25 @@ import { createSelloService } from "../sdk/service.js";
|
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
|
|
47
66
|
|
|
48
67
|
|
|
49
68
|
const textEncoder = new TextEncoder();
|
|
@@ -285,16 +304,17 @@ async function handleDevRequest(input
|
|
|
285
304
|
const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
|
|
286
305
|
|
|
287
306
|
if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/actions")) {
|
|
288
|
-
const result =
|
|
289
|
-
authorizationTokenBytes: textEncoder.encode(state.agentToken),
|
|
290
|
-
trustedLogs: [log],
|
|
291
|
-
registry,
|
|
292
|
-
ownerPrivateKey: normalizeHpkePrivateKey(state.ownerKey),
|
|
293
|
-
});
|
|
307
|
+
const result = verifyDevActions({ log, state, registry });
|
|
294
308
|
sendHtml(response, renderActionsHtml(result));
|
|
295
309
|
return;
|
|
296
310
|
}
|
|
297
311
|
|
|
312
|
+
if (request.method === "GET" && url.pathname === "/api/actions") {
|
|
313
|
+
const result = verifyDevActions({ log, state, registry });
|
|
314
|
+
sendJson(response, 200, actionsViewModel(result));
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
|
|
298
318
|
if (request.method === "POST" && url.pathname === "/api/entries") {
|
|
299
319
|
const body = await readJson(request);
|
|
300
320
|
if (!isRecord(body) || typeof body.envelope !== "string") {
|
|
@@ -326,6 +346,19 @@ async function handleDevRequest(input
|
|
|
326
346
|
sendJson(response, 404, { error: "not found" });
|
|
327
347
|
}
|
|
328
348
|
|
|
349
|
+
function verifyDevActions(input
|
|
350
|
+
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
) {
|
|
354
|
+
return verifyReceipts({
|
|
355
|
+
authorizationTokenBytes: textEncoder.encode(input.state.agentToken),
|
|
356
|
+
trustedLogs: [input.log],
|
|
357
|
+
registry: input.registry,
|
|
358
|
+
ownerPrivateKey: normalizeHpkePrivateKey(input.state.ownerKey),
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
|
|
329
362
|
async function loadViewerRegistry(devState ) {
|
|
330
363
|
if (process.env.SELLO_REGISTRY_PATH) {
|
|
331
364
|
return parseRegistry(readFileBytes(process.env.SELLO_REGISTRY_PATH));
|
|
@@ -461,16 +494,38 @@ function printActions(result ) {
|
|
|
461
494
|
}
|
|
462
495
|
}
|
|
463
496
|
|
|
497
|
+
function actionsViewModel(result ) {
|
|
498
|
+
return {
|
|
499
|
+
receipts: result.receipts.map((record) => ({
|
|
500
|
+
integratedTime: record.integratedTime,
|
|
501
|
+
serviceIdentifier: record.serviceIdentifier,
|
|
502
|
+
actionType: record.receipt["action-type"],
|
|
503
|
+
resultStatus: record.receipt["result-status"],
|
|
504
|
+
status: record.status,
|
|
505
|
+
logUrl: record.logUrl,
|
|
506
|
+
logCompleteness: record.logCompleteness,
|
|
507
|
+
sameSecondActivity: record.sameSecondActivity,
|
|
508
|
+
})),
|
|
509
|
+
rejected: result.rejected.map((record) => ({
|
|
510
|
+
code: record.code,
|
|
511
|
+
message: record.message,
|
|
512
|
+
...(record.logUrl === undefined ? {} : { logUrl: record.logUrl }),
|
|
513
|
+
...(record.integratedTime === undefined ? {} : { integratedTime: record.integratedTime }),
|
|
514
|
+
})),
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
|
|
464
518
|
function renderActionsHtml(result ) {
|
|
465
|
-
const
|
|
519
|
+
const view = actionsViewModel(result);
|
|
520
|
+
const rows = view.receipts.map((record) => `
|
|
466
521
|
<tr>
|
|
467
522
|
<td>${escapeHtml(record.integratedTime)}</td>
|
|
468
523
|
<td>${escapeHtml(record.serviceIdentifier)}</td>
|
|
469
|
-
<td>${escapeHtml(record.
|
|
470
|
-
<td>${escapeHtml(record.
|
|
524
|
+
<td>${escapeHtml(record.actionType)}</td>
|
|
525
|
+
<td>${escapeHtml(record.resultStatus)}</td>
|
|
471
526
|
<td>${escapeHtml(record.status)}</td>
|
|
472
527
|
</tr>`).join("");
|
|
473
|
-
const rejected =
|
|
528
|
+
const rejected = view.rejected.map((record) => `
|
|
474
529
|
<li><strong>${escapeHtml(record.code)}</strong>: ${escapeHtml(record.message)}</li>`).join("");
|
|
475
530
|
|
|
476
531
|
return `<!doctype html>
|
package/package.json
CHANGED
package/src/cli/sello.ts
CHANGED
|
@@ -47,6 +47,25 @@ type DevState = {
|
|
|
47
47
|
registryJson: string;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
type ActionsViewModel = {
|
|
51
|
+
receipts: {
|
|
52
|
+
integratedTime: string;
|
|
53
|
+
serviceIdentifier: string;
|
|
54
|
+
actionType: string;
|
|
55
|
+
resultStatus: string;
|
|
56
|
+
status: string;
|
|
57
|
+
logUrl: string;
|
|
58
|
+
logCompleteness: string;
|
|
59
|
+
sameSecondActivity: boolean;
|
|
60
|
+
}[];
|
|
61
|
+
rejected: {
|
|
62
|
+
code: string;
|
|
63
|
+
message: string;
|
|
64
|
+
logUrl?: string;
|
|
65
|
+
integratedTime?: string;
|
|
66
|
+
}[];
|
|
67
|
+
};
|
|
68
|
+
|
|
50
69
|
const textEncoder = new TextEncoder();
|
|
51
70
|
const textDecoder = new TextDecoder();
|
|
52
71
|
const command = process.argv[2] ?? "help";
|
|
@@ -286,16 +305,17 @@ async function handleDevRequest(input: {
|
|
|
286
305
|
const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
|
|
287
306
|
|
|
288
307
|
if (request.method === "GET" && (url.pathname === "/" || url.pathname === "/actions")) {
|
|
289
|
-
const result =
|
|
290
|
-
authorizationTokenBytes: textEncoder.encode(state.agentToken),
|
|
291
|
-
trustedLogs: [log],
|
|
292
|
-
registry,
|
|
293
|
-
ownerPrivateKey: normalizeHpkePrivateKey(state.ownerKey),
|
|
294
|
-
});
|
|
308
|
+
const result = verifyDevActions({ log, state, registry });
|
|
295
309
|
sendHtml(response, renderActionsHtml(result));
|
|
296
310
|
return;
|
|
297
311
|
}
|
|
298
312
|
|
|
313
|
+
if (request.method === "GET" && url.pathname === "/api/actions") {
|
|
314
|
+
const result = verifyDevActions({ log, state, registry });
|
|
315
|
+
sendJson(response, 200, actionsViewModel(result));
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
|
|
299
319
|
if (request.method === "POST" && url.pathname === "/api/entries") {
|
|
300
320
|
const body = await readJson(request);
|
|
301
321
|
if (!isRecord(body) || typeof body.envelope !== "string") {
|
|
@@ -327,6 +347,19 @@ async function handleDevRequest(input: {
|
|
|
327
347
|
sendJson(response, 404, { error: "not found" });
|
|
328
348
|
}
|
|
329
349
|
|
|
350
|
+
function verifyDevActions(input: {
|
|
351
|
+
log: MockTransparencyLog;
|
|
352
|
+
state: DevState;
|
|
353
|
+
registry: ReturnType<typeof parseRegistry>;
|
|
354
|
+
}): ReturnType<typeof verifyReceipts> {
|
|
355
|
+
return verifyReceipts({
|
|
356
|
+
authorizationTokenBytes: textEncoder.encode(input.state.agentToken),
|
|
357
|
+
trustedLogs: [input.log],
|
|
358
|
+
registry: input.registry,
|
|
359
|
+
ownerPrivateKey: normalizeHpkePrivateKey(input.state.ownerKey),
|
|
360
|
+
});
|
|
361
|
+
}
|
|
362
|
+
|
|
330
363
|
async function loadViewerRegistry(devState: DevState | undefined) {
|
|
331
364
|
if (process.env.SELLO_REGISTRY_PATH) {
|
|
332
365
|
return parseRegistry(readFileBytes(process.env.SELLO_REGISTRY_PATH));
|
|
@@ -462,16 +495,38 @@ function printActions(result: ReturnType<typeof verifyReceipts>): void {
|
|
|
462
495
|
}
|
|
463
496
|
}
|
|
464
497
|
|
|
498
|
+
function actionsViewModel(result: ReturnType<typeof verifyReceipts>): ActionsViewModel {
|
|
499
|
+
return {
|
|
500
|
+
receipts: result.receipts.map((record) => ({
|
|
501
|
+
integratedTime: record.integratedTime,
|
|
502
|
+
serviceIdentifier: record.serviceIdentifier,
|
|
503
|
+
actionType: record.receipt["action-type"],
|
|
504
|
+
resultStatus: record.receipt["result-status"],
|
|
505
|
+
status: record.status,
|
|
506
|
+
logUrl: record.logUrl,
|
|
507
|
+
logCompleteness: record.logCompleteness,
|
|
508
|
+
sameSecondActivity: record.sameSecondActivity,
|
|
509
|
+
})),
|
|
510
|
+
rejected: result.rejected.map((record) => ({
|
|
511
|
+
code: record.code,
|
|
512
|
+
message: record.message,
|
|
513
|
+
...(record.logUrl === undefined ? {} : { logUrl: record.logUrl }),
|
|
514
|
+
...(record.integratedTime === undefined ? {} : { integratedTime: record.integratedTime }),
|
|
515
|
+
})),
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
|
|
465
519
|
function renderActionsHtml(result: ReturnType<typeof verifyReceipts>): string {
|
|
466
|
-
const
|
|
520
|
+
const view = actionsViewModel(result);
|
|
521
|
+
const rows = view.receipts.map((record) => `
|
|
467
522
|
<tr>
|
|
468
523
|
<td>${escapeHtml(record.integratedTime)}</td>
|
|
469
524
|
<td>${escapeHtml(record.serviceIdentifier)}</td>
|
|
470
|
-
<td>${escapeHtml(record.
|
|
471
|
-
<td>${escapeHtml(record.
|
|
525
|
+
<td>${escapeHtml(record.actionType)}</td>
|
|
526
|
+
<td>${escapeHtml(record.resultStatus)}</td>
|
|
472
527
|
<td>${escapeHtml(record.status)}</td>
|
|
473
528
|
</tr>`).join("");
|
|
474
|
-
const rejected =
|
|
529
|
+
const rejected = view.rejected.map((record) => `
|
|
475
530
|
<li><strong>${escapeHtml(record.code)}</strong>: ${escapeHtml(record.message)}</li>`).join("");
|
|
476
531
|
|
|
477
532
|
return `<!doctype html>
|