update request headers

This commit is contained in:
Nate Kelley 2025-03-18 15:49:50 -06:00
parent 77597cdd93
commit 62a50b0592
No known key found for this signature in database
GPG Key ID: FD90372AB8D98B4F
9 changed files with 118 additions and 15 deletions

View File

@ -1,14 +1,17 @@
import React from 'react';
import { ASSET_ICONS } from '../config/assetIcons';
import { Button } from '@/components/ui/buttons';
import { AppTooltip } from '@/components/ui/tooltip';
export const CollectionButton: React.FC<{
buttonType?: 'ghost' | 'default';
useText?: boolean;
}> = ({ buttonType = 'default', useText = false }) => {
return (
<Button prefix={<ASSET_ICONS.collections />} variant={buttonType}>
{useText ? 'Collections' : ''}
</Button>
<AppTooltip title={!useText ? 'Add to collection' : ''}>
<Button prefix={<ASSET_ICONS.collections />} variant={buttonType}>
{useText ? 'Collections' : ''}
</Button>
</AppTooltip>
);
};

View File

@ -1,9 +1,9 @@
import { Button } from '@/components/ui/buttons';
import { ShareRight3 } from '@/components/ui/icons';
import { ShareRight, ShareRight3 } from '@/components/ui/icons';
import React from 'react';
export const ShareButton = React.memo(() => {
return <Button variant="ghost" prefix={<ShareRight3 />} />;
return <Button variant="ghost" prefix={<ShareRight />} />;
});
ShareButton.displayName = 'ShareButton';

View File

@ -164,3 +164,61 @@ export const CustomOverlay: Story = {
)
}
};
export const EmptyColumnSizes: Story = {
args: {
rows: [
{
id: uuidv4(),
items: [
{
id: uuidv4(),
children: <ExampleContent text="Row 1 Item 1" />
},
{
id: uuidv4(),
children: <ExampleContent text="Row 1 Item 2" />
}
],
columnSizes: [],
rowHeight: MIN_ROW_HEIGHT
},
{
id: uuidv4(),
items: [
{
id: uuidv4(),
children: <ExampleContent text="Row 2 Item 1" />
},
{
id: uuidv4(),
children: <ExampleContent text="Row 2 Item 2" />
},
{
id: uuidv4(),
children: <ExampleContent text="Row 2 Item 3" />
}
],
columnSizes: [],
rowHeight: MIN_ROW_HEIGHT
},
{
id: uuidv4(),
items: [
{
id: uuidv4(),
children: <ExampleContent text="Row 3 Item 1" />
},
{
id: uuidv4(),
children: <ExampleContent text="Row 3 Item 2" />
}
],
columnSizes: [],
rowHeight: MIN_ROW_HEIGHT
}
],
onRowLayoutChange: fn(),
readOnly: false
}
};

View File

@ -57,8 +57,6 @@ export const BusterResizeableGrid: React.FC<{
const [rows, setRows] = useState<BusterResizeableGridRow[]>(serverRows);
const styleRef = useRef<HTMLStyleElement>(undefined);
console.log(serverRows);
const onRowLayoutChangePreflight = useMemoizedFn((newLayout: BusterResizeableGridRow[]) => {
const filteredRows = newRowPreflight(newLayout);

View File

@ -10,6 +10,7 @@ import { ShareDashboardButton } from '@/components/features/buttons/ShareDashboa
import { Button } from '@/components/ui/buttons';
import { Plus } from '@/components/ui/icons';
import { DashboardThreeDotMenu } from './DashboardThreeDotMenu';
import { AppTooltip } from '@/components/ui/tooltip';
export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps> = React.memo(
() => {
@ -19,7 +20,8 @@ export const DashboardContainerHeaderButtons: React.FC<FileContainerButtonsProps
return (
<FileButtonContainer>
<SaveToCollectionButton />
<ShareDashboardButton dashboardId={selectedFileId} /> <AddContentToDashboardButton />
<ShareDashboardButton dashboardId={selectedFileId} />
<AddContentToDashboardButton />
<DashboardThreeDotMenu dashboardId={selectedFileId} />
<HideButtonContainer show={renderViewLayoutKey === 'file'}>
<CreateChatButton />
@ -39,9 +41,9 @@ SaveToCollectionButton.displayName = 'SaveToCollectionButton';
const AddContentToDashboardButton = React.memo(() => {
return (
<div>
<AppTooltip title="Add to dashboard">
<Button variant="ghost" prefix={<Plus />} />
</div>
</AppTooltip>
);
});
AddContentToDashboardButton.displayName = 'AddContentToDashboardButton';

View File

@ -251,7 +251,11 @@ const useFilterDashboardSelectMenu = () => {
label: 'Filter dashboard',
value: 'filter-dashboard',
icon: <Filter />,
items: [<div key="coming-soon">Coming soon...</div>]
items: [
<div className="p-2" key="coming-soon">
Coming soon...
</div>
]
}),
[]
);

View File

@ -13,7 +13,6 @@ export async function middleware(request: NextRequest) {
nextPathnameMiddleware(request, supabaseResponse);
if (performUserCheck && !user) {
console.log(performUserCheck, user, request.nextUrl.pathname);
return NextResponse.redirect(
new URL(createBusterRoute({ route: BusterRoutes.AUTH_LOGIN }), process.env.NEXT_PUBLIC_URL)
);

View File

@ -43,7 +43,7 @@ const embedCspHeader = {
// Fonts
"font-src 'self' https://fonts.gstatic.com",
// Frame ancestors - allow embedding from any domain for /embed routes
'frame-ancestors *',
`frame-ancestors 'self' *`,
// Connect sources for API calls
"connect-src 'self' https://*.vercel.app https://*.supabase.co wss://*.supabase.co",
// Media
@ -65,15 +65,23 @@ export const cspPolicyMiddleware = (request: NextRequest) => {
// Add CSP headers based on route
request.headers.set(
'Content-Security-Policy',
isEmbedRoute
(isEmbedRoute
? embedCspHeader['Content-Security-Policy']
: defaultCspHeader['Content-Security-Policy']
).trim()
);
// Add additional security headers
if (!isEmbedRoute) request.headers.set('X-Frame-Options', 'DENY');
if (isEmbedRoute) {
request.headers.set('X-Frame-Options', 'ALLOW-FROM *');
} else {
request.headers.set('X-Frame-Options', 'DENY');
}
request.headers.set('X-Content-Type-Options', 'nosniff');
request.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
request.headers.set('frame-ancestors', '*');
console.log('request.headers', isEmbedRoute ? 'embed' : 'default', request.headers);
return request;
};

View File

@ -0,0 +1,31 @@
import { isEmbedPage } from './publicPageMiddleware';
// Unit tests for isEmbedPage
describe('isEmbedPage', () => {
it('should return true for embed metric routes', () => {
const request = {
nextUrl: {
pathname: '/embed/metrics/123'
}
} as any;
expect(isEmbedPage(request)).toBe(true);
});
it('should return true for embed dashboard routes', () => {
const request = {
nextUrl: {
pathname: '/embed/dashboards/456'
}
} as any;
expect(isEmbedPage(request)).toBe(true);
});
it('should return false for non-embed routes', () => {
const request = {
nextUrl: {
pathname: '/metrics/123'
}
} as any;
expect(isEmbedPage(request)).toBe(false);
});
});