remove username as public input from /sponsors/github

Extends the previous commit's fix. The only caller (Donate.vue via
apiService.getSponsors()) never sends a username and always relied on the
server-side default, so the parameter had no legitimate use even after
being parameterized — it just let anyone use deflock's server as an
unauthenticated relay onto GitHub's GraphQL API under the server's own
token. Drop it entirely: the route no longer accepts a username
querystring param, and GithubClient.getSponsors() takes no argument,
hardcoding the maintainer's login via MAINTAINER_USERNAME. Keeps the
$username GraphQL-variable parameterization technique so reintroducing a
variable input later can't reintroduce the injection.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Chris Bowles
2026-07-08 02:33:12 -04:00
parent 3eceedb9c6
commit 34e2cbdc2d
4 changed files with 61 additions and 43 deletions
+1 -9
View File
@@ -205,22 +205,14 @@ const start = async () => {
server.get('/sponsors/github', {
schema: {
querystring: {
type: 'object',
properties: {
// GitHub usernames are 1-39 chars of letters, digits, and hyphens.
username: { type: 'string', pattern: '^[A-Za-z0-9-]{1,39}$', default: 'frillweeman' },
},
},
response: {
200: SponsorsResponseSchema,
500: { type: 'object', properties: { error: { type: 'string' } } },
},
},
}, async (request, reply) => {
const { username } = request.query as { username?: string };
reply.header('Cache-Control', 'public, max-age=60, s-maxage=600');
const result = await githubClient.getSponsors(username || 'frillweeman');
const result = await githubClient.getSponsors();
return result;
});