mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-06-02 22:26:57 -05:00
Add check for member being in two groups when match is created
This commit is contained in:
parent
b635a788a0
commit
a9febdd989
|
|
@ -8,8 +8,14 @@ import {
|
|||
matchMapList,
|
||||
} from "~/features/sendouq-match/core/match.server";
|
||||
import * as QRepository from "~/features/sendouq/QRepository.server";
|
||||
import type { LookingGroupWithInviteCode } from "~/features/sendouq/q-types";
|
||||
import invariant from "~/utils/invariant";
|
||||
import { errorToastIfFalsy, parseRequestPayload } from "~/utils/remix.server";
|
||||
import { logger } from "~/utils/logger";
|
||||
import {
|
||||
errorToast,
|
||||
errorToastIfFalsy,
|
||||
parseRequestPayload,
|
||||
} from "~/utils/remix.server";
|
||||
import { errorIsSqliteForeignKeyConstraintFailure } from "~/utils/sql";
|
||||
import { assertUnreachable } from "~/utils/types";
|
||||
import { SENDOUQ_PAGE, sendouQMatchPage } from "~/utils/urls";
|
||||
|
|
@ -232,6 +238,21 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
ignoreModePreferences: data._action === "MATCH_UP_RECHALLENGE",
|
||||
},
|
||||
);
|
||||
|
||||
const memberInManyGroups = verifyNoMemberInTwoGroups(
|
||||
[...ourGroup.members, ...theirGroup.members],
|
||||
lookingGroups,
|
||||
);
|
||||
if (memberInManyGroups) {
|
||||
logger.error("User in two groups preventing match creation", {
|
||||
userId: memberInManyGroups.id,
|
||||
});
|
||||
|
||||
errorToast(
|
||||
`${memberInManyGroups.username} is in two groups so match can't be started`,
|
||||
);
|
||||
}
|
||||
|
||||
const createdMatch = createMatch({
|
||||
alphaGroupId: ourGroup.id,
|
||||
bravoGroupId: theirGroup.id,
|
||||
|
|
@ -367,3 +388,23 @@ export const action: ActionFunction = async ({ request }) => {
|
|||
|
||||
return null;
|
||||
};
|
||||
|
||||
/** Sanity check that no member is in two groups due to a bug or race condition.
|
||||
*
|
||||
* @returns null if no member is in two groups, otherwise return the problematic member
|
||||
*/
|
||||
function verifyNoMemberInTwoGroups(
|
||||
members: LookingGroupWithInviteCode["members"],
|
||||
allGroups: LookingGroupWithInviteCode[],
|
||||
) {
|
||||
for (const member of members) {
|
||||
if (
|
||||
allGroups.filter((group) => group.members.some((m) => m.id === member.id))
|
||||
.length > 1
|
||||
) {
|
||||
return member;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ export function parseSearchParams<T extends z.ZodTypeAny>({
|
|||
} catch (e) {
|
||||
logger.error("Error parsing search params", e);
|
||||
|
||||
throw errorToast("Validation failed");
|
||||
throw errorToastRedirect("Validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -93,7 +93,7 @@ export async function parseRequestPayload<T extends z.ZodTypeAny>({
|
|||
} catch (e) {
|
||||
logger.error("Error parsing request payload", e);
|
||||
|
||||
throw errorToast("Validation failed");
|
||||
throw errorToastRedirect("Validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -117,7 +117,7 @@ export async function parseFormData<T extends z.ZodTypeAny>({
|
|||
} catch (e) {
|
||||
logger.error("Error parsing form data", e);
|
||||
|
||||
throw errorToast("Validation failed");
|
||||
throw errorToastRedirect("Validation failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ function formDataToObject(formData: FormData) {
|
|||
|
||||
// TODO: investigate better solution to toasts when middlewares land (current one has a problem of clearing search params)
|
||||
|
||||
export function errorToast(message: string) {
|
||||
export function errorToastRedirect(message: string) {
|
||||
return redirect(`?__error=${message}`);
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +194,12 @@ export function errorToastIfFalsy(
|
|||
): asserts condition {
|
||||
if (condition) return;
|
||||
|
||||
throw errorToast(message);
|
||||
throw errorToastRedirect(message);
|
||||
}
|
||||
|
||||
/** Throws a redirect triggering an error toast with given message. */
|
||||
export function errorToast(message: string) {
|
||||
throw errorToastRedirect(message);
|
||||
}
|
||||
|
||||
export function successToast(message: string) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user