Skip to content

Commit 7c5ae53

Browse files
committed
fix: prevent unauthorized match winner setting and add state validation
Fix inverted permission checks in setMatchWinner and forfeitMatch that allowed non-organizers to set winners/forfeit while blocking organizers. Add match state validation to reject winner setting on matches that haven't started or already ended, and reject forfeiting ended matches. Closes #312
1 parent 363caf6 commit 7c5ae53

1 file changed

Lines changed: 54 additions & 2 deletions

File tree

src/matches/matches.controller.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,37 @@ export class MatchesController {
606606
}) {
607607
const { match_id, user, winning_lineup_id } = data;
608608

609-
if (await this.matchAssistant.isOrganizer(match_id, user)) {
609+
if (!(await this.matchAssistant.isOrganizer(match_id, user))) {
610610
throw Error("you are not a match organizer");
611611
}
612612

613+
const { matches_by_pk: matchToSetWinner } = await this.hasura.query({
614+
matches_by_pk: {
615+
__args: {
616+
id: match_id,
617+
},
618+
status: true,
619+
},
620+
});
621+
622+
if (!matchToSetWinner) {
623+
throw Error("match not found");
624+
}
625+
626+
const terminalOrPreStartStatuses: string[] = [
627+
"Finished",
628+
"Canceled",
629+
"Forfeit",
630+
"Tie",
631+
"Surrendered",
632+
"Scheduled",
633+
"PickingPlayers",
634+
];
635+
636+
if (terminalOrPreStartStatuses.includes(matchToSetWinner.status)) {
637+
throw Error("cannot set winner for a match in this state");
638+
}
639+
613640
await this.hasura.mutation({
614641
update_matches_by_pk: {
615642
__args: {
@@ -641,10 +668,35 @@ export class MatchesController {
641668
}) {
642669
const { match_id, user, winning_lineup_id } = data;
643670

644-
if (await this.matchAssistant.isOrganizer(match_id, user)) {
671+
if (!(await this.matchAssistant.isOrganizer(match_id, user))) {
645672
throw Error("you are not a match organizer");
646673
}
647674

675+
const { matches_by_pk: matchToForfeit } = await this.hasura.query({
676+
matches_by_pk: {
677+
__args: {
678+
id: match_id,
679+
},
680+
status: true,
681+
},
682+
});
683+
684+
if (!matchToForfeit) {
685+
throw Error("match not found");
686+
}
687+
688+
const terminalStatuses: string[] = [
689+
"Finished",
690+
"Canceled",
691+
"Forfeit",
692+
"Tie",
693+
"Surrendered",
694+
];
695+
696+
if (terminalStatuses.includes(matchToForfeit.status)) {
697+
throw Error("cannot forfeit a match that has already ended");
698+
}
699+
648700
const { update_matches_by_pk: match } = await this.hasura.mutation({
649701
update_matches_by_pk: {
650702
__args: {

0 commit comments

Comments
 (0)