Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .husky/pre-push
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export NVM_DIR="$HOME/.nvm"
if [ $(git branch --no-color | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/') = "master" ] && [ $(git remote get-url origin) = "https://github.com/monkeytypegame/monkeytype" ]; then
nvm install
echo "Running a full check before pushing to master..."
npm run full-check
pnpm run full-check
if [ $? -ne 0 ]; then
echo "Full check failed, aborting push."
exit 1
Expand Down
3 changes: 2 additions & 1 deletion backend/__tests__/__testData__/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ export async function mockAuthenticateWithApeKey(
uid: string,
config: Configuration,
): Promise<string> {
if (!config.apeKeys.acceptKeys)
if (!config.apeKeys.acceptKeys) {
throw Error("config.apeKeys.acceptedKeys needs to be set to true");
}
const { apeKeyBytes, apeKeySaltRounds } = config.apeKeys;

const apiKey = randomBytes(apeKeyBytes).toString("base64url");
Expand Down
11 changes: 7 additions & 4 deletions backend/src/api/controllers/dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ async function createTestResults(
const results = createArray(day.amount, () =>
createResult(user, day.timestamp),
);
if (results.length > 0)
if (results.length > 0) {
await ResultDal.getResultCollection().insertMany(results);
}
}
}

Expand Down Expand Up @@ -221,9 +222,10 @@ async function updateUser(uid: string): Promise<void> {
{ sort: { wpm: -1, timestamp: 1 } },
)) as DBResult;

if (personalBests[mode.mode] === undefined) personalBests[mode.mode] = {};
if (personalBests[mode.mode][mode.mode2] === undefined)
personalBests[mode.mode] ??= {};
if (personalBests[mode.mode][mode.mode2] === undefined) {
personalBests[mode.mode][mode.mode2] = [];
}

const entry = {
acc: best.acc,
Expand All @@ -241,8 +243,9 @@ async function updateUser(uid: string): Promise<void> {
(personalBests[mode.mode][mode.mode2] as PersonalBest[]).push(entry);

if (mode.mode === "time") {
if (lbPersonalBests[mode.mode][mode.mode2] === undefined)
if (lbPersonalBests[mode.mode][mode.mode2] === undefined) {
lbPersonalBests[mode.mode][mode.mode2] = {};
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
lbPersonalBests[mode.mode][mode.mode2][mode.language] = entry;
Expand Down
4 changes: 1 addition & 3 deletions backend/src/api/controllers/quote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ export async function submitRating(
shouldUpdateRating,
);

if (!userQuoteRatings[language]) {
userQuoteRatings[language] = {};
}
userQuoteRatings[language] ??= {};
userQuoteRatings[language][quoteId] = rating;

await updateQuoteRatings(uid, userQuoteRatings);
Expand Down
24 changes: 6 additions & 18 deletions backend/src/api/controllers/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,24 +170,12 @@ export async function updateTags(
await ResultDAL.updateTags(uid, resultId, tagIds);
const result = await ResultDAL.getResult(uid, resultId);

if (!result.difficulty) {
result.difficulty = "normal";
}
if (!(result.language ?? "")) {
result.language = "english";
}
if (result.funbox === undefined) {
result.funbox = [];
}
if (!result.lazyMode) {
result.lazyMode = false;
}
if (!result.punctuation) {
result.punctuation = false;
}
if (!result.numbers) {
result.numbers = false;
}
result.difficulty ??= "normal";
result.language ??= "english";
result.funbox ??= [];
result.lazyMode ??= false;
result.punctuation ??= false;
result.numbers ??= false;

const user = await UserDAL.getPartialUser(uid, "update tags", ["tags"]);
const tagPbs = await UserDAL.checkIfTagPb(uid, user, result);
Expand Down
3 changes: 2 additions & 1 deletion backend/src/api/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1207,8 +1207,9 @@ export function generateCurrentTestActivity(
let thisYearData = testActivity?.[thisYear.getFullYear().toString()];
let lastYearData = testActivity?.[lastYear.getFullYear().toString()];

if (lastYearData === undefined && thisYearData === undefined)
if (lastYearData === undefined && thisYearData === undefined) {
return undefined;
}

lastYearData = lastYearData ?? [];
thisYearData = thisYearData ?? [];
Expand Down
3 changes: 2 additions & 1 deletion backend/src/api/controllers/webhooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ export async function githubRelease(

if (action === "published") {
const releaseId = req.body.release?.id;
if (releaseId === undefined)
if (releaseId === undefined) {
throw new MonkeyError(422, 'Missing property "release.id".');
}

await GeorgeQueue.sendReleaseAnnouncement(releaseId);
return new MonkeyResponse("Added release announcement task to queue", null);
Expand Down
3 changes: 2 additions & 1 deletion backend/src/dal/connections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ export async function getConnections(options: {
}): Promise<DBConnection[]> {
const { initiatorUid, receiverUid, status } = options;

if (initiatorUid === undefined && receiverUid === undefined)
if (initiatorUid === undefined && receiverUid === undefined) {
throw new Error("Missing filter");
}

let filter: Filter<DBConnection> = { $or: [] };

Expand Down
2 changes: 1 addition & 1 deletion backend/src/dal/result.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function addResult(
const { data: user } = await tryCatch(getUser(uid, "add result"));

if (!user) throw new MonkeyError(404, "User not found", "add result");
if (result.uid === undefined) result.uid = uid;
result.uid ??= uid;
// result.ir = true;
const res = await getResultCollection().insertOne(result);
return {
Expand Down
24 changes: 17 additions & 7 deletions backend/src/dal/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ export async function findByName(name: string): Promise<DBUser | undefined> {
{ collation: { locale: "en", strength: 1 } },
);

return found !== null ? found : undefined;
return found ?? undefined;
}

export async function isNameAvailable(
Expand Down Expand Up @@ -459,8 +459,9 @@ export async function checkIfPb(
"stopOnLetter" in result &&
result.stopOnLetter === true &&
result.acc < 100
)
) {
return false;
}

if (mode === "quote") {
return false;
Expand Down Expand Up @@ -510,8 +511,9 @@ export async function checkIfTagPb(
"stopOnLetter" in result &&
result.stopOnLetter === true &&
result.acc < 100
)
) {
return [];
}

if (mode === "quote") {
return [];
Expand Down Expand Up @@ -605,8 +607,9 @@ export async function linkDiscord(
discordAvatar?: string,
): Promise<void> {
const updates: Partial<DBUser> = { discordId };
if (discordAvatar !== undefined && discordAvatar !== null)
if (discordAvatar !== undefined && discordAvatar !== null) {
updates.discordAvatar = discordAvatar;
}

await updateUser({ uid }, { $set: updates }, { stack: "link discord" });
}
Expand Down Expand Up @@ -1053,10 +1056,15 @@ export async function updateInbox(
.filter((it) => it.type === "badge")
.map((it) => it.item);

if (inventory === null)
// mongo doesnt support ??= i think
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (inventory === null) {
inventory = {
badges: [],
};
}
// mongo doesnt support ??= i think
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (inventory.badges === null) inventory.badges = [];

const uniqueBadgeIds = new Set();
Expand Down Expand Up @@ -1100,8 +1108,9 @@ export async function updateInbox(
{ $unset: "tmp" },
]);

if (update.matchedCount !== 1)
if (update.matchedCount !== 1) {
throw new MonkeyError(404, "User not found", "update inbox");
}
}

export async function updateStreak(
Expand Down Expand Up @@ -1225,12 +1234,13 @@ async function updateUser(
): Promise<void> {
const result = await getUsersCollection().updateOne(filter, update);

if (result.matchedCount !== 1)
if (result.matchedCount !== 1) {
throw new MonkeyError(
error.statusCode ?? 404,
error.message ?? "User not found",
error.stack,
);
}
}

export async function getFriends(uid: string): Promise<DBFriend[]> {
Expand Down
2 changes: 1 addition & 1 deletion backend/src/jobs/update-leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ async function updateLeaderboardAndNotifyChanges(
const isRecentRecord =
record.timestamp > Date.now() - RECENT_AGE_MILLISECONDS;

return (userImprovedRank || newUserInTop10) && isRecentRecord;
return (userImprovedRank === true || newUserInTop10) && isRecentRecord;
});

if (newRecords.length > 0) {
Expand Down
5 changes: 3 additions & 2 deletions backend/src/middlewares/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ export function authenticateTsRestRequest<
let authType = "None";

const isPublic =
options.isPublic || (options.isPublicOnDev && isDevEnvironment());
options.isPublic === true ||
(options.isPublicOnDev && isDevEnvironment());

const {
authorization: authHeader,
Expand Down Expand Up @@ -241,7 +242,7 @@ async function authenticateWithApeKey(
options: RequestAuthenticationOptions,
): Promise<DecodedToken> {
const isPublic =
options.isPublic || (options.isPublicOnDev && isDevEnvironment());
options.isPublic === true || (options.isPublicOnDev && isDevEnvironment());

if (!isPublic) {
if (!configuration.apeKeys.acceptKeys) {
Expand Down
12 changes: 8 additions & 4 deletions backend/src/middlewares/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,30 @@ function getValue(
result = result[key];
}

if (result === undefined || result === null)
if (result === undefined || result === null) {
throw new MonkeyError(
500,
`Required configuration doesnt exist: "${path}"`,
);
if (typeof result !== "boolean")
}
if (typeof result !== "boolean") {
throw new MonkeyError(
500,
`Required configuration is not a boolean: "${path}"`,
);
}
return result;
}

function getRequireConfigurations(
metadata: EndpointMetadata | undefined,
): RequireConfiguration[] | undefined {
if (metadata === undefined || metadata.requireConfiguration === undefined)
if (metadata === undefined || metadata.requireConfiguration === undefined) {
return undefined;
}

if (Array.isArray(metadata.requireConfiguration))
if (Array.isArray(metadata.requireConfiguration)) {
return metadata.requireConfiguration;
}
return [metadata.requireConfiguration];
}
9 changes: 6 additions & 3 deletions backend/src/middlewares/permission.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,11 +136,13 @@ export function verifyPermissions<
function getRequiredPermissionIds(
metadata: EndpointMetadata | undefined,
): PermissionId[] | undefined {
if (metadata === undefined || metadata.requirePermission === undefined)
if (metadata === undefined || metadata.requirePermission === undefined) {
return undefined;
}

if (Array.isArray(metadata.requirePermission))
if (Array.isArray(metadata.requirePermission)) {
return metadata.requirePermission;
}
return [metadata.requirePermission];
}

Expand Down Expand Up @@ -186,11 +188,12 @@ async function checkUserPermissions(
)) as DBUser;

for (const check of checks) {
if (!check.criteria(user))
if (!check.criteria(user)) {
return {
passed: false,
invalidMessage: check.invalidMessage,
};
}
}

return {
Expand Down
4 changes: 1 addition & 3 deletions backend/src/utils/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,7 @@ export function isDevEnvironment(): boolean {
export function getFrontendUrl(): string {
return isDevEnvironment()
? "http://localhost:3000"
: process.env["FRONTEND_URL"] !== undefined
? process.env["FRONTEND_URL"]
: "https://monkeytype.com";
: (process.env["FRONTEND_URL"] ?? "https://monkeytype.com");
}

/**
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/styles/test.scss
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,10 @@
caret-color: transparent;
resize: none;
overflow: hidden;
white-space: nowrap; // if the text wraps, ctrl backspace will not work on firefox >:|
// if the text wraps, ctrl backspace will not work on firefox >:|
// and holy shit do not use white-space: nowrap here because the hellspawn that is safari
// is TRIMMING the value on focus when using that (and the input system relies on a leading space)
text-wrap-mode: nowrap;
}

#capsWarning {
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/ts/controllers/chart-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -594,10 +594,7 @@ export const accountHistory = new ChartWithUpdateColors<
label += resultData.mode2;
}

let diff = resultData.difficulty;
if (diff === undefined) {
diff = "normal";
}
let diff = resultData.difficulty ?? "normal";
label += `\ndifficulty: ${diff}`;

label +=
Expand Down Expand Up @@ -1363,8 +1360,9 @@ async function updateColors<
ao10accDataset === undefined ||
ao100wpmDataset === undefined ||
ao100accDataset === undefined
)
) {
return;
}

if (avg10On && avg100On) {
wpmDataset.pointBackgroundColor = main02;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/controllers/pw-ad-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,11 @@ export function init(): void {
headOfDocument.appendChild(rampScript);

window._pwGA4PageviewId = "".concat(Date.now());
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-assignment
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/prefer-nullish-coalescing
window.dataLayer = window.dataLayer || [];
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
window.gtag =
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
// eslint-disable-next-line @typescript-eslint/strict-boolean-expressions, @typescript-eslint/prefer-nullish-coalescing
window.gtag ||
function (): void {
// eslint-disable-next-line prefer-rest-params
Expand Down
8 changes: 2 additions & 6 deletions frontend/src/ts/controllers/quotes-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -239,12 +239,8 @@ class QuotesController {
});

if (response.status === 200) {
if (snapshot.favoriteQuotes === undefined) {
snapshot.favoriteQuotes = {};
}
if (!snapshot.favoriteQuotes[quote.language]) {
snapshot.favoriteQuotes[quote.language] = [];
}
snapshot.favoriteQuotes ??= {};
snapshot.favoriteQuotes[quote.language] ??= [];
snapshot.favoriteQuotes[quote.language]?.push(`${quote.id}`);
} else {
throw new Error(response.body.message);
Expand Down
Loading
Loading