Back to Body Journal
SOURCE / PINNED RELEASE

Made of little things.

Body Journal

Release
e8049f8da4e2…
Author-recorded commit
61c04bf0e8aa…
License
LICENSE
Author’s source reference
nostr://npub182jczunncwe0jn6frpqwq3e0qjws7yqqnc3auccqv9nte2dnd63scjm4rf/wss%3A%2F%2Fgit.napplet.soy%2F/n-6c4554844c7

Archive hash verified: 4369d778da046a8b…. The source-to-build association is the author’s claim; it has not been independently rebuilt.

src/identity-backup.ts
import QRCode from 'qrcode';
import { privateText, publicKey } from './report-identity.js';
/** One-page, entirely local PDF. Vector QR keeps the recovery key legible in print. */
export function recoveryPdf(key: Uint8Array, service: string): Uint8Array {
  if (!/^[a-f0-9]{64}$/.test(service)) throw new Error('Invalid recovery service.');
  const secret = privateText(key), pubkey = publicKey(key), qr = QRCode.create(secret, { errorCorrectionLevel: 'M' }).modules;
  const cmds: string[] = ['0.08 0.19 0.17 rg', '0 735 595 107 re f'];
  const label = (text: string, x: number, y: number, size = 12, color = '0.08 0.19 0.17') => cmds.push(`${color} rg BT /F1 ${size} Tf ${x} ${y} Td (${text.replace(/[\\()]/g,'\\$&')}) Tj ET`);
  label('AI DOC / PRIVATE RECOVERY KEY',42,790,20,'1 1 1');
  label('Keep offline. Anyone with this key can access your reports.',42,758,11,'1 1 1');
  const cell = 5, edge = (qr.size+8)*cell, x = (595-edge)/2, y = 410;
  cmds.push('0 0 0 rg');
  for(let row=0;row<qr.size;row++) for(let col=0;col<qr.size;col++) if(qr.get(row,col)) cmds.push(`${x+(col+4)*cell} ${y+(qr.size+3-row)*cell} ${cell} ${cell} re f`);
  label('Recovery key (nsec)',42,389,13);
  label(secret,42,365,9);
  label('Public identity',42,325,13);label(pubkey,42,302,9);
  label('Report service public key',42,262,13);label(service,42,239,9);
  label('Restore in AI Doc: Paid report service > Restore identity.',42,188,12);
  label('Scan the QR image or paste the private key. Never send it to support.',42,165,11);
  label('One identity can own many reports. This is not your shell login.',42,132,11);
  label('The key restores retained reports, not deleted reports or unsaved drafts.',42,109,11);
  label('Recovery format 1. No medical information is included in this backup.',42,62,10);
  const stream=cmds.join('\n');
  const objects = ['<< /Type /Catalog /Pages 2 0 R >>','<< /Type /Pages /Kids [3 0 R] /Count 1 >>','<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 4 0 R >> >> /Contents 5 0 R >>','<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>',`<< /Length ${stream.length} >>\nstream\n${stream}\nendstream`];
  let pdf='%PDF-1.4\n';const offsets=[0];
  objects.forEach((o,i)=>{offsets.push(pdf.length);pdf+=`${i+1} 0 obj\n${o}\nendobj\n`;});
  const start=pdf.length; pdf+=`xref\n0 6\n0000000000 65535 f \n${offsets.slice(1).map(n=>n.toString().padStart(10,'0')+' 00000 n \n').join('')}trailer\n<< /Size 6 /Root 1 0 R >>\nstartxref\n${start}\n%%EOF\n`;
  return new TextEncoder().encode(pdf);
}