1459
This commit is contained in:
1 parent
4ab47a3e47
commit
ba016efbe8
21 files changed
+921
-72
No files matched your search
@@ -0,0 +1,71 @@
|
||||
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";
|
||||
}
|
||||
@@ -76,8 +76,9 @@ export function listPosts(options?: {
|
||||
page?: number;
|
||||
perPage?: number;
|
||||
includeDrafts?: boolean;
|
||||
author?: string;
|
||||
}): { posts: PostListItem[]; total: number; totalPages: number } {
|
||||
const { search = "", page = 1, perPage = ITEMS_PER_PAGE, includeDrafts = true } = options || {};
|
||||
const { search = "", page = 1, perPage = ITEMS_PER_PAGE, includeDrafts = true, author } = options || {};
|
||||
const dirs = findPostDirectories();
|
||||
|
||||
const allPosts: PostListItem[] = [];
|
||||
@@ -102,6 +103,9 @@ export function listPosts(options?: {
|
||||
|
||||
if (!includeDrafts && post.draft) continue;
|
||||
|
||||
// 按作者过滤
|
||||
if (author && post.author !== author) continue;
|
||||
|
||||
if (search) {
|
||||
const q = search.toLowerCase();
|
||||
const match =
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { DEEPSEEK_API_KEY, DEEPSEEK_BASE_URL } from "@/lib/config";
|
||||
|
||||
// 语音转文字:使用 OpenAI Whisper API 或其他兼容服务
|
||||
const WHISPER_API_KEY = process.env.WHISPER_API_KEY || DEEPSEEK_API_KEY || "";
|
||||
const WHISPER_API_BASE = process.env.WHISPER_API_BASE || (DEEPSEEK_API_KEY ? DEEPSEEK_BASE_URL : "https://api.openai.com/v1");
|
||||
const WHISPER_API_KEY = process.env.WHISPER_API_KEY || process.env.DEEPSEEK_API_KEY || "";
|
||||
const WHISPER_API_BASE = process.env.WHISPER_API_BASE || process.env.DEEPSEEK_BASE_URL || "https://api.openai.com/v1";
|
||||
const WHISPER_MODEL = process.env.WHISPER_MODEL || "whisper-1";
|
||||
|
||||
export async function transcribeAudio(audioBuffer: ArrayBuffer, filename: string): Promise<string> {
|
||||
|
||||
Reference in new issue
Block a user