fix(findings): 补齐「按资产」视图的 mock,修两处标签重复
demo 模式(NEXT_PUBLIC_MOCK=1)下资产树接口没有实现,点开是空白。 - mock findings 关联到 fixture 里已有的资产:一条挂两个资产(验证父节点不重复 计数)、一条不挂(演示「未关联资产」桶) - mock handler 实现 asset-tree,并在平铺/分组两个列表分支接上 asset_scope。 父子优先级、祖先补齐、去重计数、企业层出现条件都与 db/finding_assets.go 一致;顺带把三处重复的筛选链抽成 mockFilterFindings - 没有 URL 的服务(SMB、非 HTTP 端口)标签回退成裸 IP,与宿主那行显示得一模 一样 —— 后端与 mock 都改为补端口(10.10.10.20:8080) - 接口挂在 host:port 形式的服务下时没触发简写,仍显示完整 URL。宿主判断统一 成解析后的 host,现在显示 /script 跑 mock handler 实测:17 个节点逐个对账「树上 total == 该节点子树查出的条数」, 无不一致。
This commit is contained in:
1 parent
23cfb9ed4e
commit
48e14e8cf2
4 files changed
+352
-33
No files matched your search
@@ -66,6 +66,15 @@ function parseAssetURL(raw: string): URL | null {
|
||||
}
|
||||
}
|
||||
|
||||
// hostOf 取一个节点代表的宿主:URL 取 hostname,「host:port」取 host,其余就是
|
||||
// 标签本身(根域名 / 子域名 / IP)。
|
||||
function hostOf(label: string): string {
|
||||
const url = parseAssetURL(label);
|
||||
if (url) return stripBrackets(url.hostname);
|
||||
const hostPort = label.match(/^(.+):(\d+)$/);
|
||||
return stripBrackets(hostPort ? hostPort[1] : label);
|
||||
}
|
||||
|
||||
// shortLabel 去掉与父节点重复的前缀。service / endpoint 的 label 是完整 URL,而
|
||||
// 宿主域名/IP 上一行已经写过了 —— 深层节点本来就窄,再把 host 重复一遍,真正有
|
||||
// 信息量的端口和路径就全被截断掉了。完整值仍在 title 与面包屑里。
|
||||
@@ -78,16 +87,17 @@ function shortLabel(node: FindingAssetNode, parent?: FindingAssetNode): string {
|
||||
}
|
||||
if (node.kind !== "service" && node.kind !== "endpoint") return node.label;
|
||||
|
||||
// 接口挂在服务下:直接砍掉服务那段前缀,剩下的就是路径。
|
||||
// 父标签正好是自己的前缀(接口挂在同 URL 的服务下、服务挂在同 IP 下):直接砍掉。
|
||||
if (node.label.startsWith(parent.label)) {
|
||||
return node.label.slice(parent.label.length) || node.label;
|
||||
}
|
||||
|
||||
// 否则只有父节点确实就是这个 URL 的宿主时才简写,不然会丢掉辨识信息
|
||||
// (比如服务因为缺子域名资产行而直接挂在根域名下,那就得显示完整 URL)。
|
||||
if (hostOf(node.label) !== hostOf(parent.label)) return node.label;
|
||||
|
||||
const url = parseAssetURL(node.label);
|
||||
if (!url) return node.label;
|
||||
// 只有父节点确实就是这个 URL 的宿主时才简写,否则会丢掉辨识信息。
|
||||
if (stripBrackets(url.hostname) !== parent.label) return node.label;
|
||||
|
||||
if (node.kind === "endpoint") return `${url.pathname}${url.search}` || "/";
|
||||
const scheme = url.protocol.replace(":", "");
|
||||
const port = url.port || (url.protocol === "https:" ? "443" : "80");
|
||||
|
||||
Reference in new issue
Block a user