f2e-server3
Version:
f2e-server 3.0
67 lines (66 loc) • 2.86 kB
text/typescript
import { createHash } from "node:crypto";
import { logger } from "../../utils";
import { IUserStore, LoginUser } from "./interface";
import * as fs from 'node:fs'
import { DBFile } from "../../utils/dbfile";
export class UserStore implements IUserStore {
private db_user: DBFile<Map<string, LoginUser>>;
private deleteCallbacks: {(username: string): void}[] = []
private mock_user?: LoginUser;
/**
* @param db_path 用户密码存储文件路径
* 用户密码文件格式(密码为md5密文): 每行一个用户
* ```
* username1:password1:nickname1
* username2:password2:nickname2
* username3:password3:nickname3
* ```
*/
constructor (db_path: string, mock_user?: LoginUser) {
this.mock_user = mock_user
this.db_user = new DBFile<Map<string, LoginUser>>({
filePath: db_path,
watchFile: true,
initData: new Map([
['admin:e10adc3949ba59abbe56e057f20f883e', { username: 'admin', nickname: '管理员' }],
['user:e10adc3949ba59abbe56e057f20f883e', { username: 'user', nickname: '用户' }],
]),
fileToData: (filePath) => {
const lines = fs.readFileSync(filePath, 'utf8').split(/[\r\n]+/)
const user_map = new Map<string, LoginUser>()
for (const line of lines) {
const [username, password, nickname] = line.split(':')
user_map.set(`${username}:${password}`, { username, nickname })
}
return user_map
},
dataToFile: (data) => {
const lines: string[] = []
data.forEach((v, key) => {
lines.push(`${key}:${v.nickname}`)
})
return lines.join('\n')
},
onFileChange: (newData, oldData) => {
const deleteCallbacks = this.deleteCallbacks
oldData?.forEach(function (v, key) {
if (!newData?.has(key)) {
const username = key.split(':')[0]
logger.info(`user: "${username}" deleted`)
deleteCallbacks.forEach(callback => callback(username))
}
})
}
})
}
async getUser(username: string, password: string): Promise<LoginUser | undefined> {
const pwd = createHash('md5').update(password).digest('hex')
return this.db_user.data?.get(`${username}:${pwd}`)
}
onDeleteUser(callback: (username: string) => void): void {
this.deleteCallbacks.push(callback)
}
async getLoginUser(): Promise<LoginUser | undefined> {
return this.mock_user
}
}