Protect advanced request diagnostics for non-admins
Magent CI/CD / verify (push) Successful in 11m8s
Magent CI/CD / deploy-prod (push) Skipped
Magent CI/CD / deploy-beta (push) Successful in 19s

This commit is contained in:
2026-08-31 16:09:17 +12:00
parent ecf9b230c1
commit 3402e53c31
3 changed files with 129 additions and 21 deletions
+28 -13
View File
@@ -275,6 +275,7 @@ export default function RequestTimelinePage() {
const [historySnapshots, setHistorySnapshots] = useState<SnapshotHistory[]>([])
const [historyActions, setHistoryActions] = useState<ActionHistory[]>([])
const [operationProgress, setOperationProgress] = useState<OperationProgress | null>(null)
const [isAdmin, setIsAdmin] = useState(false)
useEffect(() => {
if (!requestId) return
@@ -287,29 +288,43 @@ export default function RequestTimelinePage() {
return
}
const baseUrl = getApiBase()
const [snapshotResponse, historyResponse, actionsResponse] = await Promise.all([
const [meResponse, snapshotResponse] = await Promise.all([
authFetch(`${baseUrl}/auth/me`),
authFetch(`${baseUrl}/requests/${requestId}/snapshot`),
authFetch(`${baseUrl}/requests/${requestId}/history?limit=10`),
authFetch(`${baseUrl}/requests/${requestId}/actions?limit=10`),
])
if ([snapshotResponse, historyResponse, actionsResponse].some((response) => response.status === 401)) {
if ([meResponse, snapshotResponse].some((response) => response.status === 401)) {
clearToken()
router.push('/login')
return
}
if (!meResponse.ok) {
throw new Error('Unable to verify your request access.')
}
const me = await meResponse.json()
const viewerIsAdmin = me?.role === 'admin'
setIsAdmin(viewerIsAdmin)
if (!snapshotResponse.ok) {
throw new Error(await readApiError(snapshotResponse, 'Unable to load this request.'))
}
const snapshotData = await snapshotResponse.json()
if (!isSnapshotPayload(snapshotData)) throw new Error('Unable to load this request.')
setSnapshot(snapshotData)
if (historyResponse.ok) {
const historyData = await historyResponse.json()
if (Array.isArray(historyData.snapshots)) setHistorySnapshots(historyData.snapshots)
}
if (actionsResponse.ok) {
const actionsData = await actionsResponse.json()
if (Array.isArray(actionsData.actions)) setHistoryActions(actionsData.actions)
if (viewerIsAdmin) {
const [historyResponse, actionsResponse] = await Promise.all([
authFetch(`${baseUrl}/requests/${requestId}/history?limit=10`),
authFetch(`${baseUrl}/requests/${requestId}/actions?limit=10`),
])
if (historyResponse.ok) {
const historyData = await historyResponse.json()
if (Array.isArray(historyData.snapshots)) setHistorySnapshots(historyData.snapshots)
}
if (actionsResponse.ok) {
const actionsData = await actionsResponse.json()
if (Array.isArray(actionsData.actions)) setHistoryActions(actionsData.actions)
}
} else {
setHistorySnapshots([])
setHistoryActions([])
}
} catch (error) {
console.error(error)
@@ -811,7 +826,7 @@ export default function RequestTimelinePage() {
)}
</section>
<section className="request-advanced">
{isAdmin && <section className="request-advanced">
<button type="button" className="request-advanced-toggle" aria-expanded={showDetails} onClick={() => setShowDetails((current) => !current)}>
<span><strong>Advanced details</strong><small>Service diagnostics, status history and recorded actions</small></span>
<span>{showDetails ? 'Hide' : 'Show'}</span>
@@ -846,7 +861,7 @@ export default function RequestTimelinePage() {
</div>
</div>
)}
</section>
</section>}
</main>
)
}