@nocobase/plugin-ai 2.4.0-alpha.3 → 2.4.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai/docs/nocobase/file-manager/stable-url.md +1 -1
- package/dist/ai/docs/nocobase/file-manager/storage/index.md +11 -3
- package/dist/ai/docs/nocobase/file-manager/storage/local.md +4 -2
- package/dist/ai/docs/nocobase/get-started/installation/docker-nginx.mdx +4 -1
- package/dist/ai/docs/nocobase/get-started/installation/docker.mdx +2 -0
- package/dist/ai/docs/nocobase/get-started/installation/env.md +12 -0
- package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/caddy.md +28 -5
- package/dist/ai/docs/nocobase/nocobase-cli/production/reverse-proxy/nginx.md +25 -0
- package/dist/ai/docs/nocobase/security/guide.md +17 -2
- package/dist/client/{244.276308c9b2090ec2.js → 244.12a92ac906b07849.js} +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client-v2/{244.e85b8d4659ca66c0.js → 244.a0c8684f23fa5fa9.js} +1 -1
- package/dist/client-v2/index.js +1 -1
- package/dist/common/ai-employee-validation.d.ts +2 -0
- package/dist/common/ai-employee-validation.js +6 -0
- package/dist/common/error-codes.d.ts +1 -0
- package/dist/common/error-codes.js +3 -0
- package/dist/externalVersion.js +15 -15
- package/dist/locale/en-US.json +2 -0
- package/dist/locale/zh-CN.json +2 -0
- package/dist/node_modules/@langchain/mistralai/package.json +1 -1
- package/dist/node_modules/@langchain/xai/package.json +1 -1
- package/dist/node_modules/fs-extra/package.json +1 -1
- package/dist/node_modules/jsonrepair/package.json +1 -1
- package/dist/node_modules/just-bash/package.json +1 -1
- package/dist/node_modules/nodejs-snowflake/package.json +1 -1
- package/dist/node_modules/openai/package.json +1 -1
- package/dist/node_modules/zod/package.json +1 -1
- package/dist/server/ai-employees/ai-employee.d.ts +28 -1
- package/dist/server/ai-employees/ai-employee.js +257 -34
- package/dist/server/ai-employees/ai-knowledge-base.js +11 -4
- package/dist/server/ai-employees/middleware/conversation.js +19 -20
- package/dist/server/ai-employees/middleware/index.d.ts +1 -0
- package/dist/server/ai-employees/middleware/index.js +2 -0
- package/dist/server/ai-employees/middleware/tool-result-integrity.d.ts +22 -0
- package/dist/server/ai-employees/middleware/tool-result-integrity.js +211 -0
- package/dist/server/resource/aiEmployees.js +26 -0
- package/package.json +2 -2
|
@@ -72,7 +72,7 @@ curl -L \
|
|
|
72
72
|
- Do not persist `temporaryAccessToken` or use it as a sharing link
|
|
73
73
|
- Do not cache the `302 Location` as a permanent URL because storage signatures can expire
|
|
74
74
|
- Do not rewrite the app, data source, collection, ID, or extension in the path
|
|
75
|
-
- Reverse proxies must forward the `/files/` route under `APP_PUBLIC_PATH` to NocoBase. For subpath deployments, keep a compatible root-level `/files/` route as well. Configurations generated by the NocoBase CLI include both routes automatically
|
|
75
|
+
- Reverse proxies must forward the `/files/` route under `APP_PUBLIC_PATH` to NocoBase. For subpath deployments, keep a compatible root-level `/files/` route as well. Configurations generated by the NocoBase CLI include both routes automatically; for manually maintained configurations, see [Nginx Reverse Proxy](../nocobase-cli/production/reverse-proxy/nginx.md)
|
|
76
76
|
- Deployments where the pages access the API cross-origin (with `API_BASE_URL` pointing to another origin) must add the page origin to `CORS_ORIGIN_WHITELIST`; otherwise the login cookie is never stored and stable URLs return `403` for lack of credentials. See [Environment Variables](../get-started/installation/env.md#api_base_url)
|
|
77
77
|
- Use a different `hostname` for each independent NocoBase service instead of separating services only by port. Browser cookies are not isolated by port; see [Production Environment Deployment](../get-started/deployment/production.md)
|
|
78
78
|
- Sub-apps in the same NocoBase deployment are distinguished by app name and do not need separate hostnames. However, an independent service on another port still needs hostname isolation if it contains a main app or sub-app with the same name
|
|
@@ -97,13 +97,13 @@ The file record directly returns the address generated by the storage service, f
|
|
|
97
97
|
https://storage.example.com/path/to/file.png
|
|
98
98
|
```
|
|
99
99
|
|
|
100
|
-
This URL does not
|
|
100
|
+
This URL does not check the file record's view permissions. For local storage, it is usually a legacy `/storage/uploads/` URL, which requires sign-in by default but does not check the individual file record again. For cloud storage, it is usually an object storage or CDN address whose access policy is controlled by that storage service.
|
|
101
101
|
|
|
102
102
|
Select Original URL only when the caller cannot use a NocoBase URL—for example, when it cannot follow `302` redirects or explicitly requires an object storage or CDN address.
|
|
103
103
|
|
|
104
104
|
:::warning Note
|
|
105
105
|
|
|
106
|
-
After Original URL is selected, anyone with a valid URL can bypass NocoBase
|
|
106
|
+
After Original URL is selected, anyone with a valid URL can bypass NocoBase file-record permissions. For local storage, the legacy URL is still subject to the `/storage/uploads/` login check; exposing the upload directory directly through custom Nginx may bypass that check. For cloud storage, if the URL has no signature or expiration, make sure the bucket and file allow public read access.
|
|
107
107
|
|
|
108
108
|
:::
|
|
109
109
|
|
|
@@ -115,6 +115,14 @@ This option does not change the storage service's own public-read configuration.
|
|
|
115
115
|
|
|
116
116
|
Markdown, external pages, and third-party services can also use a public NocoBase URL. For external use, convert the path returned by the API into an absolute URL that includes the NocoBase domain, and make sure the caller can follow `302` redirects.
|
|
117
117
|
|
|
118
|
+
:::warning Local storage behavior
|
|
119
|
+
|
|
120
|
+
A local-storage NocoBase URL eventually redirects to `/storage/uploads/`. Selecting Allow public access skips file-record permissions at the `/files/` stage, but the legacy URL still requires sign-in by default. To make local files anonymously readable, also set `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` and restart the application. This environment variable exposes the entire legacy `/storage/uploads/` path, not only the storage where Allow public access was selected, so assess all existing files before enabling it.
|
|
121
|
+
|
|
122
|
+
When using custom Nginx, configure `auth_request` for `/storage/uploads/` as well. See [Nginx Reverse Proxy](../../nocobase-cli/production/reverse-proxy/nginx.md) for the complete configuration.
|
|
123
|
+
|
|
124
|
+
:::
|
|
125
|
+
|
|
118
126
|
### How to choose
|
|
119
127
|
|
|
120
128
|
| Use case | File URL | Allow public access |
|
|
@@ -125,7 +133,7 @@ Markdown, external pages, and third-party services can also use a public NocoBas
|
|
|
125
133
|
|
|
126
134
|
:::warning Note
|
|
127
135
|
|
|
128
|
-
[Local Storage](./local), [Amazon S3](./amazon-s3), [Aliyun OSS](./aliyun-oss), and [Tencent COS](./tencent-cos) do not generate temporary signed URLs. Even when NocoBase URL and file
|
|
136
|
+
[Local Storage](./local), [Amazon S3](./amazon-s3), [Aliyun OSS](./aliyun-oss), and [Tencent COS](./tencent-cos) do not generate temporary signed URLs. Even when NocoBase URL and file-record permissions are enabled, someone who has obtained the storage service's original address can bypass file-record permissions. Legacy local-storage URLs still require sign-in by default; access to an original cloud-storage URL depends on that service's public-read configuration.
|
|
129
137
|
|
|
130
138
|
For contracts, identity documents, internal materials, or other files that should not be public, use [S3 Pro](./s3-pro) and refer to its dedicated access-control configuration.
|
|
131
139
|
|
|
@@ -5,11 +5,13 @@ Uploaded files will be saved in a local directory on the server's hard drive. Th
|
|
|
5
5
|
|
|
6
6
|
:::warning Note
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Use `/files/` stable URLs for local files whenever possible so NocoBase can check the file record and the current role's view permission. Legacy `/storage/uploads/` URLs do not enforce record-level permissions, but Docker, the built-in Nginx, and Nginx configurations generated by the NocoBase CLI restrict them to signed-in users by default.
|
|
9
9
|
|
|
10
10
|
If you need to store contracts, identity documents, internal materials, or other files that should not be public, use [S3 Pro](./s3-pro). If historical files already exist, see [Migrate to S3 Pro](./migrate-to-s3-pro.md).
|
|
11
11
|
|
|
12
|
-
If
|
|
12
|
+
If custom Nginx serves local uploads through `alias`, its `/storage/uploads/` location must use `auth_request` to call the NocoBase auth endpoint. Otherwise, it bypasses the default login check. Also set `X-Content-Type-Options: nosniff` and return active content files such as `html`, `svg`, `xhtml`, and `pdf` as attachments. See [Nginx Reverse Proxy](../../nocobase-cli/production/reverse-proxy/nginx.md) for a complete example and sub-application configuration, and [Security guide: File storage](../../security/guide.md#file-storage) for the associated risks.
|
|
13
|
+
|
|
14
|
+
If an existing integration depends on anonymous access to legacy URLs, set `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` and restart the application. This compatibility switch affects only `/storage/uploads/` and does not change record-level permissions for `/files/`.
|
|
13
15
|
|
|
14
16
|
:::
|
|
15
17
|
|
|
@@ -96,8 +96,11 @@ services:
|
|
|
96
96
|
- `./storage` must be mounted into both the `app` and `nginx` containers so they can share proxy config, static assets, and uploaded files
|
|
97
97
|
- The `nginx` container should wait until `nocobase.conf` is generated, then link it to `/etc/nginx/conf.d/default.conf` with `ln -sf`
|
|
98
98
|
- The generated config forwards both the `/files/` route under `APP_PUBLIC_PATH` and the root-level `/files/` route to NocoBase for authenticated file previews and downloads
|
|
99
|
+
- Before Nginx returns a legacy `/storage/uploads/` file through `alias`, the generated config uses `auth_request` to ask NocoBase to verify the login state; anonymous access returns `401` by default
|
|
99
100
|
- If you use an external Nginx container, let the `nginx` container handle the host port mapping. For testing, you can start with `13000:80`; in production, you usually expose the host `80` and `443` ports directly, while the `app` service does not need to expose its port to the host
|
|
100
101
|
|
|
102
|
+
If an existing program depends on anonymous access to `/storage/uploads/`, add `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` to `app.environment` and restart the application container. Do not remove or rewrite the `auth_request` in the generated config; the auth endpoint uses this variable to decide whether anonymous access is allowed. This variable does not change record-level permissions for `/files/`.
|
|
103
|
+
|
|
101
104
|
## If you use a local host Nginx
|
|
102
105
|
|
|
103
106
|
If your Nginx is installed directly on the host instead of running in a Docker container, it is better to use a separate `docker-compose.yml`. In this setup, the `app` service must expose a host port directly, and the proxy-related environment variables should use host-side values.
|
|
@@ -171,7 +174,7 @@ sudo systemctl reload nginx
|
|
|
171
174
|
|
|
172
175
|
If your host Nginx does not use the `conf.d` directory, replace the link target with your own config path. Usually it is safer to keep `nocobase.conf` as a file included from the `http {}` context instead of copying its content manually.
|
|
173
176
|
|
|
174
|
-
If you maintain Nginx yourself instead of using the generated config, make sure `/files/` and the corresponding route under `APP_PUBLIC_PATH` are forwarded to NocoBase before the SPA fallback rules. See [Nginx Reverse Proxy](../../nocobase-cli/production/reverse-proxy/nginx.md) for a complete example.
|
|
177
|
+
If you maintain Nginx yourself instead of using the generated config, make sure `/files/` and the corresponding route under `APP_PUBLIC_PATH` are forwarded to NocoBase before the SPA fallback rules. When serving `/storage/uploads/` through `alias`, you must also configure `auth_request` so the static directory cannot bypass the application login check. See [Nginx Reverse Proxy](../../nocobase-cli/production/reverse-proxy/nginx.md) for a complete example.
|
|
175
178
|
|
|
176
179
|
## Related links
|
|
177
180
|
|
|
@@ -660,6 +660,8 @@ If you also want to enable HTTPS, configure `443` and the certificate on the hos
|
|
|
660
660
|
|
|
661
661
|
The `location /` block in this root-path configuration also proxies `/api/`, `/ws`, and `/files/`. If you split static assets from application routes, make sure `/files/` is still forwarded to NocoBase and is not handled as a static directory.
|
|
662
662
|
|
|
663
|
+
Before returning a legacy `/storage/uploads/` file, the built-in Nginx asks NocoBase to verify the login state; anonymous access returns `401` by default. If a program already depended on anonymous access to these legacy URLs before an upgrade, add `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` to `app.environment` and restart the container. Keep forwarding this path from the host Nginx to the container. Do not expose the host upload directory directly with another `alias`, because that would bypass the check.
|
|
664
|
+
|
|
663
665
|
### Subpath deployment
|
|
664
666
|
|
|
665
667
|
If you want to deploy the app under a subpath, such as `https://your_domain.com/nocobase/`, configure the `APP_PUBLIC_PATH` environment variable first:
|
|
@@ -107,6 +107,18 @@ NocoBase uses cookies to maintain login state and to authorize [stable file URLs
|
|
|
107
107
|
Prefer serving the pages and the API from the same origin through a reverse proxy and leaving `API_BASE_URL` empty.
|
|
108
108
|
:::
|
|
109
109
|
|
|
110
|
+
### LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS
|
|
111
|
+
|
|
112
|
+
Controls whether legacy local file URLs under `/storage/uploads/` allow anonymous access. The default is `false`, so only signed-in users can access them.
|
|
113
|
+
|
|
114
|
+
If an existing integration depends on public access through these URLs, explicitly enable compatibility mode:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Restart the application after changing this variable. It affects only legacy `/storage/uploads/` URLs and does not change record-level permissions for `/files/`. Public access may expose uploaded files, so enable it only after confirming that the files are safe to publish.
|
|
121
|
+
|
|
110
122
|
### CORS_ORIGIN_WHITELIST
|
|
111
123
|
|
|
112
124
|
Whitelist of origins allowed to access the API cross-origin with credentials (cookies). Multiple origins are separated by commas. Empty by default.
|
|
@@ -135,7 +135,7 @@ Taking `test2` as an example, key directories related to Caddy usually include:
|
|
|
135
135
|
In other words, handwritten configuration usually needs to cover at least the following types of entries:
|
|
136
136
|
|
|
137
137
|
- `v`: Redirect `/v` to `/v/`
|
|
138
|
-
- `uploads`: Expose upload directory
|
|
138
|
+
- `uploads`: Expose the upload directory after NocoBase authentication
|
|
139
139
|
- `dist`: Expose the front-end build product directory
|
|
140
140
|
- `oauth well-known`: Handle OAuth discovery paths
|
|
141
141
|
- `openid well-known`: Handle OpenID discovery paths
|
|
@@ -164,10 +164,31 @@ c.local.nocobase.com {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
handle_path /storage/uploads/* {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
167
|
+
route {
|
|
168
|
+
request_header -X-NocoBase-Auth-Set-Cookie
|
|
169
|
+
forward_auth host.docker.internal:56575 {
|
|
170
|
+
uri /api/auth:checkLegacyFileAccess
|
|
171
|
+
header_up X-App {query.__appName}
|
|
172
|
+
copy_headers Set-Cookie>X-NocoBase-Auth-Set-Cookie
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
@refreshedAuth header X-NocoBase-Auth-Set-Cookie *
|
|
176
|
+
header @refreshedAuth Set-Cookie {header.X-NocoBase-Auth-Set-Cookie}
|
|
177
|
+
header Cache-Control "private, no-store"
|
|
178
|
+
header Content-Security-Policy sandbox
|
|
179
|
+
header X-Content-Type-Options nosniff
|
|
180
|
+
header Content-Disposition inline
|
|
181
|
+
|
|
182
|
+
@activeUploadedContent path_regexp activeUploadedContent (?i)\.(?:htm|html|pdf|svg|svgz|xht|xhtml|xml|xsl|xslt)$
|
|
183
|
+
header @activeUploadedContent Content-Disposition attachment
|
|
184
|
+
@download query download=1
|
|
185
|
+
header @download Content-Disposition attachment
|
|
186
|
+
@markdown path_regexp markdown (?i)\.md$
|
|
187
|
+
header @markdown Content-Type text/markdown
|
|
188
|
+
|
|
189
|
+
root * NB_CLI_ROOT/test2/storage/uploads
|
|
190
|
+
file_server
|
|
191
|
+
}
|
|
171
192
|
}
|
|
172
193
|
|
|
173
194
|
handle_path /dist/* {
|
|
@@ -258,6 +279,8 @@ This is usually less likely to miss details related to `/files/`, WebSockets, st
|
|
|
258
279
|
|
|
259
280
|
:::warning Note
|
|
260
281
|
|
|
282
|
+
URLs under `/storage/uploads/` are legacy local file URLs and must pass NocoBase sign-in authentication by default. Do not expose the upload directory with `file_server` alone, because that bypasses access control. The example above uses `forward_auth` to call the NocoBase auth endpoint before Caddy sends the file. Set `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` and restart the application only when anonymous access is explicitly required for compatibility.
|
|
283
|
+
|
|
261
284
|
`/files/` is an application route that must pass through NocoBase authorization. Do not handle it as a static directory or let it fall through to the SPA fallback. Forward it to the NocoBase backend and place the rule before `handle_path /*` and other front-end fallback rules.
|
|
262
285
|
|
|
263
286
|
If `APP_PUBLIC_PATH=/nocobase/` is configured, also forward `/nocobase/files/*`. Keep the root-level `/files/*` rule for compatibility with existing file URLs.
|
|
@@ -111,6 +111,7 @@ in:
|
|
|
111
111
|
- `NB_CLI_ROOT/test2/storage/...` The following are the application's own static resources and upload directories
|
|
112
112
|
- `app.conf` can be changed, but the NocoBase managed block must be retained
|
|
113
113
|
- `index-v1.html` and `index-v2.html` will automatically rewrite resource addresses according to the current env subpath, active client version, and `CDN_BASE_URL`
|
|
114
|
+
- `maps-http.conf` and `uploads-location.conf` protect legacy `/storage/uploads/` URLs together: the former resolves the sub-application parameter, and the latter runs an `auth_request` login check before Nginx returns a local file
|
|
114
115
|
|
|
115
116
|
:::warning note
|
|
116
117
|
|
|
@@ -154,6 +155,11 @@ location / {
|
|
|
154
155
|
For a CLI-hosted application like `test2`, a structure closer to a real deployment would usually look like this:
|
|
155
156
|
|
|
156
157
|
```nginx
|
|
158
|
+
map $request_uri $legacy_file_app {
|
|
159
|
+
default "";
|
|
160
|
+
~[?&]__appName=(?<legacy_file_app_name>[A-Za-z0-9_-]+)(?:&|$) $legacy_file_app_name;
|
|
161
|
+
}
|
|
162
|
+
|
|
157
163
|
server {
|
|
158
164
|
listen 80;
|
|
159
165
|
server_name c.local.nocobase.com;
|
|
@@ -165,6 +171,19 @@ server {
|
|
|
165
171
|
include NB_CLI_ROOT/.nocobase/proxy/nginx/snippets/mime-types.conf;
|
|
166
172
|
include NB_CLI_ROOT/.nocobase/proxy/nginx/snippets/gzip.conf;
|
|
167
173
|
|
|
174
|
+
location = /_nocobase_legacy_file_auth {
|
|
175
|
+
internal;
|
|
176
|
+
proxy_pass http://127.0.0.1:56575/api/auth:checkLegacyFileAccess;
|
|
177
|
+
proxy_pass_request_body off;
|
|
178
|
+
proxy_set_header Content-Length "";
|
|
179
|
+
proxy_set_header Cookie $http_cookie;
|
|
180
|
+
proxy_set_header Authorization $http_authorization;
|
|
181
|
+
proxy_set_header X-App $legacy_file_app;
|
|
182
|
+
proxy_set_header X-Original-URI $request_uri;
|
|
183
|
+
proxy_set_header Host $final_host;
|
|
184
|
+
proxy_set_header X-Forwarded-Proto $upstream_x_forwarded_proto;
|
|
185
|
+
}
|
|
186
|
+
|
|
168
187
|
location /storage/uploads/ {
|
|
169
188
|
alias NB_CLI_ROOT/test2/storage/uploads/;
|
|
170
189
|
include NB_CLI_ROOT/.nocobase/proxy/nginx/snippets/uploads-location.conf;
|
|
@@ -216,6 +235,8 @@ server {
|
|
|
216
235
|
}
|
|
217
236
|
```
|
|
218
237
|
|
|
238
|
+
The `map` directive must be placed in Nginx's `http {}` context, not inside `server {}` or `location {}`. It identifies a sub-application from the `__appName` query parameter in a legacy file URL. The `/api/` segment in `proxy_pass` must match the application's actual `API_BASE_PATH`; when `APP_PUBLIC_PATH` is configured, use the same prefix for both the upload location and auth endpoint.
|
|
239
|
+
|
|
219
240
|
There are two key points here:
|
|
220
241
|
|
|
221
242
|
- `NB_CLI_ROOT/.nocobase/proxy/nginx/...` The following are agent auxiliary files maintained by CLI
|
|
@@ -243,6 +264,10 @@ This is usually less likely to miss details related to `/files/`, WebSockets, st
|
|
|
243
264
|
|
|
244
265
|
If `APP_PUBLIC_PATH=/nocobase/` is configured, also forward `/nocobase/files/`. Keep the root-level `/files/` rule for compatibility with existing file URLs.
|
|
245
266
|
|
|
267
|
+
Legacy `/storage/uploads/` URLs also require sign-in by default. When serving files directly with `alias`, run an `auth_request` to NocoBase's `auth:checkLegacyFileAccess` endpoint first. Configuring only the static directory bypasses the login check. The `uploads-location.conf` snippet in the example already contains the `auth_request` directive; if you do not use the CLI snippets, add the equivalent logic to the upload location yourself.
|
|
268
|
+
|
|
269
|
+
If an existing integration must access legacy URLs anonymously, set `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` for the NocoBase application and restart it. The auth endpoint evaluates this setting, so do not regenerate or remove the Nginx `auth_request` configuration. The switch affects only `/storage/uploads/` and does not change record-level permissions for `/files/`.
|
|
270
|
+
|
|
246
271
|
:::
|
|
247
272
|
|
|
248
273
|
## How to handle HTTPS
|
|
@@ -213,17 +213,30 @@ If you need to store sensitive files, it is recommended to use a cloud storage s
|
|
|
213
213
|
|
|
214
214
|

|
|
215
215
|
|
|
216
|
-
For local storage or other
|
|
216
|
+
For local storage or other storage that can be accessed directly through same-origin application URLs, you should also pay extra attention to the risks introduced by active content files. Files such as `html`, `xhtml`, and `svg` may be parsed and executed directly by the browser. If an attacker can upload such a file and trick a user into opening it, the attacker may use your trusted application domain to host a malicious page or script.
|
|
217
217
|
|
|
218
218
|
NocoBase upload validation does not trust the `Content-Type` sent by the request. It prefers the MIME type detected on the server side. A file extension only represents the filename and should not be treated as the authoritative file content type. Therefore, when serving public uploaded files, you also need to make sure the file access path has proper security response headers.
|
|
219
219
|
|
|
220
|
-
If you deploy with Docker or use the nginx configuration generated by NocoBase,
|
|
220
|
+
If you deploy with Docker or use the nginx configuration generated by NocoBase, legacy `/storage/uploads/` URLs are restricted to signed-in users. All uploaded files also return `X-Content-Type-Options: nosniff`, and active content files such as `html`, `xhtml`, `svg`, `svgz`, and `pdf` are returned as downloads through `Content-Disposition: attachment`. New `/files/` URLs continue to enforce record-level file permissions.
|
|
221
|
+
|
|
222
|
+
If an existing integration still depends on anonymous access to legacy URLs, set `LEGACY_LOCAL_STORAGE_PUBLIC_ACCESS=true` and restart the application to restore public access to `/storage/uploads/`. This compatibility switch is disabled by default, affects only legacy URLs, and does not change record-level permissions for `/files/`. Public access may expose uploaded files, so confirm that they contain no sensitive content before enabling it.
|
|
221
223
|
|
|
222
224
|
If you use a custom proxy, CDN, object storage, or expose the local upload directory directly, make sure these rules are not bypassed. You can use the following nginx configuration as a reference:
|
|
223
225
|
|
|
224
226
|
```nginx
|
|
227
|
+
location = /_nocobase_legacy_file_auth {
|
|
228
|
+
internal;
|
|
229
|
+
proxy_pass http://127.0.0.1:13000/api/auth:checkLegacyFileAccess;
|
|
230
|
+
proxy_pass_request_body off;
|
|
231
|
+
proxy_set_header Content-Length "";
|
|
232
|
+
proxy_set_header Cookie $http_cookie;
|
|
233
|
+
proxy_set_header Authorization $http_authorization;
|
|
234
|
+
}
|
|
235
|
+
|
|
225
236
|
location ~* ^/storage/uploads/(.*\.(?:htm|html|svg|svgz|xhtml|pdf))$ {
|
|
226
237
|
alias /path/to/nocobase/storage/uploads/$1;
|
|
238
|
+
auth_request /_nocobase_legacy_file_auth;
|
|
239
|
+
add_header Cache-Control "private, no-store" always;
|
|
227
240
|
add_header Content-Disposition "attachment" always;
|
|
228
241
|
add_header X-Content-Type-Options "nosniff" always;
|
|
229
242
|
autoindex off;
|
|
@@ -231,6 +244,8 @@ location ~* ^/storage/uploads/(.*\.(?:htm|html|svg|svgz|xhtml|pdf))$ {
|
|
|
231
244
|
|
|
232
245
|
location /storage/uploads/ {
|
|
233
246
|
alias /path/to/nocobase/storage/uploads/;
|
|
247
|
+
auth_request /_nocobase_legacy_file_auth;
|
|
248
|
+
add_header Cache-Control "private, no-store" always;
|
|
234
249
|
add_header X-Content-Type-Options "nosniff" always;
|
|
235
250
|
autoindex off;
|
|
236
251
|
}
|