mirror of https://github.com/buster-so/buster.git
update request headers
This commit is contained in:
parent
77597cdd93
commit
62a50b0592
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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>
|
||||
]
|
||||
}),
|
||||
[]
|
||||
);
|
||||
|
|
|
@ -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)
|
||||
);
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue