frontend/hooks/usePermissions.ts (view raw)
1import { PassengerEntity, TravelEntity } from '../generated/graphql';
2import useEventStore from '../stores/useEventStore';
3import useProfile from './useProfile';
4
5interface UserPermissions {
6 canEditEventOptions: () => boolean;
7 canEditEventDetails: () => boolean;
8 canEditWaitingList: () => boolean;
9 canAddTravel: () => boolean;
10 canEditTravel: (travel: TravelEntity) => boolean;
11 canJoinTravels: () => boolean;
12 canAddToTravel: () => boolean;
13 canDeletePassenger: (passenger: PassengerEntity) => boolean;
14 canSeePassengerDetails: (passenger: PassengerEntity) => boolean;
15}
16
17const noPermissions = {
18 canEditEventOptions: () => false,
19 canEditEventDetails: () => false,
20 canEditWaitingList: () => false,
21 canAddTravel: () => false,
22 canEditTravel: () => false,
23 canJoinTravels: () => false,
24 canAddToTravel: () => false,
25 canDeletePassenger: () => false,
26 canSeePassengerDetails: () => false,
27};
28
29const usePermissions = (): { userPermissions: UserPermissions } => {
30 const { event } = useEventStore();
31 const { profile, connected, userId } = useProfile();
32
33 const carosterPlus = event?.enabled_modules?.includes('caroster-plus');
34 const userIsAnonymous = !connected;
35 const userIsEventCreator = event && profile?.email === event.email;
36 const userIsEventAdmin = event?.administrators?.includes(profile?.email);
37
38 const allPermissions: UserPermissions = {
39 canEditEventOptions: () => true,
40 canEditEventDetails: () => true,
41 canEditWaitingList: () => true,
42 canAddTravel: () => true,
43 canEditTravel: () => true,
44 canJoinTravels: () => true,
45 canAddToTravel: () => true,
46 canDeletePassenger: () => true,
47 canSeePassengerDetails: () => true,
48 };
49
50 if (carosterPlus) {
51 if (userIsAnonymous) return { userPermissions: noPermissions };
52 else if (userIsEventCreator || userIsEventAdmin)
53 return {
54 userPermissions: { ...allPermissions, canAddToTravel: () => false },
55 };
56 else {
57 const carosterPlusPermissions: UserPermissions = {
58 ...noPermissions,
59 canEditTravel: travel => {
60 const travelCreatorId =
61 travel.attributes.user?.data?.id || travel.attributes.user;
62 return travelCreatorId === userId;
63 },
64 canJoinTravels: () => true,
65 canAddTravel: () => true,
66 canDeletePassenger: passenger => {
67 const travel = event?.travels?.data?.find(travel =>
68 travel.attributes.passengers.data.some(
69 travelPassenger => travelPassenger.id === passenger.id
70 )
71 );
72 const isTravelCreator = travel?.attributes.user?.data?.id === userId;
73 const isCurrentPassenger =
74 passenger.attributes.user?.data?.id === userId;
75 return isTravelCreator || isCurrentPassenger;
76 },
77 canSeePassengerDetails: (passenger) => {
78 const travel = event?.travels?.data?.find(travel => travel?.id === passenger.attributes.travel.data?.id)
79 const userIsDriver = travel?.attributes.user?.data?.id === userId;
80 return userIsDriver || passenger.attributes.user?.data?.id === userId;
81 }
82 };
83 return { userPermissions: carosterPlusPermissions };
84 }
85 }
86 // Caroster Vanilla permissions
87 else
88 return {
89 userPermissions: {
90 ...allPermissions,
91 canSeePassengerDetails: () => false,
92 canDeletePassenger: () => true,
93 canEditEventOptions: () => userIsEventCreator,
94 canJoinTravels: () => connected,
95 },
96 };
97};
98
99export default usePermissions;