/** * 密码哈希抽象 — 把 bcrypt 从 Shrimp 核心彻底剥离 * * 默认仍用 bcrypt(行业标准,Shrimp 大多数场景都需要),但通过抽象接口 * 让消费方可以: * - 完全不装 bcrypt(走 plainHasher / 自己写一个 argon2 / scrypt 等) * - 在测试里跳过哈希计算开销 * - 接入已有的密码系统(SHA256 + salt 之类) * * 配置方式: * import { Shrimp, plainHasher } from "shrimp-server" * Shrimp.passwordHasher = plainHasher // 或自己实现的 IPasswordHasher */ export interface IPasswordHasher { /** 把明文密码加密成存储字符串 */ hash(plain: string): Promise /** 校验明文密码是否匹配已存储的哈希 */ verify(plain: string, hashed: string): Promise } /** * 默认实现 — bcrypt * * 通过动态 import 加载,确保只有真正调用 hash/verify 时才 require('bcrypt')。 * 这样消费方:不创建 Password 字段 + 不登录的话,可以完全不装 bcrypt。 */ export const bcryptHasher: IPasswordHasher = { async hash(plain: string): Promise { const bcrypt = await import("bcrypt") return bcrypt.hash(plain, 10) }, async verify(plain: string, hashed: string): Promise { const bcrypt = await import("bcrypt") return bcrypt.compare(plain, hashed) }, } /** * 明文实现 — 仅用于测试 / 开发环境 / 自己已经在上层做了加密 * * **生产环境严禁使用**。存储明文密码的后果你懂的。 */ export const plainHasher: IPasswordHasher = { async hash(plain: string): Promise { return plain }, async verify(plain: string, hashed: string): Promise { return plain === hashed }, }