1
1
mirror of https://github.com/ZeroCatDev/ClassworksKV.git synced 2025-12-07 13:03:09 +00:00

规范代码格式

This commit is contained in:
Sunwuyuan 2025-11-16 16:15:05 +08:00
parent 4ec10acfcf
commit c545612c9c
No known key found for this signature in database
GPG Key ID: A6A54CF66F56BB64
34 changed files with 3982 additions and 3965 deletions

4
app.js
View File

@ -1,7 +1,7 @@
import "./utils/instrumentation.js";
// import createError from "http-errors";
import express from "express";
import { join, dirname } from "path";
import {dirname, join} from "path";
import {fileURLToPath} from "url";
// import cookieParser from "cookie-parser";
import logger from "morgan";
@ -16,10 +16,10 @@ import deviceAuthRouter from "./routes/device-auth.js";
import accountsRouter from "./routes/accounts.js";
import autoAuthRouter from "./routes/auto-auth.js";
import {register} from "./utils/metrics.js";
import cors from "cors";
var app = express();
import cors from "cors";
app.options("/{*path}", cors());
app.use(
cors({

View File

@ -10,8 +10,6 @@
* 或配置为可执行chmod +x cli/get-token.js && ./cli/get-token.js
*/
import readline from 'readline';
// 配置
const CONFIG = {
// API服务器地址

View File

@ -6,7 +6,7 @@
* 适用于只需要账户验证的接口
*/
import { verifyAccessToken, validateAccountToken, generateAccessToken } from "../utils/tokenManager.js";
import {generateAccessToken, validateAccountToken, verifyAccessToken} from "../utils/tokenManager.js";
import {verifyToken} from "../utils/jwt.js";
import {PrismaClient} from "@prisma/client";
import errors from "../utils/errors.js";

View File

@ -56,7 +56,6 @@ export const prepareTokenForRateLimit = (req, res, next) => {
};
// 认证相关路由限速器(防止暴力破解)
export const authLimiter = rateLimit({
windowMs: 30 * 60 * 1000, // 30分钟

View File

@ -109,6 +109,7 @@ export const extractDeviceInfo = async (req,res,next) => {
res.locals.deviceId = device.id;
next();
}
/**
* 从请求中提取UUID
*/

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>登录失败</title>
<style>
* {
@ -50,9 +50,15 @@
}
@keyframes shake {
0%, 100% { transform: translateX(0); }
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
20%, 40%, 60%, 80% { transform: translateX(5px); }
0%, 100% {
transform: translateX(0);
}
10%, 30%, 50%, 70%, 90% {
transform: translateX(-5px);
}
20%, 40%, 60%, 80% {
transform: translateX(5px);
}
}
h1 {
@ -123,7 +129,7 @@
<div class="container">
<div class="error-icon">
<svg fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
<path d="M6 18L18 6M6 6l12 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>
@ -134,7 +140,7 @@
<div class="error-code" id="errorCode"></div>
</div>
<a href="javascript:history.back()" class="retry-btn">返回重试</a>
<a class="retry-btn" href="javascript:history.back()">返回重试</a>
<button class="close-btn" onclick="window.close()">关闭窗口</button>
<div class="help-text">

View File

@ -2,7 +2,7 @@
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<title>登录成功</title>
<style>
* {
@ -135,7 +135,7 @@
<div class="container">
<div class="success-icon">
<svg fill="none" viewBox="0 0 24 24">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" d="M5 13l4 4L19 7" />
<path d="M5 13l4 4L19 7" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</div>

View File

@ -1,8 +1,8 @@
import {Router} from "express";
import {PrismaClient} from "@prisma/client";
import crypto from "crypto";
import { oauthProviders, getCallbackURL, generateState } from "../config/oauth.js";
import { generateAccountToken, generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken } from "../utils/jwt.js";
import {generateState, getCallbackURL, oauthProviders} from "../config/oauth.js";
import {generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken} from "../utils/jwt.js";
import {jwtAuth} from "../middleware/jwt-auth.js";
import errors from "../utils/errors.js";

View File

@ -1,13 +1,12 @@
import {Router} from "express";
const router = Router();
import {uuidAuth} from "../middleware/uuidAuth.js";
import { jwtAuth } from "../middleware/jwt-auth.js";
import { kvTokenAuth } from "../middleware/kvTokenAuth.js";
import {PrismaClient} from "@prisma/client";
import crypto from "crypto";
import errors from "../utils/errors.js";
import {verifyDevicePassword} from "../utils/crypto.js";
const router = Router();
const prisma = new PrismaClient();
/**
@ -217,7 +216,7 @@ router.post(
}
} catch (err) {
// 如果验证失败,继续尝试下一个
continue;
}
}
}

View File

@ -1,9 +1,10 @@
import {Router} from "express";
const router = Router();
import {jwtAuth} from "../middleware/jwt-auth.js";
import {PrismaClient} from "@prisma/client";
import errors from "../utils/errors.js";
const router = Router();
const prisma = new PrismaClient();
/**
@ -127,7 +128,8 @@ router.post(
},
});
})
);/**
);
/**
* PUT /auto-auth/devices/:uuid/auth-configs/:configId
* 更新自动授权配置 (需要 JWT 认证且设备必须绑定到该账户)
* Body: { password?: string, deviceType?: string, isReadOnly?: boolean }

View File

@ -7,7 +7,6 @@ const router = Router();
const prisma = new PrismaClient();
/**
* POST /device/code
* 生成设备授权码

View File

@ -1,13 +1,12 @@
import {Router} from "express";
const router = Router();
import { uuidAuth, extractDeviceInfo } from "../middleware/uuidAuth.js";
import {extractDeviceInfo} from "../middleware/uuidAuth.js";
import {PrismaClient} from "@prisma/client";
import crypto from "crypto";
import errors from "../utils/errors.js";
import { hashPassword, verifyDevicePassword } from "../utils/crypto.js";
import {getOnlineDevices} from "../utils/socket.js";
import {registeredDevicesTotal} from "../utils/metrics.js";
const router = Router();
const prisma = new PrismaClient();
/**
@ -147,7 +146,8 @@ router.get(
namespace: device.namespace,
});
})
);/**
);
/**
* PUT /devices/:uuid/name
* 设置设备名称 (需要UUID认证)
*/
@ -181,7 +181,6 @@ router.put(
);
/**
* GET /devices/online
* 查询在线设备WebSocket 已连接

View File

@ -1,4 +1,5 @@
import {Router} from "express";
var router = Router();
/* GET home page. */

View File

@ -1,18 +1,19 @@
import {Router} from "express";
const router = Router();
import kvStore from "../utils/kvStore.js";
import {broadcastKeyChanged} from "../utils/socket.js";
import {kvTokenAuth} from "../middleware/kvTokenAuth.js";
import {
tokenReadLimiter,
tokenWriteLimiter,
tokenDeleteLimiter,
prepareTokenForRateLimit,
tokenBatchLimiter,
prepareTokenForRateLimit
tokenDeleteLimiter,
tokenReadLimiter,
tokenWriteLimiter
} from "../middleware/rateLimiter.js";
import errors from "../utils/errors.js";
import {PrismaClient} from "@prisma/client";
const router = Router();
const prisma = new PrismaClient();
// 使用KV专用token认证

View File

@ -1,4 +1,5 @@
import dotenv from "dotenv";
dotenv.config();
export const siteKey = process.env.SITE_KEY || "";

View File

@ -5,6 +5,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import {BatchSpanProcessor} from "@opentelemetry/sdk-trace-base";
import {resourceFromAttributes} from "@opentelemetry/resources";
import {SemanticResourceAttributes} from "@opentelemetry/semantic-conventions";
if (process.env.AXIOM_TOKEN && process.env.AXIOM_DATASET) {
// Initialize OTLP trace exporter with the endpoint URL and headers
// Initialize OTLP trace exporter with the endpoint URL and headers

View File

@ -1,11 +1,11 @@
import jwt from 'jsonwebtoken';
import {
generateAccessToken,
verifyAccessToken,
generateTokenPair,
refreshAccessToken,
revokeAllTokens,
revokeRefreshToken,
verifyAccessToken,
} from './tokenManager.js';
// JWT 配置(支持 HS256 与 RS256

View File

@ -2,6 +2,7 @@ import { PrismaClient } from "@prisma/client";
import {keysTotal} from "./metrics.js";
const prisma = new PrismaClient();
class KVStore {
/**
* 通过设备ID和键名获取值

View File

@ -46,14 +46,16 @@ export function initSocket(server) {
// 仅允许通过 query.token/apptoken 加入
const qToken = socket.handshake?.query?.token || socket.handshake?.query?.apptoken;
if (qToken && typeof qToken === "string") {
joinByToken(socket, qToken).catch(() => {});
joinByToken(socket, qToken).catch(() => {
});
}
// 客户端使用 KV token 加入房间
socket.on("join-token", (payload) => {
const token = payload?.token || payload?.apptoken;
if (typeof token === "string" && token.length > 0) {
joinByToken(socket, token).catch(() => {});
joinByToken(socket, token).catch(() => {
});
}
});

View File

@ -259,11 +259,16 @@ function parseExpirationToMs(expiresIn) {
const unit = match[2];
switch (unit) {
case 's': return value * 1000;
case 'm': return value * 60 * 1000;
case 'h': return value * 60 * 60 * 1000;
case 'd': return value * 24 * 60 * 60 * 1000;
default: throw new Error('Invalid time unit');
case 's':
return value * 1000;
case 'm':
return value * 60 * 1000;
case 'h':
return value * 60 * 60 * 1000;
case 'd':
return value * 24 * 60 * 60 * 1000;
default:
throw new Error('Invalid time unit');
}
}

View File

@ -11,5 +11,7 @@
<h1>Classworks 服务端</h1>
<p>服务运行中</p>
</body>
<script>
window.open('https://kv.houlang.cloud')
</script>
</html>