openvibers/openvibe.studio Commits

Add .env.example; CSP allows Cloudflare's beacon; home spacing (#2)

OP OpenVibers committed 5 days ago · 17ccc9965e · 5 files, +19 −3

* Add .env.example (the host's env helper builds studio.env from it)

* .gitignore: keep .env.example

* CSP: allow Cloudflare's analytics beacon (it was refused on every page)

* Home: the two app cards are the choice (no repeated buttons in the hero); space before Good to know

Changes

ddiff --git a/.env.example b/.env.example
nnew file mode 100644
iindex 0000000..db021fe
---- /dev/null
++++ b/.env.example
@@@ -0,0 +1,15 @@
++# OpenVibe.Studio environment (production: /etc/openvibe/studio.env; the unit sets NODE_ENV, PORT and HOST).
++# The host helper `ov-svc-env studio KEY=VALUE…` creates the env file from this one.
++BASE_URL=https://openvibe.studio
++TRUST_PROXY=2
++OV_NETWORK_URL=https://openvibe.network
++OV_NETWORK_INTERNAL_URL=http://127.0.0.1:4000
++OV_OAUTH_CLIENT_ID=studio
++# Written by Network's service-principal setup (never in a repo).
++OV_OAUTH_CLIENT_SECRET=
++# Where scripts/fetch-bundles.sh puts the checksummed Photo and Light bundles.
++STUDIO_BUNDLE_ROOT=/var/lib/openvibe-studio/apps
++# Optional: links to the network's sister sites, and the cookie rule outside production.
++# OV_DOWNLOAD_URL=https://openvibe.download
++# OV_PICS_URL=https://openvibe.pics
++# COOKIE_SECURE=true
ddiff --git a/.gitignore b/.gitignore
iindex 1e32494..fd66b27 100644
---- a/.gitignore
++++ b/.gitignore
@@@ -1,6 +1,7 @@
node_modules/
.env
.env.*
++!.env.example
public/apps/
artifacts/
dist/
ddiff --git a/public/css/studio.css b/public/css/studio.css
iindex 7f8d0c0..f242213 100644
---- a/public/css/studio.css
++++ b/public/css/studio.css
@@@ -65,6 +65,7 @@ html { background: var(--paper); color: var(--ink); }
.app-features { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; margin: 4px 0 16px; padding: 0; }
.app-features li { padding: 4px 10px; border: 1px solid var(--line); border-radius: 999px; font-size: .85rem; color: var(--muted); }
.app-card h3 { font-size: 1.5rem; margin: 0 0 6px; }
++#limits { margin-top: 44px; }
#limits h2 { font-size: 1.25rem; margin: 0 0 10px; }
#licences .fine-print a { color: inherit; }
@media (max-width: 600px) { .hero .button-primary, .hero .button-secondary { display: flex; align-items: center; justify-content: center; min-height: 48px; padding-top: 0; padding-bottom: 0; margin: 0 0 10px; } }
ddiff --git a/server/app.js b/server/app.js
iindex 42465eb..6f2f9cf 100644
---- a/server/app.js
++++ b/server/app.js
@@@ -23,11 +23,11 @@ function createApp(opts = {}) {
app.set('trust proxy', config.trustProxy);
app.use(helmet({ contentSecurityPolicy: { directives: {
defaultSrc: ["'self'"],
-- scriptSrc: ["'self'", "'unsafe-inline'", "'wasm-unsafe-eval'", 'https://openvibe.network'],
++ scriptSrc: ["'self'", "'unsafe-inline'", "'wasm-unsafe-eval'", 'https://openvibe.network', 'https://static.cloudflareinsights.com'],
styleSrc: ["'self'", "'unsafe-inline'", 'https://openvibe.network', 'https://fonts.googleapis.com'],
fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
imgSrc: ["'self'", 'data:', 'https://openvibe.network'],
-- connectSrc: ["'self'", 'https://openvibe.network', 'https://openvibe.download', 'https://openvibe.pics'],
++ connectSrc: ["'self'", 'https://openvibe.network', 'https://openvibe.download', 'https://openvibe.pics', 'https://cloudflareinsights.com'],
frameSrc: ["'self'"],
frameAncestors: ["'none'"],
objectSrc: ["'none'"],
ddiff --git a/server/pages.js b/server/pages.js
iindex dfb7a12..95190fd 100644
---- a/server/pages.js
++++ b/server/pages.js
@@@ -27,7 +27,6 @@ function createPages({ config, sso }) {
'<span class="eyebrow">OPENVIBE STUDIO</span>' +
'<h1>Edit photos right in your browser.</h1>' +
'<p>Photo for layers and retouching. Light for your library and RAW files. Free and open source, with your files on OpenVibe.</p>' +
-- '<p><a class="button-primary" href="/photo">Open Photo</a> <a class="button-secondary" href="/light">Open Light</a></p>' +
'</div></section>' +
'<section id="apps"><div class="app-grid">' + HOME_APPS.map(appCard).join('') + '</div></section>' +
'<section id="limits"><h2>Good to know</h2><ul class="limit-list">' +