Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

GraphQL queries bypass the per-route scope their REST equivalents require

Chiusa
#618 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

@sparkysolutions10-pixel ci sta già lavorando.

Dal 24/10/2026.

  • #623 di @sparkysolutions10-pixel — integrata

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Funzionalità
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
graphql, typescript

Direzione di ricerca

Start with src/api/auth.ts to follow the existing scope check, then read the GraphQL resolver setup and formatGraphQLErrors; the issue does not name their files. Use src/__tests__/graphqlScreener.test.ts and src/__tests__/graphqlPairs.test.ts to learn how to exercise GraphQL requests. Done means every schema field has its REST-equivalent scope, insufficient keys receive the REST 403 insufficient_scope error, tests cover refusal and success for each field and multi-field selections, and docs/graphql.md lists the requirements.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Background

Mercurius registers /graphql itself, with no Fastify route config:

await app.register(mercurius, {
  schema, resolvers, graphiql: true,
  path: '/graphql',
  …
})

So routeConfig.scope is undefined for every GraphQL request. The API-key hook still demands a key — /graphql is not marked public, so an unauthenticated request is rejected — but the scope loop has nothing to check:

const requiredScopes = routeConfig.scopes ?? (routeConfig.scope ? [routeConfig.scope] : [])
for (const scope of requiredScopes) { … }   // empty, so never runs

Meanwhile the REST routes serving the same data each declare one:

GraphQL field REST equivalent Scope REST requires
getPrice /price/:assetA/:assetB read:prices
getBestRoute /price/:assetA/:assetB/route read:prices
getPriceHistory /candles/:assetA/:assetB read:history
oracle /compare/:asset read:prices
screener /screener read:prices
priceUpdated (subscription) /ws subscribe

A key issued with only read:prices can read history through getPriceHistory; a key issued with no scopes at all can read everything. Scopes are the mechanism by which a key is restricted, so on this route they currently do nothing.

This is not new — it has been true since GraphQL was added — but it widens every time a resolver is added, most recently screener in #609.

What to build

Enforce the same scope per GraphQL field as its REST equivalent. The shape that avoids a second list to keep in sync is to put the requirement next to the resolver and check it in one place, rather than hand-maintaining a field→scope map somewhere else:

  • a per-field scope declaration (a wrapper around each resolver, or a Mercurius preExecution hook that reads the selected fields),
  • resolved against req.apiKey.scopes with hasScope from src/api/auth.ts — the same function the REST hook uses, so the two cannot disagree about what a scope means,
  • a 403 insufficient_scope shaped like the REST one, surfaced through formatGraphQLErrors.

A document selecting several fields should need every scope those fields require.

Acceptance criteria
  • Each query, mutation and subscription field declares the scope it needs, matching its REST equivalent in the table above
  • A key lacking the scope is refused with the same code REST uses, not a generic GraphQL error
  • A multi-field document requires the union of its fields' scopes
  • A test per field asserting refusal with an insufficient key and success with a sufficient one
  • A test that fails if a new resolver is added with no scope declared — the registry and the schema must not drift
  • docs/graphql.md documents the scope each field needs
Notes

hasScope is in src/api/auth.ts; do not reimplement it. src/__tests__/graphqlScreener.test.ts and src/__tests__/graphqlPairs.test.ts show how to drive the GraphQL layer in tests.

The last criterion is the one that matters most — without it this comes back the next time someone adds a resolver.

Lingua principale
TypeScript
Stelle
4
Fork
71
Merge medio
3g 10h
PR unite (30g)
154

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di Divinity-Labs/Lens

Tutte le issue di Divinity-Labs/Lens

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.