mirror of
https://github.com/ZeroCatDev/ClassworksKV.git
synced 2025-12-07 21:13:10 +00:00
规范代码格式
This commit is contained in:
parent
4ec10acfcf
commit
c545612c9c
4
app.js
4
app.js
@ -1,7 +1,7 @@
|
|||||||
import "./utils/instrumentation.js";
|
import "./utils/instrumentation.js";
|
||||||
// import createError from "http-errors";
|
// import createError from "http-errors";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import { join, dirname } from "path";
|
import {dirname, join} from "path";
|
||||||
import {fileURLToPath} from "url";
|
import {fileURLToPath} from "url";
|
||||||
// import cookieParser from "cookie-parser";
|
// import cookieParser from "cookie-parser";
|
||||||
import logger from "morgan";
|
import logger from "morgan";
|
||||||
@ -16,10 +16,10 @@ import deviceAuthRouter from "./routes/device-auth.js";
|
|||||||
import accountsRouter from "./routes/accounts.js";
|
import accountsRouter from "./routes/accounts.js";
|
||||||
import autoAuthRouter from "./routes/auto-auth.js";
|
import autoAuthRouter from "./routes/auto-auth.js";
|
||||||
import {register} from "./utils/metrics.js";
|
import {register} from "./utils/metrics.js";
|
||||||
|
import cors from "cors";
|
||||||
|
|
||||||
var app = express();
|
var app = express();
|
||||||
|
|
||||||
import cors from "cors";
|
|
||||||
app.options("/{*path}", cors());
|
app.options("/{*path}", cors());
|
||||||
app.use(
|
app.use(
|
||||||
cors({
|
cors({
|
||||||
|
|||||||
@ -10,8 +10,6 @@
|
|||||||
* 或配置为可执行:chmod +x cli/get-token.js && ./cli/get-token.js
|
* 或配置为可执行:chmod +x cli/get-token.js && ./cli/get-token.js
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import readline from 'readline';
|
|
||||||
|
|
||||||
// 配置
|
// 配置
|
||||||
const CONFIG = {
|
const CONFIG = {
|
||||||
// API服务器地址
|
// API服务器地址
|
||||||
|
|||||||
@ -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 {verifyToken} from "../utils/jwt.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
import {PrismaClient} from "@prisma/client";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
|||||||
@ -56,7 +56,6 @@ export const prepareTokenForRateLimit = (req, res, next) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 认证相关路由限速器(防止暴力破解)
|
// 认证相关路由限速器(防止暴力破解)
|
||||||
export const authLimiter = rateLimit({
|
export const authLimiter = rateLimit({
|
||||||
windowMs: 30 * 60 * 1000, // 30分钟
|
windowMs: 30 * 60 * 1000, // 30分钟
|
||||||
|
|||||||
@ -109,6 +109,7 @@ export const extractDeviceInfo = async (req,res,next) => {
|
|||||||
res.locals.deviceId = device.id;
|
res.locals.deviceId = device.id;
|
||||||
next();
|
next();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 从请求中提取UUID
|
* 从请求中提取UUID
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<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>
|
<title>登录失败</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
@ -50,9 +50,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@keyframes shake {
|
@keyframes shake {
|
||||||
0%, 100% { transform: translateX(0); }
|
0%, 100% {
|
||||||
10%, 30%, 50%, 70%, 90% { transform: translateX(-5px); }
|
transform: translateX(0);
|
||||||
20%, 40%, 60%, 80% { transform: translateX(5px); }
|
}
|
||||||
|
10%, 30%, 50%, 70%, 90% {
|
||||||
|
transform: translateX(-5px);
|
||||||
|
}
|
||||||
|
20%, 40%, 60%, 80% {
|
||||||
|
transform: translateX(5px);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
@ -123,7 +129,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="error-icon">
|
<div class="error-icon">
|
||||||
<svg fill="none" viewBox="0 0 24 24">
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -134,7 +140,7 @@
|
|||||||
<div class="error-code" id="errorCode"></div>
|
<div class="error-code" id="errorCode"></div>
|
||||||
</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>
|
<button class="close-btn" onclick="window.close()">关闭窗口</button>
|
||||||
|
|
||||||
<div class="help-text">
|
<div class="help-text">
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
<html lang="zh-CN">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<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>
|
<title>登录成功</title>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
@ -135,7 +135,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="success-icon">
|
<div class="success-icon">
|
||||||
<svg fill="none" viewBox="0 0 24 24">
|
<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>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
import {PrismaClient} from "@prisma/client";
|
import {PrismaClient} from "@prisma/client";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import { oauthProviders, getCallbackURL, generateState } from "../config/oauth.js";
|
import {generateState, getCallbackURL, oauthProviders} from "../config/oauth.js";
|
||||||
import { generateAccountToken, generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken } from "../utils/jwt.js";
|
import {generateTokenPair, refreshAccessToken, revokeAllTokens, revokeRefreshToken} from "../utils/jwt.js";
|
||||||
import {jwtAuth} from "../middleware/jwt-auth.js";
|
import {jwtAuth} from "../middleware/jwt-auth.js";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
const router = Router();
|
|
||||||
import {uuidAuth} from "../middleware/uuidAuth.js";
|
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 {PrismaClient} from "@prisma/client";
|
||||||
import crypto from "crypto";
|
import crypto from "crypto";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {verifyDevicePassword} from "../utils/crypto.js";
|
import {verifyDevicePassword} from "../utils/crypto.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -217,7 +216,7 @@ router.post(
|
|||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// 如果验证失败,继续尝试下一个
|
// 如果验证失败,继续尝试下一个
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
const router = Router();
|
|
||||||
import {jwtAuth} from "../middleware/jwt-auth.js";
|
import {jwtAuth} from "../middleware/jwt-auth.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
import {PrismaClient} from "@prisma/client";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -127,7 +128,8 @@ router.post(
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);/**
|
);
|
||||||
|
/**
|
||||||
* PUT /auto-auth/devices/:uuid/auth-configs/:configId
|
* PUT /auto-auth/devices/:uuid/auth-configs/:configId
|
||||||
* 更新自动授权配置 (需要 JWT 认证,且设备必须绑定到该账户)
|
* 更新自动授权配置 (需要 JWT 认证,且设备必须绑定到该账户)
|
||||||
* Body: { password?: string, deviceType?: string, isReadOnly?: boolean }
|
* Body: { password?: string, deviceType?: string, isReadOnly?: boolean }
|
||||||
|
|||||||
@ -7,7 +7,6 @@ const router = Router();
|
|||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* POST /device/code
|
* POST /device/code
|
||||||
* 生成设备授权码
|
* 生成设备授权码
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
const router = Router();
|
import {extractDeviceInfo} from "../middleware/uuidAuth.js";
|
||||||
import { uuidAuth, extractDeviceInfo } from "../middleware/uuidAuth.js";
|
|
||||||
import {PrismaClient} from "@prisma/client";
|
import {PrismaClient} from "@prisma/client";
|
||||||
import crypto from "crypto";
|
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import { hashPassword, verifyDevicePassword } from "../utils/crypto.js";
|
|
||||||
import {getOnlineDevices} from "../utils/socket.js";
|
import {getOnlineDevices} from "../utils/socket.js";
|
||||||
import {registeredDevicesTotal} from "../utils/metrics.js";
|
import {registeredDevicesTotal} from "../utils/metrics.js";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -147,7 +146,8 @@ router.get(
|
|||||||
namespace: device.namespace,
|
namespace: device.namespace,
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
);/**
|
);
|
||||||
|
/**
|
||||||
* PUT /devices/:uuid/name
|
* PUT /devices/:uuid/name
|
||||||
* 设置设备名称 (需要UUID认证)
|
* 设置设备名称 (需要UUID认证)
|
||||||
*/
|
*/
|
||||||
@ -181,7 +181,6 @@ router.put(
|
|||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GET /devices/online
|
* GET /devices/online
|
||||||
* 查询在线设备(WebSocket 已连接)
|
* 查询在线设备(WebSocket 已连接)
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
|
|
||||||
var router = Router();
|
var router = Router();
|
||||||
|
|
||||||
/* GET home page. */
|
/* GET home page. */
|
||||||
|
|||||||
@ -1,18 +1,19 @@
|
|||||||
import {Router} from "express";
|
import {Router} from "express";
|
||||||
const router = Router();
|
|
||||||
import kvStore from "../utils/kvStore.js";
|
import kvStore from "../utils/kvStore.js";
|
||||||
import {broadcastKeyChanged} from "../utils/socket.js";
|
import {broadcastKeyChanged} from "../utils/socket.js";
|
||||||
import {kvTokenAuth} from "../middleware/kvTokenAuth.js";
|
import {kvTokenAuth} from "../middleware/kvTokenAuth.js";
|
||||||
import {
|
import {
|
||||||
tokenReadLimiter,
|
prepareTokenForRateLimit,
|
||||||
tokenWriteLimiter,
|
|
||||||
tokenDeleteLimiter,
|
|
||||||
tokenBatchLimiter,
|
tokenBatchLimiter,
|
||||||
prepareTokenForRateLimit
|
tokenDeleteLimiter,
|
||||||
|
tokenReadLimiter,
|
||||||
|
tokenWriteLimiter
|
||||||
} from "../middleware/rateLimiter.js";
|
} from "../middleware/rateLimiter.js";
|
||||||
import errors from "../utils/errors.js";
|
import errors from "../utils/errors.js";
|
||||||
import {PrismaClient} from "@prisma/client";
|
import {PrismaClient} from "@prisma/client";
|
||||||
|
|
||||||
|
const router = Router();
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
// 使用KV专用token认证
|
// 使用KV专用token认证
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
export const siteKey = process.env.SITE_KEY || "";
|
export const siteKey = process.env.SITE_KEY || "";
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|||||||
import {BatchSpanProcessor} from "@opentelemetry/sdk-trace-base";
|
import {BatchSpanProcessor} from "@opentelemetry/sdk-trace-base";
|
||||||
import {resourceFromAttributes} from "@opentelemetry/resources";
|
import {resourceFromAttributes} from "@opentelemetry/resources";
|
||||||
import {SemanticResourceAttributes} from "@opentelemetry/semantic-conventions";
|
import {SemanticResourceAttributes} from "@opentelemetry/semantic-conventions";
|
||||||
|
|
||||||
if (process.env.AXIOM_TOKEN && process.env.AXIOM_DATASET) {
|
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
|
||||||
// Initialize OTLP trace exporter with the endpoint URL and headers
|
// Initialize OTLP trace exporter with the endpoint URL and headers
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
import jwt from 'jsonwebtoken';
|
import jwt from 'jsonwebtoken';
|
||||||
import {
|
import {
|
||||||
generateAccessToken,
|
generateAccessToken,
|
||||||
verifyAccessToken,
|
|
||||||
generateTokenPair,
|
generateTokenPair,
|
||||||
refreshAccessToken,
|
refreshAccessToken,
|
||||||
revokeAllTokens,
|
revokeAllTokens,
|
||||||
revokeRefreshToken,
|
revokeRefreshToken,
|
||||||
|
verifyAccessToken,
|
||||||
} from './tokenManager.js';
|
} from './tokenManager.js';
|
||||||
|
|
||||||
// JWT 配置(支持 HS256 与 RS256)
|
// JWT 配置(支持 HS256 与 RS256)
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import { PrismaClient } from "@prisma/client";
|
|||||||
import {keysTotal} from "./metrics.js";
|
import {keysTotal} from "./metrics.js";
|
||||||
|
|
||||||
const prisma = new PrismaClient();
|
const prisma = new PrismaClient();
|
||||||
|
|
||||||
class KVStore {
|
class KVStore {
|
||||||
/**
|
/**
|
||||||
* 通过设备ID和键名获取值
|
* 通过设备ID和键名获取值
|
||||||
|
|||||||
@ -46,14 +46,16 @@ export function initSocket(server) {
|
|||||||
// 仅允许通过 query.token/apptoken 加入
|
// 仅允许通过 query.token/apptoken 加入
|
||||||
const qToken = socket.handshake?.query?.token || socket.handshake?.query?.apptoken;
|
const qToken = socket.handshake?.query?.token || socket.handshake?.query?.apptoken;
|
||||||
if (qToken && typeof qToken === "string") {
|
if (qToken && typeof qToken === "string") {
|
||||||
joinByToken(socket, qToken).catch(() => {});
|
joinByToken(socket, qToken).catch(() => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 客户端使用 KV token 加入房间
|
// 客户端使用 KV token 加入房间
|
||||||
socket.on("join-token", (payload) => {
|
socket.on("join-token", (payload) => {
|
||||||
const token = payload?.token || payload?.apptoken;
|
const token = payload?.token || payload?.apptoken;
|
||||||
if (typeof token === "string" && token.length > 0) {
|
if (typeof token === "string" && token.length > 0) {
|
||||||
joinByToken(socket, token).catch(() => {});
|
joinByToken(socket, token).catch(() => {
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -259,11 +259,16 @@ function parseExpirationToMs(expiresIn) {
|
|||||||
const unit = match[2];
|
const unit = match[2];
|
||||||
|
|
||||||
switch (unit) {
|
switch (unit) {
|
||||||
case 's': return value * 1000;
|
case 's':
|
||||||
case 'm': return value * 60 * 1000;
|
return value * 1000;
|
||||||
case 'h': return value * 60 * 60 * 1000;
|
case 'm':
|
||||||
case 'd': return value * 24 * 60 * 60 * 1000;
|
return value * 60 * 1000;
|
||||||
default: throw new Error('Invalid time unit');
|
case 'h':
|
||||||
|
return value * 60 * 60 * 1000;
|
||||||
|
case 'd':
|
||||||
|
return value * 24 * 60 * 60 * 1000;
|
||||||
|
default:
|
||||||
|
throw new Error('Invalid time unit');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,5 +11,7 @@
|
|||||||
<h1>Classworks 服务端</h1>
|
<h1>Classworks 服务端</h1>
|
||||||
<p>服务运行中</p>
|
<p>服务运行中</p>
|
||||||
</body>
|
</body>
|
||||||
|
<script>
|
||||||
|
window.open('https://kv.houlang.cloud')
|
||||||
|
</script>
|
||||||
</html>
|
</html>
|
||||||
Loading…
x
Reference in New Issue
Block a user