fix(jira,evidence,tempo,settings): 4-issue fix batch
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

Jira — PoC custom field:
- Add customfield_10309 (Proof of Concept) to issue fields when creating
  test tickets so the attack procedure appears in the dedicated Jira field

Tempo — blue team exclusion:
- Remove blue_team_evaluation from _TEMPO_ACTIVITY_TYPES; blue team time
  is tracked internally (worklogs) for SLA but never sent to Tempo since
  blue team has no Jira access

Evidence — uploaded_at NULL fix:
- Set uploaded_at=datetime.utcnow() explicitly in upload_evidence router;
  the DB column has no server default so it was saving as NULL

Evidence — presigned URL browser access:
- Add MINIO_PUBLIC_ENDPOINT setting (config.py, docker-compose.prod.yml)
- storage.py uses a dedicated _public_client for presigned URL generation
  so browsers receive URLs with the publicly accessible hostname instead of
  the internal Docker service name (minio:9000)
- Expose MinIO port 9000 in docker-compose.prod.yml

Evidence — Jira attachment:
- After upload to MinIO, call jira.add_attachment() to attach the file to
  the linked Jira ticket (non-fatal; errors are logged and swallowed)

Settings — hide Jira/Tempo from blue team:
- ProfileSection checks user role; blue_lead and blue_tech do not see the
  Jira Integration or Tempo Integration personal settings sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-05-28 11:06:31 +02:00
parent d8a0b0c449
commit c886b6e8bb
7 changed files with 86 additions and 9 deletions

View File

@@ -810,6 +810,9 @@ function NotificationSection() {
function ProfileSection() {
const qc = useQueryClient();
const [toast, setToast] = useState<{ msg: string; type: "success" | "error" } | null>(null);
const { user } = useAuth();
// Blue team roles have no Jira/Tempo access — hide those settings for them
const showJiraTempoSettings = !["blue_lead", "blue_tech"].includes(user?.role ?? "");
const { data: me, isLoading } = useQuery({
queryKey: ["me-prefs"],
@@ -927,7 +930,7 @@ function ProfileSection() {
</div>
</div>
<div className="border-t border-gray-800 pt-4">
{showJiraTempoSettings && <div className="border-t border-gray-800 pt-4">
<p className="text-sm font-semibold text-gray-300 mb-1">Jira Integration (personal settings)</p>
<p className="text-xs text-gray-500 mb-4">
Configure your personal Atlassian credentials for Jira integration.
@@ -1020,10 +1023,10 @@ function ProfileSection() {
</p>
</div>
</div>
</div>
</div>}
{/* ── Tempo Integration ─────────────────────────────────── */}
<div className="border-t border-gray-800 pt-4">
{showJiraTempoSettings && <div className="border-t border-gray-800 pt-4">
<p className="text-sm font-semibold text-gray-300 mb-1">Tempo Integration (personal settings)</p>
<p className="text-xs text-gray-500 mb-4">
Your personal Tempo API token logs work time on Jira tickets automatically.
@@ -1119,7 +1122,7 @@ function ProfileSection() {
</button>
</div>
</div>
</div>
</div>}
</div>
</>
);