@bkazemi/verily 0.6.0 → 0.8.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.
Files changed (62) hide show
  1. package/README.md +197 -91
  2. package/dist/browser/connect-dialog.js +3 -4
  3. package/dist/browser/evidence-dialog.d.ts +7 -2
  4. package/dist/browser/evidence-dialog.js +62 -26
  5. package/dist/browser/index.js +3 -0
  6. package/dist/browser/mark.d.ts +2 -6
  7. package/dist/browser/mark.js +6 -12
  8. package/dist/browser/provider-mark.d.ts +3 -3
  9. package/dist/browser/provider-mark.js +15 -90
  10. package/dist/core/index.d.ts +78 -2
  11. package/dist/core/index.js +26 -2
  12. package/dist/instance/auth.d.ts +14 -0
  13. package/dist/instance/auth.js +80 -0
  14. package/dist/instance/bin.d.ts +2 -0
  15. package/dist/instance/bin.js +36 -0
  16. package/dist/instance/cloudflare.d.ts +57 -0
  17. package/dist/instance/cloudflare.js +71 -0
  18. package/dist/instance/env.d.ts +51 -0
  19. package/dist/instance/env.js +84 -0
  20. package/dist/instance/index.d.ts +136 -0
  21. package/dist/instance/index.js +777 -0
  22. package/dist/instance/init.d.ts +6 -0
  23. package/dist/instance/init.js +28 -0
  24. package/dist/instance/limits.d.ts +30 -0
  25. package/dist/instance/limits.js +45 -0
  26. package/dist/instance/node.d.ts +13 -0
  27. package/dist/instance/node.js +43 -0
  28. package/dist/instance/page.d.ts +18 -0
  29. package/dist/instance/page.js +30 -0
  30. package/dist/instance/postgres.d.ts +19 -0
  31. package/dist/instance/postgres.js +83 -0
  32. package/dist/instance/routes.d.ts +7 -0
  33. package/dist/instance/routes.js +22 -0
  34. package/dist/instance/serve.d.ts +31 -0
  35. package/dist/instance/serve.js +49 -0
  36. package/dist/instance/sites.d.ts +169 -0
  37. package/dist/instance/sites.js +413 -0
  38. package/dist/instance/starter.d.ts +6 -0
  39. package/dist/instance/starter.js +99 -0
  40. package/dist/instance/store.d.ts +20 -0
  41. package/dist/instance/store.js +11 -0
  42. package/dist/instance/undici.d.ts +8 -0
  43. package/dist/instance/undici.js +9 -0
  44. package/dist/marks.d.ts +44 -0
  45. package/dist/marks.js +98 -0
  46. package/dist/server/discord.js +3 -0
  47. package/dist/server/domain.js +37 -10
  48. package/dist/server/github-gist.js +16 -4
  49. package/dist/server/github.js +3 -0
  50. package/dist/server/index.js +20 -47
  51. package/dist/server/link.js +9 -4
  52. package/dist/server/render.d.ts +49 -0
  53. package/dist/server/render.js +104 -0
  54. package/dist/server/service.d.ts +44 -1
  55. package/dist/server/service.js +225 -19
  56. package/dist/server/style.d.ts +1 -1
  57. package/dist/server/style.js +132 -2
  58. package/dist/server/youtube.js +5 -0
  59. package/dist/verily.js +155 -124
  60. package/dist/version.d.ts +1 -1
  61. package/dist/version.js +1 -1
  62. package/package.json +30 -2
package/dist/verily.js CHANGED
@@ -9573,15 +9573,18 @@ var Verily = (() => {
9573
9573
  // src/browser.ts
9574
9574
  var browser_exports = {};
9575
9575
  __export(browser_exports, {
9576
+ Absent: () => Absent,
9576
9577
  Refused: () => Refused,
9577
9578
  accountsOf: () => accountsOf,
9578
9579
  attestationLabel: () => attestationLabel,
9579
9580
  dialogPath: () => dialogPath,
9580
9581
  dialogRoute: () => dialogRoute,
9582
+ expired: () => expired,
9581
9583
  externalId: () => externalId,
9582
9584
  externalIdGroups: () => externalIdGroups,
9583
9585
  externalLink: () => externalLink,
9584
9586
  externalName: () => externalName,
9587
+ externalSince: () => externalSince,
9585
9588
  fresh: () => fresh,
9586
9589
  freshnessMs: () => freshnessMs,
9587
9590
  init: () => init,
@@ -9624,9 +9627,9 @@ var Verily = (() => {
9624
9627
  async function read(signed) {
9625
9628
  if (typeof signed !== "string" || signed.length > maxSignedLength) return void 0;
9626
9629
  const text = signed.trim();
9627
- const lines2 = text.split(/\r?\n/);
9628
- const only = (line) => lines2.indexOf(line) === lines2.lastIndexOf(line);
9629
- if (lines2[0] !== "-----BEGIN PGP SIGNED MESSAGE-----" || lines2.at(-1) !== "-----END PGP SIGNATURE-----" || !lines2.includes("-----BEGIN PGP SIGNATURE-----") || ![lines2[0], lines2.at(-1), "-----BEGIN PGP SIGNATURE-----"].every(only))
9630
+ const lines = text.split(/\r?\n/);
9631
+ const only = (line) => lines.indexOf(line) === lines.lastIndexOf(line);
9632
+ if (lines[0] !== "-----BEGIN PGP SIGNED MESSAGE-----" || lines.at(-1) !== "-----END PGP SIGNATURE-----" || !lines.includes("-----BEGIN PGP SIGNATURE-----") || ![lines[0], lines.at(-1), "-----BEGIN PGP SIGNATURE-----"].every(only))
9630
9633
  return void 0;
9631
9634
  try {
9632
9635
  const { pgp, config } = await library();
@@ -9716,6 +9719,8 @@ var Verily = (() => {
9716
9719
  // src/core/index.ts
9717
9720
  var Refused = class extends Error {
9718
9721
  };
9722
+ var Absent = class extends Refused {
9723
+ };
9719
9724
  function isArtifactProvider(provider) {
9720
9725
  return "verify" in provider;
9721
9726
  }
@@ -9729,15 +9734,19 @@ var Verily = (() => {
9729
9734
  return provider.method ?? "oauth";
9730
9735
  }
9731
9736
  var freshnessMs = 7 * 864e5;
9737
+ function expired(record2, now) {
9738
+ return record2.expiresAt <= now;
9739
+ }
9732
9740
  function status(connection, now, freshness = freshnessMs) {
9733
9741
  if (connection.revokedAt !== void 0) return "revoked";
9734
9742
  if (connection.retiredAt !== void 0) return "retired";
9735
- if (now >= connection.expiresAt) return "expired";
9743
+ if (expired(connection, now)) return "expired";
9736
9744
  const main = connection.attestations?.external[0];
9737
9745
  if (main && !fresh(main, now, freshness)) return "unconfirmed";
9738
9746
  return "verified";
9739
9747
  }
9740
9748
  function fresh(attestation, now, freshness = freshnessMs) {
9749
+ if (attestation.absentAt !== void 0) return false;
9741
9750
  return !attestation.artifactUrl || attestation.hosted === true || freshness === Infinity || now < attestation.confirmedAt + freshness;
9742
9751
  }
9743
9752
  function lastProved(evidence) {
@@ -9747,7 +9756,7 @@ var Verily = (() => {
9747
9756
  function statusLabel(evidence, now) {
9748
9757
  if (evidence.status === "revoked") return "Revoked";
9749
9758
  if (evidence.status === "retired") return "Retired";
9750
- if (evidence.status === "expired" || evidence.expiresAt <= now) return "Expired";
9759
+ if (evidence.status === "expired" || expired(evidence, now)) return "Expired";
9751
9760
  return evidence.status === "unconfirmed" ? "Unconfirmed" : "Verified";
9752
9761
  }
9753
9762
  function place(account) {
@@ -9805,6 +9814,9 @@ var Verily = (() => {
9805
9814
  function externalIdGroups(external) {
9806
9815
  return external.kind === "key" ? external.id.match(/.{1,4}/g) ?? void 0 : void 0;
9807
9816
  }
9817
+ function externalSince(external, day) {
9818
+ return typeof external.createdAt === "number" && Number.isFinite(external.createdAt) ? `Joined ${day(external.createdAt)}` : void 0;
9819
+ }
9808
9820
  function externalLink(external) {
9809
9821
  return external.kind === "mailbox" ? void 0 : external.profileUrl;
9810
9822
  }
@@ -9813,12 +9825,75 @@ var Verily = (() => {
9813
9825
  return attestation.hosted ? where : `${where} | Last checked ${when(attestation.confirmedAt)}`;
9814
9826
  }
9815
9827
 
9816
- // src/browser/mark.ts
9828
+ // src/marks.ts
9829
+ var github = {
9830
+ viewBox: "0 0 16 16",
9831
+ paths: [
9832
+ "M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"
9833
+ ]
9834
+ };
9835
+ var discord = {
9836
+ viewBox: "0 0 24 24",
9837
+ paths: [
9838
+ "M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"
9839
+ ]
9840
+ };
9841
+ var youtube = {
9842
+ viewBox: "0 0 24 24",
9843
+ paths: [
9844
+ "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
9845
+ ]
9846
+ };
9847
+ var key = {
9848
+ viewBox: "0 0 16 16",
9849
+ stroke: true,
9850
+ paths: [
9851
+ "M7.4 8.6a3.3 3.3 0 1 0-4.7 4.7 3.3 3.3 0 0 0 4.7-4.7Z",
9852
+ "M7.4 8.6 14 2",
9853
+ "M11.2 4.8l1.6 1.6",
9854
+ "M9.4 6.6l1.6 1.6"
9855
+ ]
9856
+ };
9857
+ var globe = {
9858
+ viewBox: "0 0 16 16",
9859
+ stroke: true,
9860
+ paths: [
9861
+ "M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13Z",
9862
+ "M1.5 8h13",
9863
+ "M8 1.5C6.1 3.3 5.1 5.5 5.1 8s1 4.7 2.9 6.5",
9864
+ "M8 1.5c1.9 1.8 2.9 4 2.9 6.5s-1 4.7-2.9 6.5"
9865
+ ]
9866
+ };
9867
+ var envelope = {
9868
+ viewBox: "0 0 16 16",
9869
+ stroke: true,
9870
+ paths: ["M2 3.5h12v9H2z", "M2.4 4l5.6 4.6L13.6 4"]
9871
+ };
9872
+ var marks2 = { github, discord, youtube, openpgp: key, email: envelope };
9873
+ function markOf(provider, method) {
9874
+ return marks2[provider] ?? (["backlink", "dns", "wellknown"].includes(method ?? "") ? globe : void 0);
9875
+ }
9876
+ var pathAttributes = (mark) => mark.stroke ? [
9877
+ ["stroke", "currentColor"],
9878
+ ["stroke-width", "1.6"],
9879
+ ["stroke-linecap", "round"],
9880
+ ["stroke-linejoin", "round"]
9881
+ ] : [];
9817
9882
  var tones = {
9818
9883
  current: ["#D3444C", "#149766"],
9819
9884
  inactive: ["#149766", "#D3444C"],
9820
9885
  pending: ["currentColor", "currentColor"]
9821
9886
  };
9887
+ var verification = {
9888
+ viewBox: "-4 -4 264 264",
9889
+ /** The box around the strokes alone: the arms' squared ends and the mitred foot. */
9890
+ strokes: "25.6 29.1 204.8 228",
9891
+ path: "M40 36 128 220 216 36",
9892
+ /** The check's stretch of the V, as a dash along a path measured as 176 long. */
9893
+ check: { pathLength: "176", "stroke-dasharray": "108 176", "stroke-dashoffset": "-54" }
9894
+ };
9895
+
9896
+ // src/browser/mark.ts
9822
9897
  var markStyles = `
9823
9898
  @media (prefers-reduced-motion: no-preference) {
9824
9899
  .mark.current path:last-child { animation: verily-draw .8s cubic-bezier(.65, 0, .35, 1) .1s backwards; }
@@ -9834,20 +9909,18 @@ var Verily = (() => {
9834
9909
  function verificationMark(tone = "current") {
9835
9910
  const namespace2 = "http://www.w3.org/2000/svg";
9836
9911
  const svg = document.createElementNS(namespace2, "svg");
9837
- svg.setAttribute("viewBox", "-4 -4 264 264");
9912
+ svg.setAttribute("viewBox", verification.viewBox);
9838
9913
  svg.setAttribute("fill", "none");
9839
9914
  svg.setAttribute("aria-hidden", "true");
9840
9915
  svg.setAttribute("focusable", "false");
9841
9916
  for (const layer of [0, 1]) {
9842
9917
  const path = document.createElementNS(namespace2, "path");
9843
- path.setAttribute("d", "M40 36 128 220 216 36");
9918
+ path.setAttribute("d", verification.path);
9844
9919
  path.setAttribute("stroke-width", "32");
9845
9920
  path.setAttribute("stroke-linejoin", "miter");
9846
- if (layer === 1) {
9847
- path.setAttribute("pathLength", "176");
9848
- path.setAttribute("stroke-dasharray", "108 176");
9849
- path.setAttribute("stroke-dashoffset", "-54");
9850
- }
9921
+ if (layer === 1)
9922
+ for (const [name, value] of Object.entries(verification.check))
9923
+ path.setAttribute(name, value);
9851
9924
  svg.append(path);
9852
9925
  }
9853
9926
  paintMark(svg, tone);
@@ -9884,92 +9957,23 @@ var Verily = (() => {
9884
9957
 
9885
9958
  // src/browser/provider-mark.ts
9886
9959
  var namespace = "http://www.w3.org/2000/svg";
9887
- function mark() {
9960
+ function providerMark(provider, method) {
9961
+ const mark = markOf(provider, method);
9962
+ if (!mark) return void 0;
9888
9963
  const svg = document.createElementNS(namespace, "svg");
9889
- svg.setAttribute("viewBox", "0 0 16 16");
9964
+ svg.setAttribute("viewBox", mark.viewBox);
9890
9965
  svg.setAttribute("class", "provider");
9891
9966
  svg.setAttribute("aria-hidden", "true");
9892
9967
  svg.setAttribute("focusable", "false");
9893
- return svg;
9894
- }
9895
- function github() {
9896
- const svg = mark();
9897
- const path = document.createElementNS(namespace, "path");
9898
- svg.setAttribute("fill", "currentColor");
9899
- path.setAttribute(
9900
- "d",
9901
- "M6.766 11.328c-2.063-.25-3.516-1.734-3.516-3.656 0-.781.281-1.625.75-2.188-.203-.515-.172-1.609.063-2.062.625-.078 1.468.25 1.968.703.594-.187 1.219-.281 1.985-.281.765 0 1.39.094 1.953.265.484-.437 1.344-.765 1.969-.687.218.422.25 1.515.046 2.047.5.593.766 1.39.766 2.203 0 1.922-1.453 3.375-3.547 3.64.531.344.89 1.094.89 1.954v1.625c0 .468.391.734.86.547C13.781 14.359 16 11.53 16 8.03 16 3.61 12.406 0 7.984 0 3.563 0 0 3.61 0 8.031a7.88 7.88 0 0 0 5.172 7.422c.422.156.828-.125.828-.547v-1.25c-.219.094-.5.156-.75.156-1.031 0-1.64-.562-2.078-1.609-.172-.422-.36-.672-.719-.719-.187-.015-.25-.093-.25-.187 0-.188.313-.328.625-.328.453 0 .844.281 1.25.86.313.452.64.655 1.031.655s.641-.14 1-.5c.266-.265.47-.5.657-.656"
9902
- );
9903
- svg.append(path);
9904
- return svg;
9905
- }
9906
- function discord() {
9907
- const svg = mark();
9908
- const path = document.createElementNS(namespace, "path");
9909
- svg.setAttribute("viewBox", "0 0 24 24");
9910
- svg.setAttribute("fill", "currentColor");
9911
- path.setAttribute(
9912
- "d",
9913
- "M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z"
9914
- );
9915
- svg.append(path);
9916
- return svg;
9917
- }
9918
- function youtube() {
9919
- const svg = mark();
9920
- const path = document.createElementNS(namespace, "path");
9921
- svg.setAttribute("viewBox", "0 0 24 24");
9922
- svg.setAttribute("fill", "currentColor");
9923
- path.setAttribute(
9924
- "d",
9925
- "M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"
9926
- );
9927
- svg.append(path);
9928
- return svg;
9929
- }
9930
- function key() {
9931
- return lines([
9932
- "M7.4 8.6a3.3 3.3 0 1 0-4.7 4.7 3.3 3.3 0 0 0 4.7-4.7Z",
9933
- "M7.4 8.6 14 2",
9934
- "M11.2 4.8l1.6 1.6",
9935
- "M9.4 6.6l1.6 1.6"
9936
- ]);
9937
- }
9938
- function globe() {
9939
- return lines([
9940
- "M8 1.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13Z",
9941
- "M1.5 8h13",
9942
- "M8 1.5C6.1 3.3 5.1 5.5 5.1 8s1 4.7 2.9 6.5",
9943
- "M8 1.5c1.9 1.8 2.9 4 2.9 6.5s-1 4.7-2.9 6.5"
9944
- ]);
9945
- }
9946
- function envelope() {
9947
- return lines(["M2 3.5h12v9H2z", "M2.4 4l5.6 4.6L13.6 4"]);
9948
- }
9949
- function lines(paths) {
9950
- const svg = mark();
9951
- svg.setAttribute("fill", "none");
9952
- for (const d2 of paths) {
9968
+ svg.setAttribute("fill", mark.stroke ? "none" : "currentColor");
9969
+ for (const d2 of mark.paths) {
9953
9970
  const path = document.createElementNS(namespace, "path");
9954
9971
  path.setAttribute("d", d2);
9955
- path.setAttribute("stroke", "currentColor");
9956
- path.setAttribute("stroke-width", "1.6");
9957
- path.setAttribute("stroke-linecap", "round");
9958
- path.setAttribute("stroke-linejoin", "round");
9972
+ for (const [name, value] of pathAttributes(mark)) path.setAttribute(name, value);
9959
9973
  svg.append(path);
9960
9974
  }
9961
9975
  return svg;
9962
9976
  }
9963
- function providerMark(provider, method) {
9964
- const marks2 = {
9965
- github,
9966
- discord,
9967
- youtube,
9968
- openpgp: key,
9969
- email: envelope
9970
- };
9971
- return marks2[provider]?.() ?? (["backlink", "dns", "wellknown"].includes(method ?? "") ? globe() : void 0);
9972
- }
9973
9977
 
9974
9978
  // src/browser/badge.ts
9975
9979
  var styles = `
@@ -10122,8 +10126,8 @@ var Verily = (() => {
10122
10126
  }
10123
10127
  function renderBadgePending(element) {
10124
10128
  if (intact(element) && messages.get(element) === pendingKey) return;
10125
- const { pill, mark: mark2 } = frame(element, "pending");
10126
- paintMark(mark2, "pending");
10129
+ const { pill, mark } = frame(element, "pending");
10130
+ paintMark(mark, "pending");
10127
10131
  pill.setAttribute("role", "status");
10128
10132
  pill.setAttribute("aria-label", "Checking verification");
10129
10133
  const divider = span("divider", "");
@@ -10135,8 +10139,8 @@ var Verily = (() => {
10135
10139
  }
10136
10140
  function renderBadgeMessage(element, message) {
10137
10141
  if (intact(element) && messages.get(element) === message) return;
10138
- const { pill, mark: mark2 } = frame(element, "message");
10139
- paintMark(mark2, "inactive");
10142
+ const { pill, mark } = frame(element, "message");
10143
+ paintMark(mark, "inactive");
10140
10144
  pill.setAttribute("tabindex", "0");
10141
10145
  pill.setAttribute("role", "status");
10142
10146
  pill.setAttribute("aria-label", message);
@@ -10163,11 +10167,11 @@ var Verily = (() => {
10163
10167
  const key2 = renderKey(evidence, current, label, more, linked, rows, peek, href);
10164
10168
  if (intact(element) && shown.get(element) === key2) return null;
10165
10169
  const handle = externalName(evidence.external);
10166
- const { pill: badge, mark: mark2 } = frame(element, state, !linked);
10170
+ const { pill: badge, mark } = frame(element, state, !linked);
10167
10171
  const unnamed = Math.max(more - rows.length, 0);
10168
10172
  const named = rows.map((row) => `, ${row.providerName} ${externalName(row.external)}`).join("");
10169
10173
  const others = `${named}${unnamed ? ` and ${unnamed} more` : ""}`;
10170
- paintMark(mark2, current ? "current" : retired ? "pending" : "inactive");
10174
+ paintMark(mark, current ? "current" : retired ? "pending" : "inactive");
10171
10175
  if (linked) {
10172
10176
  badge.href = href;
10173
10177
  badge.rel = "noreferrer";
@@ -10304,9 +10308,9 @@ var Verily = (() => {
10304
10308
  panel.style.left = `${Math.max(edge, Math.min(at2.left, innerWidth - edge - size.width))}px`;
10305
10309
  }
10306
10310
  function renderConnectPill(element) {
10307
- const { pill, mark: mark2 } = frame(element, "connect");
10311
+ const { pill, mark } = frame(element, "connect");
10308
10312
  const button2 = pill;
10309
- paintMark(mark2, "pending");
10313
+ paintMark(mark, "pending");
10310
10314
  button2.type = "button";
10311
10315
  const divider = span("divider", "");
10312
10316
  divider.setAttribute("aria-hidden", "true");
@@ -10516,7 +10520,7 @@ ${claims(evidence)}`;
10516
10520
  }
10517
10521
 
10518
10522
  // src/version.ts
10519
- var version = "v0.6.0";
10523
+ var version = "v0.8.0";
10520
10524
 
10521
10525
  // src/browser/evidence-dialog.ts
10522
10526
  function stampLink() {
@@ -10554,9 +10558,12 @@ ${claims(evidence)}`;
10554
10558
  .spinner { width: 14px; height: 14px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: spin .7s linear infinite; }
10555
10559
  @keyframes spin { to { transform: rotate(360deg); } }
10556
10560
  @media (prefers-reduced-motion: reduce) { .spinner { animation: none; } }
10557
- .caution { display: inline-block; margin-left: 4px; color: #a15c00; cursor: help; vertical-align: -1.5px; }
10558
- .caution svg { display: block; width: 12px; height: 12px; }
10559
- .bad { color: #b3261e; font-weight: 650; text-decoration: underline dotted; text-underline-offset: 3px; cursor: help; }
10561
+ /* The "signed" pill after the verifier's name, one size smaller than the line it sits on. */
10562
+ .summary .signed { display: inline-block; margin-left: 5px; padding: 0 6px; border: 1px solid #cfdcd3; border-radius: 999px; font-size: 10px; font-weight: 550; line-height: 1.3; text-decoration: none; vertical-align: 1px; }
10563
+ .summary a.signed:hover { background: #f2f5f1; }
10564
+ .summary .signed.bad { border-color: #b3261e; color: #b3261e; font-weight: 650; cursor: help; }
10565
+ .caution { display: inline-block; margin-left: 3px; color: #a15c00; vertical-align: -1.5px; }
10566
+ .caution svg { display: block; width: 10px; height: 10px; }
10560
10567
  .account { padding: 14px 16px; border: 1px solid #e0e6df; border-radius: 10px; margin-top: 12px; }
10561
10568
  .account h3 { display: flex; align-items: center; gap: 6px; margin: 0 0 3px; color: #6b786f; font-size: 11px; font-weight: 550; }
10562
10569
  .account a, .account strong { font-weight: 650; font-size: 14px; }
@@ -10572,7 +10579,13 @@ ${claims(evidence)}`;
10572
10579
  .listing.preferred { border-color: #245f43; color: #245f43; }
10573
10580
  /* Quiet, as its pill is: the surface and the name step back, and the controls do not. */
10574
10581
  .account.retired { background: #f6f8f5; }
10575
- .account.retired > a, .account.retired > strong { color: #6b786f; }
10582
+ .account.retired > a, .account.retired > strong, .account.retired > .named > a, .account.retired > .named > strong { color: #6b786f; }
10583
+ /* The name, then a dot and the account's creation date. The date wraps under a long name. */
10584
+ /* Clipped 4px left of the text, which hides the dot when the date wraps to a new line. */
10585
+ .named { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 14px; margin-left: -4px; padding-left: 4px; overflow-x: clip; }
10586
+ .since { position: relative; white-space: nowrap; }
10587
+ /* The dot sits in the gap before the date. */
10588
+ .since::before { content: "\xB7"; position: absolute; left: -7px; transform: translateX(-50%); }
10576
10589
  .account.retired .mark { opacity: .45; }
10577
10590
  .group { margin: 20px 0 0; color: #6b786f; font-size: 11px; font-weight: 550; }
10578
10591
  summary.group { display: flex; align-items: center; gap: 4px; width: fit-content; border-radius: 4px; list-style: none; cursor: pointer; }
@@ -10714,12 +10727,34 @@ ${claims(evidence)}`;
10714
10727
  return new Date(time).toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" });
10715
10728
  }
10716
10729
  function accountCard(heading, name, reference, url, ...extra) {
10730
+ return side(heading, name, reference, url, void 0, extra);
10731
+ }
10732
+ function namedCard(heading, external, ...extra) {
10733
+ return side(
10734
+ heading,
10735
+ externalName(external),
10736
+ // A mailbox's address or a domain is its name already, so there is no second identifier.
10737
+ externalIdGroups(external) ?? externalId(external),
10738
+ externalLink(external),
10739
+ // In UTC, so the day matches the one the verifier's own pages print.
10740
+ externalSince(
10741
+ external,
10742
+ (time) => new Date(time).toLocaleDateString(void 0, { dateStyle: "medium", timeZone: "UTC" })
10743
+ ),
10744
+ extra
10745
+ );
10746
+ }
10747
+ function side(heading, name, reference, url, since, extra) {
10717
10748
  const card = node("section", "", "account");
10718
10749
  const title = node("h3");
10719
10750
  const value = node(url ? "a" : "strong", name);
10720
10751
  title.append(...heading);
10721
10752
  if (value instanceof HTMLAnchorElement) outward(value, url);
10722
- card.append(title, value);
10753
+ if (since) {
10754
+ const named = node("div", "", "named");
10755
+ named.append(value, node("span", since, "muted since"));
10756
+ card.append(title, named);
10757
+ } else card.append(title, value);
10723
10758
  if (typeof reference === "string") card.append(node("div", reference, "muted reference"));
10724
10759
  else if (reference) {
10725
10760
  const groups = node("div", "", "muted reference fingerprint");
@@ -10785,14 +10820,14 @@ ${claims(evidence)}`;
10785
10820
  return control;
10786
10821
  };
10787
10822
  const [named] = removable(evidence);
10788
- const { mark: mark2 } = manage;
10789
- const listable = mark2 !== void 0 && named !== void 0 && !["revoked", "retired"].includes(evidence.status);
10823
+ const { mark } = manage;
10824
+ const listable = mark !== void 0 && named !== void 0 && !["revoked", "retired"].includes(evidence.status);
10790
10825
  const list = (label, as2) => {
10791
10826
  const control = act(label);
10792
10827
  control.onclick = async () => {
10793
10828
  for (const other of row.children) other.disabled = true;
10794
10829
  try {
10795
- await mark2(named, as2);
10830
+ await mark(named, as2);
10796
10831
  } catch {
10797
10832
  offer("That did not go through.");
10798
10833
  }
@@ -10867,23 +10902,23 @@ ${claims(evidence)}`;
10867
10902
  );
10868
10903
  }
10869
10904
  function signedMark(evidence, later, warned) {
10870
- const mark2 = node("span");
10871
- const link = outward(node("a", "signed"), `${evidence.evidenceUrl}#signed`);
10905
+ const mark = node("span");
10906
+ const link = outward(node("a", "signed", "signed"), `${evidence.evidenceUrl}#signed`);
10872
10907
  const see = "See the signature (opens in a new tab)";
10873
10908
  const settle = (results) => {
10874
10909
  const first = results[0];
10875
10910
  if (results.some((result) => result.state === "invalid")) {
10876
- const warning = node("span", "invalid signature", "bad");
10911
+ const warning = node("span", "bad signature", "signed bad");
10877
10912
  warning.setAttribute("role", "alert");
10878
10913
  warning.title = `This record does not match the signature ${evidence.verifierName} put on it, so it may have been altered. Do not rely on it.`;
10879
- mark2.replaceChildren(document.createTextNode(" \xB7 "), warning);
10914
+ mark.replaceChildren(warning);
10880
10915
  warned();
10881
10916
  return;
10882
10917
  }
10883
10918
  if (first?.state === "valid" && results.every((result) => result.state === "valid")) {
10884
- link.textContent = "signed \u2713";
10919
+ link.textContent = "signed";
10885
10920
  link.title = `Signature checked in this browser against the keys ${new URL(evidence.evidenceUrl).host} publishes (key ${first.keyId}). ${see}`;
10886
- mark2.replaceChildren(document.createTextNode(" \xB7 "), link);
10921
+ mark.replaceChildren(link);
10887
10922
  return;
10888
10923
  }
10889
10924
  const why = results.find((result) => result.state === "unchecked");
@@ -10894,12 +10929,13 @@ ${claims(evidence)}`;
10894
10929
  caution.setAttribute("aria-label", reason);
10895
10930
  caution.append(cautionMark());
10896
10931
  link.textContent = "signed";
10932
+ link.append(caution);
10897
10933
  link.title = `${reason} ${see}`;
10898
- mark2.replaceChildren(document.createTextNode(" \xB7 "), link, caution);
10934
+ mark.replaceChildren(link);
10899
10935
  if (why) later(() => void signatures(evidence).then(settle));
10900
10936
  };
10901
10937
  void signatures(evidence).then(settle);
10902
- return mark2;
10938
+ return mark;
10903
10939
  }
10904
10940
  function cautionMark() {
10905
10941
  const namespace2 = "http://www.w3.org/2000/svg";
@@ -10981,14 +11017,11 @@ ${claims(evidence)}`;
10981
11017
  ];
10982
11018
  if (fold) bar.append(foldToggle([...methods, dates], fold), ...row);
10983
11019
  const logo2 = providerMark(evidence.provider, evidence.attestations.external[0].method);
10984
- const card = accountCard(
11020
+ const card = namedCard(
10985
11021
  // The mark and the name, or just the name. A mark that falls back to writing the name
10986
11022
  // would print it twice here, since this heading writes it either way.
10987
11023
  logo2 ? [logo2, document.createTextNode(provider)] : [document.createTextNode(provider)],
10988
- externalName(evidence.external),
10989
- // A mailbox's address or a domain is its name already, so there is no second identifier.
10990
- externalIdGroups(evidence.external) ?? externalId(evidence.external),
10991
- externalLink(evidence.external),
11024
+ evidence.external,
10992
11025
  // Status first, then how it was shown, then when. The proof explains the state
10993
11026
  // above it, so it cannot sit before that state has been given.
10994
11027
  summary,
@@ -11641,11 +11674,9 @@ ${record2.external.id}`;
11641
11674
  }
11642
11675
  function approve(flow) {
11643
11676
  const logo2 = providerMark(flow.provider.id, flow.provider.method);
11644
- const external = accountCard(
11677
+ const external = namedCard(
11645
11678
  logo2 ? [logo2, document.createTextNode(flow.provider.name)] : [document.createTextNode(flow.provider.name)],
11646
- externalName(flow.external),
11647
- externalIdGroups(flow.external) ?? externalId(flow.external),
11648
- externalLink(flow.external)
11679
+ flow.external
11649
11680
  );
11650
11681
  const parts = [subjectCard(flow.local), linkMark(), external];
11651
11682
  const choice = node("fieldset");
@@ -12192,7 +12223,7 @@ ${record2.external.id}`;
12192
12223
  (k2) => typeof value.local[k2] === "string"
12193
12224
  ) && ["id", "handle", "profileUrl"].every(
12194
12225
  (k2) => typeof value.external[k2] === "string"
12195
- ) && (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
12226
+ ) && (value.local.profileUrl === void 0 || typeof value.local.profileUrl === "string") && (value.external.createdAt === void 0 || typeof value.external.createdAt === "number" && Number.isFinite(value.external.createdAt)) && // A signed record lives beside the record it was made from and nowhere else, since the
12196
12227
  // keys it is checked against are read from where the record lives.
12197
12228
  (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", "domain"].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.
12198
12229
  (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(
package/dist/version.d.ts CHANGED
@@ -7,4 +7,4 @@
7
7
  * output stays what tsc emitted and nothing has to be substituted into it. A version bump
8
8
  * changes this line with package.json.
9
9
  */
10
- export declare const version = "v0.6.0";
10
+ export declare const version = "v0.8.0";
package/dist/version.js CHANGED
@@ -7,4 +7,4 @@
7
7
  * output stays what tsc emitted and nothing has to be substituted into it. A version bump
8
8
  * changes this line with package.json.
9
9
  */
10
- export const version = 'v0.6.0';
10
+ export const version = 'v0.8.0';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bkazemi/verily",
3
- "version": "0.6.0",
3
+ "version": "0.8.0",
4
4
  "description": "Self-hosted account-to-account verification for Node.js",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,8 @@
30
30
  "preview": "npm run build && tsx example/preview.ts",
31
31
  "cloudflare:dev": "wrangler dev --local",
32
32
  "cloudflare:check": "wrangler deploy --dry-run --outdir .wrangler/build",
33
- "cloudflare:deploy": "wrangler deploy"
33
+ "starter:check": "rm -rf .wrangler/starter && node dist/instance/bin.js init cloudflare .wrangler/starter && wrangler deploy --dry-run --config .wrangler/starter/wrangler.jsonc --outdir .wrangler/starter-build",
34
+ "release:deploy": "wrangler deploy"
34
35
  },
35
36
  "devDependencies": {
36
37
  "@cloudflare/workers-types": "^5.20260915.1",
@@ -62,6 +63,9 @@
62
63
  "dist",
63
64
  "docs/licenses"
64
65
  ],
66
+ "bin": {
67
+ "verily": "./dist/instance/bin.js"
68
+ },
65
69
  "exports": {
66
70
  ".": {
67
71
  "browser": {
@@ -81,6 +85,30 @@
81
85
  "types": "./dist/site/index.d.ts",
82
86
  "default": "./dist/site/index.js"
83
87
  },
88
+ "./instance": {
89
+ "types": "./dist/instance/index.d.ts",
90
+ "default": "./dist/instance/index.js"
91
+ },
92
+ "./instance/node": {
93
+ "types": "./dist/instance/node.d.ts",
94
+ "default": "./dist/instance/node.js"
95
+ },
96
+ "./instance/postgres": {
97
+ "types": "./dist/instance/postgres.d.ts",
98
+ "default": "./dist/instance/postgres.js"
99
+ },
100
+ "./instance/serve": {
101
+ "types": "./dist/instance/serve.d.ts",
102
+ "default": "./dist/instance/serve.js"
103
+ },
104
+ "./instance/cloudflare": {
105
+ "types": "./dist/instance/cloudflare.d.ts",
106
+ "default": "./dist/instance/cloudflare.js"
107
+ },
108
+ "./instance/undici": {
109
+ "types": "./dist/instance/undici.d.ts",
110
+ "default": "./dist/instance/undici.js"
111
+ },
84
112
  "./verily.js": "./dist/verily.js"
85
113
  }
86
114
  }