forked from Fluxora-Org/Fluxora-Frontend
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
161 lines (149 loc) · 7.86 KB
/
Copy pathindex.html
File metadata and controls
161 lines (149 loc) · 7.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Fluxora — Continuous Capital</title>
<meta
name="description"
content="Fluxora helps teams stream treasury capital continuously on Stellar with dashboard, recipient, and wallet workflows."
/>
<meta name="theme-color" content="#06B6D4" />
<link rel="canonical" href="https://fluxora.app/" />
<link rel="icon" type="image/svg+xml" href="/src/public/Icon.svg" id="favicon" />
<link rel="alternate icon" type="image/png" href="/src/public/Icon.png" />
<!--
Content Security Policy
Allowed sources:
default-src 'self' — only same-origin resources by default
script-src 'self' — scripts from same origin only (no inline scripts)
style-src 'self' 'unsafe-inline' — same-origin styles + inline styles (React/Tailwind)
img-src 'self' data: https: — same-origin, data URIs, and HTTPS images
connect-src 'self' https: — XHR/fetch to same-origin and HTTPS APIs (Horizon, Soroban RPC)
font-src 'self' — fonts from same origin only
object-src 'none' — block plugins (Flash, etc.)
frame-ancestors 'none' — prevent clickjacking (equivalent to X-Frame-Options: DENY)
base-uri 'self' — prevent base-tag hijacking
EMBED ROUTE EXCEPTION (/embed/streams/:streamId):
The /embed/streams/* route is designed to be loaded inside a host-site
iframe. This meta tag's frame-ancestors 'none' applies to ALL routes
served by this HTML shell and cannot be scoped per-route via a <meta>
tag — browsers only honour frame-ancestors from HTTP response headers.
For production deployment, the reverse-proxy / CDN must emit a
SEPARATE, ROUTE-SCOPED Content-Security-Policy response header that
overrides this value only for /embed/streams/* requests, e.g.:
# Nginx example
location /embed/streams/ {
add_header Content-Security-Policy
"frame-ancestors https://trusted-host.example https://another.example";
}
location / {
add_header Content-Security-Policy "frame-ancestors 'none'";
}
The allow-list MUST:
• Name specific HTTPS origins — never use frame-ancestors *
• Cover only /embed/* paths, leaving all other routes at 'none'
• Be updated in the server config whenever a new embedding host is approved
See docs/EMBEDDABLE_STREAM_WIDGET_SPEC.md §Content Security Policy for
full rationale, Nginx/Caddy/Vercel config snippets, and the audit log
requirements for adding new trusted origins.
Note: Server-side CSP overrides are mandatory because client-side meta tags
do not support frame-ancestors restrictions.
-->
<!--
The 'sha256-...' hash in script-src covers only the inline theme-bootstrap
script immediately below. Recompute the hash whenever the script body
changes:
node -e "const c=require('crypto'),s=require('fs').readFileSync('index.html','utf8').match(/<script id=\"theme-bootstrap\">([\s\S]*?)<\/script>/)[1];console.log('sha256-'+c.createHash('sha256').update(s).digest('base64'))"
-->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' 'sha256-rYHtv2kv2J9mGq+H5er2MOudnal5QmHotnNLc03Df6s='; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; connect-src 'self' https:; font-src 'self' https://fonts.gstatic.com; object-src 'none'; frame-ancestors 'none'; base-uri 'self';"
/>
<!--
Site-Wide Default Open Graph & Twitter link previews
PER-ROUTE OVERRIDE PATTERN:
For single stream detail routes (/app/streams/:streamId), src/components/MetaTags.tsx
dynamically overrides og:title, og:description, og:url, og:image, and og:image:alt via
react-helmet-async to reference per-stream auto-generated 1200x630 cards
(e.g., https://fluxora.app/og-image/:streamId.png?v=:updatedAtTimestamp).
See docs/STREAM_OG_IMAGE_TEMPLATE_SPEC.md for full specifications.
-->
<meta property="og:type" content="website" />
<meta property="og:site_name" content="Fluxora" />
<meta property="og:title" content="Fluxora - Continuous Capital" />
<meta
property="og:description"
content="Stream treasury capital continuously on Stellar with clear dashboards, recipient flows, and wallet-ready controls."
/>
<meta property="og:url" content="https://fluxora.app/" />
<meta
property="og:image"
content="https://fluxora.app/freighter-wallet.jpeg"
/>
<meta property="og:image:alt" content="Fluxora Stellar wallet preview" />
<!-- Twitter Card link previews -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="Fluxora - Continuous Capital" />
<meta
name="twitter:description"
content="Stream treasury capital continuously on Stellar with clear dashboards, recipient flows, and wallet-ready controls."
/>
<meta
name="twitter:image"
content="https://fluxora.app/freighter-wallet.jpeg"
/>
<meta name="twitter:image:alt" content="Fluxora Stellar wallet preview" />
</head>
<body>
<div id="root"></div>
<!--
Theme Bootstrap Script
──────────────────────
Runs synchronously before any ES module is parsed so the correct
data-theme / data-font attributes land on <html> on the very first paint,
preventing a flash of the wrong theme (FOUC).
Resolution order:
1. Persisted custom theme → data-theme="custom" + --custom-* tokens
2. Persisted built-in pref → data-theme="light|dark|cyberpunk"
3. OS prefers-color-scheme → data-theme="light|dark"
CSS injection prevention:
• Only 3-/6-digit lowercase hex colours (#rgb / #rrggbb) are accepted
for custom token values. Any other value is silently dropped before
it can reach the DOM.
• The built-in theme is validated against a strict allowlist
(light, dark, cyberpunk). Any other localStorage value is ignored.
CSP compliance:
The script hash in script-src covers this exact script body.
Recompute when the script changes (see comment above the CSP meta tag).
-->
<script id="theme-bootstrap">(function(){
var VALID=['light','dark','cyberpunk'];
var THEME_KEY='theme';
var CUSTOM_KEY='theme:custom';
var FONT_KEY='easy-read-font';
function safeHex(v){return typeof v==='string'&&/^#[0-9a-f]{3}([0-9a-f]{3})?$/.test(v);}
var root=document.documentElement;
try{
var raw=localStorage.getItem(CUSTOM_KEY);
if(raw){
var p=JSON.parse(raw);
if(p&&typeof p==='object'&&p.validatedTokens&&typeof p.validatedTokens==='object'){
var tokens=p.validatedTokens;
for(var k in tokens){if(Object.prototype.hasOwnProperty.call(tokens,k)&&safeHex(tokens[k])){root.style.setProperty(k.replace(/^--/,'--custom-'),tokens[k]);}}
root.setAttribute('data-theme','custom');
root.setAttribute('data-font',localStorage.getItem(FONT_KEY)==='true'?'easy-read':'default');
return;
}
}
}catch(e){}
try{
var stored=localStorage.getItem(THEME_KEY);
var theme=(stored&&VALID.indexOf(stored)!==-1)?stored:(window.matchMedia&&window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'light');
root.setAttribute('data-theme',theme);
root.setAttribute('data-font',localStorage.getItem(FONT_KEY)==='true'?'easy-read':'default');
}catch(e){root.setAttribute('data-theme','light');root.setAttribute('data-font','default');}
})();</script>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>