map $uri $toolbox_cache_control { default "no-cache"; "~^/(?:.*/)?assets/.*-[A-Za-z0-9_-]{8,}\.[^/]+$" "public, max-age=31536000, immutable"; "~^/apps/[a-z0-9][a-z0-9-]*/vendor/ffmpeg/(?:(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)\.(?:0|[1-9][0-9]*)|0\.12\.10-reviewed-stack5m\.1)/(?:version\.json|(?:st|mt)/ffmpeg-core\.(?:js|wasm)|mt/ffmpeg-core\.worker\.js)$" "public, max-age=31536000, immutable"; } map $uri $toolbox_resource_policy { default "same-origin"; "/apps/svg/canvas-frame-controller.js" "cross-origin"; } map $uri $toolbox_access_control_allow_origin { default ""; "/apps/svg/canvas-frame-controller.js" "*"; } map "$host:$uri" $toolbox_permissions_policy { default "camera=(), microphone=(), display-capture=(), geolocation=(), payment=(), usb=()"; "~^auth\.toolbox\.add-ideas\.de:" "camera=(self), microphone=(), display-capture=(), geolocation=(), payment=(), usb=()"; "~^[^:]+:/apps/barcode(?:/|$)" "camera=(self), microphone=(), display-capture=(), geolocation=(), payment=(), usb=()"; "~^[^:]+:/apps/scan(?:/|$)" "camera=(self), microphone=(), display-capture=(), geolocation=(), payment=(), usb=()"; "~^[^:]+:/apps/device(?:/|$)" "camera=(self), microphone=(self), display-capture=(self), geolocation=(), payment=(), usb=()"; } server { listen 8080; listen [::]:8080; server_name _; root /usr/share/nginx/html; server_tokens off; charset utf-8; etag on; add_header X-Content-Type-Options "nosniff" always; add_header Referrer-Policy "no-referrer" always; add_header X-Frame-Options "DENY" always; add_header Cross-Origin-Opener-Policy "same-origin" always; add_header Cross-Origin-Embedder-Policy "require-corp" always; add_header Cross-Origin-Resource-Policy $toolbox_resource_policy always; add_header Access-Control-Allow-Origin $toolbox_access_control_allow_origin always; add_header Permissions-Policy $toolbox_permissions_policy always; add_header Content-Security-Policy "default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; form-action 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' blob:; font-src 'self' data: blob:; connect-src 'self'; worker-src 'self' blob:; manifest-src 'self'" always; add_header Cache-Control $toolbox_cache_control always; gzip on; gzip_vary on; gzip_min_length 1024; gzip_types application/json application/javascript application/wasm image/svg+xml text/css text/plain text/xml; location ~* /(?:toolbox\.catalog|toolbox\.release|toolbox-app)\.json$ { try_files $uri =404; } location ~* \.wasm$ { types { application/wasm wasm; } try_files $uri =404; } location ~* \.mjs$ { types { application/javascript mjs; } try_files $uri =404; } location ~* ^/apps/scan/ocr/lang/[a-z0-9_-]+\.traineddata\.gz$ { types { application/gzip gz; } try_files $uri =404; } location ~* \.(?:css|js|mjs|woff2?|png|jpe?g|gif|webp|svg|ico|webmanifest)$ { try_files $uri =404; } location / { try_files $uri $uri/ =404; } }