Skip to content

Commit 38fec9e

Browse files
committed
Port #2343
1 parent 63ff3f9 commit 38fec9e

File tree

2 files changed

+142
-85
lines changed

2 files changed

+142
-85
lines changed

docusaurus/docs/dev-docs/configurations/plugins.md

Lines changed: 1 addition & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Plugin configurations are stored in `/config/plugins.js|ts` (see [project struct
2525
| `resolve`<br/> _Optional, only required for local plugins_ | Path to the plugin's folder | String |
2626

2727
:::note
28-
Some features of Strapi are provided by plugins and the following plugins can also have specific configuration options: [GraphQL](#graphql) and [Upload](#upload).
28+
Some features of Strapi are provided by plugins and the following plugins can also have specific configuration options: the [GraphQL](/dev-docs/plugins/graphql#code-based-configuration) plugin and the [Upload](/user-docs/features/media-library#available-options) package which powers the Media Library.
2929
:::
3030

3131
**Basic example custom configuration for plugins:**
@@ -91,70 +91,3 @@ export default ({ env }) => ({
9191
:::tip
9292
If no specific configuration is required, a plugin can also be declared with the shorthand syntax `'plugin-name': true`.
9393
:::
94-
95-
## GraphQL configuration {#graphql}
96-
97-
The [GraphQL plugin](/dev-docs/plugins/graphql) has the following specific configuration options that should be declared in a `graphql.config` object within the `config/plugins` file. All parameters are optional:
98-
99-
| Parameter | Description | Type | Default |
100-
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | ------- |
101-
| `apolloServer` | Additional configuration for [`ApolloServer`](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserver). | Object | `{}` |
102-
| `artifacts` | Object containing filepaths, defining where to store generated artifacts. Can include the following properties: <ul><li>`schema`: path to the generated GraphQL schema file</li><li>`typegen`: path to generated TypeScript types</li></ul>Only works if `generateArtifacts` is set to `true`. | Object | <ul><li>`schema: false`</li><li>`typegen: false`</li></ul> |
103-
| `defaultLimit` | Default value for [the `pagination[limit]` parameter](/dev-docs/api/graphql#pagination-by-offset) used in API calls | Integer | 100 |
104-
| `depthLimit` | Limits the [complexity of GraphQL queries](https://www.npmjs.com/package/graphql-depth-limit). | Integer | `10` |
105-
| `endpoint` | The URL path on which the plugin is exposed | String | `/graphql` |
106-
| `generateArtifacts`| Whether Strapi should automatically generate and output a GraphQL schema file and corresponding TypeScript definitions.<br/><br/>The file system location can be configured through `artifacts`. | Boolean | `false` |
107-
| `maxLimit` | Maximum value for [the `pagination[limit]` parameter](/dev-docs/api/graphql#pagination-by-offset) used in API calls | Integer | `-1` |
108-
| `playgroundAlways` | Whether the playground should be publicly exposed.<br/><br/>Enabled by default in if `NODE_ENV` is set to `development`. | Boolean | `false` |
109-
| `shadowCRUD` | Whether type definitions for queries, mutations and resolvers based on models should be created automatically (see [Shadow CRUD documentation](/dev-docs/plugins/graphql#shadow-crud)). | Boolean | `true` |
110-
| `v4ComptabilityMode` | Enables the retro-compatibility with the Strapi v4 format (see more details in the [breaking change entry](/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated) | Boolean | `false` |
111-
112-
**Example custom configuration**:
113-
114-
<Tabs groupId="js-ts">
115-
116-
<TabItem value="javascript" label="JavaScript">
117-
118-
```js title="./config/plugins.js"
119-
120-
module.exports = () => ({
121-
graphql: {
122-
enabled: true,
123-
config: {
124-
playgroundAlways: false,
125-
defaultLimit: 10,
126-
maxLimit: 20,
127-
apolloServer: {
128-
tracing: true,
129-
},
130-
}
131-
}
132-
})
133-
```
134-
135-
</TabItem>
136-
137-
<TabItem value="typescript" label="TypeScript">
138-
139-
```ts title="./config/plugins.ts"
140-
141-
export default () => ({
142-
graphql: {
143-
enabled: true,
144-
config: {
145-
playgroundAlways: false,
146-
defaultLimit: 10,
147-
maxLimit: 20,
148-
apolloServer: {
149-
tracing: true,
150-
},
151-
}
152-
}
153-
})
154-
```
155-
156-
</TabItem>
157-
158-
</Tabs>
159-
160-
## Upload configuration {#upload}

docusaurus/docs/dev-docs/plugins/graphql.md

Lines changed: 141 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ tags:
1919

2020
# GraphQL plugin
2121

22-
By default Strapi create [REST endpoints](/dev-docs/api/rest#endpoints) for each of your content-types. The GraphQL plugin adds a GraphQL endpoint to fetch and mutate your content. With the GraphQL plugin installed, you can use the Apollo Server-based GraphQL Playground to interactively build your queries and mutations and read documentation tailored to your content types.
22+
By default Strapi create [REST endpoints](/dev-docs/api/rest#endpoints) for each of your content-types. The GraphQL plugin adds a GraphQL endpoint to fetch and mutate your content. With the GraphQL plugin installed, you can use the Apollo Server-based GraphQL Sandbox to interactively build your queries and mutations and read documentation tailored to your content types.
2323

2424
:::prerequisites Identity Card of the Plugin
2525
<Icon name="navigation-arrow"/> **Location:** Usable via the admin panel. Configured through both admin panel and server code, with different sets of options.<br/>
@@ -57,9 +57,9 @@ npm install @strapi/plugin-graphql
5757

5858
</Tabs>
5959

60-
Once installed, the GraphQL playground is accessible at the `/graphql` URL and can be used to interactively build your queries and mutations and read documentation tailored to your content-types.
60+
Once installed, the GraphQL sandbox is accessible at the `/graphql` URL and can be used to interactively build your queries and mutations and read documentation tailored to your content-types.
6161

62-
Once the plugin is installed, the **GraphQL Playground** is accessible at the `/graphql` route (e.g., [localhost:1337/graphql](http://localhost:1337/graphql)) when your Strapi application server is running.
62+
Once the plugin is installed, the **GraphQL Sandbox** is accessible at the `/graphql` route (e.g., [localhost:1337/graphql](http://localhost:1337/graphql)) when your Strapi application server is running.
6363

6464
## Configuration
6565

@@ -73,29 +73,43 @@ The Strapi admin panel does not provide Strapi-specific settings for the GraphQL
7373

7474
Plugins configuration are defined in the `config/plugins.js` file. This configuration file can include a `graphql.config` object to define specific configurations for the GraphQL plugin (see [plugins configuration documentation](/dev-docs/configurations/plugins#graphql)).
7575

76-
Apollo Server options can be set with the `graphql.config.apolloServer` [configuration object](/dev-docs/configurations/plugins#graphql). Apollo Server options can be used for instance to enable the [tracing feature](https://www.apollographql.com/docs/federation/metrics/), which is supported by the GraphQL playground to track the response time of each part of your query. From `Apollo Server` version 3.9 default cache option is `cache: 'bounded'`. You can change it in the `apolloServer` configuration (for details, see [Apollo Server Docs](https://www.apollographql.com/docs/apollo-server/performance/cache-backends/)).
76+
#### Available options
77+
78+
[Apollo Server](https://www.apollographql.com/docs/apollo-server/api/apollo-server/#apolloserver) options can be passed directly to Apollo with the `graphql.config.apolloServer` [configuration object](/dev-docs/configurations/plugins#graphql). Apollo Server options can be used for instance to enable the [tracing feature](https://www.apollographql.com/docs/federation/metrics/), which is supported by the GraphQL Sandbox to track the response time of each part of your query. The `Apollo Server` default cache option is `cache: 'bounded'`. You can change it in the `apolloServer` configuration. For more information visit [Apollo Server Docs](https://www.apollographql.com/docs/apollo-server/performance/cache-backends/).
79+
80+
The [GraphQL plugin](/dev-docs/plugins/graphql) has the following specific configuration options that should be declared in a `graphql.config` object within the `config/plugins` file. All parameters are optional:
81+
82+
| Option | Type | Description | Default Value | Notes |
83+
| ------------------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | --------------------------------------------------- |
84+
| `endpoint` | String | Sets the GraphQL endpoint path. | `'/graphql'` | Example: `/custom-graphql` |
85+
| `shadowCRUD` | Boolean | Enables or disables automatic schema generation for content types. | `true` | |
86+
| `depthLimit` | Number | Limits the depth of GraphQL queries to prevent excessive nesting. | `10` | Use this to mitigate potential DoS attacks. |
87+
| `amountLimit` | Number | Limits the maximum number of items returned in a single response. | `100` | Use cautiously to avoid performance issues. |
88+
| `playgroundAlways` | Boolean | [Deprecated] Enables GraphQL Playground in all environments (deprecated). | `false` | Prefer using `landingPage` instead. |
89+
| `landingPage` | Boolean \| Function | Enables or disables the landing page for GraphQL. Accepts a boolean or a function returning a boolean or an ApolloServerPlugin implementing `renderLandingPage`. | | `false` in production, `true` in other environments |
90+
| `apolloServer` | Object | Passes configuration options directly to Apollo Server. | `{}` | Example: `{ tracing: true }`
7791

7892
:::caution
7993
The maximum number of items returned by the response is limited to 100 by default. This value can be changed using the `amountLimit` configuration option, but should only be changed after careful consideration: a large query can cause a DDoS (Distributed Denial of Service) and may cause abnormal load on your Strapi server, as well as your database server.
8094
:::
8195

8296
:::note
83-
The GraphQL Playground is enabled by default for both the development and staging environments, but disabled in production environments. Set the `playgroundAlways` configuration option to `true` to also enable the GraphQL Playground in production environments (see [plugins configuration documentation](/dev-docs/configurations/plugins#graphql)).
97+
The GraphQL Sandbox is enabled by default in all environments except production. Set the `landingPage` configuration option to `true` to also enable the GraphQL Sandbox in production environments.
8498
:::
8599

100+
The following is an example custom configuration:
101+
86102
<Tabs groupId="js-ts">
87103

88104
<TabItem value="javascript" label="JavaScript">
89105

90106
```js title="/config/plugins.js"
91-
92107
module.exports = {
93-
//
94108
graphql: {
95109
config: {
96110
endpoint: '/graphql',
97111
shadowCRUD: true,
98-
playgroundAlways: false,
112+
landingPage: false, // disable Sandbox everywhere
99113
depthLimit: 7,
100114
amountLimit: 100,
101115
apolloServer: {
@@ -111,21 +125,131 @@ module.exports = {
111125
<TabItem value="typescript" label="TypeScript">
112126

113127
```ts title="/config/plugins.ts"
114-
115-
export default {
116-
//
128+
export default () => ({
117129
graphql: {
118130
config: {
119131
endpoint: '/graphql',
120132
shadowCRUD: true,
121-
playgroundAlways: false,
133+
landingPage: false, // disable Sandbox everywhere
122134
depthLimit: 7,
123135
amountLimit: 100,
124136
apolloServer: {
125137
tracing: false,
126138
},
127139
},
128140
},
141+
})
142+
```
143+
144+
</TabItem>
145+
146+
</Tabs>
147+
148+
149+
#### Dynamically enable Apollo Sandbox
150+
151+
You can use a function to dynamically enable Apollo Sandbox depending on the environment:
152+
153+
<Tabs groupId="js-ts">
154+
155+
<TabItem value="javascript" label="JavaScript">
156+
157+
```javascript title="./config/plugins.js" {6-12}
158+
module.exports = ({ env }) => {
159+
graphql: {
160+
config: {
161+
endpoint: '/graphql',
162+
shadowCRUD: true,
163+
landingPage: (strapi) => {
164+
if (env("NODE_ENV") !== "production") {
165+
return true;
166+
} else {
167+
return false;
168+
}
169+
},
170+
},
171+
},
172+
};
173+
```
174+
175+
</TabItem>
176+
177+
<TabItem value="typescript" label="TypeScript">
178+
179+
```ts title="./config/plugins.ts" {6-12}
180+
export default ({ env }) => {
181+
graphql: {
182+
config: {
183+
endpoint: '/graphql',
184+
shadowCRUD: true,
185+
landingPage: (strapi) => {
186+
if (env("NODE_ENV") !== "production") {
187+
return true;
188+
} else {
189+
return false;
190+
}
191+
},
192+
},
193+
},
194+
};
195+
```
196+
</TabItem>
197+
198+
</Tabs>
199+
200+
#### CORS exceptions for Landing Page
201+
202+
If the landing page is enabled in production environments (which is not recommended), CORS headers for the Apollo Server landing page must be added manually.
203+
204+
To add them globally, you can merge the following into your middleware configuration:
205+
206+
```javascript title="/config/middlewares"
207+
{
208+
name: "strapi::security",
209+
config: {
210+
contentSecurityPolicy: {
211+
useDefaults: true,
212+
directives: {
213+
"connect-src": ["'self'", "https:", "apollo-server-landing-page.cdn.apollographql.com"],
214+
"img-src": ["'self'", "data:", "blob:", "apollo-server-landing-page.cdn.apollographql.com"],
215+
"script-src": ["'self'", "'unsafe-inline'", "apollo-server-landing-page.cdn.apollographql.com"],
216+
"style-src": ["'self'", "'unsafe-inline'", "apollo-server-landing-page.cdn.apollographql.com"],
217+
"frame-src": ["sandbox.embed.apollographql.com"]
218+
}
219+
}
220+
}
221+
}
222+
```
223+
224+
To add these exceptions only for the `/graphql` path (recommended), you can create a new middleware to handle it. For example:
225+
226+
<Tabs groupId="js-ts">
227+
228+
<TabItem value="javascript" label="JavaScript">
229+
230+
```javascript title="./middlewares/graphql-security.js"
231+
module.exports = (config, { strapi }) => {
232+
return async (ctx, next) => {
233+
if (ctx.request.path === '/graphql') {
234+
ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.jsdelivr.net apollo-server-landing-page.cdn.apollographql.com; connect-src 'self' https:; img-src 'self' data: blob: apollo-server-landing-page.cdn.apollographql.com; media-src 'self' data: blob: apollo-server-landing-page.cdn.apollographql.com; frame-src sandbox.embed.apollographql.com; manifest-src apollo-server-landing-page.cdn.apollographql.com;");
235+
}
236+
await next();
237+
};
238+
};
239+
```
240+
241+
</TabItem>
242+
243+
<TabItem value="typescript" label="TypeScript">
244+
245+
```ts title="./middlewares/graphql-security.ts"
246+
export default (config, { strapi }) => {
247+
return async (ctx, next) => {
248+
if (ctx.request.path === '/graphql') {
249+
ctx.set('Content-Security-Policy', "default-src 'self'; script-src 'self' 'unsafe-inline' cdn.jsdelivr.net apollo-server-landing-page.cdn.apollographql.com; connect-src 'self' https:; img-src 'self' data: blob: apollo-server-landing-page.cdn.apollographql.com; media-src 'self' data: blob: apollo-server-landing-page.cdn.apollographql.com; frame-src sandbox.embed.apollographql.com; manifest-src apollo-server-landing-page.cdn.apollographql.com;");
250+
}
251+
await next();
252+
};
129253
};
130254
```
131255

@@ -913,10 +1037,10 @@ export default {
9131037

9141038
GraphQL is a query language allowing users to use a broader panel of inputs than traditional REST APIs. GraphQL APIs are inherently prone to security risks, such as credential leakage and denial of service attacks, that can be reduced by taking appropriate precautions.
9151039

916-
###### Disable introspection and playground in production
1040+
### Disable introspection and Sandbox in production
9171041

918-
In production environments, disabling the GraphQL Playground and the introspection query is recommended.
919-
If you haven't edited the [configuration file](/dev-docs/configurations/plugins#graphql), it is already disabled in production by default.
1042+
In production environments, disabling the GraphQL Sandbox and the introspection query is strongly recommended.
1043+
If you haven't edited the [configuration file](#availabel-options), it is already disabled in production by default.
9201044

9211045
###### Limit max depth and complexity
9221046

@@ -973,14 +1097,14 @@ mutation {
9731097

9741098
</Request>
9751099

976-
Then on each request, send along an `Authorization` header in the form of `{ "Authorization": "Bearer YOUR_JWT_GOES_HERE" }`. This can be set in the HTTP Headers section of your GraphQL Playground.
1100+
Then on each request, send along an `Authorization` header in the form of `{ "Authorization": "Bearer YOUR_JWT_GOES_HERE" }`. This can be set in the HTTP Headers section of your GraphQL Sandbox.
9771101

9781102
#### Usage with API tokens
9791103

9801104
To use API tokens for authentication, pass the token in the `Authorization` header using the format `Bearer your-api-token`.
9811105

9821106
:::note
983-
Using API tokens in the the GraphQL playground requires adding the authorization header with your token in the `HTTP HEADERS` tab:
1107+
Using API tokens in the the GraphQL Sandbox requires adding the authorization header with your token in the `HTTP HEADERS` tab:
9841108

9851109
```http
9861110
{

0 commit comments

Comments
 (0)