1
votes

Let's have simplified TypeORM entity User:

@Entity()
export class User extends BaseDatabaseEntity {
  @Column({
    length: 255,
  })
  public firstName!: string;

  @Column({ length: 60 })
  @Exclude()
  public password: string;

  @BeforeUpdate()
  @BeforeInsert()
  private hashPassword(): void {
    const tmpPassword = hashSync(
      this.password + 'config.auth.password.secret',
      genSaltSync(),
    );
    this.password = tmpPassword;
  }
}

}

I need to replace config.auth.password.secret with NestJS's config (namespace from ConfigService):

export default registerAs('app', () => {
   return {
    password: {
      secret: process.env.AUTH_PASSWORD_SECRET,
    }
  };
});

, but entities are not part of NestJS structure so I cannot just inject it as usual.

How to achieve NestJS configs in TypeORM entities?

2

2 Answers

1
votes

Entities are not a part of the injectable providers in NestJS so inherently this isn't possible. You can make it a part of your service code, however, and do the password hashing there before insert/update.

0
votes

I needed this too and came up with workaround. You can't inject the config to Entity, as was said already.

I came up with solution to export object with config values that I need in Entities:

Initialize Config in app module:

  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [defaultConfig]
    }),
// .....other imports
  ]

defaultConfig is a function gathering and checking config values. On top of that it sets values to STATIC_CONFIG object.

export const STATIC_CONFIG = {
  WEB_APP_URL: '',
  BASE_URL: '',
};

export const defaultConfig = () => {
  const port = +(process.env[ENV_SERVER.PORT] || 3000);
  const production = process.env.NODE_ENV === 'production';
  const retVal = {
    PRODUCTION: production,
    PORT: port,
    BASE_URL: process.env.BASE_URL || 'http://localhost:3000',
    URL_PREFIX: process.env.URL_PREFIX || 'http://localhost:3000',
//    ..... plenty of other values
  }

  if (retVal[ENV_S3.HOST] && !(retVal[ENV_S3.ACCESS] && retVal[ENV_S3.SECRET])) {
    // tslint:disable-next-line:no-console
    console.error('S3 configuration error: no access or secret set; exiting');
    process.exit(1);
  }

  STATIC_CONFIG.WEB_APP_URL = retVal.WEB_APP_URL;
  STATIC_CONFIG.BASE_URL = retVal.BASE_URL;

  return retVal;
};

And finally in my entities I use the STATIC_CONFIG object, for example:

  @Expose({ name: 'image', toPlainOnly: true, groups: [TG_MOBILE] })
  get mobileAppImage() {
    return this.id ? `${STATIC_CONFIG.BASE_URL}/static/image/${this.id}` : undefined;
  }