@bkazemi/verily 0.2.0 → 0.3.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 +23 -16
- package/dist/browser/badge.js +16 -5
- package/dist/browser/connect-dialog.d.ts +13 -2
- package/dist/browser/connect-dialog.js +17 -7
- package/dist/browser/evidence-dialog.d.ts +19 -1
- package/dist/browser/evidence-dialog.js +163 -16
- package/dist/browser/index.d.ts +10 -1
- package/dist/browser/index.js +57 -13
- package/dist/browser/logo.d.ts +2 -0
- package/dist/browser/logo.js +2 -0
- package/dist/browser/mark.d.ts +2 -0
- package/dist/browser/mark.js +6 -0
- package/dist/browser/signed.d.ts +4 -0
- package/dist/browser/signed.js +23 -6
- package/dist/core/index.d.ts +29 -3
- package/dist/core/index.js +14 -0
- package/dist/core/signed.d.ts +20 -5
- package/dist/core/signed.js +5 -2
- package/dist/server/index.js +69 -31
- package/dist/server/service.d.ts +42 -3
- package/dist/server/service.js +156 -10
- package/dist/site/index.d.ts +2 -1
- package/dist/verily.js +203 -32
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/verily.js
CHANGED
|
@@ -9583,6 +9583,7 @@ var Verily = (() => {
|
|
|
9583
9583
|
isArtifactProvider: () => isArtifactProvider,
|
|
9584
9584
|
isCodeProvider: () => isCodeProvider,
|
|
9585
9585
|
isRedirectProvider: () => isRedirectProvider,
|
|
9586
|
+
lastProved: () => lastProved,
|
|
9586
9587
|
localSide: () => localSide,
|
|
9587
9588
|
presentConnections: () => presentConnections,
|
|
9588
9589
|
proofTitle: () => proofTitle,
|
|
@@ -9651,7 +9652,7 @@ var Verily = (() => {
|
|
|
9651
9652
|
});
|
|
9652
9653
|
await signatures2[0].verified;
|
|
9653
9654
|
const document2 = JSON.parse(data);
|
|
9654
|
-
return document2?.type === "verily-evidence" && document2.version === 1 && typeof document2.
|
|
9655
|
+
return document2?.type === "verily-evidence" && typeof document2.issuedAt === "number" && (document2.version === 1 || document2.version === 2 && document2.status === "retired" && typeof document2.retiredAt === "number") ? document2 : void 0;
|
|
9655
9656
|
} catch {
|
|
9656
9657
|
continue;
|
|
9657
9658
|
}
|
|
@@ -9677,6 +9678,7 @@ var Verily = (() => {
|
|
|
9677
9678
|
var freshnessMs = 7 * 864e5;
|
|
9678
9679
|
function status(connection, now, freshness = freshnessMs) {
|
|
9679
9680
|
if (connection.revokedAt !== void 0) return "revoked";
|
|
9681
|
+
if (connection.retiredAt !== void 0) return "retired";
|
|
9680
9682
|
if (now >= connection.expiresAt) return "expired";
|
|
9681
9683
|
const main = connection.attestations?.external[0];
|
|
9682
9684
|
if (main && !fresh(main, now, freshness)) return "unconfirmed";
|
|
@@ -9685,8 +9687,13 @@ var Verily = (() => {
|
|
|
9685
9687
|
function fresh(attestation, now, freshness = freshnessMs) {
|
|
9686
9688
|
return !attestation.artifactUrl || attestation.hosted === true || freshness === Infinity || now < attestation.confirmedAt + freshness;
|
|
9687
9689
|
}
|
|
9690
|
+
function lastProved(evidence) {
|
|
9691
|
+
const main = evidence.attestations.external[0];
|
|
9692
|
+
return main.artifactUrl ? main.confirmedAt : evidence.authenticatedAt;
|
|
9693
|
+
}
|
|
9688
9694
|
function statusLabel(evidence, now) {
|
|
9689
9695
|
if (evidence.status === "revoked") return "Revoked";
|
|
9696
|
+
if (evidence.status === "retired") return "Retired";
|
|
9690
9697
|
if (evidence.status === "expired" || evidence.expiresAt <= now) return "Expired";
|
|
9691
9698
|
return evidence.status === "unconfirmed" ? "Unconfirmed" : "Verified";
|
|
9692
9699
|
}
|
|
@@ -9782,6 +9789,11 @@ var Verily = (() => {
|
|
|
9782
9789
|
["circle", { cx: "8", cy: "8", r: "6.2" }],
|
|
9783
9790
|
["path", { d: "M8 4.6V8h2.6" }]
|
|
9784
9791
|
]);
|
|
9792
|
+
var boxMark = () => statusMark("box", [
|
|
9793
|
+
["path", { d: "M2.6 3.8h10.8v2.6H2.6z" }],
|
|
9794
|
+
["path", { d: "M3.7 6.4v5.8h8.6V6.4" }],
|
|
9795
|
+
["path", { d: "M6.6 9h2.8" }]
|
|
9796
|
+
]);
|
|
9785
9797
|
var dashMark = () => statusMark("dash", [["path", { d: "M4.4 8h7.2" }]]);
|
|
9786
9798
|
|
|
9787
9799
|
// src/browser/provider-mark.ts
|
|
@@ -9926,7 +9938,9 @@ var Verily = (() => {
|
|
|
9926
9938
|
.peek .via { display: block; margin-top: 6px; font-size: 11px; color: var(--verily-muted, #65726c); }
|
|
9927
9939
|
.provider { display: block; flex-shrink: 0; width: 14px; height: 14px; }
|
|
9928
9940
|
.expired .icon { color: #815a12; background: #fbefce; }
|
|
9929
|
-
.revoked .icon, .message .icon { color: #626d69; background: #edf0ee; }
|
|
9941
|
+
.revoked .icon, .retired .icon, .message .icon { color: #626d69; background: #edf0ee; }
|
|
9942
|
+
/* Nothing ran out and nothing wants attention: the holder chose this, so it is only quiet. */
|
|
9943
|
+
.retired .name { color: var(--verily-muted, #65726c); }
|
|
9930
9944
|
.message { color: var(--verily-muted, #65726c); }
|
|
9931
9945
|
.add { font-weight: 600; }
|
|
9932
9946
|
@media (prefers-reduced-motion: no-preference) {
|
|
@@ -10055,7 +10069,8 @@ var Verily = (() => {
|
|
|
10055
10069
|
} = {}) {
|
|
10056
10070
|
const provider = evidence.providerName;
|
|
10057
10071
|
const current = evidence.status === "verified" && evidence.expiresAt > Date.now();
|
|
10058
|
-
const
|
|
10072
|
+
const retired = evidence.status === "retired";
|
|
10073
|
+
const state = current ? "verified" : retired ? "retired" : evidence.status === "revoked" ? "revoked" : "expired";
|
|
10059
10074
|
const label = statusLabel(evidence, Date.now());
|
|
10060
10075
|
const key2 = renderKey(evidence, current, label, more, linked, rows, peek);
|
|
10061
10076
|
if (intact(element) && shown.get(element) === key2) return null;
|
|
@@ -10064,7 +10079,7 @@ var Verily = (() => {
|
|
|
10064
10079
|
const unnamed = Math.max(more - rows.length, 0);
|
|
10065
10080
|
const named = rows.map((row) => `, ${row.providerName} ${externalName(row.external)}`).join("");
|
|
10066
10081
|
const others = `${named}${unnamed ? ` and ${unnamed} more` : ""}`;
|
|
10067
|
-
paintMark(mark2, current ? "current" : "inactive");
|
|
10082
|
+
paintMark(mark2, current ? "current" : retired ? "pending" : "inactive");
|
|
10068
10083
|
if (linked) {
|
|
10069
10084
|
badge.href = evidence.evidenceUrl;
|
|
10070
10085
|
badge.rel = "noreferrer";
|
|
@@ -10101,7 +10116,7 @@ var Verily = (() => {
|
|
|
10101
10116
|
}
|
|
10102
10117
|
if (!current) {
|
|
10103
10118
|
const icon = span("icon", "");
|
|
10104
|
-
icon.append(state === "expired" ? clockMark() : dashMark());
|
|
10119
|
+
icon.append(retired ? boxMark() : state === "expired" ? clockMark() : dashMark());
|
|
10105
10120
|
icon.setAttribute("aria-hidden", "true");
|
|
10106
10121
|
badge.append(span("label", label), icon);
|
|
10107
10122
|
}
|
|
@@ -10232,6 +10247,7 @@ var Verily = (() => {
|
|
|
10232
10247
|
status: _status,
|
|
10233
10248
|
revokedAt: _revokedAt,
|
|
10234
10249
|
signedUrl: _signedUrl,
|
|
10250
|
+
mark: _mark,
|
|
10235
10251
|
links: _links,
|
|
10236
10252
|
type: _type,
|
|
10237
10253
|
version: _version,
|
|
@@ -10298,11 +10314,23 @@ ${claims(evidence)}`;
|
|
|
10298
10314
|
const document2 = await verifySigned(signed, keys);
|
|
10299
10315
|
if (!document2 || document2.id !== evidence.id || document2.verifierName !== evidence.verifierName || document2.evidenceUrl !== evidence.evidenceUrl || document2.siteName !== evidence.siteName || document2.local.reference !== evidence.local.reference || document2.provider !== evidence.provider || document2.external.id !== evidence.external.id)
|
|
10300
10316
|
return { state: "invalid" };
|
|
10301
|
-
|
|
10317
|
+
if (document2.version === 2 !== (evidence.status === "retired"))
|
|
10318
|
+
return { state: "unchecked", why: "unreadable" };
|
|
10319
|
+
const {
|
|
10320
|
+
type: _type,
|
|
10321
|
+
version: _version,
|
|
10322
|
+
issuedAt: _issuedAt,
|
|
10323
|
+
status: _status,
|
|
10324
|
+
retiredAt: _retiredAt,
|
|
10325
|
+
mark: _mark,
|
|
10326
|
+
...said
|
|
10327
|
+
} = document2;
|
|
10302
10328
|
const record2 = {
|
|
10303
10329
|
...said,
|
|
10304
10330
|
status: evidence.status,
|
|
10305
10331
|
...evidence.revokedAt === void 0 ? {} : { revokedAt: evidence.revokedAt },
|
|
10332
|
+
...document2.version === 2 ? { retiredAt: document2.retiredAt } : {},
|
|
10333
|
+
...evidence.mark === void 0 ? {} : { mark: evidence.mark },
|
|
10306
10334
|
signedUrl: evidence.signedUrl
|
|
10307
10335
|
};
|
|
10308
10336
|
return drawable(record2) ? { state: "valid", keyId: by2, record: record2 } : { state: "unchecked", why: "unreadable" };
|
|
@@ -10336,12 +10364,15 @@ ${claims(evidence)}`;
|
|
|
10336
10364
|
if (evidence.signedUrl === void 0) return evidence;
|
|
10337
10365
|
const key2 = shown2(evidence);
|
|
10338
10366
|
const signed = signedAs.get(key2);
|
|
10339
|
-
if (signed)
|
|
10367
|
+
if (signed) {
|
|
10368
|
+
const { mark: _mark, ...said } = signed;
|
|
10340
10369
|
return {
|
|
10341
|
-
...
|
|
10370
|
+
...said,
|
|
10342
10371
|
status: evidence.status,
|
|
10343
|
-
...evidence.revokedAt === void 0 ? {} : { revokedAt: evidence.revokedAt }
|
|
10372
|
+
...evidence.revokedAt === void 0 ? {} : { revokedAt: evidence.revokedAt },
|
|
10373
|
+
...evidence.mark === void 0 ? {} : { mark: evidence.mark }
|
|
10344
10374
|
};
|
|
10375
|
+
}
|
|
10345
10376
|
return evidence.status === "verified" && failures.has(key2) ? { ...evidence, status: "unconfirmed" } : evidence;
|
|
10346
10377
|
}
|
|
10347
10378
|
function watchSigned(records, changed) {
|
|
@@ -10379,6 +10410,7 @@ ${claims(evidence)}`;
|
|
|
10379
10410
|
var logo = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${-pad} ${-26 - pad} ${2637 + 2 * pad} ${916 + 2 * pad}" class="logo" role="img" aria-label="Verily"><rect x="${-pad}" y="${-26 - pad}" width="${2637 + 2 * pad}" height="${916 + 2 * pad}" rx="166" fill="#0d1117"/>` + logoPaths.map(({ d: d2, fill }) => `<path d="${d2}" fill="${fill === "currentColor" ? "#ffffff" : fill}"/>`).join("") + "</svg>";
|
|
10380
10411
|
|
|
10381
10412
|
// src/browser/logo.ts
|
|
10413
|
+
var projectUrl = "https://github.com/bkazemi/verily";
|
|
10382
10414
|
function verilyLogo() {
|
|
10383
10415
|
const namespace2 = "http://www.w3.org/2000/svg";
|
|
10384
10416
|
const svg = document.createElementNS(namespace2, "svg");
|
|
@@ -10396,9 +10428,14 @@ ${claims(evidence)}`;
|
|
|
10396
10428
|
}
|
|
10397
10429
|
|
|
10398
10430
|
// src/version.ts
|
|
10399
|
-
var version = "v0.
|
|
10431
|
+
var version = "v0.3.0";
|
|
10400
10432
|
|
|
10401
10433
|
// src/browser/evidence-dialog.ts
|
|
10434
|
+
function stampLink() {
|
|
10435
|
+
const link = outward(node("a"), projectUrl);
|
|
10436
|
+
link.append(verilyLogo());
|
|
10437
|
+
return link;
|
|
10438
|
+
}
|
|
10402
10439
|
var openDialogs = /* @__PURE__ */ new WeakMap();
|
|
10403
10440
|
var styles2 = `
|
|
10404
10441
|
* { box-sizing: border-box; }
|
|
@@ -10431,6 +10468,14 @@ ${claims(evidence)}`;
|
|
|
10431
10468
|
.summary a, .method a, .additional a { font: inherit; }
|
|
10432
10469
|
.reference { margin-top: 2px; }
|
|
10433
10470
|
.method { margin-top: 8px; }
|
|
10471
|
+
/* In the corner the heading leaves empty, apart from everything that was checked. */
|
|
10472
|
+
.listing { position: absolute; top: 12px; right: 14px; padding: 1px 8px; border: 1px solid #e0e6df; border-radius: 999px; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
10473
|
+
.listing.preferred { border-color: #245f43; color: #245f43; }
|
|
10474
|
+
/* Quiet, as its pill is: the surface and the name step back, and the controls do not. */
|
|
10475
|
+
.account.retired { background: #f6f8f5; }
|
|
10476
|
+
.account.retired > a, .account.retired > strong { color: #6b786f; }
|
|
10477
|
+
.account.retired .mark { opacity: .45; }
|
|
10478
|
+
.group { margin: 20px 0 0; color: #6b786f; font-size: 11px; font-weight: 550; }
|
|
10434
10479
|
.additional { margin-top: 2px; padding-left: 12px; }
|
|
10435
10480
|
.joiner { display: block; width: 20px; height: 20px; margin: 8px auto -4px; color: #90a096; }
|
|
10436
10481
|
dl { margin: 16px 0 0; padding-top: 12px; border-top: 1px solid #e5e9e3; display: grid; grid-template-columns: auto 1fr; gap: 5px 16px; font-size: 11px; }
|
|
@@ -10443,9 +10488,10 @@ ${claims(evidence)}`;
|
|
|
10443
10488
|
.action:disabled { opacity: .6; cursor: progress; }
|
|
10444
10489
|
.action.danger:hover { border-color: #b3261e; background: #fdecea; color: #b3261e; }
|
|
10445
10490
|
.row { display: flex; justify-content: end; gap: 8px; margin-top: 16px; }
|
|
10446
|
-
.account .row { align-items: center; justify-content: start; margin-top: 12px; }
|
|
10491
|
+
.account .row { align-items: center; justify-content: start; flex-wrap: wrap; margin-top: 12px; }
|
|
10447
10492
|
.account .action { padding: 5px 10px; font-size: 12px; }
|
|
10448
|
-
footer { display: flex; align-items: center; justify-content: start; gap: 6px; margin
|
|
10493
|
+
footer { display: flex; align-items: center; justify-content: start; gap: 6px; margin: 20px 0 -8px; color: #9aa9a0; font-size: 11px; }
|
|
10494
|
+
footer a { display: flex; color: inherit; }
|
|
10449
10495
|
.logo { display: block; height: 13px; }
|
|
10450
10496
|
${markStyles}
|
|
10451
10497
|
`;
|
|
@@ -10510,6 +10556,7 @@ ${claims(evidence)}`;
|
|
|
10510
10556
|
card.append(...extra);
|
|
10511
10557
|
return card;
|
|
10512
10558
|
}
|
|
10559
|
+
var retiringNote = "Retiring keeps this record as history. It will no longer read as verified, and who can read it cannot be changed afterwards.";
|
|
10513
10560
|
var removable = (evidence) => evidence.links ?? (evidence.status === "revoked" ? [] : [evidence.id]);
|
|
10514
10561
|
function manageRow(evidence, manage) {
|
|
10515
10562
|
const row = node("div", "", "row");
|
|
@@ -10518,12 +10565,49 @@ ${claims(evidence)}`;
|
|
|
10518
10565
|
control.type = "button";
|
|
10519
10566
|
return control;
|
|
10520
10567
|
};
|
|
10568
|
+
const [named] = removable(evidence);
|
|
10569
|
+
const { mark: mark2 } = manage;
|
|
10570
|
+
const listable = mark2 !== void 0 && named !== void 0 && !["revoked", "retired"].includes(evidence.status);
|
|
10571
|
+
const list = (label, as2) => {
|
|
10572
|
+
const control = act(label);
|
|
10573
|
+
control.onclick = async () => {
|
|
10574
|
+
for (const other of row.children) other.disabled = true;
|
|
10575
|
+
try {
|
|
10576
|
+
await mark2(named, as2);
|
|
10577
|
+
} catch {
|
|
10578
|
+
offer("That did not go through.");
|
|
10579
|
+
}
|
|
10580
|
+
};
|
|
10581
|
+
return control;
|
|
10582
|
+
};
|
|
10521
10583
|
const offer = (note = "") => {
|
|
10522
10584
|
const renew = act("Renew");
|
|
10523
10585
|
const remove = act("Remove", true);
|
|
10524
|
-
renew.onclick = () => manage.
|
|
10586
|
+
renew.onclick = () => manage.renew && evidence.status !== "revoked" ? manage.renew(
|
|
10587
|
+
evidence.id,
|
|
10588
|
+
evidence.provider,
|
|
10589
|
+
evidence.status === "retired" ? evidence.attestations.external[0].method : void 0
|
|
10590
|
+
) : manage.connect(evidence.provider);
|
|
10525
10591
|
remove.onclick = confirm;
|
|
10526
|
-
|
|
10592
|
+
const listing = [];
|
|
10593
|
+
if (listable) {
|
|
10594
|
+
const retire = act("Retire");
|
|
10595
|
+
retire.onclick = retiring;
|
|
10596
|
+
listing.push(
|
|
10597
|
+
...evidence.mark === "preferred" ? [] : [list("Mark as preferred", "preferred")],
|
|
10598
|
+
...evidence.mark === "unused" ? [] : [list("Mark as unused", "unused")],
|
|
10599
|
+
...evidence.mark === void 0 ? [] : [list("Mark as current", "current")],
|
|
10600
|
+
retire
|
|
10601
|
+
);
|
|
10602
|
+
}
|
|
10603
|
+
row.replaceChildren(renew, ...listing, remove, ...note ? [node("span", note, "muted")] : []);
|
|
10604
|
+
};
|
|
10605
|
+
const retiring = () => {
|
|
10606
|
+
const cancel = act("Cancel");
|
|
10607
|
+
const sure = list("Retire", "retired");
|
|
10608
|
+
cancel.onclick = () => offer();
|
|
10609
|
+
row.replaceChildren(node("span", retiringNote, "muted"), cancel, sure);
|
|
10610
|
+
cancel.focus();
|
|
10527
10611
|
};
|
|
10528
10612
|
const confirm = () => {
|
|
10529
10613
|
const cancel = act("Cancel");
|
|
@@ -10626,11 +10710,15 @@ ${claims(evidence)}`;
|
|
|
10626
10710
|
} else attribution.append(document.createTextNode(evidence.verifierName));
|
|
10627
10711
|
if (evidence.signedUrl) attribution.append(signedMark(evidence, later));
|
|
10628
10712
|
copy.append(node("div", status2, "state"), attribution);
|
|
10629
|
-
|
|
10713
|
+
const retired = evidence.status === "retired";
|
|
10714
|
+
summary.append(verificationMark(current ? "current" : retired ? "pending" : "inactive"), copy);
|
|
10630
10715
|
const dates = node("dl");
|
|
10631
10716
|
const dateRows = [["Approved", evidence.approvedAt]];
|
|
10632
10717
|
if (evidence.status === "revoked") {
|
|
10633
10718
|
if (evidence.revokedAt !== void 0) dateRows.push(["Revoked on", evidence.revokedAt]);
|
|
10719
|
+
} else if (retired) {
|
|
10720
|
+
dateRows.push(["Last verified", lastProved(evidence)]);
|
|
10721
|
+
if (evidence.retiredAt !== void 0) dateRows.push(["Retired", evidence.retiredAt]);
|
|
10634
10722
|
} else {
|
|
10635
10723
|
dateRows.push([
|
|
10636
10724
|
evidence.expiresAt > Date.now() ? "Valid until" : "Expired on",
|
|
@@ -10638,7 +10726,7 @@ ${claims(evidence)}`;
|
|
|
10638
10726
|
]);
|
|
10639
10727
|
}
|
|
10640
10728
|
const main = evidence.attestations.external[0];
|
|
10641
|
-
if (main.artifactUrl) dateRows.push(["Last checked", main.confirmedAt]);
|
|
10729
|
+
if (main.artifactUrl && !retired) dateRows.push(["Last checked", main.confirmedAt]);
|
|
10642
10730
|
for (const [label, time] of dateRows) {
|
|
10643
10731
|
dates.append(node("dt", label), node("dd", moment(time)));
|
|
10644
10732
|
}
|
|
@@ -10657,19 +10745,22 @@ ${claims(evidence)}`;
|
|
|
10657
10745
|
summary,
|
|
10658
10746
|
...attestationNote(main, names),
|
|
10659
10747
|
...evidence.attestations.external.slice(1).flatMap((a2) => attestationNote(a2, names, true)),
|
|
10748
|
+
...evidence.status === "revoked" || retired ? [] : evidence.mark === "preferred" ? [node("div", "Preferred", "listing preferred")] : evidence.mark === "unused" ? [node("div", "No longer used", "listing")] : [],
|
|
10660
10749
|
dates,
|
|
10661
10750
|
...manage && removable(evidence).length ? [manageRow(evidence, manage)] : []
|
|
10662
10751
|
);
|
|
10752
|
+
const surface = retired ? "account retired" : "account";
|
|
10753
|
+
card.className = surface;
|
|
10663
10754
|
if (evidence.signedUrl) {
|
|
10664
10755
|
const veiled = [...card.children];
|
|
10665
10756
|
const checking = node("div", "", "checking");
|
|
10666
10757
|
checking.setAttribute("role", "status");
|
|
10667
10758
|
checking.append(node("span", "", "spinner"), document.createTextNode("Checking signature\u2026"));
|
|
10668
|
-
card.className =
|
|
10759
|
+
card.className = `${surface} veiled`;
|
|
10669
10760
|
for (const part of veiled) part.inert = true;
|
|
10670
10761
|
card.append(checking);
|
|
10671
10762
|
void signatures(evidence).then(() => {
|
|
10672
|
-
card.className =
|
|
10763
|
+
card.className = surface;
|
|
10673
10764
|
for (const part of veiled) part.inert = false;
|
|
10674
10765
|
checking.remove();
|
|
10675
10766
|
});
|
|
@@ -10700,11 +10791,16 @@ ${claims(evidence)}`;
|
|
|
10700
10791
|
provider: first.providerName
|
|
10701
10792
|
})
|
|
10702
10793
|
);
|
|
10794
|
+
const retired = records.filter((record2) => record2.status === "retired");
|
|
10703
10795
|
content.replaceChildren(
|
|
10704
10796
|
localCard,
|
|
10705
10797
|
linkMark(),
|
|
10706
|
-
...records.map((record2) => externalCard(record2, manage, later)),
|
|
10798
|
+
...records.filter((record2) => record2.status !== "retired").map((record2) => externalCard(record2, manage, later)),
|
|
10707
10799
|
...manage ? [addRow(manage)] : [],
|
|
10800
|
+
...retired.length ? [
|
|
10801
|
+
node("h3", "Retired accounts", "group"),
|
|
10802
|
+
...retired.map((record2) => externalCard(record2, manage, later))
|
|
10803
|
+
] : [],
|
|
10708
10804
|
// Nothing below the cards may name a provider. Approval, method and dates belong to
|
|
10709
10805
|
// the card they came from, and a second provider on this subject gets its own card.
|
|
10710
10806
|
node(
|
|
@@ -10736,11 +10832,30 @@ ${claims(evidence)}`;
|
|
|
10736
10832
|
close.type = "button";
|
|
10737
10833
|
close.setAttribute("aria-label", "Close verification details");
|
|
10738
10834
|
content.setAttribute("aria-live", "polite");
|
|
10739
|
-
stamp.append(
|
|
10835
|
+
stamp.append(stampLink(), node("span", version));
|
|
10740
10836
|
header.append(heading, close);
|
|
10741
10837
|
dialog.append(header, content, stamp);
|
|
10742
10838
|
const removed = /* @__PURE__ */ new Map();
|
|
10839
|
+
const listed = [];
|
|
10840
|
+
const listing = (record2) => JSON.stringify([record2.status, record2.mark, record2.retiredAt, record2.approvedAt]);
|
|
10841
|
+
const listings = (given) => new Map([given].flat().map((record2) => [record2.id, listing(record2)]));
|
|
10743
10842
|
let held;
|
|
10843
|
+
const relisted = (evidence) => {
|
|
10844
|
+
let record2 = evidence;
|
|
10845
|
+
for (const { ids, as: as2, at: at2 } of listed) {
|
|
10846
|
+
if (["revoked", "retired"].includes(record2.status)) break;
|
|
10847
|
+
if (!ids.includes(record2.id)) {
|
|
10848
|
+
if (as2 === "preferred" && record2.mark === "preferred")
|
|
10849
|
+
record2 = { ...record2, mark: void 0 };
|
|
10850
|
+
continue;
|
|
10851
|
+
}
|
|
10852
|
+
record2 = as2 === "retired" ? (
|
|
10853
|
+
// Its signed form is another document now, to be read with the records to come.
|
|
10854
|
+
{ ...record2, status: "retired", retiredAt: at2, mark: void 0, signedUrl: void 0 }
|
|
10855
|
+
) : { ...record2, mark: as2 === "current" ? void 0 : as2 };
|
|
10856
|
+
}
|
|
10857
|
+
return record2;
|
|
10858
|
+
};
|
|
10744
10859
|
const actions = manage && {
|
|
10745
10860
|
// The other dialog opens over this one before this one goes, so the page behind is
|
|
10746
10861
|
// never uncovered between the two.
|
|
@@ -10748,11 +10863,32 @@ ${claims(evidence)}`;
|
|
|
10748
10863
|
manage.connect(provider);
|
|
10749
10864
|
dialog.close();
|
|
10750
10865
|
},
|
|
10866
|
+
...manage.renew ? {
|
|
10867
|
+
renew(id, provider, method) {
|
|
10868
|
+
manage.renew(id, provider, method);
|
|
10869
|
+
dialog.close();
|
|
10870
|
+
}
|
|
10871
|
+
} : {},
|
|
10751
10872
|
async remove(ids) {
|
|
10752
10873
|
await manage.remove(ids);
|
|
10753
10874
|
for (const id of ids) removed.set(id, Date.now());
|
|
10754
10875
|
if (held && dialog.open) draw(held);
|
|
10755
|
-
}
|
|
10876
|
+
},
|
|
10877
|
+
...manage.mark ? {
|
|
10878
|
+
async mark(id, as2) {
|
|
10879
|
+
await manage.mark(id, as2);
|
|
10880
|
+
const account = arrange2([held ?? []].flat()).find(
|
|
10881
|
+
(card) => removable(card).includes(id)
|
|
10882
|
+
);
|
|
10883
|
+
listed.push({
|
|
10884
|
+
ids: account ? removable(account) : [id],
|
|
10885
|
+
as: as2,
|
|
10886
|
+
at: Date.now(),
|
|
10887
|
+
before: listings(held ?? [])
|
|
10888
|
+
});
|
|
10889
|
+
if (held && dialog.open) draw(held);
|
|
10890
|
+
}
|
|
10891
|
+
} : {}
|
|
10756
10892
|
};
|
|
10757
10893
|
root.append(dialog);
|
|
10758
10894
|
document.body.append(host);
|
|
@@ -10763,9 +10899,13 @@ ${claims(evidence)}`;
|
|
|
10763
10899
|
const retries = /* @__PURE__ */ new Set();
|
|
10764
10900
|
const draw = (given) => {
|
|
10765
10901
|
held = given;
|
|
10902
|
+
const now = listings(given);
|
|
10903
|
+
for (const change of [...listed])
|
|
10904
|
+
if (change.ids.some((id) => now.get(id) !== change.before.get(id)))
|
|
10905
|
+
listed.splice(listed.indexOf(change), 1);
|
|
10766
10906
|
const records = arrange2(
|
|
10767
10907
|
[given].flat().map(
|
|
10768
|
-
(e2) => removed.has(e2.id) && e2.status !== "revoked" ? { ...e2, status: "revoked", revokedAt: removed.get(e2.id) } : standing(e2)
|
|
10908
|
+
(e2) => removed.has(e2.id) && e2.status !== "revoked" ? { ...e2, status: "revoked", revokedAt: removed.get(e2.id) } : relisted(standing(e2))
|
|
10769
10909
|
)
|
|
10770
10910
|
);
|
|
10771
10911
|
const key2 = JSON.stringify(records.map((e2) => [e2, statusLabel(e2, Date.now())]));
|
|
@@ -10906,7 +11046,7 @@ ${claims(evidence)}`;
|
|
|
10906
11046
|
return element;
|
|
10907
11047
|
}
|
|
10908
11048
|
var openDialogs2 = /* @__PURE__ */ new WeakMap();
|
|
10909
|
-
function openConnectDialog(opener, api, back, provider) {
|
|
11049
|
+
function openConnectDialog(opener, api, back, provider, renew) {
|
|
10910
11050
|
const existing = openDialogs2.get(opener);
|
|
10911
11051
|
if (existing?.open) {
|
|
10912
11052
|
existing.focus();
|
|
@@ -10928,7 +11068,7 @@ ${claims(evidence)}`;
|
|
|
10928
11068
|
close.type = "button";
|
|
10929
11069
|
close.setAttribute("aria-label", "Close");
|
|
10930
11070
|
content.setAttribute("aria-live", "polite");
|
|
10931
|
-
stamp.append(
|
|
11071
|
+
stamp.append(stampLink(), node("span", version));
|
|
10932
11072
|
header.append(heading, close);
|
|
10933
11073
|
dialog.append(header, content, stamp);
|
|
10934
11074
|
root.append(dialog);
|
|
@@ -11006,7 +11146,11 @@ ${claims(evidence)}`;
|
|
|
11006
11146
|
return;
|
|
11007
11147
|
}
|
|
11008
11148
|
if (!current(asked)) return;
|
|
11009
|
-
const
|
|
11149
|
+
const renewing = methods.methods.filter(
|
|
11150
|
+
(m2) => m2.provider === provider && (renew?.method === void 0 || m2.method === renew.method)
|
|
11151
|
+
);
|
|
11152
|
+
if (renew && !renewing.length) renew = void 0;
|
|
11153
|
+
const all = renew ? renewing : methods.methods;
|
|
11010
11154
|
if (group !== void 0 && !all.some((m2) => m2.provider === group)) group = void 0;
|
|
11011
11155
|
const count = (provider2) => all.filter((m2) => m2.provider === provider2).length;
|
|
11012
11156
|
const list = node("div", "", "choices");
|
|
@@ -11035,7 +11179,7 @@ ${claims(evidence)}`;
|
|
|
11035
11179
|
return;
|
|
11036
11180
|
}
|
|
11037
11181
|
}
|
|
11038
|
-
void busy(control, () => api.start(choice.provider, choice.method), show);
|
|
11182
|
+
void busy(control, () => api.start(choice.provider, choice.method, renew?.id), show);
|
|
11039
11183
|
};
|
|
11040
11184
|
list.append(control);
|
|
11041
11185
|
}
|
|
@@ -11049,7 +11193,7 @@ ${claims(evidence)}`;
|
|
|
11049
11193
|
),
|
|
11050
11194
|
list
|
|
11051
11195
|
];
|
|
11052
|
-
if (group !== void 0) {
|
|
11196
|
+
if (group !== void 0 && !renew) {
|
|
11053
11197
|
const back2 = button("\u2039 All options");
|
|
11054
11198
|
back2.onclick = () => {
|
|
11055
11199
|
group = void 0;
|
|
@@ -11399,7 +11543,11 @@ ${claims(evidence)}`;
|
|
|
11399
11543
|
// Every record the card speaks for, so its signature mark answers for all of them.
|
|
11400
11544
|
sources: verified.length ? verified : [base]
|
|
11401
11545
|
};
|
|
11402
|
-
}).sort((a2, b2) => a2.connectedAt - b2.connectedAt);
|
|
11546
|
+
}).sort((a2, b2) => place2(a2) - place2(b2) || a2.connectedAt - b2.connectedAt);
|
|
11547
|
+
}
|
|
11548
|
+
function place2(account) {
|
|
11549
|
+
if (account.status === "retired") return 3;
|
|
11550
|
+
return account.mark === "preferred" ? 0 : account.mark === "unused" ? 2 : 1;
|
|
11403
11551
|
}
|
|
11404
11552
|
function presentGroup(element, records, load2) {
|
|
11405
11553
|
const ordered = accounts(records.map(standing));
|
|
@@ -11506,7 +11654,12 @@ ${claims(evidence)}`;
|
|
|
11506
11654
|
if (typeof data.local.profileUrl === "string") safeUrl(data.local.profileUrl);
|
|
11507
11655
|
return data;
|
|
11508
11656
|
},
|
|
11509
|
-
start: async (provider, method) => flowView(
|
|
11657
|
+
start: async (provider, method, renew) => flowView(
|
|
11658
|
+
await ask(
|
|
11659
|
+
"/sessions",
|
|
11660
|
+
renew ? { kind: "renew", connectionId: renew, provider, method } : { kind: "connect", provider, method }
|
|
11661
|
+
)
|
|
11662
|
+
),
|
|
11510
11663
|
read: async (id) => flowView(await ask(`/flows/${encodeURIComponent(id)}?format=json`, void 0, id)),
|
|
11511
11664
|
submit: async (id, artifact) => flowView(await ask(`/flows/${encodeURIComponent(id)}/submit`, { artifact }, id)),
|
|
11512
11665
|
async approve(id, visibility, cancel) {
|
|
@@ -11550,11 +11703,11 @@ ${claims(evidence)}`;
|
|
|
11550
11703
|
* Opens the connect dialog over the current page. Resolves when it closes, with how
|
|
11551
11704
|
* the last attempt in it ended. Call from a click: a sign-in method opens a window.
|
|
11552
11705
|
*/
|
|
11553
|
-
openConnect(opener = document.body, back, provider) {
|
|
11706
|
+
openConnect(opener = document.body, back, provider, renew) {
|
|
11554
11707
|
if (remote && !handoffUrl)
|
|
11555
11708
|
throw new Error("A backend on another origin requires a handoff URL");
|
|
11556
11709
|
session = void 0;
|
|
11557
|
-
return openConnectDialog(opener, flows, back, provider);
|
|
11710
|
+
return openConnectDialog(opener, flows, back, provider, renew);
|
|
11558
11711
|
},
|
|
11559
11712
|
/**
|
|
11560
11713
|
* Draws the pill that opens the connect dialog. The host receives a `verily-result`
|
|
@@ -11682,6 +11835,14 @@ ${claims(evidence)}`;
|
|
|
11682
11835
|
if (remote) session = void 0;
|
|
11683
11836
|
return ask(`/connections/${encodeURIComponent(id)}/disconnect`, {});
|
|
11684
11837
|
},
|
|
11838
|
+
/**
|
|
11839
|
+
* Says how the holder would have an account listed, or retires it. Names one record
|
|
11840
|
+
* and acts on the account: every record of it the holder has.
|
|
11841
|
+
*/
|
|
11842
|
+
mark(id, as2) {
|
|
11843
|
+
if (remote) session = void 0;
|
|
11844
|
+
return ask(`/connections/${encodeURIComponent(id)}/mark`, { as: as2 });
|
|
11845
|
+
},
|
|
11685
11846
|
issueShare: (id) => request(`/connections/${encodeURIComponent(id)}/share`, {}),
|
|
11686
11847
|
revokeShare: (id) => request(`/connections/${encodeURIComponent(id)}/share-revoke`, {})
|
|
11687
11848
|
};
|
|
@@ -11753,7 +11914,8 @@ ${claims(evidence)}`;
|
|
|
11753
11914
|
(k2) => typeof value.external[k2] === "string"
|
|
11754
11915
|
) && (value.local.profileUrl === void 0 || typeof value.local.profileUrl === "string") && // A signed record lives beside the record it was made from and nowhere else, since the
|
|
11755
11916
|
// keys it is checked against are read from where the record lives.
|
|
11756
|
-
(value.signedUrl === void 0 || value.signedUrl === `${value.evidenceUrl}?format=signed`) && validAttestations(value.attestations) && (value.local.kind === void 0 || typeof value.local.kind === "string") && (value.external.kind === void 0 || ["account", "key", "page", "mailbox"].includes(String(value.external.kind))) && (value.revokedAt === void 0 || typeof value.revokedAt === "number" && Number.isFinite(value.revokedAt)) && ["verified", "unconfirmed", "expired", "revoked"].includes(String(value.status)) &&
|
|
11917
|
+
(value.signedUrl === void 0 || value.signedUrl === `${value.evidenceUrl}?format=signed`) && validAttestations(value.attestations) && (value.local.kind === void 0 || typeof value.local.kind === "string") && (value.external.kind === void 0 || ["account", "key", "page", "mailbox"].includes(String(value.external.kind))) && (value.revokedAt === void 0 || typeof value.revokedAt === "number" && Number.isFinite(value.revokedAt)) && ["verified", "unconfirmed", "expired", "retired", "revoked"].includes(String(value.status)) && // A retired record stands on its dates, so one that does not say when is not one.
|
|
11918
|
+
(value.status === "retired" ? typeof value.retiredAt === "number" && Number.isFinite(value.retiredAt) : value.retiredAt === void 0) && (value.mark === void 0 || ["preferred", "unused"].includes(String(value.mark))) && ["public", "unlisted"].includes(String(value.visibility)) && (value.connectedAt === void 0 || typeof value.connectedAt === "number" && Number.isFinite(value.connectedAt)) && ["authenticatedAt", "approvedAt", "expiresAt"].every(
|
|
11757
11919
|
(k2) => typeof value[k2] === "number" && Number.isFinite(value[k2])
|
|
11758
11920
|
);
|
|
11759
11921
|
}
|
|
@@ -11862,6 +12024,11 @@ ${claims(evidence)}`;
|
|
|
11862
12024
|
if (result.outcome === "complete") changed(result);
|
|
11863
12025
|
});
|
|
11864
12026
|
},
|
|
12027
|
+
renew: (id, provider, method) => {
|
|
12028
|
+
void client.openConnect(this, () => details(this), provider, { id, method }).then((result) => {
|
|
12029
|
+
if (result.outcome === "complete") changed(result);
|
|
12030
|
+
});
|
|
12031
|
+
},
|
|
11865
12032
|
// One at a time, each told as it goes: if a later one fails, the host still
|
|
11866
12033
|
// hears of those that went and reads its records again.
|
|
11867
12034
|
remove: async (ids2) => {
|
|
@@ -11869,6 +12036,10 @@ ${claims(evidence)}`;
|
|
|
11869
12036
|
await client.disconnect(id);
|
|
11870
12037
|
changed({ outcome: "removed", connectionId: id });
|
|
11871
12038
|
}
|
|
12039
|
+
},
|
|
12040
|
+
mark: async (id, as2) => {
|
|
12041
|
+
await client.mark(id, as2);
|
|
12042
|
+
changed({ outcome: "marked", connectionId: id, as: as2 });
|
|
11872
12043
|
}
|
|
11873
12044
|
});
|
|
11874
12045
|
} else managers.delete(this);
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED