fix(netflow): защитить приватный экспорт и разделить результаты сохранения

This commit is contained in:
Denozordec committed 2026-10-03 12:31:51 +07:00
1 parent 4af4fdc544
commit 8b017bab3f
9 files changed
+120 -31

No files matched your search

@@ -0,0 +1,24 @@
import assert from "node:assert/strict"
import Fastify from "fastify"
import { SignJWT } from "jose"
process.env.AUTH_REQUIRED = "true"
process.env.AUTH_JWT_SECRET = "netflow-test-secret"
process.env.AUTH_ISSUER = "https://auth.test.local"
process.env.NODE_ENV = "test"
const { default: authPlugin, requireAuth } = await import("./auth.js")
const { permissionForRequest } = await import("../lib/permissions.js")
assert.equal(permissionForRequest("GET","/api/traffic/flow/host-files?download=true"),"mm:traffic:write")
assert.equal(permissionForRequest("GET","/api/traffic/flow/settings"),"mm:traffic:read")
const app=Fastify();await app.register(authPlugin);app.addHook("preHandler",requireAuth)
let invoked=0
for(const [method,url] of [["GET","/api/traffic/flow/settings"],["GET","/api/traffic/flow/host-files"],["POST","/api/traffic/flow/settings/generate-keys"],["PUT","/api/traffic/flow/settings"]] as const) app.route({method,url,handler:async()=>{invoked++;return {ok:true}}})
for(const permission of ["mm:dashboard:read","mm:traffic:read","mm:traffic:write","mm:traffic:admin","mm:settings:admin"]){
const token=await new SignJWT({sub:"fixture",apps:["mm"],permissions:[permission]}).setProtectedHeader({alg:"HS256"}).setIssuer("https://auth.test.local").setExpirationTime("1h").sign(new TextEncoder().encode("netflow-test-secret"))
for(const [method,url] of [["GET","/api/traffic/flow/settings"],["GET","/api/traffic/flow/host-files"],["POST","/api/traffic/flow/settings/generate-keys"],["PUT","/api/traffic/flow/settings"]] as const){
const before=invoked;const response=await app.inject({method,url,headers:{authorization:"Bearer "+token}})
const allowed=permission==="mm:traffic:write"||permission==="mm:traffic:admin"||(permission==="mm:traffic:read"&&url.endsWith("/settings")&&method==="GET")
assert.equal(response.statusCode,allowed?200:403,permission+" "+method+" "+url);assert.equal(invoked,before+(allowed?1:0))
}
}
assert.equal((await app.inject({method:"GET",url:"/api/traffic/flow/host-files"})).statusCode,401)
await app.close();console.log("NetFlow JWT gate: private export requires traffic write, settings remain readable")