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); } satisfies AgentPsdTemplateListResponse);
response.headers.set( response.headers.set(
"Cache-Control", "Cache-Control",
"private, max-age=60, stale-while-revalidate=300" "private, no-store, max-age=0"
); );
return response; return response;
} catch (error) { } catch (error) {

View File

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

View File

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