fix(tests): lock editing for operators until timer starts
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
red_tech can only edit procedure/tool/summary when the test is in red_executing state (after pressing Start Execution). In draft state they see a read-only view and an orange hint 'Press Start Execution to begin editing — the timer must be running first.' blue_tech can only edit when blue_work_started_at is set (after pressing Start Evaluation). Before that they see an indigo hint 'Press Start Evaluation to begin editing — pick up the test first.' red_lead, blue_lead and admin are unaffected — they retain full edit access in all applicable states including draft.
This commit is contained in:
@@ -118,18 +118,46 @@ export default function TeamTabs({
|
|||||||
enabled: !!test.technique_mitre_id,
|
enabled: !!test.technique_mitre_id,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Leads and admins can edit during both draft and executing phases.
|
||||||
|
// Operators (red_tech) may only edit once execution has started —
|
||||||
|
// the timer must be running before they can document the attack.
|
||||||
const canEditRed =
|
const canEditRed =
|
||||||
RED_EDITABLE_STATES.includes(test.state) &&
|
(test.state === "red_executing" &&
|
||||||
(role === "red_tech" || role === "red_lead" || role === "admin");
|
(role === "red_tech" || role === "red_lead" || role === "admin")) ||
|
||||||
|
(test.state === "draft" && (role === "red_lead" || role === "admin"));
|
||||||
|
|
||||||
|
// Blue operators may only edit after they explicitly pick up the test
|
||||||
|
// (Start Evaluation pressed → blue_work_started_at is set).
|
||||||
|
// Blue leads and admins can edit at any point during blue_evaluating.
|
||||||
const canEditBlue =
|
const canEditBlue =
|
||||||
BLUE_EDITABLE_STATES.includes(test.state) &&
|
BLUE_EDITABLE_STATES.includes(test.state) &&
|
||||||
(role === "blue_tech" || role === "blue_lead" || role === "admin");
|
((role === "blue_lead" || role === "admin") ||
|
||||||
|
(role === "blue_tech" && !!test.blue_work_started_at));
|
||||||
|
|
||||||
|
// Hint messages shown to operators when editing is locked
|
||||||
|
const redLockedHint =
|
||||||
|
test.state === "draft" && role === "red_tech"
|
||||||
|
? "Press Start Execution to begin editing — the timer must be running first."
|
||||||
|
: null;
|
||||||
|
|
||||||
|
const blueLockedHint =
|
||||||
|
BLUE_EDITABLE_STATES.includes(test.state) &&
|
||||||
|
role === "blue_tech" &&
|
||||||
|
!test.blue_work_started_at
|
||||||
|
? "Press Start Evaluation to begin editing — pick up the test first."
|
||||||
|
: null;
|
||||||
|
|
||||||
// ── Red Team Tab ─────────────────────────────────────────────────
|
// ── Red Team Tab ─────────────────────────────────────────────────
|
||||||
|
|
||||||
const renderRedTab = () => (
|
const renderRedTab = () => (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
|
{/* Locked hint for red_tech in draft state */}
|
||||||
|
{redLockedHint && (
|
||||||
|
<div className="flex items-center gap-2 rounded-lg border border-orange-500/30 bg-orange-500/5 px-4 py-3 text-sm text-orange-400">
|
||||||
|
<span className="text-base">⏱</span>
|
||||||
|
{redLockedHint}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Procedure */}
|
{/* Procedure */}
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-1.5 block text-sm font-medium text-gray-300">
|
<label className="mb-1.5 block text-sm font-medium text-gray-300">
|
||||||
@@ -262,6 +290,13 @@ export default function TeamTabs({
|
|||||||
|
|
||||||
const renderBlueTab = () => (
|
const renderBlueTab = () => (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
|
{/* Locked hint for blue_tech before Start Evaluation */}
|
||||||
|
{blueLockedHint && (
|
||||||
|
<div className="flex items-center gap-2 rounded-lg border border-indigo-500/30 bg-indigo-500/5 px-4 py-3 text-sm text-indigo-400">
|
||||||
|
<span className="text-base">⏱</span>
|
||||||
|
{blueLockedHint}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
{/* Detection Result */}
|
{/* Detection Result */}
|
||||||
<div>
|
<div>
|
||||||
<label className="mb-2 block text-sm font-medium text-gray-300">
|
<label className="mb-2 block text-sm font-medium text-gray-300">
|
||||||
|
|||||||
Reference in New Issue
Block a user