In typeorm, I am trying to use a subscriber decorator to hash users password before persisting to the database. Unfortunately, I can't find a reference in the docs.
In sequelizejs, I use the following code,
User.hashPassword = (user, options) => {
if (!user.changed('password')) {
return null;
}
// hash password
return Bcrypt.hash(user.get('password'), SALT_ROUNDS)
.then(hash => user.set('password', hash));
};
Right now, I am trying to migrate the code to typeorm
and my translation is roughly
@BeforeInsert()
@BeforeUpdate()
hashPassword() {
// conditional to detect if password has changed goes here
this.password = bcrypt.hashSync(this.password, SALT_ROUNDS);
}
The issue is, I stuck at !user.changed('password')
. Is there an equivalent function in typeorm
to do this without rolling out my own solution?
In typeorm, I am trying to use a subscriber decorator to hash users password before persisting to the database. Unfortunately, I can't find a reference in the docs.
In sequelizejs, I use the following code,
User.hashPassword = (user, options) => {
if (!user.changed('password')) {
return null;
}
// hash password
return Bcrypt.hash(user.get('password'), SALT_ROUNDS)
.then(hash => user.set('password', hash));
};
Right now, I am trying to migrate the code to typeorm
and my translation is roughly
@BeforeInsert()
@BeforeUpdate()
hashPassword() {
// conditional to detect if password has changed goes here
this.password = bcrypt.hashSync(this.password, SALT_ROUNDS);
}
The issue is, I stuck at !user.changed('password')
. Is there an equivalent function in typeorm
to do this without rolling out my own solution?
4 Answers
Reset to default 6The solution to this question was found in @adetoola's own issue.
You can use @AfterLoad
to load the user password and check if the current password is different:
@Entity()
export class User extends BaseEntity {
@PrimaryColumn()
public username: string;
@Column()
public password: string;
@Column({ nullable: true })
public jwtToken: string;
private tempPassword: string;
@AfterLoad()
private loadTempPassword(): void {
this.tempPassword = this.password;
}
@BeforeUpdate()
private encryptPassword(): void {
if (this.tempPassword !== this.password) {
//
}
}
You can try this:
@BeforeInsert()
@BeforeUpdate()
hashPassword() {
if (this.password) {
this.password = createHmac('sha256', this.password).digest('hex');
}
}
I just check if a password is present in the DTO (before update and insert). If it is present, I should hash it.
----------
private tempPassword: string
/// commit to handle the password if i not change it it will be not encription
@AfterLoad()
private loadTempPassword(): void {
this.tempPassword = this.password;
}
@BeforeInsert()
@BeforeUpdate()
async hashPassword(): Promise<void> {
// cheack if that password changing or not
if (this.tempPassword !== this.password) {
try {
this.password = await bcrypt.hash(this.password, 10)
} catch (e) {
throw new InternalServerErrorException('there are some issiue in the hash')
}
}
}
we can make the selection of password from the Column
@Column('string', { select: false })
password:string
then we try to hash
we check if the password is found or not
if (this.password) {
//make hash
}
or another way it should make private tempPassword: string
@AfterLoad()
private loadTempPassword(): void {
this.tempPassword = this.password;
}
or
@BeforeInsert()
@BeforeUpdate()
async hashPassword(): Promise<void> {
// cheack if that password changing or not
if (this.password) {
if (this.tempPassword !== this.password) {
try {
this.password = await bcrypt.hash(this.password, 10)
} catch (e) {
throw new InternalServerErrorException('there are some issiue in the hash')
}
}
}
user.password
property is present in the update request. If it is present, confirm that it is a plain string to prevent a double hash. Then manually run thebcrypt.hash()
on the plain string before persisting. – adetoola Commented Aug 24, 2018 at 9:26