GraphQL queries bypass the per-route scope their REST equivalents require
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
- Ambito
- api, authentication, security
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
preExecutionhook that reads the selected fields), - resolved against
req.apiKey.scopeswithhasScopefromsrc/api/auth.ts— the same function the REST hook uses, so the two cannot disagree about what a scope means, - a
403 insufficient_scopeshaped like the REST one, surfaced throughformatGraphQLErrors.
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.mddocuments 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
- Include un Dockerfile o un file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Divinity-Labs/Lens
-
Webhook retries have no jitter, so failures synchroniseForse già presa @Richard-tobi l’ha presa 10 giorni fa. Apertaarea:reliability difficulty:easy help wanted points:100 Stellar Wave
Difficoltà 2/5 1-3 ore Idoneità per principianti 80/100
Divinity-Labs/Lens#341 · 2 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 3 giorni
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
Divinity-Labs/Lens#626 ·
I maintainer di solito rispondono entro 3 giorni
-
enhancement
Difficoltà 5/5 Più di una settimana Idoneità per principianti 35/100
Divinity-Labs/Lens#625 ·
I maintainer di solito rispondono entro 3 giorni
-
area:tests automated live-spec-report
Difficoltà 4/5 3-5 giorni Idoneità per principianti 28/100
Divinity-Labs/Lens#606 · 3 commenti ·
I maintainer di solito rispondono entro 3 giorni
-
The key is accepted only as a bearer token, and nothing says soForse già presa @krsnak l’ha presa 8 giorni fa. Apertaarea:docs difficulty:easy help wanted points:100 Stellar Wave
Divinity-Labs/Lens#512 · 4 commenti · 1 assegnatario ·
I maintainer di solito rispondono entro 3 giorni
Tutte le issue di Divinity-Labs/Lens
Issue simili
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 73/100
ajv-validator/ajv#2689 ·
-
[Bug]: IME confirmation Enter can submit the SSH port-forward dialogForse già presa @seijikohara l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
home-assistant/frontend#55323 ·
I maintainer di solito rispondono entro 1 giorno
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 72/100
lingdojo/kana-dojo#33188 · 1 commento · 5 reazioni ·
I maintainer di solito rispondono entro 1 giorno
-
self-driving
Difficoltà 1/5 1-3 ore Idoneità per principianti 86/100
I maintainer di solito rispondono entro 1 giorno