Files
memegoat/backend/src/database/schemas/pgp.ts
Mathis HERRIOT 40cfff683d fix: ensure decrypted PGP values are cast to text in SQL queries
- Added `::text` cast to `pgp_sym_decrypt` function calls for consistent data type handling.
2026-01-29 17:44:50 +01:00

68 lines
2.2 KiB
TypeScript

import { SQL, sql } from "drizzle-orm";
import { AnyPgColumn, customType } from "drizzle-orm/pg-core";
// Clé de chiffrement PGP récupérée depuis l'environnement
const getPgpKey = () => process.env.PGP_ENCRYPTION_KEY || "default-pgp-key";
/**
* Type personnalisé pour les données chiffrées PGP (stockées en bytea dans Postgres).
* Le chiffrement est géré automatiquement à l'écriture (INSERT/UPDATE) via `toDriver`.
*
* **Pour que le déchiffrement soit automatique à la lecture (SELECT), il faut impérativement utiliser l'utilitaire
* `withAutomaticPgpDecrypt` sur la colonne après la définition de la table. Attention à la consommation CPU et mémoire**
*
* @example
* ```ts
* export const users = pgTable('users', {
* email: pgpEncrypted('email').notNull(),
* });
*
* // Activation du déchiffrement automatique
* withAutomaticPgpDecrypt(users.email);
* ```
*/
export const pgpEncrypted = customType<{ data: string; driverData: Buffer }>({
dataType() {
return "bytea";
},
toDriver(value: string): SQL {
return sql`pgp_sym_encrypt(${value}, ${getPgpKey()})`;
},
fromDriver(value: Buffer | string): string {
if (typeof value === "string") return value;
return value.toString();
},
});
/**
* Utilitaire pour injecter le déchiffrement automatique dans une colonne.
* Modifie la méthode getSQL de la colonne pour inclure pgp_sym_decrypt.
*/
export function withAutomaticPgpDecrypt<T extends AnyPgColumn>(column: T): T {
const originalGetSQL = column.getSQL.bind(column);
column.getSQL = () =>
sql`pgp_sym_decrypt(${originalGetSQL()}, ${getPgpKey()})::text`.mapWith(
column,
);
return column;
}
/**
* @deprecated Utiliser directement les colonnes de type pgpEncrypted qui gèrent maintenant le chiffrement automatiquement.
*/
export function pgpSymEncrypt(value: string | SQL, key: string | SQL) {
return sql`pgp_sym_encrypt(${value}, ${key})`;
}
/**
* @deprecated Utiliser directement les colonnes de type pgpEncrypted qui gèrent maintenant le déchiffrement automatiquement.
*/
export function pgpSymDecrypt(
column: AnyPgColumn,
key: string | SQL,
): SQL<string> {
return sql`pgp_sym_decrypt(${column}, ${key})::text`.mapWith(
column,
) as SQL<string>;
}