72 lines
2.0 KiB
TypeScript
72 lines
2.0 KiB
TypeScript
import fs from "fs";
|
|
import path from "path";
|
|
import { createHash, randomBytes } from "crypto";
|
|
|
|
interface StoredUser {
|
|
username: string;
|
|
passwordHash: string;
|
|
salt: string;
|
|
name: string;
|
|
role: "admin" | "user";
|
|
}
|
|
|
|
interface User {
|
|
username: string;
|
|
name: string;
|
|
role: "admin" | "user";
|
|
}
|
|
|
|
// 密码哈希
|
|
export function hashPassword(password: string, salt: string): string {
|
|
return createHash("sha256").update(salt + password).digest("hex");
|
|
}
|
|
|
|
// 生成密码哈希(用于创建用户)
|
|
export function generatePasswordHash(password: string): { hash: string; salt: string } {
|
|
const salt = randomBytes(16).toString("hex");
|
|
const hash = hashPassword(password, salt);
|
|
return { hash, salt };
|
|
}
|
|
|
|
// 从请求头获取用户信息
|
|
export function getAuthFromRequest(request: Request): User | null {
|
|
const authHeader = request.headers.get("X-Auth-User");
|
|
if (!authHeader) return null;
|
|
const stored = findStoredUser(authHeader);
|
|
if (!stored) return null;
|
|
return { username: stored.username, name: stored.name, role: stored.role };
|
|
}
|
|
|
|
// 查找用户
|
|
function findStoredUser(username: string): StoredUser | null {
|
|
const users = loadStoredUsers();
|
|
return users.find(u => u.username === username) || null;
|
|
}
|
|
|
|
// 认证用户
|
|
export function authenticateUser(username: string, password: string): User | null {
|
|
const stored = findStoredUser(username);
|
|
if (!stored) return null;
|
|
const hash = hashPassword(password, stored.salt);
|
|
if (hash !== stored.passwordHash) return null;
|
|
return { username: stored.username, name: stored.name, role: stored.role };
|
|
}
|
|
|
|
// 加载用户列表
|
|
function loadStoredUsers(): StoredUser[] {
|
|
try {
|
|
const usersPath = path.join(process.cwd(), "users.json");
|
|
if (!fs.existsSync(usersPath)) return [];
|
|
const data = JSON.parse(fs.readFileSync(usersPath, "utf-8"));
|
|
return data.users || [];
|
|
} catch {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
// 是否是管理员
|
|
export function isAdmin(request: Request): boolean {
|
|
const user = getAuthFromRequest(request);
|
|
return user?.role === "admin";
|
|
}
|