openvibers/openvibe.studio Commits
Add .env.example; CSP allows Cloudflare's beacon; home spacing (#2)
Changes
nnew file mode 100644@@@ -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@@@ -1,6 +1,7 @@node_modules/.env.env.*++!.env.examplepublic/apps/artifacts/dist/@@@ -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; } }@@@ -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'"],@@@ -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">' +
new file mode 100644
new file mode 100644
@@ -0,0 +1,15 @@
@@ -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
@@ -1,6 +1,7 @@
@@ -1,6 +1,7 @@
node_modules/
node_modules/
.env
.env
.env.*
.env.*
+!.env.example
public/apps/
public/apps/
artifacts/
artifacts/
dist/
dist/
@@ -65,6 +65,7 @@ html { background: var(--paper); color: var(--ink); }
@@ -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 { 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-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; }
.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; }
#limits h2 { font-size: 1.25rem; margin: 0 0 10px; }
#licences .fine-print a { color: inherit; }
#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; } }
@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; } }
@@ -23,11 +23,11 @@ function createApp(opts = {}) {
@@ -23,11 +23,11 @@ function createApp(opts = {}) {
app.set('trust proxy', config.trustProxy);
app.set('trust proxy', config.trustProxy);
app.use(helmet({ contentSecurityPolicy: { directives: {
app.use(helmet({ contentSecurityPolicy: { directives: {
defaultSrc: ["'self'"],
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'],
styleSrc: ["'self'", "'unsafe-inline'", 'https://openvibe.network', 'https://fonts.googleapis.com'],
fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
fontSrc: ["'self'", 'data:', 'https://fonts.gstatic.com'],
imgSrc: ["'self'", 'data:', 'https://openvibe.network'],
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'"],
frameSrc: ["'self'"],
frameAncestors: ["'none'"],
frameAncestors: ["'none'"],
objectSrc: ["'none'"],
objectSrc: ["'none'"],
@@ -27,7 +27,6 @@ function createPages({ config, sso }) {
@@ -27,7 +27,6 @@ function createPages({ config, sso }) {
'<span class="eyebrow">OPENVIBE STUDIO</span>' +
'<span class="eyebrow">OPENVIBE STUDIO</span>' +
'<h1>Edit photos right in your browser.</h1>' +
'<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>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>' +
'</div></section>' +
'<section id="apps"><div class="app-grid">' + HOME_APPS.map(appCard).join('') + '</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">' +
'<section id="limits"><h2>Good to know</h2><ul class="limit-list">' +