diff options
Diffstat (limited to 'src/components/signature/Authors.astro')
-rw-r--r-- | src/components/signature/Authors.astro | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/src/components/signature/Authors.astro b/src/components/signature/Authors.astro deleted file mode 100644 index 4e52d4e..0000000 --- a/src/components/signature/Authors.astro +++ /dev/null @@ -1,275 +0,0 @@ ---- -import { toPK } from "@lib/pgp"; -import { createKeyFromArmor } from "@lib/pgp/create"; -import type { Verification } from "@lib/pgp/verify"; -import { defined, get, instanciate } from "@utils/anonymous"; -import { z } from "astro:content"; -import type { EntityTypesEnum } from "src/consts"; -import qrcode from "yaqrcode"; -import type { getSigners } from "@lib/collection/helpers"; - -interface Props { - verifications: NonNullable<Verification["verifications"]>; - expectedSigners: Awaited<ReturnType<typeof getSigners>>; - commitSignerKey?: string; -} - -const { - verifications: verificationsPromise, - expectedSigners, - commitSignerKey, -} = Astro.props; - -const fingerprintToData = new Map< - string, - { websites: URL[]; role: z.infer<typeof EntityTypesEnum> } ->(); - -for (const { entity, role } of expectedSigners) { - const key = await createKeyFromArmor(entity.data.publickey.armor); - const fingerprint = key.getFingerprint(); - fingerprintToData.set(fingerprint, { - websites: entity.data.websites?.map(instanciate(URL)) ?? [], - role, - }); -} - -let verifications = await Promise.all( - verificationsPromise.map(async ({ key, keyID, userID, verified }) => { - return { - key: await key, - keyID, - userID: await userID, - verified: await verified.catch(() => false), - }; - }), -); - -const expectedKeys = await Promise.all( - expectedSigners.map(get("entity")).map(({ data }) => - createKeyFromArmor(data.publickey.armor) - ), -); - -const expectedFingerprints = new Set( - expectedKeys.map((key) => key.getFingerprint()), -); - -const verifiedFingerprints = new Set( - verifications.map((v) => v.key).filter(defined).map(toPK).map((key) => - key.getFingerprint() - ), -); - -if (!expectedFingerprints.isSubsetOf(verifiedFingerprints)) { - throw new Error( - `Missing signature from expected signers: ${[ - ...expectedFingerprints.difference(verifiedFingerprints).values(), - ]}`, - ); -} ---- - -<div> - <table> - <caption> - <strong>Assinaturas</strong> - <p> - Para verificar uma assinatura é necessário a <a href="#message" - >mensagem</a>, a <a href="#signature">assinatura digital</a> e as <em - >chaves públicas</em> dos assinantes. Esta tabela mostra algumas - informações sobre os assinantes e as suas chaves públicas. - </p> - </caption> - <colgroup> - <col /> - <col /> - </colgroup> - <colgroup> - <col /> - <col /> - <col /> - </colgroup> - <thead> - <tr> - <th scope="col">Assinante</th> - <th scope="col">Função</th> - <th scope="col">Fingerprint</th> - <th scope="col">Válido</th> - <th scope="col">Commiter</th> - </tr> - </thead> - <tbody> - { - verifications.map(({ userID, key, keyID, verified }) => { - const fingerprint = key - ? toPK(key).getFingerprint() - : undefined; - const info = fingerprint - ? fingerprintToData.get(fingerprint) - : undefined; - const primary = userID?.[0]; - let role = ""; - switch (info?.role) { - case "author": { - role = "Autor"; - break; - } - case "co-author": { - role = "Co-autor"; - break; - } - case "translator": { - role = "Tradutor"; - break; - } - } - return ( - <tr> - <th scope="row"> - <address - itemprop="author" - itemscope - itemtype="https://schema.org/Person" - > - { - primary?.name - ? info?.websites[0] ? ( - <a - itemprop="url" - rel="author external noreferrer" - target="_blank" - href={info.websites[0]} - ><span itemprop="name">{primary.name}</span></a> - ) : <span itemprop="name">{primary.name}</span> - : primary?.email - ? ( - <><<a - itemprop="email" - rel="author external noreferrer" - target="_blank" - href={primary?.email && `mailto:${primary.email}`} - >{primary?.email}</a>></> - ) - : "" - } - { - primary && ( - <> - <button - popovertarget={`user-id-${fingerprint}`} - class="emoji" - > - ➕ - </button> - <section - class="user-id" - popover - id={`user-id-${fingerprint}`} - > - { - userID && ( - <><p><code>UserID</code>s</p><ul> - {userID.map((x) => <li>{x.userID}</li>)} - </ul></> - ) - } - { - info?.websites && ( - <><p>Websites</p><ul> - { - info.websites.map(( - x, - ) => <li><a href={x}>{x}</a></li>) - } - </ul></> - ) - } - </section> - </> - ) - } - </address> - </th> - <td>{role}</td> - <td> - <><span title={fingerprint?.replace(/(....)/g, "$1 ")}>{ - key - ? "0x" + toPK(key).getKeyID().toHex() - : "0x" + keyID.toHex() - }</span> - { - key && false && ( - <img - src={qrcode(toPK(key).armor(), { - typeNumber: 40, - errorCorrectLevel: "L", - })} - /> - ) - } - { - key && - ( - <button popovertarget={`armor-${fingerprint}`}> - Armor - </button> - <section class="armor" popover id={`armor-${fingerprint}`}> - <pre><code>{toPK(key).armor()}</code></pre> - </section> - ) - } - </> - </td> - <td>{verified ? "✅" : "❌"}</td> - <td> - { - commitSignerKey && - key?.getFingerprint().toUpperCase()?.endsWith( - commitSignerKey.toUpperCase(), - ) && "✅" - } - </td> - </tr> - ); - }) - } - </tbody> - </table> -</div> - -<style> - div { - overflow-x: auto; - } - - table { - table-layout: fixed; - border-collapse: collapse; - border: 3px solid; - margin-inline: auto; - max-width: 90svw; - } - - th, - td { - padding: 1rem; - text-align: center; - } - - tbody tr:nth-child(odd) { - background-color: #e7e7e7; - } - - section[popover] { - text-align: initial; - } - section[popover].armor { - max-height: calc(200dvh / 3); - } - @media (prefers-color-scheme: dark) { - tbody tr:nth-child(odd) { - background-color: #181818; - } - } -</style> |