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