@bkazemi/verily 0.4.0 → 0.5.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 +47 -10
- package/dist/browser/evidence-dialog.js +1 -1
- package/dist/browser/index.js +28 -22
- package/dist/core/index.d.ts +67 -4
- package/dist/core/index.js +11 -5
- package/dist/core/routes.d.ts +57 -0
- package/dist/core/routes.js +52 -0
- package/dist/server/domain.d.ts +76 -10
- package/dist/server/domain.js +140 -51
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +65 -27
- package/dist/server/pgp.d.ts +2 -0
- package/dist/server/pgp.js +1 -1
- package/dist/server/service.d.ts +72 -1
- package/dist/server/service.js +233 -22
- package/dist/site/index.js +2 -2
- package/dist/verily.js +88 -34
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/verily.js
CHANGED
|
@@ -9575,6 +9575,8 @@ var Verily = (() => {
|
|
|
9575
9575
|
__export(browser_exports, {
|
|
9576
9576
|
Refused: () => Refused,
|
|
9577
9577
|
attestationLabel: () => attestationLabel,
|
|
9578
|
+
dialogPath: () => dialogPath,
|
|
9579
|
+
dialogRoute: () => dialogRoute,
|
|
9578
9580
|
externalId: () => externalId,
|
|
9579
9581
|
externalLink: () => externalLink,
|
|
9580
9582
|
externalName: () => externalName,
|
|
@@ -9589,6 +9591,9 @@ var Verily = (() => {
|
|
|
9589
9591
|
presentConnections: () => presentConnections,
|
|
9590
9592
|
proofTitle: () => proofTitle,
|
|
9591
9593
|
providerMethod: () => providerMethod,
|
|
9594
|
+
routeOf: () => routeOf,
|
|
9595
|
+
routePath: () => routePath,
|
|
9596
|
+
routes: () => routes,
|
|
9592
9597
|
signedBy: () => signedBy,
|
|
9593
9598
|
status: () => status,
|
|
9594
9599
|
statusLabel: () => statusLabel,
|
|
@@ -9661,6 +9666,50 @@ var Verily = (() => {
|
|
|
9661
9666
|
return void 0;
|
|
9662
9667
|
}
|
|
9663
9668
|
|
|
9669
|
+
// src/core/routes.ts
|
|
9670
|
+
var routes = {
|
|
9671
|
+
methods: { method: "GET", path: "/methods" },
|
|
9672
|
+
start: { method: "POST", path: "/sessions" },
|
|
9673
|
+
flow: { method: "GET", path: "/flows/:id", format: "json" },
|
|
9674
|
+
submit: { method: "POST", path: "/flows/:id/submit" },
|
|
9675
|
+
approve: { method: "POST", path: "/flows/:id/approve" },
|
|
9676
|
+
disconnect: { method: "POST", path: "/connections/:id/disconnect", manages: true },
|
|
9677
|
+
mark: { method: "POST", path: "/connections/:id/mark", manages: true },
|
|
9678
|
+
share: { method: "POST", path: "/connections/:id/share", manages: true, dialog: false },
|
|
9679
|
+
shareRevoke: {
|
|
9680
|
+
method: "POST",
|
|
9681
|
+
path: "/connections/:id/share-revoke",
|
|
9682
|
+
manages: true,
|
|
9683
|
+
dialog: false
|
|
9684
|
+
}
|
|
9685
|
+
};
|
|
9686
|
+
var names = Object.keys(routes);
|
|
9687
|
+
function matches(route, path) {
|
|
9688
|
+
const want = route.path.split("/");
|
|
9689
|
+
const got = path.split("/");
|
|
9690
|
+
return want.length === got.length && want.every((part, at2) => part === ":id" ? got[at2] !== "" : part === got[at2]);
|
|
9691
|
+
}
|
|
9692
|
+
function routePath(name, id) {
|
|
9693
|
+
const route = routes[name];
|
|
9694
|
+
const path = route.path.replace(":id", encodeURIComponent(id ?? ""));
|
|
9695
|
+
return route.format ? `${path}?format=${route.format}` : path;
|
|
9696
|
+
}
|
|
9697
|
+
function routeOf(method, path) {
|
|
9698
|
+
return names.find((name) => routes[name].method === method && matches(routes[name], path));
|
|
9699
|
+
}
|
|
9700
|
+
function dialogRoute(method, path, query) {
|
|
9701
|
+
const name = routeOf(method, path);
|
|
9702
|
+
const route = name && routes[name];
|
|
9703
|
+
if (!route || route.dialog === false) return void 0;
|
|
9704
|
+
return !route.format || query.get("format") === route.format ? name : void 0;
|
|
9705
|
+
}
|
|
9706
|
+
function dialogPath(path) {
|
|
9707
|
+
return names.some((name) => {
|
|
9708
|
+
const route = routes[name];
|
|
9709
|
+
return route.dialog !== false && matches(route, path);
|
|
9710
|
+
});
|
|
9711
|
+
}
|
|
9712
|
+
|
|
9664
9713
|
// src/core/index.ts
|
|
9665
9714
|
var Refused = class extends Error {
|
|
9666
9715
|
};
|
|
@@ -9710,14 +9759,16 @@ var Verily = (() => {
|
|
|
9710
9759
|
function externalName(external) {
|
|
9711
9760
|
return external.kind === void 0 || external.kind === "account" ? `@${external.handle.replace(/^@/, "")}` : external.handle;
|
|
9712
9761
|
}
|
|
9713
|
-
function attestationLabel(method,
|
|
9762
|
+
function attestationLabel(method, names2, proof = {}) {
|
|
9763
|
+
const dnssec = proof.dnssec ? ", validated by DNSSEC" : "";
|
|
9714
9764
|
return {
|
|
9715
|
-
|
|
9716
|
-
|
|
9717
|
-
|
|
9718
|
-
|
|
9719
|
-
|
|
9720
|
-
|
|
9765
|
+
// A site's word carries a proof only where its own DNS was read naming this verifier.
|
|
9766
|
+
declared: proof.artifactUrl ? `Stated by ${names2.site}, whose DNS names this verifier${dnssec}` : `Stated by ${names2.site}`,
|
|
9767
|
+
oauth: `Signed in with ${names2.provider}`,
|
|
9768
|
+
gist: `Published a proof on ${names2.provider}`,
|
|
9769
|
+
backlink: `Linked back to ${names2.site}`,
|
|
9770
|
+
dns: `Published a proof in its DNS${dnssec}`,
|
|
9771
|
+
wellknown: "Published a proof in a file it serves",
|
|
9721
9772
|
signature: "Proved with a signature",
|
|
9722
9773
|
code: "Entered a code sent to this address"
|
|
9723
9774
|
}[method];
|
|
@@ -10434,7 +10485,7 @@ ${claims(evidence)}`;
|
|
|
10434
10485
|
}
|
|
10435
10486
|
|
|
10436
10487
|
// src/version.ts
|
|
10437
|
-
var version = "v0.
|
|
10488
|
+
var version = "v0.5.0";
|
|
10438
10489
|
|
|
10439
10490
|
// src/browser/evidence-dialog.ts
|
|
10440
10491
|
function stampLink() {
|
|
@@ -10535,8 +10586,8 @@ ${claims(evidence)}`;
|
|
|
10535
10586
|
}
|
|
10536
10587
|
return svg;
|
|
10537
10588
|
}
|
|
10538
|
-
function attestationNote(attestation,
|
|
10539
|
-
const label = attestationLabel(attestation.method,
|
|
10589
|
+
function attestationNote(attestation, names2, additional = false) {
|
|
10590
|
+
const label = attestationLabel(attestation.method, names2, attestation);
|
|
10540
10591
|
if (!label) return [];
|
|
10541
10592
|
const note = node("div", additional ? "+ " : "", `muted ${additional ? "additional" : "method"}`);
|
|
10542
10593
|
if (!attestation.artifactUrl) {
|
|
@@ -10736,7 +10787,7 @@ ${claims(evidence)}`;
|
|
|
10736
10787
|
for (const [label, time] of dateRows) {
|
|
10737
10788
|
dates.append(node("dt", label), node("dd", moment(time)));
|
|
10738
10789
|
}
|
|
10739
|
-
const
|
|
10790
|
+
const names2 = { site: evidence.siteName, provider };
|
|
10740
10791
|
const logo2 = providerMark(evidence.provider, evidence.attestations.external[0].method);
|
|
10741
10792
|
const card = accountCard(
|
|
10742
10793
|
// The mark and the name, or just the name. A mark that falls back to writing the name
|
|
@@ -10749,8 +10800,8 @@ ${claims(evidence)}`;
|
|
|
10749
10800
|
// Status first, then how it was shown, then when. The proof explains the state
|
|
10750
10801
|
// above it, so it cannot sit before that state has been given.
|
|
10751
10802
|
summary,
|
|
10752
|
-
...attestationNote(main,
|
|
10753
|
-
...evidence.attestations.external.slice(1).flatMap((a2) => attestationNote(a2,
|
|
10803
|
+
...attestationNote(main, names2),
|
|
10804
|
+
...evidence.attestations.external.slice(1).flatMap((a2) => attestationNote(a2, names2, true)),
|
|
10754
10805
|
...evidence.status === "revoked" || retired ? [] : evidence.mark === "preferred" ? [node("div", "Preferred", "listing preferred")] : evidence.mark === "unused" ? [node("div", "No longer used", "listing")] : [],
|
|
10755
10806
|
dates,
|
|
10756
10807
|
...manage && removable(evidence).length ? [manageRow(evidence, manage)] : []
|
|
@@ -11594,7 +11645,7 @@ ${claims(evidence)}`;
|
|
|
11594
11645
|
function init({ backendUrl, handoffUrl }) {
|
|
11595
11646
|
const base = new URL(backendUrl, location.href);
|
|
11596
11647
|
if (!["https:", "http:"].includes(base.protocol)) throw new Error("Invalid backend URL");
|
|
11597
|
-
|
|
11648
|
+
const root = base.href.replace(/\/$/, "");
|
|
11598
11649
|
const remote = base.origin !== location.origin;
|
|
11599
11650
|
const bindings = /* @__PURE__ */ new Map();
|
|
11600
11651
|
let session;
|
|
@@ -11607,7 +11658,7 @@ ${claims(evidence)}`;
|
|
|
11607
11658
|
const vouched = handed.ok ? await handed.json() : void 0;
|
|
11608
11659
|
if (!record(vouched) || typeof vouched.token !== "string")
|
|
11609
11660
|
throw new Error("Verily request unavailable");
|
|
11610
|
-
const traded = await fetch(`${
|
|
11661
|
+
const traded = await fetch(`${root}/site/session`, {
|
|
11611
11662
|
method: "POST",
|
|
11612
11663
|
credentials: "omit",
|
|
11613
11664
|
cache: "no-store",
|
|
@@ -11622,11 +11673,12 @@ ${claims(evidence)}`;
|
|
|
11622
11673
|
async function ask(path, data, flow) {
|
|
11623
11674
|
if (!remote) return request(path, data);
|
|
11624
11675
|
const binding = flow && bindings.get(flow);
|
|
11625
|
-
const response = await fetch(`${
|
|
11676
|
+
const response = await fetch(`${root}${path}`, {
|
|
11626
11677
|
credentials: "omit",
|
|
11627
11678
|
cache: "no-store",
|
|
11628
11679
|
method: data ? "POST" : "GET",
|
|
11629
11680
|
headers: {
|
|
11681
|
+
Accept: "application/json",
|
|
11630
11682
|
Authorization: `Bearer ${await (session ??= openSession())}`,
|
|
11631
11683
|
...binding ? { "X-Verily-Flow": binding } : {},
|
|
11632
11684
|
...data ? { "Content-Type": "application/json" } : {}
|
|
@@ -11640,21 +11692,23 @@ ${claims(evidence)}`;
|
|
|
11640
11692
|
return answer;
|
|
11641
11693
|
}
|
|
11642
11694
|
async function request(path, data) {
|
|
11643
|
-
const response = await fetch(`${
|
|
11695
|
+
const response = await fetch(`${root}${path}`, {
|
|
11644
11696
|
credentials: "same-origin",
|
|
11645
11697
|
cache: "no-store",
|
|
11646
|
-
|
|
11647
|
-
|
|
11648
|
-
|
|
11649
|
-
|
|
11650
|
-
|
|
11698
|
+
// Says what is wanted back, whatever is sent. A header any page may send to another
|
|
11699
|
+
// origin without asking first, so a badge on a static site reads as it did.
|
|
11700
|
+
headers: {
|
|
11701
|
+
Accept: "application/json",
|
|
11702
|
+
...data ? { "Content-Type": "application/json" } : {}
|
|
11703
|
+
},
|
|
11704
|
+
...data ? { method: "POST", body: JSON.stringify(data) } : {}
|
|
11651
11705
|
});
|
|
11652
11706
|
if (!response.ok) throw new Error("Verily request unavailable");
|
|
11653
11707
|
return response.json();
|
|
11654
11708
|
}
|
|
11655
11709
|
const flows = {
|
|
11656
11710
|
async methods() {
|
|
11657
|
-
const data = await ask("
|
|
11711
|
+
const data = await ask(routePath("methods"));
|
|
11658
11712
|
if (!record(data) || !record(data.local) || !Array.isArray(data.methods))
|
|
11659
11713
|
throw new Error("Invalid methods response");
|
|
11660
11714
|
if (typeof data.local.profileUrl === "string") safeUrl(data.local.profileUrl);
|
|
@@ -11662,15 +11716,15 @@ ${claims(evidence)}`;
|
|
|
11662
11716
|
},
|
|
11663
11717
|
start: async (provider, method, renew) => flowView(
|
|
11664
11718
|
await ask(
|
|
11665
|
-
"
|
|
11719
|
+
routePath("start"),
|
|
11666
11720
|
renew ? { kind: "renew", connectionId: renew, provider, method } : { kind: "connect", provider, method }
|
|
11667
11721
|
)
|
|
11668
11722
|
),
|
|
11669
|
-
read: async (id) => flowView(await ask(
|
|
11670
|
-
submit: async (id, artifact) => flowView(await ask(
|
|
11723
|
+
read: async (id) => flowView(await ask(routePath("flow", id), void 0, id)),
|
|
11724
|
+
submit: async (id, artifact) => flowView(await ask(routePath("submit", id), { artifact }, id)),
|
|
11671
11725
|
async approve(id, visibility, cancel) {
|
|
11672
11726
|
const data = await ask(
|
|
11673
|
-
|
|
11727
|
+
routePath("approve", id),
|
|
11674
11728
|
{ action: cancel ? "cancel" : "approve", visibility },
|
|
11675
11729
|
id
|
|
11676
11730
|
);
|
|
@@ -11700,7 +11754,7 @@ ${claims(evidence)}`;
|
|
|
11700
11754
|
);
|
|
11701
11755
|
};
|
|
11702
11756
|
window.addEventListener("message", receive);
|
|
11703
|
-
popup.location.href = `${
|
|
11757
|
+
popup.location.href = `${root}/site/enter`;
|
|
11704
11758
|
}
|
|
11705
11759
|
} : {}
|
|
11706
11760
|
};
|
|
@@ -11724,7 +11778,7 @@ ${claims(evidence)}`;
|
|
|
11724
11778
|
pill.setAttribute("aria-haspopup", "dialog");
|
|
11725
11779
|
pill.onclick = async () => {
|
|
11726
11780
|
if (typeof HTMLDialogElement === "undefined" && !remote) {
|
|
11727
|
-
location.href = `${
|
|
11781
|
+
location.href = `${root}/verify`;
|
|
11728
11782
|
return;
|
|
11729
11783
|
}
|
|
11730
11784
|
const result = await client.openConnect(element);
|
|
@@ -11839,7 +11893,7 @@ ${claims(evidence)}`;
|
|
|
11839
11893
|
},
|
|
11840
11894
|
disconnect(id) {
|
|
11841
11895
|
if (remote) session = void 0;
|
|
11842
|
-
return ask(
|
|
11896
|
+
return ask(routePath("disconnect", id), {});
|
|
11843
11897
|
},
|
|
11844
11898
|
/**
|
|
11845
11899
|
* Says how the holder would have an account listed, or retires it. Names one record
|
|
@@ -11847,10 +11901,10 @@ ${claims(evidence)}`;
|
|
|
11847
11901
|
*/
|
|
11848
11902
|
mark(id, as2) {
|
|
11849
11903
|
if (remote) session = void 0;
|
|
11850
|
-
return ask(
|
|
11904
|
+
return ask(routePath("mark", id), { as: as2 });
|
|
11851
11905
|
},
|
|
11852
|
-
issueShare: (id) => request(
|
|
11853
|
-
revokeShare: (id) => request(
|
|
11906
|
+
issueShare: (id) => request(routePath("share", id), {}),
|
|
11907
|
+
revokeShare: (id) => request(routePath("shareRevoke", id), {})
|
|
11854
11908
|
};
|
|
11855
11909
|
return client;
|
|
11856
11910
|
}
|
|
@@ -11899,7 +11953,7 @@ ${claims(evidence)}`;
|
|
|
11899
11953
|
}
|
|
11900
11954
|
function validAttestation(attestation) {
|
|
11901
11955
|
if (!record(attestation)) return false;
|
|
11902
|
-
return ["backend", "provider"].includes(String(attestation.by)) && typeof attestation.method === "string" && typeof attestation.confirmedAt === "number" && Number.isFinite(attestation.confirmedAt) && (attestation.expect === void 0 || typeof attestation.expect === "string") && // Rendered as a link later, so only http(s) may ever reach an href.
|
|
11956
|
+
return ["backend", "provider"].includes(String(attestation.by)) && typeof attestation.method === "string" && typeof attestation.confirmedAt === "number" && Number.isFinite(attestation.confirmedAt) && (attestation.expect === void 0 || typeof attestation.expect === "string") && (attestation.dnssec === void 0 || typeof attestation.dnssec === "boolean") && // Rendered as a link later, so only http(s) may ever reach an href.
|
|
11903
11957
|
(attestation.artifactUrl === void 0 || httpUrl2(attestation.artifactUrl));
|
|
11904
11958
|
}
|
|
11905
11959
|
function httpUrl2(value) {
|
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED