diff --git a/examples/external-demo/index.html b/examples/external-demo/index.html
index d3e7910..6d88b58 100644
--- a/examples/external-demo/index.html
+++ b/examples/external-demo/index.html
@@ -113,7 +113,7 @@ const W = {
list: (map, label, pattern, opts = {}) => {
const rows = Object.values(map || {}).filter((s) => !opts.filter || opts.filter(s)).sort((a, b) => a.id.localeCompare(b.id))
return h('div', { class: 'tile wide' }, h('div', { class: 'label' }, `${label} ยท ${rows.length}`),
- rows.length ? h('div', { class: 'rows' }, rows.map((s) => { const f = frac(s); return h('div', { class: 'row' }, h('span', { class: 'k', title: s.id }, opts.name ? opts.name(s) : s.name), typeof s.value === 'boolean' ? h('span', { class: 'pill ' + (s.value ? 'ok' : 'bad') }, s.value ? 'up' : 'down') : h('span', { class: 'n' }, fmt(s)), f === null ? null : h('div', { class: 'meter' }, h('i', { class: sev(s), style: `width:${f * 100}%` }))) })) : h('div', { class: 'mut' }, 'nothing matches on this machine'),
+ rows.length ? h('div', { class: 'rows' }, rows.map((s) => { const f = frac(s); return h('div', { class: 'row' }, h('span', { class: 'k', title: s.id }, opts.name ? opts.name(s) : s.name), typeof s.value === 'boolean' ? h('span', { class: 'pill ' + (s.value ? 'ok' : 'bad') }, s.value ? 'up' : 'down') : h('span', { class: 'n' }, fmt(s)), f === null ? null : h('div', { class: 'meter' }, h('i', { class: sev(s), style: `width:${f * 100}%` }))) })) : h('div', { class: 'mut' }, 'nothing here that this token may see'),
h('div', { class: 'id mono' }, pattern))
},
}
diff --git a/internal/nodes/nodes.go b/internal/nodes/nodes.go
index bb5056b..2d2c4cd 100644
--- a/internal/nodes/nodes.go
+++ b/internal/nodes/nodes.go
@@ -442,6 +442,15 @@ func (m *Manager) Proxy(name string) (http.Handler, bool) {
},
Transport: transportFor(n),
FlushInterval: -1, // stream task output / log tails immediately
+ // The node answers with its own policy headers and this hub adds the same ones to
+ // everything it serves; relayed twice, Access-Control-Allow-Origin is invalid and a
+ // browser on another origin refuses the response. The hub's copy is the one that counts.
+ ModifyResponse: func(resp *http.Response) error {
+ for _, h := range []string{"Access-Control-Allow-Origin", "X-Frame-Options", "Content-Security-Policy", "X-Content-Type-Options", "Referrer-Policy"} {
+ resp.Header.Del(h)
+ }
+ return nil
+ },
ErrorHandler: func(w http.ResponseWriter, r *http.Request, err error) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusBadGateway)