Reputation: 3714
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?
Upvotes: 2
Views: 3878
Reputation: 39
@Entity()
export class User extends BaseDatabaseEntity {
@Column({
length: 255,
})
public firstName!: string;
@Column({
length: 60,
transformer: new PasswordTransformer(new ConfigService())
})
@Exclude()
public password: string;
}
export class PasswordTransformer implements ValueTransformer {
constructor(private config: ConfigService) {}
from(value: string): string {
return value;
}
to(value: string): string {
return hashSync(
this.password + this.config.get('AUTH_PASSWORD_SECRET'),
genSaltSync(),
);
}
}
Upvotes: -1
Reputation: 4039
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;
}
Upvotes: 2
Reputation: 70221
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.
Upvotes: 1