- Meet: add external-api backend path, CSRF trusted origins - Drive: fix media proxy regex for preview URLs and S3 key signing - OpenBao: enable Prometheus telemetry - Postgres alerts: fix metric name (cnpg_backends_total) - Gitea: bump memory limits for mirror workloads - Alertbot: expanded deployment config - Kratos: add find/cal/projects to allowed return URLs, settings path - Pingora: meet external-api route fix - Sol: config update
89 lines
4.0 KiB
YAML
89 lines
4.0 KiB
YAML
# nginx config for drive-frontend.
|
|
#
|
|
# /media/ requests are validated via auth_request to the Drive backend before
|
|
# being proxied to SeaweedFS. This avoids exposing S3 credentials to the browser
|
|
# while still serving private files through the CDN path.
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
metadata:
|
|
name: drive-frontend-nginx-conf
|
|
namespace: lasuite
|
|
data:
|
|
default.conf: |
|
|
server {
|
|
listen 8080;
|
|
server_name localhost;
|
|
server_tokens off;
|
|
|
|
root /usr/share/nginx/html;
|
|
|
|
# Rewrite hardcoded upstream La Gaufre widget and services API URLs to our
|
|
# integration service. sub_filter doesn't work on gzip-compressed responses.
|
|
gzip off;
|
|
sub_filter_once off;
|
|
sub_filter_types text/html application/javascript;
|
|
sub_filter 'https://static.suite.anct.gouv.fr/widgets/lagaufre.js'
|
|
'https://integration.DOMAIN_SUFFIX/api/v2/lagaufre.js';
|
|
sub_filter 'https://lasuite.numerique.gouv.fr/api/services'
|
|
'https://integration.DOMAIN_SUFFIX/api/v2/services.json';
|
|
sub_filter 'https://operateurs.suite.anct.gouv.fr/api/v1.0/lagaufre/services/?operator=9f5624fc-ef99-4d10-ae3f-403a81eb16ef&siret=21870030000013'
|
|
'https://integration.DOMAIN_SUFFIX/api/v2/services.json';
|
|
sub_filter '</head>' '<link rel="stylesheet" href="https://integration.DOMAIN_SUFFIX/api/v2/theme.css"></head>';
|
|
|
|
# Public file viewer — Next.js static export generates a literal [id].html
|
|
# template for this dynamic route. Serve it for any file UUID so the
|
|
# client-side router hydrates the correct FilePage component without auth.
|
|
location ~ ^/explorer/items/files/[^/]+$ {
|
|
try_files $uri $uri.html /explorer/items/files/[id].html;
|
|
}
|
|
|
|
# Item detail routes (folders, workspaces, shared items).
|
|
location ~ ^/explorer/items/[^/]+$ {
|
|
try_files $uri $uri.html /explorer/items/[id].html;
|
|
}
|
|
|
|
location / {
|
|
# Try the exact path, then path + .html (Next.js static export generates
|
|
# e.g. explorer/items/my-files.html), then fall back to index.html for
|
|
# client-side routes that have no pre-rendered file.
|
|
try_files $uri $uri.html /index.html;
|
|
}
|
|
|
|
# Protected media: auth via Drive backend, then proxy to S3 with signed headers.
|
|
# media-auth returns SigV4 Authorization/X-Amz-Date/X-Amz-Content-SHA256
|
|
# headers signed for the S3 key (item/UUID/file). nginx captures them and
|
|
# forwards to SeaweedFS. The regex strips /media/ and optional /preview/
|
|
# so the proxy path matches the signed S3 key exactly.
|
|
location ~ ^/media/(preview/)?(.*) {
|
|
set $original_uri $request_uri;
|
|
set $s3_key $2;
|
|
resolver kube-dns.kube-system.svc.cluster.local valid=30s;
|
|
set $s3_backend http://seaweedfs-filer.storage.svc.cluster.local:8333;
|
|
auth_request /internal/media-auth;
|
|
auth_request_set $auth_header $upstream_http_authorization;
|
|
auth_request_set $amz_date $upstream_http_x_amz_date;
|
|
auth_request_set $amz_content $upstream_http_x_amz_content_sha256;
|
|
proxy_set_header Authorization $auth_header;
|
|
proxy_set_header X-Amz-Date $amz_date;
|
|
proxy_set_header X-Amz-Content-Sha256 $amz_content;
|
|
proxy_pass $s3_backend/sunbeam-drive/$s3_key;
|
|
}
|
|
|
|
# Internal subrequest: Django checks session and item access, returns S3 auth headers.
|
|
location = /internal/media-auth {
|
|
internal;
|
|
proxy_pass http://drive-backend.lasuite.svc.cluster.local:80/api/v1.0/items/media-auth/;
|
|
proxy_pass_request_body off;
|
|
proxy_set_header Content-Length "";
|
|
proxy_set_header Cookie $http_cookie;
|
|
proxy_set_header Host drive.DOMAIN_SUFFIX;
|
|
proxy_set_header X-Original-URL https://drive.DOMAIN_SUFFIX$original_uri;
|
|
}
|
|
|
|
error_page 500 502 503 504 @blank_error;
|
|
location @blank_error {
|
|
return 200 '';
|
|
add_header Content-Type text/html;
|
|
}
|
|
}
|