Files
WYF-koubo/server/local-auth/app-api.cjs
T
2026-06-20 10:07:44 +08:00

178 lines
6.4 KiB
JavaScript

const { publicUser, findUserByToken } = require("./auth.cjs");
const { loadDb, saveDb, getSubscription, addUserLog, addGenerationLog } = require("./db.cjs");
const { sendJson } = require("./http-utils.cjs");
const { nowIso, createToken, checkPassword, passwordHash, daysRemaining } = require("./security.cjs");
function findLoginUser(db, account) {
const value = String(account || "").trim();
return db.users.find(user => user.email === value || user.username === value);
}
async function handleAppApi(req, res, pathname, body) {
const db = loadDb();
if (req.method === "GET" && pathname === "/api/system/config/public") {
sendJson(res, 200, { success: true, config: db.systemConfigs });
return true;
}
if (req.method === "POST" && pathname === "/api/register") {
const username = String(body.username || "").trim();
const email = String(body.email || "").trim();
const password = String(body.password || "");
if (!username || !email || !password) {
sendJson(res, 200, { success: false, message: "用户名、手机号和密码不能为空" });
return true;
}
if (db.users.some(user => user.email === email || user.username === username)) {
sendJson(res, 200, { success: false, message: "用户名或手机号已存在" });
return true;
}
const isFirstUser = db.users.length === 0;
const user = {
id: db.nextUserId++,
username,
email,
password: passwordHash(password),
role: isFirstUser ? "admin" : "user",
status: "active",
points: isFirstUser ? 999999 : 1000,
is_super_admin: isFirstUser ? 1 : 0,
owner_admin_id: null,
invite_code: body.invite_code || null,
max_devices: 99,
device_fingerprint: body.device_fingerprint || "",
created_at: nowIso(),
updated_at: nowIso(),
last_login_at: nowIso(),
last_login_device: body.device_fingerprint || null,
current_token: "",
cloud_digital_human_disabled: 0,
};
const token = createToken(user.id);
user.current_token = token;
db.users.push(user);
const subscription = getSubscription(db, user.id);
addUserLog(db, user.id, "register", "本地注册成功", { device_fingerprint: body.device_fingerprint });
saveDb(db);
sendJson(res, 200, {
success: true,
token,
userId: user.id,
user: publicUser(user),
subscription,
message: "本地注册成功",
});
return true;
}
if (req.method === "POST" && pathname === "/api/login") {
const account = body.email || body.username || body.phone;
const password = String(body.password || "");
const user = findLoginUser(db, account);
if (!user || !checkPassword(password, user.password)) {
sendJson(res, 200, { success: false, message: "账号或密码错误" });
return true;
}
if (user.status !== "active") {
sendJson(res, 200, { success: false, message: "账户已被禁用" });
return true;
}
const token = createToken(user.id);
user.current_token = token;
user.last_login_at = nowIso();
user.last_login_device = body.device_fingerprint || null;
const subscription = getSubscription(db, user.id);
addUserLog(db, user.id, "login", "本地登录成功", { device_fingerprint: body.device_fingerprint });
saveDb(db);
sendJson(res, 200, {
success: true,
token,
user: publicUser(user),
subscription,
message: "本地登录成功",
});
return true;
}
if (req.method === "POST" && pathname === "/api/verify") {
const user = findUserByToken(db, body.token);
if (!user || user.status !== "active") {
sendJson(res, 200, { valid: false, success: false, message: "Token 无效" });
return true;
}
const subscription = getSubscription(db, user.id);
saveDb(db);
sendJson(res, 200, {
valid: true,
success: true,
payload: { userId: user.id, role: user.role },
user: publicUser(user),
subscription,
});
return true;
}
if (req.method === "POST" && pathname === "/api/subscription/check") {
const userId = Number(body.user_id || body.userId);
const subscription = getSubscription(db, userId);
const remainingDays = daysRemaining(subscription.expires_at);
saveDb(db);
sendJson(res, 200, {
success: true,
hasAccess: remainingDays > 0,
expiresAt: subscription.expires_at,
remainingDays,
isExpired: remainingDays <= 0,
subscription,
});
return true;
}
if (req.method === "POST" && pathname === "/api/device/checkin") {
const userId = Number(body.user_id || body.userId || 0);
if (userId) {
const user = db.users.find(item => Number(item.id) === userId);
if (user) {
user.device_fingerprint = body.device_fingerprint || user.device_fingerprint || "";
user.last_login_device = body.device_fingerprint || user.last_login_device || null;
user.updated_at = nowIso();
}
if (body.device_fingerprint && !db.devices.some(item => item.user_id === userId && item.device_fingerprint === body.device_fingerprint)) {
db.devices.push({ user_id: userId, device_fingerprint: body.device_fingerprint, created_at: nowIso() });
}
saveDb(db);
}
sendJson(res, 200, { success: true, message: "本地设备校验通过" });
return true;
}
if (req.method === "POST" && pathname === "/api/user/generation-log") {
addGenerationLog(
db,
body.user_id || body.userId,
body.type,
body.detail || body.message || body,
{ device_fingerprint: body.device_fingerprint },
);
saveDb(db);
sendJson(res, 200, { success: true });
return true;
}
return false;
}
module.exports = {
handleAppApi,
};