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