Skip to content

Commit

Permalink
fix(auth): Allows RedwoodAuthCurrentUserQuery when using Auth, GraphQ…
Browse files Browse the repository at this point in the history
…L and Trusted Documents (#10817)

Fixes #10816

This is a draft proposal to allow authentication to function as expected
when using Trusted Documents.

See the issue above for more detail.

One way to solve is to allow an arbitrary ad-hoc query -- but just a
very narrow and well-defined (aka trusted so-to-speak) one.

The plgin for persisted operations lets one define what can bypass
trusted docs hash id checks:
https://the-guild.dev/graphql/yoga-server/docs/features/persisted-operations#allowing-arbitrary-graphql-operations

So, we can use that in the useTrustedDocuments plugin to just allow that
specific request.

```
const REDWOOD__AUTH_GET_CURRENT_USER_QUERY =
  '{"query":"query __REDWOOD__AUTH_GET_CURRENT_USER { redwood { currentUser } }"}'
```

When using Redwood Auth, we want to allow the known, trusted
`redwood.currentUser` query to be executed without a persisted
operation.

This is because the `currentUser` query is a special case that is used
to get the current user from the auth provider.

We'll check if the request is for the `currentUser` query and has the
correct headers which are set by the useCurrentUser hook in the auth
package.

The usePersistedOperations plugin relies on this function to determine
if a request should be allowed to execute via its
allowArbitraryOperations option.

By checking for that very exact string, and that there is a content type
header, an auth-provider header and an authorization header then we can
allow this to execute.

The auth provider will still be used by the apes getCurrentUser resolver
to determine if the credentials whatever they are are valid.

Needs discussion.
  • Loading branch information
dthyresson authored Jun 20, 2024
1 parent 2a47498 commit 60a3b1a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 0 deletions.
25 changes: 25 additions & 0 deletions .changesets/10817.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
fix(auth): Allows RedwoodAuthCurrentUserQuery when using Auth, GraphQL and Trusted Documents (#10817) by @dthyresson

This PR allows authentication to function as expected when using Trusted Documents.

See issue #10816 above for more detail.

One way to solve is to allow an arbitrary ad-hoc query -- but just a very narrow and well-defined (aka trusted so-to-speak) one.

The plgin for persisted operations lets one define what can bypass trusted docs hash id checks: https://the-guild.dev/graphql/yoga-server/docs/features/persisted-operations#allowing-arbitrary-graphql-operations

So, we can use that in the useTrustedDocuments plugin to just allow that specific request.

const REDWOOD__AUTH_GET_CURRENT_USER_QUERY =
'{"query":"query __REDWOOD__AUTH_GET_CURRENT_USER { redwood { currentUser } }"}'
When using Redwood Auth, we want to allow the known, trusted redwood.currentUser query to be executed without a persisted operation.

This is because the currentUser query is a special case that is used to get the current user from the auth provider.

We'll check if the request is for the currentUser query and has the correct headers which are set by the useCurrentUser hook in the auth package.

The usePersistedOperations plugin relies on this function to determine if a request should be allowed to execute via its allowArbitraryOperations option.

By checking for that very exact string, and that there is a content type header, an auth-provider header and an authorization header then we can allow this to execute.

The auth provider will still be used by the apes getCurrentUser resolver to determine if the credentials whatever they are are valid.
33 changes: 33 additions & 0 deletions packages/graphql-server/src/plugins/useRedwoodTrustedDocuments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,36 @@ export type RedwoodTrustedDocumentOptions = {
customErrors?: CustomPersistedQueryErrors
}

const REDWOOD__AUTH_GET_CURRENT_USER_QUERY =
'{"query":"query __REDWOOD__AUTH_GET_CURRENT_USER { redwood { currentUser } }"}'

/**
* When using Redwood Auth, we want to allow the known, trusted `redwood.currentUser` query to be
* executed without a persisted operation.
*
* This is because the `currentUser` query is a special case that is used to get
* the current user from the auth provider.
*
* This function checks if the request is for the `currentUser` query and has the correct headers
* which are set by the useCurrentUser hook in the auth package.
*
* The usePersistedOperations plugin relies on this function to determine if a request
* should be allowed to execute via its allowArbitraryOperations option.
*/
const allowRedwoodAuthCurrentUserQuery = async (request: Request) => {
const headers = request.headers
const hasContentType = headers.get('content-type') === 'application/json'
const hasAuthProvider = !!headers.get('auth-provider')
const hasAuthorization = !!headers.get('authorization')
const hasAllowedHeaders =
hasContentType && hasAuthProvider && hasAuthorization

const query = await request.text()
const hasAllowedQuery = query === REDWOOD__AUTH_GET_CURRENT_USER_QUERY

return hasAllowedHeaders && hasAllowedQuery
}

export const useRedwoodTrustedDocuments = (
options: RedwoodTrustedDocumentOptions,
): Plugin<RedwoodGraphQLContext> => {
Expand All @@ -21,5 +51,8 @@ export const useRedwoodTrustedDocuments = (
getPersistedOperation(sha256Hash: string) {
return options.store[sha256Hash]
},
allowArbitraryOperations: async (request) => {
return allowRedwoodAuthCurrentUserQuery(request)
},
})
}

0 comments on commit 60a3b1a

Please sign in to comment.