// Pass L / D1: read latest messages in couples/{COUPLE}/conversations/main/messages. // Print ONLY metadata + enc-status (never decrypted/plaintext content). Also assert a plaintext // marker does NOT appear anywhere (at-rest leak check). const admin = require('firebase-admin') const path = require('path') const fs = require('fs') const SA = path.join(__dirname, '..', 'closer-app-22014-firebase-adminsdk-fbsvc-ed20bf6003.json') const COUPLE = process.env.COUPLE_ID || 'Xal3Kw3gjSdn0niERYKJ' const MARKER = (fs.existsSync(path.join(__dirname,'last_marker.txt')) ? fs.readFileSync(path.join(__dirname,'last_marker.txt'),'utf8').trim() : '') admin.initializeApp({ credential: admin.credential.cert(require(SA)) }) const db = admin.firestore() const CIPHER = /^(enc:v1:|sealed:v1:)/ const enc = v => typeof v==='string' ? (CIPHER.test(v)?`enc✓(${v.length})`:`RAW?(${v.length})`) : typeof v ;(async () => { const col = db.collection('couples').doc(COUPLE).collection('conversations').doc('main').collection('messages') const snap = await col.orderBy('createdAt','desc').limit(6).get() console.log(`marker=${MARKER||'(none)'} latest ${snap.size} messages (newest first):`) let leak = false snap.forEach(d => { const m = d.data() const ts = m.createdAt && m.createdAt.toDate ? m.createdAt.toDate().toISOString() : m.createdAt console.log(` ${ts} sender=${(m.senderId||'').slice(0,6)}… text=${enc(m.text)}`) // leak check across the whole doc JSON if (MARKER) { const blob = JSON.stringify(m); if (blob.includes(MARKER)) { leak = true; console.log(' ❌❌ PLAINTEXT MARKER LEAK in this doc') } } }) if (MARKER) console.log(leak ? '=== LEAK: marker found in plaintext ===' : '=== OK: marker NOT present in plaintext (encrypted or not yet sent) ===') process.exit(0) })().catch(e=>{console.error('FATAL',e.message);process.exit(1)})