Initial commit: Nosterm client (terminal-style Nostr chat SPA)
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# Caddy config for serving the standalone Nosterm client SPA.
|
||||
#
|
||||
# In production, replace `:80` with your domain to get automatic HTTPS, e.g.:
|
||||
# nosterm.example.com { ... }
|
||||
#
|
||||
# The `/relay*` proxy is OPTIONAL. It lets the client reach a relay on the same
|
||||
# origin (ws://<host>/relay), which sidesteps mixed-content and CORS concerns.
|
||||
# The upstream is configurable via the RELAY_UPSTREAM env var (default
|
||||
# `relay:3334`, the service name in this dir's docker-compose.yml). If you point
|
||||
# the client directly at an external relay via PUBLIC_DEFAULT_RELAYS, you can
|
||||
# delete the `handle /relay*` block.
|
||||
|
||||
:80 {
|
||||
encode gzip zstd
|
||||
|
||||
# Tor-overlay relay bridge: proxy to a clearnet→onion bridge sidecar that
|
||||
# forwards through Tor to an onion-only relay. Exposing it at a same-origin
|
||||
# wss:// path lets a plain browser reach the onion relay without Tor Browser
|
||||
# and without an HTTPS-page/insecure-ws mixed-content block. Only wired when
|
||||
# RELAY_TOR_UPSTREAM is set (the demo deploy sets it); otherwise it points at
|
||||
# a dead default and simply 502s, which is harmless if unused. MUST precede
|
||||
# the /relay* block below, which would otherwise swallow this prefix.
|
||||
handle /relay-tor* {
|
||||
reverse_proxy {$RELAY_TOR_UPSTREAM:tor-bridge:3335}
|
||||
}
|
||||
|
||||
# Home relay: proxy WebSocket + NIP-11 requests to the configured relay.
|
||||
handle /relay* {
|
||||
reverse_proxy {$RELAY_UPSTREAM:relay:3334}
|
||||
}
|
||||
|
||||
# Runtime client config: regenerated by the entrypoint from env on startup.
|
||||
# Never cache it so per-deployment relay changes take effect immediately.
|
||||
handle /config.json {
|
||||
root * /srv
|
||||
header Cache-Control "no-store"
|
||||
file_server
|
||||
}
|
||||
|
||||
# Everything else: serve the static SPA with client-side-routing fallback.
|
||||
handle {
|
||||
root * /srv
|
||||
try_files {path} /index.html
|
||||
file_server
|
||||
}
|
||||
|
||||
# Baseline security headers. No third-party analytics are ever included.
|
||||
header {
|
||||
X-Content-Type-Options nosniff
|
||||
X-Frame-Options DENY
|
||||
Referrer-Policy no-referrer
|
||||
|
||||
# Content-Security-Policy for a client-only SPA:
|
||||
# - default-src 'self' only same-origin by default
|
||||
# - connect-src wss:/ws: reach ANY relay the user configures (core)
|
||||
# - connect-src https: NIP-05 verification fetches a domain's
|
||||
# /.well-known/nostr.json over HTTPS. Read-only
|
||||
# JSON GETs; no credentials are ever sent.
|
||||
# - script-src 'unsafe-inline' required for SvelteKit's hydration
|
||||
# bootstrap + the anti-FOUC theme script,
|
||||
# which are inlined into the static fallback
|
||||
# page (not prerendered, so hashes cannot be
|
||||
# pinned at build time).
|
||||
# - script-src 'unsafe-eval' required by NDK's event-emitter dependency
|
||||
# (tseep), which JIT-compiles listener
|
||||
# dispatch via `new Function`. Only triggers
|
||||
# once a relay subscription opens. No REMOTE
|
||||
# scripts are ever allowed, and remote Nostr
|
||||
# content is never rendered as HTML, so it
|
||||
# cannot inject code.
|
||||
# - object-src 'none' no plugins
|
||||
Content-Security-Policy "default-src 'self'; connect-src 'self' wss: ws: https:; img-src 'self' data: https:; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; object-src 'none'; base-uri 'self'; frame-ancestors 'none'"
|
||||
-Server
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user