--- import { type RevocationReason, toPK } from "@lib/pgp"; import type { Verification } from "@lib/pgp/verify"; import { defined, get } from "@utils/anonymous"; import type { getSigners } from "@lib/collection/helpers"; import type { PublicKey, UserIDPacket } from "openpgp"; import { createVerificationSummary, VerificationResult, } from "@lib/pgp/summary"; import Date from "@components/organisms/Date.astro"; interface Props { verifications: NonNullable; expectedSigners: Map< string, { signer: Awaited>[number]; users: UserIDPacket[]; key: PublicKey; } >; commitSignerKey?: string; } const { verifications: verificationsPromise, expectedSigners, commitSignerKey, } = Astro.props; let verifications = await Promise.all( verificationsPromise.map(async (verification) => { const { key, keyID, userID, verified } = verification; return { key: await key, keyID, userID: await userID, verified: await verified.catch(() => false), summary: await createVerificationSummary(verification), }; }), ); const expectedKeys = Array.from(expectedSigners.values()).map(get("key")); 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, summary }) => { const fingerprint = key ? toPK(key).getFingerprint() : undefined; const info = fingerprint ? expectedSigners.get(fingerprint) : undefined; const primary = userID?.[0]; const signer = info?.signer; let role = ""; switch (signer?.role) { case "author": { role = "Autor"; break; } case "co-author": { role = "Co-autor"; break; } case "translator": { role = "Tradutor"; break; } } const { reasons, created, expired, revoked, revocationReason, trusted, } = (summary[1].get(keyID.toHex()) ?? []).reduce( (acc, x) => { if (!("key" in x || "keyID" in x)) { return acc; } switch (x.result) { case VerificationResult.MISSING_KEY: acc.reasons.push(x.reason); acc.created = x.created ?? undefined; break; case VerificationResult.UNTRUSTED_KEY: acc.created = x.created ?? undefined; acc.trusted &&= false; break; case VerificationResult.TRUSTED_KEY: acc.created = x.created ?? undefined; acc.trusted = true; break; case VerificationResult .EXPIRATION_AFTER_SIGNATURE: acc.created = x.created ?? undefined; acc.expired = x.expired; break; case VerificationResult .EXPIRATION_BEFORE_SIGNATURE: acc.created = x.created ?? undefined; acc.expired = x.expired; break; case VerificationResult .REVOCATION_AFTER_SIGNATURE: acc.created = x.created ?? undefined; acc.revoked = x.revoked; acc.revocationReason = x.revocationReason; break; case VerificationResult .REVOCATION_BEFORE_SIGNATURE: acc.created = x.created ?? undefined; acc.revoked = x.revoked; acc.revocationReason = x.revocationReason; break; case VerificationResult.KEY_DOES_NOT_SIGN: break; } return acc; }, { reasons: [], created: undefined, expired: undefined, revoked: undefined, revocationReason: undefined, trusted: false, } as { reasons: Error[]; created?: Date; expired?: Date; revoked?: Date; revocationReason?: RevocationReason; trusted: boolean; }, ); 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, as suas chaves públicas e as suas assinaturas.

Assinante Função Fingerprint Válido Commiter Mais Informações
{signer !== undefined && <>
Ver perfil}
{role} { key ? "0x" + toPK(key).getKeyID().toHex() : "0x" + keyID.toHex() } {verified ? "✅" : "❌"} { commitSignerKey && key?.getFingerprint().toUpperCase()?.endsWith( commitSignerKey.toUpperCase(), ) && "✅" } { key && ( <>

Erros

{ summary[0].map((x) => { if (!("reason" in x)) { return undefined; } let reason = x.reason; return
{reason.message}
; }) }

Informações

{ reasons.map(({ message }) => ( <>
Erro
{message}
)) } { created && ( <>
Data da assinatura
) } { expired && ( <>
Data de expiração
) } { revoked && ( <>
Data de revogação
) } { revocationReason && ( <>
Razão para a revogação
{revocationReason.flag}: {revocationReason.msg}
) }
Chave confiável
{trusted ? "✅" : "❌"}
) }