generalpiston / typeorm-encrypted

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

Use embedded entities to define instead of a decorator #1

Closed generalpiston closed 4 years ago

generalpiston commented 6 years ago

typeorm has embedded entities (http://typeorm.io/#/embedded-entities) which allows for custom type definitions. If listeners can operate on embedded entities, this would negate the need for decorators and complicated field search code.

Example defintion:

import { Column, AfterLoad, BeforeInsert, BeforeUpdate } from "typeorm";

import { encryptData, decryptData } from "../transformers";
import { IEncryptedEntityOptions } from "./IEncryptedEntityOptions";

export class EncryptedEntity {
  options: IEncryptedEntityOptions;

  @Column({
    type: "varchar",
    nullable: false
  })
  data: string;

  EncryptedEntity(options: IEncryptedEntityOptions) {
    this.options = options;
  }

  @AfterLoad()
  decryptFields(): void {
    if (this.options.autoencrypt) {
      this.data = decryptData(this.data);
    }
  }

  @BeforeInsert()
  encryptFieldsBeforeInsert(): void {
    if (this.options.autoencrypt) {
      this.data = encryptData(this.data);
    }
  }

  @BeforeUpdate()
  encryptFieldsBeforeUpdate(): Promise<this> {
    if (this.options.autoencrypt) {
      this.data = encryptData(this.data);
    }
  }
}
generalpiston commented 6 years ago

It looks like embedded entities do not support listeners. They seem to make more sense with groups of fields rather than adding encapsulated functionality.

generalpiston commented 6 years ago

According to @pleerock:

support for listeners in embeds will be added in 0.1.6

pleerock commented 6 years ago

yeah I already implemented it, will publish new version today or tomorrow.

pleerock commented 6 years ago

btw few thoughts regarding this library design:

@Entity()
export class User extends EncryptedBaseEntity {
  ...
  @EncryptedColumn({
    key: "d85117047fd06d3afa79b6e44ee3a52eb426fc24c3a2e3667732e8da0342b4da",
    algorithm: "aes-256-cbc",
    ivLength: 16
  })
  @Column({
    type: "varchar",
    nullable: false
  })
  secret: string;
  ...
}

Also, its no a suggestion, just a hint most users don't know. You can override ColumnOptions properties and do it alternatively this way (it will be type-safe):

  @Column({
    type: "varchar",
    nullable: false,
    encrypt: {
        key: "d85117047fd06d3afa79b6e44ee3a52eb426fc24c3a2e3667732e8da0342b4da",
        algorithm: "aes-256-cbc",
        ivLength: 16
    }
  })
pleerock commented 6 years ago

its just my few cents, keep doing good job, I remember I had project needed such encryption feature a long time ago, we made an ugly solution, wish we had typeorm and this library those days.

generalpiston commented 6 years ago

Awesome! Thanks for the feedback @pleerock and getting 0.1.6 in so quickly!

pleerock commented 6 years ago

I was talking about a bit different design where users will not need to import anything from "typeorm-encrypted at all". Read here. Having to put ExtendedColumnOptions into @Column is not a good option for user imo.

generalpiston commented 6 years ago

@pleerock makes perfect sense. Will follow up at #11.

generalpiston commented 4 years ago

Less necessary with Transformers in #14 .