feat: team activity feed (attacks in/out) + activity tab + auto-refresh + leaderboard tab on team portal

This commit is contained in:
root
2026-09-23 22:56:07 +08:00
parent 877f14ecf3
commit 3ef905b3bb
2 changed files with 160 additions and 4 deletions
+36
View File
@@ -278,6 +278,42 @@ async def api_team_status(idx: int, req: Request):
"ssh": st["ports"][name]["ssh"], "alive": ok})
return {"results": results}
@app.get("/api/team/{idx}/activity")
async def api_team_activity(idx: int, req: Request):
"""Team-scoped activity feed: attack events where this team is attacker or
target (i.e. "ada serangan ke service kita" / "kita menyerang"), plus a
snapshot of own service health. Requires team login + own host."""
td = orch.TEAMS_DIR / f"team{idx}"
if not (td / "state.json").exists():
raise HTTPException(404, "Team not found")
st_self = json.loads((td / "state.json").read_text())
if not _check_team_host(req, st_self):
raise HTTPException(403, "Akses team lain tidak diizinkan")
if not _team_authorized(req, idx):
raise HTTPException(401, "Login portal team dulu")
# live label lookup (rename team = activity updates everywhere)
def label(i):
try:
s = json.loads((orch.TEAMS_DIR / f"team{i}" / "state.json").read_text())
return s.get("label") or f"Team {i}"
except Exception:
return f"Team {i}"
ap = orch.TEAMS_DIR / "attacks.json"
try:
events = json.loads(ap.read_text()).get("events", []) if ap.exists() else []
except Exception:
events = []
mine = []
for e in reversed(events): # newest first
if e.get("attacker") == idx or e.get("target") == idx:
e = dict(e)
e["attacker_label"] = label(e.get("attacker"))
e["target_label"] = label(e.get("target"))
mine.append(e)
return {"events": mine[:100], "team_label": st_self.get("label") or f"Team {idx}"}
@app.post("/api/login")
async def api_login(req: Request):
data = await req.json()