From 5ff66545e517d3c73a4f50ac4824c93642b20edd Mon Sep 17 00:00:00 2001
From: Christian Fehmer
Date: Thu, 13 Aug 2026 13:05:47 +0200
Subject: [PATCH 1/7] docs: add animejs and tanstack to readme (@fehmer)
(#8335)
---
README.md | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
diff --git a/README.md b/README.md
index 4c6ec06ae274..c475c2576966 100644
--- a/README.md
+++ b/README.md
@@ -1,24 +1,26 @@
[](https://monkeytype.com/)
-[](https://www.chartjs.org/)
-[](https://eslint.org/)
-[](https://expressjs.com/)
-[](https://firebase.google.com/)
-[](https://fontawesome.com/)
-[](https://developer.mozilla.org/en-US/docs/Web/HTML)
-[](https://www.mongodb.com/)
-[](https://oxc.rs/docs/guide/usage/linter.html)
-[](https://pnpm.io/)
-[](https://redis.io/)
-[](https://sass-lang.com/)
-[](https://www.solidjs.com/)
-[](https://tailwindcss.com/)
+[](https://animejs.com/)
+[](https://www.chartjs.org/)
+[](https://eslint.org/)
+[](https://expressjs.com/)
+[](https://firebase.google.com/)
+[](https://fontawesome.com/)
+[](https://developer.mozilla.org/en-US/docs/Web/HTML)
+[](https://www.mongodb.com/)
+[](https://oxc.rs/docs/guide/usage/linter.html)
+[](https://pnpm.io/)
+[](https://redis.io/)
+[](https://sass-lang.com/)
+[](https://www.solidjs.com/)
+[](https://tailwindcss.com/)
+[](https://tanstack.com/)
[](https://ts-rest.com/)
-[](https://turborepo.org/)
-[](https://www.typescriptlang.org/)
-[](https://vitejs.dev/)
-[](https://vitest.dev/)
+[](https://turborepo.org/)
+[](https://www.typescriptlang.org/)
+[](https://vitejs.dev/)
+[](https://vitest.dev/)
[](https://zod.dev/)
# About
From e46135e8545b933afa70f41ac2a7f4f259304507 Mon Sep 17 00:00:00 2001
From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com>
Date: Thu, 13 Aug 2026 14:08:33 +0300
Subject: [PATCH 2/7] fix(quote-search): make highlighting work again
(@Leonabcd123) (#8330)
---
.../ts/components/modals/QuoteSearchModal.tsx | 20 ++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/frontend/src/ts/components/modals/QuoteSearchModal.tsx b/frontend/src/ts/components/modals/QuoteSearchModal.tsx
index 5f262217d975..fa0fee84e2f4 100644
--- a/frontend/src/ts/components/modals/QuoteSearchModal.tsx
+++ b/frontend/src/ts/components/modals/QuoteSearchModal.tsx
@@ -129,8 +129,9 @@ function Item(props: {
class="text-text [&_.highlight]:text-main"
dir="auto"
// oxlint-disable-next-line solid/no-innerhtml
- innerHTML={Misc.escapeHTML(
- highlightMatches(props.quote.text, props.matchedTerms),
+ innerHTML={highlightMatches(
+ Misc.escapeHTML(props.quote.text),
+ props.matchedTerms,
)}
>
@@ -139,8 +140,9 @@ function Item(props: {
@@ -154,8 +156,9 @@ function Item(props: {
@@ -291,7 +294,10 @@ export function QuoteSearchModal(): JSXElement {
];
}
- setSearchResults({ quotes: matches, matchedTerms: matchedQueryTerms });
+ setSearchResults({
+ quotes: matches,
+ matchedTerms: matchedQueryTerms.map(Misc.escapeHTML),
+ });
};
const filteredQuotes = (): Quote[] => {
From 89535b85e90549283e26cfcfb8081a94fd12694b Mon Sep 17 00:00:00 2001
From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com>
Date: Thu, 13 Aug 2026 14:10:20 +0300
Subject: [PATCH 3/7] fix(privacy-policy): remove link to nonexistent section
(@Leonabcd123) (#8327)
---
frontend/src/privacy-policy.html | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/frontend/src/privacy-policy.html b/frontend/src/privacy-policy.html
index 4505cd492c4a..3ae78fa2e492 100644
--- a/frontend/src/privacy-policy.html
+++ b/frontend/src/privacy-policy.html
@@ -129,7 +129,7 @@
appears at the end of this Privacy Statement.
Table of Contents
-
+
- What data do we collect?
-
@@ -146,9 +146,6 @@
-
Advertisements
- -
- Advertisements Part 2
-
- What are cookies?
- How do we use cookies?
-
@@ -384,13 +381,13 @@
What are cookies?
HTTP cookie
+ "HTTP cookie" and the one after the closing `a` tag into a single space
+ located after "HTTP cookie" (inside the `a` tag), and because the `a` tag
+ has display: inline-block, the space will not be rendered. Use to make
+ sure the minifier doesn't remove it.
+ -->
on Wikipedia.
From 20b9530d720f04a4710853534c6f885d3cfe0d4c Mon Sep 17 00:00:00 2001
From: Technet <38403028+Technet8394@users.noreply.github.com>
Date: Thu, 13 Aug 2026 06:14:24 -0500
Subject: [PATCH 4/7] fix(quote): correcting source of quote (@Technet8394)
(#8301)
---
frontend/static/quotes/english.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/frontend/static/quotes/english.json b/frontend/static/quotes/english.json
index dd4d91aeacf9..d253f1ba9157 100644
--- a/frontend/static/quotes/english.json
+++ b/frontend/static/quotes/english.json
@@ -105,7 +105,7 @@
},
{
"text": "And in the end, the love you take is equal to the love you make.",
- "source": "The End",
+ "source": "The End - The Beatles",
"id": 18,
"length": 64
},
From 501ada64299ab120aa8c1b2d97a9de0bae9ef1d0 Mon Sep 17 00:00:00 2001
From: Christian Fehmer
Date: Thu, 13 Aug 2026 13:17:03 +0200
Subject: [PATCH 5/7] docs(self hosting): add security section (@fehmer)
(#8264)
---
docs/SELF_HOSTING.md | 25 +++++++++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/docs/SELF_HOSTING.md b/docs/SELF_HOSTING.md
index dea22c83821e..191287299c5c 100644
--- a/docs/SELF_HOSTING.md
+++ b/docs/SELF_HOSTING.md
@@ -11,6 +11,7 @@
- [Prerequisites](#prerequisites)
- [Quickstart](#quickstart)
- [Hosting over the network (HTTPS)](#hosting-over-the-network-https)
+ - [Security](#security)
- [Account System](#account-system)
- [Setup Firebase](#setup-firebase)
- [Update backend configuration](#update-backend-configuration)
@@ -61,6 +62,30 @@ docker compose up -d --force-recreate
> After updating your configuration and recreating the containers, clear your browser cache or perform a hard reload (Ctrl + F5) to make sure your browser isn't running an old cached version of the frontend.
+## Security
+
+Do not expose the Monkeytype backend directly to the internet. Instead, place it behind a reverse proxy and configure the backend to only accept connections from the reverse proxy.
+
+The backend's built-in rate limiting is based on the authenticated user's `uid` or, for unauthenticated requests, the client's IP address.
+
+To determine the client's IP address, the backend checks the following sources in order:
+
+1. `CF-Connecting-IP` (when requests are proxied through Cloudflare)
+2. `X-Forwarded-For`
+3. The source IP address of the HTTP connection
+
+We recommend the following configuration:
+
+- If you are **not** using Cloudflare, remove any incoming `CF-Connecting-IP` header in your reverse proxy before forwarding requests.
+- Configure your reverse proxy to set the `X-Forwarded-For` header to the client's IP address.
+- Configure the backend to only accept connections from the reverse proxy to prevent clients from spoofing trusted headers.
+
+
+Sources:
+- [cloudflare documentation for cf-connecting-ip](https://developers.cloudflare.com/fundamentals/reference/http-headers/#cf-connecting-ip)
+- [handling headers in traefik](https://doc.traefik.io/traefik/reference/routing-configuration/http/middlewares/headers)
+
+
## Account System
By default, user sign-up and login are disabled. To enable this, you'll need to set up a Firebase project.
From 85e24cfd0d086b3416bcc44c90617ef5c43b682c Mon Sep 17 00:00:00 2001
From: Luca <55391576+brentspine@users.noreply.github.com>
Date: Thu, 13 Aug 2026 13:20:05 +0200
Subject: [PATCH 6/7] docs(contributing): Fix example quote commit message
(@brentspine) (#8103)
---
docs/CONTRIBUTING.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md
index d040161513aa..d024a9d8c958 100644
--- a/docs/CONTRIBUTING.md
+++ b/docs/CONTRIBUTING.md
@@ -81,7 +81,7 @@ If you want to contribute languages but don't know how, check [LANGUAGES.md](/do
- Verify the `id` property is incremented correctly
- Please do not add extremely short quotes (less than 60 characters)
- For quotes not in English, please include translations of quotes in the description of your pull request. This assists in the verification process to ensure the integrity of the quotes.
-- Remember to name your pull request properly. For example, if you are adding new quotes for the language `French`, your pull request should be named `impr(quotes): add French quotes`.
+- Remember to name your pull request properly. For example, if you are adding new quotes for the language `French`, your pull request should be named `impr(quotes): add French quotes (@yourusername)`.
If you want to contribute quotes but don't know how, check [QUOTES.md](/docs/QUOTES.md)
From bcd64899447e0dd4fed42d6e2a7f49bceed5856d Mon Sep 17 00:00:00 2001
From: Leonabcd123 <156839416+Leonabcd123@users.noreply.github.com>
Date: Thu, 13 Aug 2026 14:23:12 +0300
Subject: [PATCH 7/7] chore(ci): remove claude workflow (@Leonabcd123) (#7985)
---
.github/workflows/claude.yml | 51 ------------------------------------
1 file changed, 51 deletions(-)
delete mode 100644 .github/workflows/claude.yml
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
deleted file mode 100644
index e31427464865..000000000000
--- a/.github/workflows/claude.yml
+++ /dev/null
@@ -1,51 +0,0 @@
-name: Claude Code
-
-on:
- issue_comment:
- types: [created]
- pull_request_review_comment:
- types: [created]
- issues:
- types: [opened, assigned]
- pull_request_review:
- types: [submitted]
-
-jobs:
- claude:
- if: |
- (
- (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
- (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
- (github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association)) ||
- (github.event_name == 'issues' && (contains(github.event.issue.body, '@claude') || contains(github.event.issue.title, '@claude')) && contains(fromJson('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
- )
- runs-on: ubuntu-latest
- permissions:
- contents: read
- pull-requests: read
- issues: read
- id-token: write
- actions: read # Required for Claude to read CI results on PRs
- steps:
- - name: Checkout repository
- uses: actions/checkout@v6
- with:
- fetch-depth: 1
-
- - name: Run Claude Code
- id: claude
- uses: anthropics/claude-code-action@v1
- with:
- claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
-
- # This is an optional setting that allows Claude to read CI results on PRs
- additional_permissions: |
- actions: read
-
- # Optional: Give a custom prompt to Claude. If this is not specified, Claude will perform the instructions specified in the comment that tagged it.
- # prompt: 'Update the pull request description to include a summary of changes.'
-
- # Optional: Add claude_args to customize behavior and configuration
- # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
- # or https://code.claude.com/docs/en/cli-reference for available options
- # claude_args: '--allowed-tools Bash(gh pr:*)'