Files
cinny/contrib/nginx/cinny.domain.tld.conf
T
jaredandClaude Opus 5 96a97a2f86 feat(pwa): register as an Android share target (#155)
public/manifest.json declares share_target (POST multipart to
/share-target: title/text/url + image/video/audio/pdf/text files). The
service worker answers that POST itself: it stashes the form in a Cache
API bucket and 303s to the in-app /share page, which lists what arrived,
offers a room search, and on pick writes the files into that room's
upload-board atom (encrypting first for E2EE rooms via the composer's
shared filesToUploadItems) and the title/text/url into its draft, then
opens the room — the user still presses Send. The stash is cleared once
placed; reopening /share afterwards says so.

nginx/caddy examples and the prod image config gain a 303 for
/share-target so a POST that reaches the origin before the worker
controls the page lands on /share instead of a 405. iOS has no share
target support and ignores the manifest entry.

Verified headless against the built preview: SW-controlled page → POST
/share-target (two PNGs + title + text) → /share lists both files and the
text → pick the DM → composer shows both files on the upload board and
the text in the draft → /share reports nothing pending.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA
2026-09-20 13:36:05 -04:00

51 lines
1.7 KiB
Plaintext

server {
listen 80;
listen [::]:80;
server_name cinny.domain.tld;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
alias /var/lib/letsencrypt/.well-known/acme-challenge/;
}
}
server {
listen 443 ssl http2;
listen [::]:443 ssl;
server_name cinny.domain.tld;
# Security headers (generic; add a Content-Security-Policy suited to your
# homeserver + any embedded services). NOTE: nginx does not inherit
# server-level add_header into a location that sets its own add_header.
add_header X-Frame-Options SAMEORIGIN always;
add_header X-Content-Type-Options nosniff always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header Permissions-Policy "accelerometer=(), autoplay=(self), camera=(self), display-capture=(self), encrypted-media=(self), fullscreen=(self), geolocation=(self), gyroscope=(), magnetometer=(), microphone=(self), midi=(), payment=(), usb=()" always;
# [Gitea #155] PWA share target. The service worker normally answers this
# POST itself; if it isn't controlling the page yet, land on /share
# (the shared files are lost, but nothing 405s).
location = /share-target {
return 303 /share;
}
location / {
root /opt/cinny/dist/;
rewrite ^/config.json$ /config.json break;
rewrite ^/manifest.json$ /manifest.json break;
rewrite ^/sw.js$ /sw.js break;
rewrite ^/pdf.worker.min.js$ /pdf.worker.min.js break;
rewrite ^/public/(.*)$ /public/$1 break;
rewrite ^/assets/(.*)$ /assets/$1 break;
rewrite ^(.+)$ /index.html break;
}
}