File size: 2,159 Bytes
37fb9ce
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/**
 * Diagnostic: vérifie si l'ENCRYPTION_SECRET actuel peut déchiffrer les secrets en DB.
 *
 * Usage:
 *   ENCRYPTION_SECRET=<ta_cle_railway> DATABASE_URL=<prod_url> \
 *     npx ts-node apps/api/scratch/check_encryption.ts
 */

import 'dotenv/config';
import { PrismaClient } from '@prisma/client';
import crypto from 'crypto';

const prisma = new PrismaClient();
const SECRET = process.env.ENCRYPTION_SECRET || '';

if (SECRET.length < 32) {
    console.error('❌ ENCRYPTION_SECRET manquant ou trop court (min 32 chars)');
    process.exit(1);
}

function tryDecrypt(value: string): { ok: boolean; result: string } {
    if (!value.startsWith('enc:')) return { ok: true, result: `[PLAINTEXT] ${value.slice(0, 20)}...` };
    const [, ivHex, encHex] = value.split(':');
    if (!ivHex || !encHex) return { ok: false, result: 'Format invalide' };
    try {
        const iv = Buffer.from(ivHex, 'hex');
        const enc = Buffer.from(encHex, 'hex');
        const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(SECRET.slice(0, 32)), iv);
        let dec = decipher.update(enc);
        dec = Buffer.concat([dec, decipher.final()]);
        const plain = dec.toString();
        return { ok: true, result: `${plain.slice(0, 6)}...${plain.slice(-4)} (len=${plain.length})` };
    } catch (err: any) {
        return { ok: false, result: err.message };
    }
}

const FIELDS = ['systemUserToken', 'webhookSecret', 'openAiApiKey', 'googleAiApiKey'] as const;

async function check() {
    const orgs = await prisma.organization.findMany({
        select: { id: true, name: true, systemUserToken: true, webhookSecret: true, openAiApiKey: true, googleAiApiKey: true }
    });

    for (const org of orgs) {
        console.log(`\n📦 Org: ${org.name} (${org.id})`);
        for (const field of FIELDS) {
            const val = (org as any)[field] as string | null;
            if (!val) { console.log(`  ${field}: (vide)`); continue; }
            const { ok, result } = tryDecrypt(val);
            console.log(`  ${ok ? '✅' : '❌'} ${field}: ${result}`);
        }
    }
    await prisma.$disconnect();
}

check().catch(console.error);