fix: prevent psd templates leaking across brands
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled

This commit is contained in:
Your Name 2026-04-27 22:49:35 +08:00
parent 5fb1b5e652
commit dfec8d7ee3
3 changed files with 37 additions and 15 deletions

View File

@ -174,7 +174,7 @@ export async function GET(request: NextRequest) {
} satisfies AgentPsdTemplateListResponse);
response.headers.set(
"Cache-Control",
"private, max-age=60, stale-while-revalidate=300"
"private, no-store, max-age=0"
);
return response;
} catch (error) {

View File

@ -4585,6 +4585,12 @@ export function AgentGenerationWorkspaceDarkV2({
</Collapsible>
);
const currentPsdWorkflowContext = getLatestWorkflowContext?.() ?? workflowContext;
const currentPsdBrandName = String(currentPsdWorkflowContext?.brand || "").trim();
const currentPsdFifthCategory = String(
currentPsdWorkflowContext?.fifthCategory || ""
).trim();
return (
<div className="flex h-dvh flex-col overflow-hidden bg-black">
<AgentCanvasTopNavDark
@ -6433,8 +6439,8 @@ export function AgentGenerationWorkspaceDarkV2({
resetKeys={[
isPsdTemplateDialogOpen ? "open" : "closed",
psdTemplateDialogSourceUrl || "",
workflowContext?.brand || "",
workflowContext?.fifthCategory || "",
currentPsdBrandName,
currentPsdFifthCategory,
psdTemplateDialogMode,
]}
fallback={
@ -6472,9 +6478,9 @@ export function AgentGenerationWorkspaceDarkV2({
}
}}
sourceImageUrl={psdTemplateDialogSourceUrl}
brandName={workflowContext?.brand || null}
selectedCategoryNames={[workflowContext?.fifthCategory || ""].filter(Boolean)}
sizeInfoText={workflowContext?.summaryText || null}
brandName={currentPsdBrandName || null}
selectedCategoryNames={[currentPsdFifthCategory].filter(Boolean)}
sizeInfoText={currentPsdWorkflowContext?.summaryText || null}
templateMode={psdTemplateDialogMode}
onDerivedImageCreated={
onResultPreviewUrlsChange ? handlePsdDerivedImageCreated : undefined

View File

@ -115,7 +115,7 @@ function buildTemplateListRequestUrl(params?: {
const fetcher = async (url: string): Promise<AgentPsdTemplateListResponse> => {
try {
const response = await fetch(url, { cache: "default" });
const response = await fetch(url, { cache: "no-store" });
const payload = (await response
.json()
.catch(() => null)) as Partial<AgentPsdTemplateListResponse> | null;
@ -511,6 +511,15 @@ function normalizeManagedBrandName(value?: string | null) {
return normalized;
}
function matchesTemplateBrand(template: AgentPsdTemplate, brandName?: string | null) {
const normalizedBrandName = normalizeManagedBrandName(brandName).toLowerCase();
if (!normalizedBrandName) {
return true;
}
return normalizeManagedBrandName(template.brandName).toLowerCase() === normalizedBrandName;
}
function getEffectiveTemplateCategoryTags(
template: AgentPsdTemplate,
activeCategoryTags: string[]
@ -1449,14 +1458,21 @@ export function AgentPsdTemplateEditorDialog({
);
const templates = useMemo(
() =>
allTemplates.filter((template) =>
matchesTemplateSelectedCategories(
template,
normalizedSelectedCategoryNames,
activeCategoryTags
)
),
[activeCategoryTags, allTemplates, normalizedSelectedCategoryNames]
allTemplates
.filter((template) => matchesTemplateBrand(template, normalizedBrandName))
.filter((template) =>
matchesTemplateSelectedCategories(
template,
normalizedSelectedCategoryNames,
activeCategoryTags
)
),
[
activeCategoryTags,
allTemplates,
normalizedBrandName,
normalizedSelectedCategoryNames,
]
);
const [selectedTemplateId, setSelectedTemplateId] = useState<string>("");
const selectedTemplateDetailRequestUrl = useMemo(() => {