37 lines
890 B
JavaScript
37 lines
890 B
JavaScript
import bcrypt from 'bcrypt';
|
||
|
||
const SALT_ROUNDS = 10;
|
||
|
||
/**
|
||
* 加密密码(bcrypt)
|
||
*/
|
||
async function hashPassword(passwd) {
|
||
return await bcrypt.hash(passwd, SALT_ROUNDS);
|
||
}
|
||
|
||
/**
|
||
* 验证密码
|
||
* 支持 bcrypt 新密码和 MD5 旧密码(渐进式迁移)
|
||
* @returns {{ valid: boolean, needsUpgrade: boolean }}
|
||
*/
|
||
async function verifyPassword(passwd, storedHash, salt) {
|
||
// 尝试 bcrypt 验证
|
||
if (storedHash && storedHash.startsWith('$2')) {
|
||
const valid = await bcrypt.compare(passwd, storedHash);
|
||
return { valid, needsUpgrade: false };
|
||
}
|
||
|
||
// 兼容旧 MD5 密码
|
||
const crypto = await import('crypto');
|
||
const hash = crypto.createHash('md5');
|
||
hash.update(passwd + (salt || ''));
|
||
const md5Hash = hash.digest('hex');
|
||
|
||
return {
|
||
valid: storedHash === md5Hash,
|
||
needsUpgrade: storedHash === md5Hash
|
||
};
|
||
}
|
||
|
||
export { hashPassword, verifyPassword };
|