mirror of https://github.com/buster-so/buster.git
must be org member
This commit is contained in:
parent
f406dd5ca3
commit
3bff20c8e0
|
@ -40,14 +40,7 @@ export const requireAuth = bearerAuth({
|
|||
|
||||
c.set('busterUser', busterUser);
|
||||
|
||||
// Ensure user is not anonymous
|
||||
const isAuthenticated = !data.user.is_anonymous;
|
||||
|
||||
if (!isAuthenticated) {
|
||||
console.info('Anonymous user attempted to access protected resource');
|
||||
}
|
||||
|
||||
return isAuthenticated;
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error('Unexpected error during token validation:', error);
|
||||
return false;
|
||||
|
|
|
@ -1,19 +1,23 @@
|
|||
import type { AssetType } from '@buster/server-shared/assets';
|
||||
import type { QueryClient } from '@tanstack/react-query';
|
||||
import { prefetchGetMetric } from '@/api/buster_rest/metrics';
|
||||
import { useGetMetricParams } from '@/context/Metrics/useGetMetricParams';
|
||||
import { MetricViewChartController } from '@/controllers/MetricController/MetricViewChartController';
|
||||
import { AppAssetCheckLayout } from '@/layouts/AppAssetCheckLayout';
|
||||
|
||||
export const ssr = true;
|
||||
|
||||
export const component = () => {
|
||||
const { metricId } = useGetMetricParams();
|
||||
return (
|
||||
<MetricViewChartController
|
||||
metricId={metricId}
|
||||
className="h-full w-full"
|
||||
cardClassName="max-h-full!"
|
||||
readOnly
|
||||
/>
|
||||
<AppAssetCheckLayout assetType={'metric_file'}>
|
||||
<MetricViewChartController
|
||||
metricId={metricId}
|
||||
className="h-full w-full"
|
||||
cardClassName="max-h-full!"
|
||||
readOnly
|
||||
/>
|
||||
</AppAssetCheckLayout>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -38,3 +42,7 @@ export const loader = async ({
|
|||
title: metric?.name,
|
||||
};
|
||||
};
|
||||
|
||||
export const staticData = {
|
||||
assetType: 'metric_file' as AssetType,
|
||||
};
|
||||
|
|
|
@ -48,6 +48,17 @@ const getAssetAccess = (
|
|||
};
|
||||
}
|
||||
|
||||
// 403 is no access
|
||||
if (error?.status === 403) {
|
||||
return {
|
||||
hasAccess: false,
|
||||
passwordRequired: false,
|
||||
isPublic: false,
|
||||
isDeleted: false,
|
||||
isFetched,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
hasAccess: true,
|
||||
passwordRequired: false,
|
||||
|
@ -86,7 +97,7 @@ export const useGetAssetPasswordConfig = (
|
|||
return chatQueryKeys.chatsGetChat(assetId);
|
||||
}, [type, assetId, chosenVersionNumber]);
|
||||
|
||||
const { error, isFetched } = useQuery({
|
||||
const { error, isFetched, data } = useQuery({
|
||||
queryKey: selectedQuery.queryKey,
|
||||
enabled: true,
|
||||
select: useCallback((v: unknown) => !!v, []),
|
||||
|
|
|
@ -10,21 +10,17 @@ export const Route = createFileRoute('/app/_app/_asset')({
|
|||
beforeLoad: async ({ matches }) => {
|
||||
const assetType = [...matches].reverse().find(({ staticData }) => staticData?.assetType)
|
||||
?.staticData?.assetType as AssetType;
|
||||
return {
|
||||
assetType,
|
||||
};
|
||||
return { assetType };
|
||||
},
|
||||
loader: async ({ context }) => {
|
||||
const { assetType } = context;
|
||||
return {
|
||||
assetType,
|
||||
};
|
||||
return { assetType };
|
||||
},
|
||||
});
|
||||
|
||||
const stableCtxSelector = (ctx: RouteContext) => ctx.assetType;
|
||||
function RouteComponent() {
|
||||
const assetType = Route.useRouteContext({ select: stableCtxSelector }) || 'metric_file';
|
||||
const assetType = Route.useLoaderData({ select: stableCtxSelector }) || 'metric_file';
|
||||
|
||||
return (
|
||||
<AppAssetCheckLayout assetType={assetType}>
|
||||
|
|
|
@ -1,15 +1,41 @@
|
|||
import { createFileRoute, Outlet } from '@tanstack/react-router';
|
||||
import type { AssetType } from '@buster/server-shared/assets';
|
||||
import { createFileRoute, Outlet, type RouteContext } from '@tanstack/react-router';
|
||||
import { prefetchGetMyUserInfo } from '@/api/buster_rest/users';
|
||||
import { signInWithAnonymousUser } from '@/integrations/supabase/signIn';
|
||||
import { AppAssetCheckLayout } from '@/layouts/AppAssetCheckLayout';
|
||||
|
||||
export const Route = createFileRoute('/embed')({
|
||||
beforeLoad: async ({ context }) => {
|
||||
beforeLoad: async ({ context, matches }) => {
|
||||
const user = await prefetchGetMyUserInfo(context.queryClient);
|
||||
if (!user) await signInWithAnonymousUser(); //we fallback to an anonymous user
|
||||
|
||||
const assetType = [...matches].reverse().find(({ staticData }) => staticData?.assetType)
|
||||
?.staticData?.assetType as AssetType;
|
||||
return {
|
||||
assetType,
|
||||
};
|
||||
},
|
||||
loader: async ({ context }) => {
|
||||
const { assetType } = context;
|
||||
return { assetType };
|
||||
},
|
||||
component: RouteComponent,
|
||||
ssr: false,
|
||||
});
|
||||
|
||||
const stableCtxSelector = (ctx: RouteContext) => ctx.assetType;
|
||||
function RouteComponent() {
|
||||
return <Outlet />;
|
||||
const assetType = Route.useLoaderData({ select: stableCtxSelector });
|
||||
|
||||
if (!assetType) {
|
||||
return (
|
||||
<div className="flex h-full w-full items-center justify-center">No asset type found</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<AppAssetCheckLayout assetType={assetType}>
|
||||
<Outlet />
|
||||
</AppAssetCheckLayout>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ export const Route = createFileRoute('/embed/dashboard/$dashboardId')({
|
|||
};
|
||||
},
|
||||
component: RouteComponent,
|
||||
staticData: {
|
||||
assetType: 'dashboard_file',
|
||||
},
|
||||
ssr: true,
|
||||
});
|
||||
|
||||
|
|
|
@ -30,6 +30,9 @@ export const Route = createFileRoute('/embed/report/$reportId')({
|
|||
],
|
||||
};
|
||||
},
|
||||
staticData: {
|
||||
assetType: 'report_file',
|
||||
},
|
||||
});
|
||||
|
||||
function RouteComponent() {
|
||||
|
|
|
@ -8,7 +8,6 @@ import {
|
|||
reportFiles,
|
||||
users,
|
||||
} from '../../schema';
|
||||
import { AssetPermissionRoleSchema } from '../../schema-types';
|
||||
import { getAssetPermission } from '../assets';
|
||||
import { getOrganizationMemberCount, getUserOrganizationId } from '../organizations';
|
||||
|
||||
|
@ -27,11 +26,8 @@ export async function getReportFileById(input: GetReportInput) {
|
|||
|
||||
const userOrg = await getUserOrganizationId(userId);
|
||||
|
||||
if (!userOrg?.organizationId) {
|
||||
throw new Error('User not found in any organization');
|
||||
}
|
||||
|
||||
const { organizationId } = userOrg;
|
||||
const organizationId = userOrg?.organizationId || '';
|
||||
const isOrganizationMember = organizationId !== '';
|
||||
|
||||
const reportCollectionsQuery = db
|
||||
.select({
|
||||
|
@ -73,13 +69,7 @@ export async function getReportFileById(input: GetReportInput) {
|
|||
})
|
||||
.from(reportFiles)
|
||||
.innerJoin(users, eq(reportFiles.createdBy, users.id))
|
||||
.where(
|
||||
and(
|
||||
eq(reportFiles.id, reportId),
|
||||
eq(reportFiles.organizationId, organizationId),
|
||||
isNull(reportFiles.deletedAt)
|
||||
)
|
||||
)
|
||||
.where(and(eq(reportFiles.id, reportId), isNull(reportFiles.deletedAt)))
|
||||
.limit(1);
|
||||
|
||||
// Individual permissions query - get users with direct permissions to this report
|
||||
|
@ -111,9 +101,9 @@ export async function getReportFileById(input: GetReportInput) {
|
|||
userPermission,
|
||||
] = await Promise.all([
|
||||
reportDataQuery,
|
||||
reportCollectionsQuery,
|
||||
individualPermissionsQuery,
|
||||
getOrganizationMemberCount(organizationId),
|
||||
isOrganizationMember ? reportCollectionsQuery : Promise.resolve([]),
|
||||
isOrganizationMember ? individualPermissionsQuery : Promise.resolve([]),
|
||||
isOrganizationMember ? getOrganizationMemberCount(organizationId) : Promise.resolve(0),
|
||||
getAssetPermission(userId, reportId, 'report_file'),
|
||||
]);
|
||||
const reportData = reportDataResult[0];
|
||||
|
|
Loading…
Reference in New Issue