Enforce tenant member permissions
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-01-16 13:33:36 +01:00
parent df60be826d
commit 7aa0a4c847
22 changed files with 592 additions and 112 deletions

View File

@@ -19,6 +19,7 @@ import { setTabHistory } from '../lib/tabHistory';
import { loadPhotoQueue } from '../lib/photoModerationQueue';
import { countQueuedPhotoActions } from '../lib/queueStatus';
import { useAdminTheme } from '../theme';
import { useAuth } from '../../auth/context';
type MobileShellProps = {
title?: string;
@@ -31,6 +32,7 @@ type MobileShellProps = {
export function MobileShell({ title, subtitle, children, activeTab, onBack, headerActions }: MobileShellProps) {
const { events, activeEvent, selectEvent } = useEventContext();
const { user } = useAuth();
const { go } = useMobileNav(activeEvent?.slug, activeTab);
const navigate = useNavigate();
const location = useLocation();
@@ -137,7 +139,22 @@ export function MobileShell({ title, subtitle, children, activeTab, onBack, head
const pageTitle = title ?? t('header.appName', 'Event Admin');
const eventContext = !isCompactHeader && effectiveActive ? resolveEventDisplayName(effectiveActive) : null;
const subtitleText = subtitle ?? eventContext ?? '';
const showQr = Boolean(effectiveActive?.slug);
const isMember = user?.role === 'member';
const memberPermissions = Array.isArray(effectiveActive?.member_permissions) ? effectiveActive?.member_permissions ?? [] : [];
const allowPermission = (permission: string) => {
if (!isMember) {
return true;
}
if (memberPermissions.includes('*') || memberPermissions.includes(permission)) {
return true;
}
if (permission.includes(':')) {
const [prefix] = permission.split(':');
return memberPermissions.includes(`${prefix}:*`);
}
return false;
};
const showQr = Boolean(effectiveActive?.slug) && allowPermission('join-tokens:manage');
const headerBackButton = onBack ? (
<HeaderActionButton onPress={onBack} ariaLabel={t('actions.back', 'Back')}>
<XStack alignItems="center" space="$1.5">