diff --git a/backend/scripts/openapi.ts b/backend/scripts/openapi.ts index 0b9c08905084..e64c24e11e6c 100644 --- a/backend/scripts/openapi.ts +++ b/backend/scripts/openapi.ts @@ -1,5 +1,5 @@ import { generateOpenApi } from "@ts-rest/open-api"; -import { contract } from "@monkeytype/contracts/index"; +import { COMPATIBILITY_CHECK, contract } from "@monkeytype/contracts/index"; import { writeFileSync, mkdirSync } from "fs"; import { EndpointMetadata, PermissionId } from "@monkeytype/contracts/util/api"; import type { OpenAPIObject, OperationObject } from "openapi3-ts"; @@ -24,7 +24,7 @@ export function getOpenApi(): OpenAPIObject { title: "Monkeytype API", description: "Documentation for the endpoints provided by the Monkeytype API server.\n\nNote that authentication is performed with the Authorization HTTP header in the format `Authorization: ApeKey YOUR_APE_KEY`\n\nThere is a rate limit of `30 requests per minute` across all endpoints with some endpoints being more strict. Rate limit rates are shared across all ape keys.", - version: "2.0.0", + version: `2.${COMPATIBILITY_CHECK}.0`, termsOfService: "https://monkeytype.com/terms-of-service", contact: { name: "Support", diff --git a/backend/src/middlewares/rate-limit.ts b/backend/src/middlewares/rate-limit.ts index da5a5a8fa729..948c7b27d311 100644 --- a/backend/src/middlewares/rate-limit.ts +++ b/backend/src/middlewares/rate-limit.ts @@ -2,6 +2,7 @@ import MonkeyError from "../utils/error"; import type { Response, NextFunction, Request } from "express"; import { RateLimiterMemory } from "rate-limiter-flexible"; import { + ipKeyGenerator, rateLimit, RateLimitRequestHandler, type Options, @@ -40,12 +41,13 @@ export const customHandler = ( }; const getKey = (req: Request, _res: Response): string => { - return ( + const ip = (req.headers["cf-connecting-ip"] as string) || (req.headers["x-forwarded-for"] as string) || (req.ip as string) || - "255.255.255.255" - ); + "255.255.255.255"; + const key = ipKeyGenerator(ip); + return key; }; const getKeyWithUid = ( diff --git a/frontend/src/ts/commandline/commandline-metadata.ts b/frontend/src/ts/commandline/commandline-metadata.ts index 46bcb4ac237c..71b01937d653 100644 --- a/frontend/src/ts/commandline/commandline-metadata.ts +++ b/frontend/src/ts/commandline/commandline-metadata.ts @@ -1,7 +1,10 @@ import * as ConfigSchemas from "@monkeytype/schemas/configs"; import * as SoundController from "../controllers/sound-controller"; import * as TestLogic from "../test/test-logic"; -import { getLanguageDisplayString } from "../utils/strings"; +import { + getLanguageDisplayString, + replaceUnderscoresWithSpaces, +} from "../utils/strings"; import { areUnsortedArraysEqual } from "../utils/arrays"; import { Config } from "../config/store"; @@ -531,7 +534,7 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = { timerStyle: { subgroup: { options: "fromSchema", - display: (value) => value.replaceAll(/_/g, " "), + display: replaceUnderscoresWithSpaces, }, alias: "timer", }, @@ -554,6 +557,7 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = { highlightMode: { subgroup: { options: "fromSchema", + display: replaceUnderscoresWithSpaces, }, }, typedEffect: { @@ -639,6 +643,7 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = { keymapStyle: { subgroup: { options: "fromSchema", + display: replaceUnderscoresWithSpaces, }, alias: "keyboard", }, diff --git a/frontend/src/ts/components/mount.tsx b/frontend/src/ts/components/mount.tsx index 6a2a1d83b3a0..ada62540a141 100644 --- a/frontend/src/ts/components/mount.tsx +++ b/frontend/src/ts/components/mount.tsx @@ -22,9 +22,9 @@ import { LoginPage } from "./pages/login/LoginPage"; import { ProfilePage } from "./pages/profile/ProfilePage"; import { ProfileSearchPage } from "./pages/profile/ProfileSearchPage"; import { SettingsPage } from "./pages/settings/SettingsPage"; +import { TestModesNotice } from "./pages/test/modes-notice/TestModesNotice"; import { TestConfig } from "./pages/test/TestConfig"; import { Popups } from "./popups/Popups"; -import { TestModesNotice } from "./test/modes-notice/TestModesNotice"; const components: Record JSXElement> = { footer: () =>