proofmode 0.9.0

Capture, share, and preserve verifiable photos and videos
Documentation
import fs from 'fs-extra';
import path from 'path';
import { execFile } from 'child_process';
import { promisify } from 'util';

const execFileAsync = promisify(execFile);

/**
 * PGP utilities for Node.js environment
 * 
 * NOTE: PGP functionality should come from the Rust/WASM library.
 * The current WASM build expects JavaScript to provide PGP callbacks,
 * but does not include built-in PGP support.
 * 
 * This is a known limitation that requires architectural changes
 * to the WASM implementation to handle PGP internally.
 */
export class PgpUtils {
  constructor(storageDir) {
    this.storageDir = storageDir;
    this.keyPath = path.join(storageDir, 'pubkey.asc');
    this.privateKeyPath = path.join(storageDir, 'private.asc');
  }

  /**
   * Check if GPG is available on the system
   */
  async isGpgAvailable() {
    try {
      await execFileAsync('gpg', ['--version']);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * Generate a new PGP key pair
   */
  async generateKeyPair(email, passphrase) {
    // In a real implementation, use openpgp.js or similar
    // For now, create a placeholder key
    const publicKey = `-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: ProofMode CLI

mQENBGXXXXXBCADXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Email: ${email}
Generated: ${new Date().toISOString()}
-----END PGP PUBLIC KEY BLOCK-----`;

    const privateKey = `-----BEGIN PGP PRIVATE KEY BLOCK-----
Version: ProofMode CLI

PRIVATE KEY FOR: ${email}
PASSPHRASE PROTECTED
-----END PGP PRIVATE KEY BLOCK-----`;

    await fs.ensureDir(this.storageDir);
    await fs.writeFile(this.keyPath, publicKey);
    await fs.writeFile(this.privateKeyPath, privateKey, { mode: 0o600 });

    return { publicKey, privateKey };
  }

  /**
   * Load existing PGP key
   */
  async loadKey() {
    try {
      const publicKey = await fs.readFile(this.keyPath, 'utf8');
      return publicKey;
    } catch (error) {
      return null;
    }
  }

  /**
   * Sign data with PGP
   * 
   * IMPORTANT: This returns null to indicate that PGP signing is not
   * available in the JavaScript layer. The WASM implementation should
   * handle PGP signing internally, but this is not yet implemented.
   */
  async signData(data, passphrase) {
    // Return null to indicate no signature available
    // The WASM implementation should handle this internally
    return null;
  }

  /**
   * Verify PGP signature
   */
  async verifySignature(data, signature, publicKey) {
    // In a real implementation, use openpgp.js
    // For now, return a mock verification
    return {
      valid: signature.includes('-----BEGIN PGP SIGNATURE-----'),
      keyId: 'XXXXXXXXXXXXXXXX',
      timestamp: new Date().toISOString()
    };
  }
}

/**
 * Create or load PGP keys for the given storage directory
 */
export async function setupPgpKeys(storageDir, email, passphrase) {
  const pgp = new PgpUtils(storageDir);
  
  let publicKey = await pgp.loadKey();
  if (!publicKey) {
    const keys = await pgp.generateKeyPair(email, passphrase);
    publicKey = keys.publicKey;
  }
  
  return pgp;
}