Require Gitea login to write GPX data; IPv6-capable bind
Upload/delete/move/create-folder now require logging in via Gitea OAuth2 (only MAPTOOL_ALLOWED_GITEA_USER is granted write access); reading stays public. Deploy secrets (session secret, OAuth2 client credentials, allowed user) are written to .env from Gitea Actions repo secrets on every deploy instead of living on the server by hand. Also switch the container's bind address to "[::]" (dual-stack) so the app is reachable over IPv6, not just IPv4.
This commit is contained in:
1 parent
ae67cc72c7
commit
e13d1a1e97
13 files changed
+261
-11
No files matched your search
@@ -84,6 +84,7 @@ export class GpxPanelControl {
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: `path=${encodeURIComponent(path.trim())}`,
|
||||
});
|
||||
if (redirectIfUnauthorized(response)) return;
|
||||
if (response.ok) {
|
||||
const { tree } = await response.json();
|
||||
this._renderTree(tree);
|
||||
@@ -351,6 +352,7 @@ export class GpxPanelControl {
|
||||
formData.append("folder", folder);
|
||||
try {
|
||||
const response = await fetch(UPLOAD_URL, { method: "POST", body: formData });
|
||||
if (redirectIfUnauthorized(response)) return;
|
||||
if (!response.ok) throw new Error("upload failed");
|
||||
({ tree } = await response.json());
|
||||
} catch (err) {
|
||||
@@ -366,6 +368,7 @@ export class GpxPanelControl {
|
||||
if (!window.confirm(`Delete "${path}"?`)) return;
|
||||
|
||||
const response = await fetch(gpxFileUrl(path), { method: "DELETE" });
|
||||
if (redirectIfUnauthorized(response)) return;
|
||||
if (!response.ok) return;
|
||||
|
||||
if (this._visible.has(path)) {
|
||||
@@ -382,6 +385,7 @@ export class GpxPanelControl {
|
||||
const response = await fetch(`/api/gpx/folder/${path.split("/").map(encodeURIComponent).join("/")}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
if (redirectIfUnauthorized(response)) return;
|
||||
if (!response.ok) return;
|
||||
|
||||
const prefix = `${path}/`;
|
||||
@@ -404,6 +408,7 @@ export class GpxPanelControl {
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: `from=${encodeURIComponent(from)}&to_folder=${encodeURIComponent(toFolder)}`,
|
||||
});
|
||||
if (redirectIfUnauthorized(response)) return;
|
||||
if (!response.ok) return;
|
||||
|
||||
const { path: newPath, tree } = await response.json();
|
||||
@@ -422,6 +427,15 @@ export class GpxPanelControl {
|
||||
}
|
||||
}
|
||||
|
||||
// Write endpoints require login (see app.rb); a 401 means the session
|
||||
// expired or was never established — send the user to log in rather than
|
||||
// silently failing.
|
||||
function redirectIfUnauthorized(response) {
|
||||
if (response.status !== 401) return false;
|
||||
window.location.href = "/login";
|
||||
return true;
|
||||
}
|
||||
|
||||
function sourceId(path) {
|
||||
return `gpx-${path}`;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user