--- 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; expectedSigners: Awaited>; commitSignerKey?: string; } const { verifications: verificationsPromise, expectedSigners, commitSignerKey, } = Astro.props; const fingerprintToData = new Map< string, { websites: URL[]; role: z.infer } >(); 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(), ]}`, ); } ---
{ 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 ( ); }) }
Assinaturas

Para verificar uma assinatura é necessário a mensagem, a assinatura digital e as chaves públicas dos assinantes. Esta tabela mostra algumas informações sobre os assinantes e as suas chaves públicas.

Assinante Função Fingerprint Válido Commiter
{role} <>{ key ? "0x" + toPK(key).getKeyID().toHex() : "0x" + keyID.toHex() } { key && false && ( ) } { key && (
{toPK(key).armor()}
) }
{verified ? "✅" : "❌"} { commitSignerKey && key?.getFingerprint().toUpperCase()?.endsWith( commitSignerKey.toUpperCase(), ) && "✅" }