fix permissions
This commit is contained in:
@@ -226,8 +226,8 @@ class BookingController {
|
|||||||
const isOwner = booking.gebucht_von === req.user!.id;
|
const isOwner = booking.gebucht_von === req.user!.id;
|
||||||
const groups: string[] = req.user?.groups ?? [];
|
const groups: string[] = req.user?.groups ?? [];
|
||||||
const isAdmin = groups.includes('dashboard_admin');
|
const isAdmin = groups.includes('dashboard_admin');
|
||||||
const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'kalender:cancel_own_bookings');
|
const canCancelOwn = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings');
|
||||||
const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'kalender:delete_bookings');
|
const canCancelAny = isAdmin || permissionService.hasPermission(groups, 'kalender:manage_bookings');
|
||||||
|
|
||||||
if (!(isOwner && canCancelOwn) && !canCancelAny) {
|
if (!(isOwner && canCancelOwn) && !canCancelAny) {
|
||||||
res.status(403).json({ success: false, message: 'Keine Berechtigung' });
|
res.status(403).json({ success: false, message: 'Keine Berechtigung' });
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ import { requirePermission } from '../middleware/rbac.middleware';
|
|||||||
|
|
||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
// ── Read-only (any authenticated user) ───────────────────────────────────────
|
// ── Read-only ────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
router.get('/', authenticate, atemschutzController.list.bind(atemschutzController));
|
router.get('/', authenticate, requirePermission('atemschutz:view'), atemschutzController.list.bind(atemschutzController));
|
||||||
router.get('/stats', authenticate, atemschutzController.getStats.bind(atemschutzController));
|
router.get('/stats', authenticate, requirePermission('atemschutz:view'), atemschutzController.getStats.bind(atemschutzController));
|
||||||
router.get('/expiring', authenticate, atemschutzController.getExpiring.bind(atemschutzController));
|
router.get('/expiring', authenticate, requirePermission('atemschutz:view'), atemschutzController.getExpiring.bind(atemschutzController));
|
||||||
router.get('/my-status', authenticate, atemschutzController.getMyStatus.bind(atemschutzController));
|
router.get('/my-status', authenticate, atemschutzController.getMyStatus.bind(atemschutzController));
|
||||||
router.get('/user/:userId', authenticate, atemschutzController.getByUserId.bind(atemschutzController));
|
router.get('/user/:userId', authenticate, requirePermission('atemschutz:view'), atemschutzController.getByUserId.bind(atemschutzController));
|
||||||
router.get('/:id', authenticate, atemschutzController.getOne.bind(atemschutzController));
|
router.get('/:id', authenticate, requirePermission('atemschutz:view'), atemschutzController.getOne.bind(atemschutzController));
|
||||||
|
|
||||||
// ── Write — gruppenfuehrer+ ─────────────────────────────────────────────────
|
// ── Write — gruppenfuehrer+ ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ router.delete(
|
|||||||
router.patch(
|
router.patch(
|
||||||
'/:id/status',
|
'/:id/status',
|
||||||
authenticate,
|
authenticate,
|
||||||
requirePermission('bestellungen:create'),
|
requirePermission('bestellungen:manage_orders'),
|
||||||
bestellungController.updateStatus.bind(bestellungController)
|
bestellungController.updateStatus.bind(bestellungController)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ router.get(
|
|||||||
*/
|
*/
|
||||||
router.post(
|
router.post(
|
||||||
'/refresh-stats',
|
'/refresh-stats',
|
||||||
requirePermission('einsaetze:delete'),
|
requirePermission('einsaetze:create'),
|
||||||
incidentController.refreshStats.bind(incidentController)
|
incidentController.refreshStats.bind(incidentController)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ const router = Router();
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// injectTeilnahmenFlag
|
// injectTeilnahmenFlag
|
||||||
//
|
//
|
||||||
// Sets req.canSeeTeilnahmen = true for users with kalender:mark_attendance.
|
// Sets req.canSeeTeilnahmen = true for users with kalender:create.
|
||||||
// Regular Mitglieder see only attendance counts; officers see the full list.
|
// Regular Mitglieder see only attendance counts; officers see the full list.
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@ async function injectTeilnahmenFlag(
|
|||||||
const groups: string[] = req.user?.groups ?? [];
|
const groups: string[] = req.user?.groups ?? [];
|
||||||
(req as any).canSeeTeilnahmen =
|
(req as any).canSeeTeilnahmen =
|
||||||
groups.includes('dashboard_admin') ||
|
groups.includes('dashboard_admin') ||
|
||||||
permissionService.hasPermission(groups, 'kalender:mark_attendance');
|
permissionService.hasPermission(groups, 'kalender:create');
|
||||||
}
|
}
|
||||||
} catch (_err) {
|
} catch (_err) {
|
||||||
// Non-fatal — default to restricted view
|
// Non-fatal — default to restricted view
|
||||||
@@ -67,12 +67,12 @@ router.get('/calendar-token', authenticate, trainingController.getCalendarToken)
|
|||||||
/**
|
/**
|
||||||
* GET /api/training/stats?year=<YYYY>
|
* GET /api/training/stats?year=<YYYY>
|
||||||
* Annual participation stats.
|
* Annual participation stats.
|
||||||
* Requires Kommandant or above (requirePermission('kalender:view_reports')).
|
* Requires Kommandant or above (requirePermission('kalender:create')).
|
||||||
*/
|
*/
|
||||||
router.get(
|
router.get(
|
||||||
'/stats',
|
'/stats',
|
||||||
authenticate,
|
authenticate,
|
||||||
requirePermission('kalender:view_reports'),
|
requirePermission('kalender:create'),
|
||||||
trainingController.getStats
|
trainingController.getStats
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ router.patch(
|
|||||||
router.delete(
|
router.delete(
|
||||||
'/:id',
|
'/:id',
|
||||||
authenticate,
|
authenticate,
|
||||||
requirePermission('kalender:cancel'),
|
requirePermission('kalender:create'),
|
||||||
trainingController.cancelEvent
|
trainingController.cancelEvent
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ router.patch(
|
|||||||
router.post(
|
router.post(
|
||||||
'/:id/attendance/mark',
|
'/:id/attendance/mark',
|
||||||
authenticate,
|
authenticate,
|
||||||
requirePermission('kalender:mark_attendance'),
|
requirePermission('kalender:create'),
|
||||||
trainingController.markAttendance
|
trainingController.markAttendance
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -14,14 +14,8 @@ const DEFAULT_GROUP_HIERARCHY: Record<string, string[]> = {
|
|||||||
|
|
||||||
const DEFAULT_PERMISSION_DEPS: Record<string, string[]> = {
|
const DEFAULT_PERMISSION_DEPS: Record<string, string[]> = {
|
||||||
'kalender:create': ['kalender:view'],
|
'kalender:create': ['kalender:view'],
|
||||||
'kalender:cancel': ['kalender:view'],
|
'kalender:view_bookings': ['kalender:view'],
|
||||||
'kalender:mark_attendance': ['kalender:view'],
|
'kalender:manage_bookings': ['kalender:view', 'kalender:view_bookings'],
|
||||||
'kalender:create_bookings': ['kalender:view'],
|
|
||||||
'kalender:edit_bookings': ['kalender:view', 'kalender:create_bookings'],
|
|
||||||
'kalender:cancel_own_bookings': ['kalender:view'],
|
|
||||||
'kalender:delete_bookings': ['kalender:view', 'kalender:edit_bookings'],
|
|
||||||
'kalender:manage_categories': ['kalender:view'],
|
|
||||||
'kalender:view_reports': ['kalender:view'],
|
|
||||||
'kalender:widget_events': ['kalender:view'],
|
'kalender:widget_events': ['kalender:view'],
|
||||||
'kalender:widget_bookings': ['kalender:view'],
|
'kalender:widget_bookings': ['kalender:view'],
|
||||||
'kalender:widget_quick_add': ['kalender:view', 'kalender:create'],
|
'kalender:widget_quick_add': ['kalender:view', 'kalender:create'],
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ export default function BestellungDetail() {
|
|||||||
const erinnerungen = data?.erinnerungen ?? [];
|
const erinnerungen = data?.erinnerungen ?? [];
|
||||||
const historie = data?.historie ?? [];
|
const historie = data?.historie ?? [];
|
||||||
|
|
||||||
const canEdit = hasPermission('bestellungen:edit');
|
const canEdit = hasPermission('bestellungen:create');
|
||||||
const nextStatus = bestellung ? getNextStatus(bestellung.status) : null;
|
const nextStatus = bestellung ? getNextStatus(bestellung.status) : null;
|
||||||
|
|
||||||
// ── Mutations ──
|
// ── Mutations ──
|
||||||
|
|||||||
@@ -96,10 +96,10 @@ function FahrzeugBuchungen() {
|
|||||||
const { user } = useAuth();
|
const { user } = useAuth();
|
||||||
const { hasPermission } = usePermissionContext();
|
const { hasPermission } = usePermissionContext();
|
||||||
const notification = useNotification();
|
const notification = useNotification();
|
||||||
const canCreate = hasPermission('kalender:create_bookings');
|
const canCreate = hasPermission('kalender:manage_bookings');
|
||||||
const canWrite = hasPermission('kalender:edit_bookings');
|
const canWrite = hasPermission('kalender:manage_bookings');
|
||||||
const canCancelOwn = hasPermission('kalender:cancel_own_bookings');
|
const canCancelOwn = hasPermission('kalender:manage_bookings');
|
||||||
const canChangeBuchungsArt = hasPermission('kalender:manage_categories');
|
const canChangeBuchungsArt = hasPermission('kalender:create');
|
||||||
|
|
||||||
// ── Week navigation ────────────────────────────────────────────────────────
|
// ── Week navigation ────────────────────────────────────────────────────────
|
||||||
const [currentWeekStart, setCurrentWeekStart] = useState<Date>(() =>
|
const [currentWeekStart, setCurrentWeekStart] = useState<Date>(() =>
|
||||||
|
|||||||
@@ -1746,8 +1746,8 @@ export default function Kalender() {
|
|||||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
const canWriteEvents = hasPermission('kalender:create');
|
const canWriteEvents = hasPermission('kalender:create');
|
||||||
const canWriteBookings = hasPermission('kalender:edit_bookings');
|
const canWriteBookings = hasPermission('kalender:manage_bookings');
|
||||||
const canCreateBookings = hasPermission('kalender:create_bookings');
|
const canCreateBookings = hasPermission('kalender:manage_bookings');
|
||||||
|
|
||||||
// ── Tab ─────────────────────────────────────────────────────────────────────
|
// ── Tab ─────────────────────────────────────────────────────────────────────
|
||||||
const [activeTab, setActiveTab] = useState(() => {
|
const [activeTab, setActiveTab] = useState(() => {
|
||||||
|
|||||||
@@ -272,7 +272,7 @@ export default function UebungDetail() {
|
|||||||
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
|
||||||
|
|
||||||
const canWrite = hasPermission('kalender:create');
|
const canWrite = hasPermission('kalender:create');
|
||||||
const canSeeAttendees = hasPermission('kalender:mark_attendance');
|
const canSeeAttendees = hasPermission('kalender:create');
|
||||||
|
|
||||||
const [markAttendanceOpen, setMarkAttendanceOpen] = useState(false);
|
const [markAttendanceOpen, setMarkAttendanceOpen] = useState(false);
|
||||||
const [rsvpLoading, setRsvpLoading] = useState<'zugesagt' | 'abgesagt' | null>(null);
|
const [rsvpLoading, setRsvpLoading] = useState<'zugesagt' | 'abgesagt' | null>(null);
|
||||||
|
|||||||
Reference in New Issue
Block a user