1 /// NOTE: These permissions are for UI cosmetics only!
2 /// They should be in sync with the backend Policies.
4 import * as Episode from './Episode';
5 import Round from './Round';
7 export const isAdmin = user => user && user.role === 'admin';
9 export const isSameUser = (user, subject) => user && subject && user.id === subject.id;
13 export const isChannelAdmin = (user, channel) =>
14 user && channel && user.channel_crews &&
15 user.channel_crews.find(c => c.role === 'admin' && c.channel_id === channel.id);
19 export const isCommentator = (user, episode) => {
20 if (!user || !episode || !episode.crew) return false;
21 return !!episode.crew.find(c => c.role === "commentary" && c.user_id === user.id);
24 export const isTracker = (user, episode) => {
25 if (!user || !episode || !episode.crew) return false;
26 return !!episode.crew.find(c => c.role === "tracking" && c.user_id === user.id);
29 export const episodeHasChannel = (episode, channel) =>
30 episode && channel && episode.channels && episode.channels.find(c => c.id === channel.id);
32 export const mayRestreamEpisodes = user =>
33 user && user.channel_crews && user.channel_crews.find(c => c.role === 'admin');
35 export const mayEditRestream = (user, episode, channel) =>
36 episodeHasChannel(episode, channel) && isChannelAdmin(user, channel);
38 export const canApplyForEpisode = (user, episode, as) => {
39 if (!user) return false;
40 if (as === 'commentary') return Episode.acceptsComms(episode) && !isCommentator(user, episode);
41 if (as === 'tracking') return Episode.acceptsTrackers(episode) && !isTracker(user, episode);
45 export const applicableChannels = (user, episode, as) => {
46 if (!user || !episode) return [];
47 const assigned_channels = (episode.crew || [])
48 .filter(c => c.user_id === user.id)
49 .map(c => c.channel_id);
50 const channels = episode.channels || [];
51 if (as === 'commentary') return channels.filter(c =>
52 c.pivot && c.pivot.accept_comms && !assigned_channels.includes(c.id));
53 if (as === 'tracking') return channels.filter(c =>
54 c.pivot && c.pivot.accept_tracker && !assigned_channels.includes(c.id));
58 export const canRestreamEpisode = (user, episode) => {
59 if (!user || !episode || !mayRestreamEpisodes(user)) return false;
60 const available_channels = user.channel_crews
61 .filter(c => c.role === 'admin')
62 .map(c => c.channel_id);
63 const claimed_channels = ((episode && episode.channels) || []).map(c => c.id);
64 const remaining_channels = available_channels.filter(id => !claimed_channels.includes(id));
65 return remaining_channels.length > 0;
70 export const isApplicant = (user, tournament) => {
71 if (!user || !tournament || !tournament.applications) {
74 return tournament.applications.find(p => p.user && p.user.id == user.id);
77 export const isDeniedApplicant = (user, tournament) => {
78 if (!user || !tournament || !tournament.applications) {
81 const applicant = tournament.applications.find(p => p.user && p.user.id == user.id);
82 return applicant && applicant.denied;
85 export const isParticipant = (user, tournament) =>
86 user && tournament && tournament.participants &&
87 tournament.participants.find(p => p.user && p.user.id == user.id);
89 export const isRunner = (user, tournament) => {
90 const p = isParticipant(user, tournament);
91 return p && p.roles && p.roles.includes('runner');
94 export const isTournamentAdmin = (user, tournament) => {
95 const p = isParticipant(user, tournament);
96 return p && p.roles && p.roles.includes('admin');
99 export const isTournamentCrew = (user, tournament) =>
100 isTournamentAdmin(user, tournament) || isTournamentMonitor(user, tournament);
102 export const isTournamentMonitor = (user, tournament) => {
103 const p = isParticipant(user, tournament);
104 return p && p.roles && p.roles.includes('monitor');
107 export const hasFinished = (user, round) =>
108 user && round && round.results &&
109 round.results.find(r => r.user_id == user.id && r.has_finished);
111 export const mayAddRounds = (user, tournament) =>
112 !tournament.locked &&
113 (isRunner(user, tournament) || isTournamentAdmin(user, tournament));
115 export const mayApply = (user, tournament) =>
116 user && tournament && tournament.accept_applications &&
117 !isRunner(user, tournament) && !isApplicant(user, tournament);
119 export const mayHandleApplications = (user, tournament) =>
120 tournament && tournament.accept_applications && isTournamentAdmin(user, tournament);
122 export const mayReportResult = (user, tournament) => {
123 if (!user || !tournament) return false;
124 if (tournament.type === 'open-async') return true;
125 return isRunner(user, tournament);
128 export const mayEditRound = (user, tournament) =>
129 !tournament.locked && isTournamentAdmin(user, tournament);
131 export const mayLockRound = (user, tournament) =>
132 !tournament.locked && isTournamentAdmin(user, tournament);
134 export const maySetSeed = (user, tournament, round) =>
136 (isRunner(user, tournament) || isTournamentAdmin(user, tournament));
138 export const mayUpdateTournament = (user, tournament) =>
139 isAdmin(user) || isTournamentAdmin(user, tournament);
141 export const mayViewProtocol = (user, tournament) =>
142 isTournamentCrew(user, tournament);
144 export const maySeeResults = (user, tournament, round) =>
146 hasFinished(user, round) ||
147 isTournamentMonitor(user, tournament) ||
148 Round.isComplete(tournament, round);
152 export const mayEditNickname = (user, subject) =>
153 isSameUser(user, subject);
155 export const mayEditStreamLink = (user, subject) =>
156 isSameUser(user, subject);