新增本地认证与管理接口服务
This commit is contained in:
@@ -0,0 +1,177 @@
|
||||
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,
|
||||
};
|
||||
Reference in New Issue
Block a user