generalpiston / typeorm-encrypted

Encrypted field for typeorm.
MIT License
75 stars 19 forks source link

json supprot #52

Closed ryraj closed 2 years ago

ryraj commented 2 years ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch typeorm-encrypted@0.6.0 for the project I'm working on.

Here is the diff that solved my problem:

diff --git a/node_modules/typeorm-encrypted/src/transformer.ts b/node_modules/typeorm-encrypted/src/transformer.ts
index ec5d1c8..f4e4d63 100644
--- a/node_modules/typeorm-encrypted/src/transformer.ts
+++ b/node_modules/typeorm-encrypted/src/transformer.ts
@@ -5,7 +5,7 @@ import { decryptData, encryptData } from './crypto';
 export class EncryptionTransformer implements ValueTransformer {
   constructor(private options: EncryptionOptions) {}

-  public from(value?: string | null): string | undefined {
+  public from(value?: string | null | object): string | undefined {
     if (!value) {
       return;
     }
@@ -55,3 +55,60 @@ export class EncryptionTransformer implements ValueTransformer {
     }
   }
 }
+export class JSONEncryptionTransformer implements ValueTransformer {
+  constructor(private options: EncryptionOptions) {}
+
+  public from(value?: string | null | object): string | undefined {
+    if (!value) {
+      return;
+    }
+
+    const decrypted = decryptData(
+      Buffer.from(value as string, 'base64'),
+      this.options
+    ).toString('utf8');
+
+    return JSON.parse(decrypted);
+  }
+
+  public to(value?: any | FindOperator<any> | null): string | FindOperator<any> | undefined{
+    if ((value ?? null) === null) {
+      return;
+    }
+
+    if (typeof value === 'object' && !value.type) {
+      return encryptData(
+        Buffer.from(JSON.stringify(value) as string, 'utf8'),
+        this.options
+      ).toString('base64');
+    }
+
+    if (!value) {
+      return;
+    }
+    // Support FindOperator.
+    // Just support "Equal", "In", "Not", and "IsNull".
+    // Other operators aren't work correctly, because values are encrypted on the db.
+    if (value.type === `in`) {
+      return In((value.value as string[]).map(s =>
+        encryptData(
+          Buffer.from(s, 'utf-8'),
+          this.options
+        ).toString('base64')
+      ));
+    } else if (value.type === 'equal') {
+      return Equal(encryptData(
+        Buffer.from(value.value as string, 'utf-8'),
+        this.options
+      ).toString('base64'));
+    } else if (value.type === 'not') {
+      return Not(
+        this.to(value.child ?? value.value)
+      );
+    } else if (value.type === 'isNull') {
+      return value
+    } else {
+      throw new Error('Only "Equal","In", "Not", and "IsNull" are supported for FindOperator');
+    }
+  }
+}

This issue body was partially generated by patch-package.

generalpiston commented 2 years ago

Merged https://github.com/generalpiston/typeorm-encrypted/pull/45 which adds support for JSON.