mirror of
https://github.com/actualbudget/actual.git
synced 2026-03-20 22:28:08 -05:00
71 lines
1.8 KiB
TypeScript
71 lines
1.8 KiB
TypeScript
import { useEffect, useState } from 'react';
|
|
import type { ReactElement } from 'react';
|
|
import { Trans } from 'react-i18next';
|
|
|
|
import { View } from '@actual-app/components/view';
|
|
|
|
import type { RemoteFile, SyncedLocalFile } from 'loot-core/types/file';
|
|
|
|
import { useAuth } from './AuthProvider';
|
|
import type { Permissions } from './types';
|
|
|
|
import { useMetadataPref } from '#hooks/useMetadataPref';
|
|
import { useSelector } from '#redux';
|
|
|
|
type ProtectedRouteProps = {
|
|
permission: Permissions;
|
|
element: ReactElement;
|
|
validateOwner?: boolean;
|
|
};
|
|
|
|
export const ProtectedRoute = ({
|
|
element,
|
|
permission,
|
|
validateOwner,
|
|
}: ProtectedRouteProps) => {
|
|
const { hasPermission } = useAuth();
|
|
const [permissionGranted, setPermissionGranted] = useState(false);
|
|
const [cloudFileId] = useMetadataPref('cloudFileId');
|
|
const allFiles = useSelector(state => state.budgetfiles.allFiles || []);
|
|
const remoteFiles = allFiles.filter(
|
|
(f): f is SyncedLocalFile | RemoteFile =>
|
|
f.state === 'remote' || f.state === 'synced' || f.state === 'detached',
|
|
);
|
|
const currentFile = remoteFiles.find(f => f.cloudFileId === cloudFileId);
|
|
const userData = useSelector(state => state.user.data);
|
|
|
|
useEffect(() => {
|
|
const hasRequiredPermission = hasPermission(permission);
|
|
setPermissionGranted(hasRequiredPermission);
|
|
|
|
if (!hasRequiredPermission && validateOwner) {
|
|
if (currentFile) {
|
|
setPermissionGranted(
|
|
currentFile.usersWithAccess.some(u => u.userId === userData?.userId),
|
|
);
|
|
}
|
|
}
|
|
}, [
|
|
cloudFileId,
|
|
permission,
|
|
validateOwner,
|
|
hasPermission,
|
|
currentFile,
|
|
userData,
|
|
]);
|
|
|
|
return permissionGranted ? (
|
|
element
|
|
) : (
|
|
<View
|
|
style={{
|
|
margin: '50px',
|
|
}}
|
|
>
|
|
<h3>
|
|
<Trans>You don't have permission to view this page</Trans>
|
|
</h3>
|
|
</View>
|
|
);
|
|
};
|