security(docs): prevent stale projection rendering
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { Link, useLocation } from "react-router-dom";
|
||||
import { ChevronDown, ChevronRight, RefreshCw } from "lucide-react";
|
||||
import {
|
||||
@@ -67,20 +67,29 @@ export default function DocsPage({ settings }: { settings: ApiSettings }) {
|
||||
const [context, setContext] = useState<DocsContext | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState("");
|
||||
const loadSequence = useRef(0);
|
||||
const [documentationType, setDocumentationType] = useState<DocumentationType>(() => documentationTypeFromSearch(location.search));
|
||||
const [expandedNodes, setExpandedNodes] = useState<Set<string>>(() => new Set());
|
||||
const locale = localeFromSearch(location.search) ?? language;
|
||||
const adminDocs = documentationType === "admin";
|
||||
|
||||
async function load() {
|
||||
const sequence = ++loadSequence.current;
|
||||
setLoading(true);
|
||||
setError("");
|
||||
setContext(null);
|
||||
try {
|
||||
setContext(await fetchDocsContext(settings, { documentationType, locale }));
|
||||
const nextContext = await fetchDocsContext(settings, { documentationType, locale });
|
||||
if (sequence !== loadSequence.current) return;
|
||||
if (nextContext.actor.documentation_type !== documentationType) {
|
||||
throw new Error("Documentation response type did not match the requested projection.");
|
||||
}
|
||||
setContext(nextContext);
|
||||
} catch (err) {
|
||||
if (sequence !== loadSequence.current) return;
|
||||
setError(adminErrorMessage(err));
|
||||
} finally {
|
||||
setLoading(false);
|
||||
if (sequence === loadSequence.current) setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user