Skip to content

Commit 78e13fa

Browse files
authored
feat(hosted): wire the shell export button to the node export endpoint (#4562)
1 parent 44c0b5b commit 78e13fa

2 files changed

Lines changed: 37 additions & 3 deletions

File tree

crates/core/src/server/path_handlers.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2503,6 +2503,12 @@ mod tests {
25032503
"access-key backup/restore controls missing"
25042504
);
25052505
assert!(hosted.contains("Export data"), "export control missing");
2506+
// The export button must be wired to the node export endpoint, not a
2507+
// placeholder. Pin the route so a refactor cannot silently revert it.
2508+
assert!(
2509+
hosted.contains("/v1/hosted/export"),
2510+
"export button is not wired to the export endpoint"
2511+
);
25062512
// The access key is read from the shell-only token global; it is never
25072513
// injected into the sandboxed iframe.
25082514
assert!(

crates/core/src/server/path_handlers/assets/hosted_bar.js

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,36 @@
5454
}
5555
});
5656
document.getElementById('fnexport').addEventListener('click', function () {
57-
alert(
58-
'Export your delegate data to your own Freenet peer.\n\nThis downloads an encrypted bundle you can import on your own node with: freenet secrets import\n\n(Coming soon.)',
59-
);
57+
var t =
58+
typeof __freenet_user_token !== 'undefined' ? __freenet_user_token : null;
59+
if (!t) {
60+
setOk('No key on this connection');
61+
return;
62+
}
63+
setOk('Preparing download...');
64+
// Read the token from the shell-only global and send it in the header the
65+
// export endpoint requires (never a query param, so it stays out of logs).
66+
// fetch->blob->download because a plain navigation cannot set the header.
67+
fetch('/v1/hosted/export', { headers: { 'X-Freenet-User-Token': t } })
68+
.then(function (r) {
69+
if (!r.ok) {
70+
throw new Error('HTTP ' + r.status);
71+
}
72+
return r.blob();
73+
})
74+
.then(function (blob) {
75+
var url = URL.createObjectURL(blob);
76+
var a = document.createElement('a');
77+
a.href = url;
78+
a.download = 'freenet-data.fnsx';
79+
document.body.appendChild(a);
80+
a.click();
81+
a.remove();
82+
URL.revokeObjectURL(url);
83+
setOk('Downloaded freenet-data.fnsx');
84+
})
85+
.catch(function (e) {
86+
setOk('Export failed (' + e.message + ')');
87+
});
6088
});
6189
})();

0 commit comments

Comments
 (0)