mirror of
https://github.com/okieselbach/AutopilotMonitor.git
synced 2026-10-25 05:00:07 +00:00
89c5c7da03
The report ZIP now captures everything an operator needs even after the session is gone, and states its own completeness: - session.csv: append the 15 newer Sessions fields that had drifted out of the export (failureSource, reconcileReason, adminMarkedAction, validatedBy, rebootCount, isHybridJoin, isSelfDeployingProfile, connectionType, geo*, avgApiLatencyMs, apiRequestCount, stalledAt, failureSnapshotJson) - completeness signal: exportedEventCount / sessionEventCount / eventStreamActive in the request and report-metadata.json; the modal warns while event pages are still streaming - includedDiagnostics records sourceBlobName/sourceDestination so a failed copy still points at the original archive - tenantContext snapshot (fail-soft): upload mode/destination, gather- rule debug flag, custom gather/analyze rule IDs + UpdatedAt, IME pattern IDs — no secrets, no definitions - robustness: 8 MB client-side screenshot cap (20 MB body cap headroom), attachments status in metadata instead of silently dropping invalid base64, SanitizeZipEntryName strips path components from customer- supplied file names (both report types) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
40 lines
1.4 KiB
C#
40 lines
1.4 KiB
C#
using AutopilotMonitor.Functions.Services;
|
|
using Xunit;
|
|
|
|
namespace AutopilotMonitor.Functions.Tests;
|
|
|
|
/// <summary>
|
|
/// Customer-supplied attachment file names go verbatim into ZIP entry names of the
|
|
/// session-report archive. The sanitizer must strip path components so a crafted name
|
|
/// cannot produce traversal-shaped entries that an extraction tool would write outside
|
|
/// the target directory.
|
|
/// </summary>
|
|
public class SessionReportZipEntryNameTests
|
|
{
|
|
[Theory]
|
|
[InlineData("agent.log", "agent.log")]
|
|
[InlineData("agent_20260729.log", "agent_20260729.log")]
|
|
[InlineData("logs/agent.log", "agent.log")]
|
|
[InlineData("..\\..\\evil.exe", "evil.exe")]
|
|
[InlineData("../../../etc/passwd", "passwd")]
|
|
[InlineData("C:\\Windows\\System32\\bad.dll", "bad.dll")]
|
|
[InlineData(" spaced.log ", "spaced.log")]
|
|
public void SanitizeZipEntryName_StripsPathComponents(string input, string expected)
|
|
{
|
|
Assert.Equal(expected, SessionReportService.SanitizeZipEntryName(input, "fallback.log"));
|
|
}
|
|
|
|
[Theory]
|
|
[InlineData(null)]
|
|
[InlineData("")]
|
|
[InlineData(" ")]
|
|
[InlineData("..")]
|
|
[InlineData(".")]
|
|
[InlineData("logs/")]
|
|
[InlineData("a/../")]
|
|
public void SanitizeZipEntryName_FallsBackWhenNothingUsable(string? input)
|
|
{
|
|
Assert.Equal("fallback.log", SessionReportService.SanitizeZipEntryName(input, "fallback.log"));
|
|
}
|
|
}
|