import { createHmac, randomBytes } from 'crypto'; function hashForPassword(salt: string,password:string){ return createHmac('sha256', salt).update(password).digest('hex') } function createPasswordHashAndSalt(password: string):{salt:string,hash:string}{ const secret = randomBytes(32).toString('hex'); return { salt: secret, hash: hashForPassword(secret,password) }; } export class Password{ private _salt:string; private _hash:string; constructor(pw : string|{salt:string,hash:string}){ const {salt,hash} = typeof pw === "string" ? createPasswordHashAndSalt(pw) : pw; this._hash = hash; this._salt = salt; } set_password(password: string){ const {salt,hash} = createPasswordHashAndSalt(password); this._hash = hash; this._salt = salt; } check_password(password: string):boolean{ return this._hash === hashForPassword(this._salt,password); } get salt(){return this._salt;} get hash(){return this._hash;} } export interface UserCreateInput{ username: string, password: string } export interface IUser{ readonly username : string; readonly password : Password; /** * return user's permission list. */ get_permissions():Promise; /** * add permission * @param name permission name to add * @returns if `name` doesn't exist, return true */ add(name :string):Promise; /** * remove permission * @param name permission name to remove * @returns if `name` exist, return true */ remove(name :string):Promise; /** * reset password. * @param password password to set */ reset_password(password: string):Promise; }; export interface UserAccessor{ /** * create user * @returns if user exist, return undefined */ createUser: (input :UserCreateInput)=> Promise, /** * find user */ findUser: (username: string)=> Promise, /** * remove user * @returns if user exist, true */ delUser: (username: string)=>Promise };