import { PasswordEncoder } from './password-protocol'; import { PBKDF2, lib, enc} from 'crypto-js'; import { Value, Component } from '@malagu/core'; @Component(PasswordEncoder) export class Pbkdf2PasswordEncoder implements PasswordEncoder { @Value('malagu.security.passwordEncoder') protected readonly options: any; async encode(rawPassword: string): Promise { const { encodeHashAsBase64 } = this.options; const salt = lib.WordArray.random(8); const encoded = this.doEncode(rawPassword, salt.toString()); if (encodeHashAsBase64) { return enc.Base64.stringify(enc.Utf8.parse(encoded)); } return encoded; } protected doEncode(rawPassword: string, salt: string): string { const { secret } = this.options; return salt + PBKDF2(rawPassword, salt + secret, this.options).toString(); } async matches(rawPassword: string, encodedPassword: string): Promise { const digested = this.doDecode(encodedPassword); const salt = digested.substring(0, 16); return digested === this.doEncode(rawPassword, salt); } protected doDecode(encoded: string): string { const { encodeHashAsBase64 } = this.options; if (encodeHashAsBase64) { return enc.Base64.parse(encoded).toString(enc.Utf8); } return encoded; } }