mirror of
https://github.com/JetSprow/J-Board-Lite.git
synced 2026-05-01 01:14:10 +05:30
fix: harden secrets and session checks
This commit is contained in:
@@ -1,8 +1,13 @@
|
||||
import type { Prisma } from "@prisma/client";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { notFound } from "next/navigation";
|
||||
import { sanitizeInboundSettings, sanitizeStreamSettings } from "@/services/node-inbound-sanitize";
|
||||
|
||||
const nodeDetailInclude = {
|
||||
const nodeDetailSelect = {
|
||||
id: true,
|
||||
name: true,
|
||||
panelUrl: true,
|
||||
status: true,
|
||||
inbounds: {
|
||||
where: { isActive: true },
|
||||
orderBy: { updatedAt: "desc" },
|
||||
@@ -12,17 +17,25 @@ const nodeDetailInclude = {
|
||||
},
|
||||
},
|
||||
},
|
||||
} satisfies Prisma.NodeServerInclude;
|
||||
} satisfies Prisma.NodeServerSelect;
|
||||
|
||||
export type NodeDetail = Prisma.NodeServerGetPayload<{
|
||||
include: typeof nodeDetailInclude;
|
||||
select: typeof nodeDetailSelect;
|
||||
}>;
|
||||
|
||||
export async function getNodeDetail(id: string): Promise<NodeDetail> {
|
||||
const node = await prisma.nodeServer.findUnique({
|
||||
where: { id },
|
||||
include: nodeDetailInclude,
|
||||
select: nodeDetailSelect,
|
||||
});
|
||||
if (!node) notFound();
|
||||
return node;
|
||||
|
||||
return {
|
||||
...node,
|
||||
inbounds: node.inbounds.map((inbound) => ({
|
||||
...inbound,
|
||||
settings: sanitizeInboundSettings(inbound.settings),
|
||||
streamSettings: sanitizeStreamSettings(inbound.streamSettings),
|
||||
})),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -60,7 +60,6 @@ function NodeCard({ node, siteUrl }: { node: NodeServerRow; siteUrl: string | nu
|
||||
name: node.name,
|
||||
panelUrl: node.panelUrl,
|
||||
panelUsername: node.panelUsername,
|
||||
panelPassword: node.panelPassword,
|
||||
}}
|
||||
triggerLabel="编辑"
|
||||
triggerVariant="outline"
|
||||
|
||||
@@ -22,7 +22,6 @@ interface NodeFormValue {
|
||||
name: string;
|
||||
panelUrl: string | null;
|
||||
panelUsername: string | null;
|
||||
panelPassword: string | null;
|
||||
}
|
||||
|
||||
export function NodeForm({
|
||||
@@ -92,7 +91,13 @@ export function NodeForm({
|
||||
</div>
|
||||
<div>
|
||||
<Label>面板密码</Label>
|
||||
<Input name="panelPassword" type="password" defaultValue={node?.panelPassword ?? ""} required />
|
||||
<Input
|
||||
name="panelPassword"
|
||||
type="password"
|
||||
placeholder={isEdit ? "留空则沿用当前密码" : "请输入面板密码"}
|
||||
required={!isEdit}
|
||||
autoComplete="new-password"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -2,8 +2,15 @@ import type { Prisma } from "@prisma/client";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { parsePage } from "@/lib/utils";
|
||||
import { getConfiguredSiteUrl } from "@/services/site-url";
|
||||
import { sanitizeInboundSettings } from "@/services/node-inbound-sanitize";
|
||||
|
||||
const nodeInclude = {
|
||||
const nodeSelect = {
|
||||
id: true,
|
||||
name: true,
|
||||
panelUrl: true,
|
||||
panelUsername: true,
|
||||
status: true,
|
||||
agentToken: true,
|
||||
_count: { select: { inbounds: true } },
|
||||
inbounds: {
|
||||
where: { isActive: true },
|
||||
@@ -16,10 +23,10 @@ const nodeInclude = {
|
||||
},
|
||||
orderBy: { updatedAt: "desc" },
|
||||
},
|
||||
} satisfies Prisma.NodeServerInclude;
|
||||
} satisfies Prisma.NodeServerSelect;
|
||||
|
||||
export type NodeServerRow = Prisma.NodeServerGetPayload<{
|
||||
include: typeof nodeInclude;
|
||||
select: typeof nodeSelect;
|
||||
}>;
|
||||
|
||||
export async function getNodeServers(
|
||||
@@ -44,7 +51,7 @@ export async function getNodeServers(
|
||||
const [nodes, total, siteUrl] = await Promise.all([
|
||||
prisma.nodeServer.findMany({
|
||||
where,
|
||||
include: nodeInclude,
|
||||
select: nodeSelect,
|
||||
orderBy: { createdAt: "desc" },
|
||||
skip,
|
||||
take: pageSize,
|
||||
@@ -53,5 +60,14 @@ export async function getNodeServers(
|
||||
getConfiguredSiteUrl(),
|
||||
]);
|
||||
|
||||
return { nodes, total, page, pageSize, filters: { q, status }, siteUrl };
|
||||
const safeNodes = nodes.map((node) => ({
|
||||
...node,
|
||||
agentToken: node.agentToken ? "configured" : null,
|
||||
inbounds: node.inbounds.map((inbound) => ({
|
||||
...inbound,
|
||||
settings: sanitizeInboundSettings(inbound.settings),
|
||||
})),
|
||||
}));
|
||||
|
||||
return { nodes: safeNodes, total, page, pageSize, filters: { q, status }, siteUrl };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user