DEV Community

Cover image for 🚨 TypeORM Hook Gotcha: Password Not Hashing! 🚨
MdGolamRabbaniRafi
MdGolamRabbaniRafi

Posted on

🚨 TypeORM Hook Gotcha: Password Not Hashing! 🚨

I ran into an interesting behavior in TypeORM while updating a user’s password in NestJS.
Here are the two scenarios:
Scenario 1 – Password Not Hashed ❌

@BeforeInsert()
@BeforeUpdate()
hashPassword(): void {
if (this.password) {
this.password = bcrypt.hashSync(this.password, saltRounds);
}
}

async changeRootUserPassword(id: string, newPassword: string): Promise {
const user = await RootUser.findOne({ where: { id } });
if (!user) return false;

user.password = newPassword;

const savedUser = await user.save();

return !!savedUser?.id;
}

Result: The password is saved in plain text!
Why? Because TypeORM does not detect a field change, so @BeforeUpdate() never triggers.

Scenario 2 – Password Hashed βœ…

@BeforeInsert()
@BeforeUpdate()
hashPassword(): void {
if (this.password) {
this.password = bcrypt.hashSync(this.password, saltRounds);
}
}

async changeRootUserPassword(id: string, newPassword: string): Promise {
const user = await RootUser.findOne({ where: { id } });
if (!user) return false;

user.password = newPassword;
user.updatedAt = new Date();

const savedUser = await user.save();

return !!savedUser?.id;
}

Result: Password is properly hashed βœ…
By updating another field (updatedAt), TypeORM detects a change and triggers the @BeforeUpdate() hook.

πŸ’‘ Key Takeaway:
When relying on TypeORM entity hooks like @BeforeUpdate(), ensure at least one other field changes β€” otherwise, your hook may not run, and important logic (like password hashing) can fail silently.

Top comments (1)

Collapse
 
alifar profile image
Ali Farhat

Good discovery, thanks!