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 isInPassengersList = travel.attributes.passengers.data?.some(
75 passenger => passenger.attributes.user?.data?.id === userId
76 );
77 return isInPassengersList;
78 },
79 canSetAlert: () => true,
80 canDeletePassenger: passenger => {
81 const travel = event?.travels?.data?.find(travel =>
82 travel.attributes.passengers.data.some(
83 travelPassenger => travelPassenger.id === passenger.id
84 )
85 );
86 const isTravelCreator = travel?.attributes.user?.data?.id === userId;
87 const isCurrentPassenger =
88 passenger.attributes.user?.data?.id === userId;
89 return isTravelCreator || isCurrentPassenger;
90 },
91 canSeePassengerDetails: passenger => {
92 const travel = event?.travels?.data?.find(
93 travel => travel?.id === passenger.attributes.travel.data?.id
94 );
95 const userIsDriver = travel?.attributes.user?.data?.id === userId;
96 return userIsDriver || passenger.attributes.user?.data?.id === userId;
97 },
98 };
99 return {userPermissions: carosterPlusPermissions};
100 }
101 }
102 // Caroster Vanilla permissions
103 else
104 return {
105 userPermissions: {
106 ...allPermissions,
107 canSeePassengerDetails: () => false,
108 canDeletePassenger: () => true,
109 canEditEventOptions: () => userIsEventCreator,
110 canSetAlert: () => false,
111 canJoinTravels: () => connected,
112 canSeeTravelDetails: () => true,
113 },
114 };
115};
116
117export default usePermissions;