fix: version display, FileBrowser auto-login, nostr relay, UID mappings
Version per build:
- Health endpoint returns "1.2.0-alpha-{git_hash}" using GIT_HASH env
- CI passes git hash to cargo build
FileBrowser auto-login:
- filebrowser-client.ts: include CSRF token + credentials:include
- First-boot: generate random password, store at secrets/filebrowser/
- Set FileBrowser admin password to match after container creation
Nostr relay:
- Use docker.io/scsibug/nostr-rs-relay:0.9.0 (not in our registry)
UID mappings:
- Added electrumx (UID 1000), mysql-mempool, archy-btcpay-db, nextcloud-db
522 tests pass, Rust compiles clean.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
b7da501182
commit
ca646afd37
@ -26,6 +26,7 @@ jobs:
|
|||||||
- name: Build backend
|
- name: Build backend
|
||||||
run: |
|
run: |
|
||||||
source $HOME/.cargo/env 2>/dev/null || true
|
source $HOME/.cargo/env 2>/dev/null || true
|
||||||
|
export GIT_HASH=$(git rev-parse --short HEAD)
|
||||||
cargo build --release --manifest-path core/Cargo.toml
|
cargo build --release --manifest-path core/Cargo.toml
|
||||||
|
|
||||||
- name: Build frontend
|
- name: Build frontend
|
||||||
|
|||||||
@ -393,7 +393,7 @@ impl RpcHandler {
|
|||||||
"status": status,
|
"status": status,
|
||||||
"crash_recovery_complete": recovery_complete,
|
"crash_recovery_complete": recovery_complete,
|
||||||
"uptime_seconds": uptime,
|
"uptime_seconds": uptime,
|
||||||
"version": env!("CARGO_PKG_VERSION"),
|
"version": format!("{}-{}", env!("CARGO_PKG_VERSION"), option_env!("GIT_HASH").unwrap_or("dev")),
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -452,11 +452,13 @@ impl RpcHandler {
|
|||||||
/// Default subuid start for archipelago user is 100000.
|
/// Default subuid start for archipelago user is 100000.
|
||||||
fn mapped_uid(package_id: &str) -> u32 {
|
fn mapped_uid(package_id: &str) -> u32 {
|
||||||
let container_uid = match package_id {
|
let container_uid = match package_id {
|
||||||
"bitcoin-knots" | "bitcoin" => 101,
|
"bitcoin-knots" | "bitcoin" | "bitcoin-core" => 101,
|
||||||
"grafana" => 472,
|
"grafana" => 472,
|
||||||
"lnd" => 1000,
|
"lnd" => 1000,
|
||||||
"mariadb" | "mysql" => 999,
|
"mariadb" | "mysql" | "mysql-mempool" | "archy-mempool-db" => 999,
|
||||||
"postgres" | "btcpay-postgres" | "immich-postgres" | "penpot-postgres" => 70,
|
"postgres" | "btcpay-postgres" | "immich-postgres" | "penpot-postgres"
|
||||||
|
| "archy-btcpay-db" | "nextcloud-db" => 70,
|
||||||
|
"electrumx" | "electrs" => 1000,
|
||||||
_ => 0, // Most containers run as root (UID 0)
|
_ => 0, // Most containers run as root (UID 0)
|
||||||
};
|
};
|
||||||
100000 + container_uid
|
100000 + container_uid
|
||||||
|
|||||||
@ -1285,6 +1285,15 @@ loginctl enable-linger archipelago 2>/dev/null || true
|
|||||||
runuser -u archipelago -- bash -c 'export XDG_RUNTIME_DIR=/run/user/1000 && systemctl --user enable --now podman.socket' 2>>"$LOG" || true
|
runuser -u archipelago -- bash -c 'export XDG_RUNTIME_DIR=/run/user/1000 && systemctl --user enable --now podman.socket' 2>>"$LOG" || true
|
||||||
|
|
||||||
# Create FileBrowser container as archipelago user (rootless podman)
|
# Create FileBrowser container as archipelago user (rootless podman)
|
||||||
|
# Generate random FileBrowser password and store for auto-login
|
||||||
|
FB_PASS_DIR="/var/lib/archipelago/secrets/filebrowser"
|
||||||
|
mkdir -p "$FB_PASS_DIR"
|
||||||
|
if [ ! -f "$FB_PASS_DIR/password" ]; then
|
||||||
|
head -c 24 /dev/urandom | base64 | tr -d '/+=' | head -c 24 > "$FB_PASS_DIR/password"
|
||||||
|
chmod 600 "$FB_PASS_DIR/password"
|
||||||
|
chown 1000:1000 "$FB_PASS_DIR/password"
|
||||||
|
fi
|
||||||
|
|
||||||
if ! runuser -u archipelago -- bash -c 'export XDG_RUNTIME_DIR=/run/user/1000 && podman ps -a --format "{{.Names}}"' 2>/dev/null | grep -q filebrowser; then
|
if ! runuser -u archipelago -- bash -c 'export XDG_RUNTIME_DIR=/run/user/1000 && podman ps -a --format "{{.Names}}"' 2>/dev/null | grep -q filebrowser; then
|
||||||
echo "[$(date)] Creating FileBrowser container ($FILEBROWSER_IMAGE)..." >> "$LOG"
|
echo "[$(date)] Creating FileBrowser container ($FILEBROWSER_IMAGE)..." >> "$LOG"
|
||||||
runuser -u archipelago -- bash -c "export XDG_RUNTIME_DIR=/run/user/1000 && podman run -d --name filebrowser --restart unless-stopped \
|
runuser -u archipelago -- bash -c "export XDG_RUNTIME_DIR=/run/user/1000 && podman run -d --name filebrowser --restart unless-stopped \
|
||||||
@ -1305,6 +1314,12 @@ if ! runuser -u archipelago -- bash -c 'export XDG_RUNTIME_DIR=/run/user/1000 &&
|
|||||||
--database=/data/database.db --root=/srv --address=0.0.0.0 --port=80" 2>>"$LOG" && \
|
--database=/data/database.db --root=/srv --address=0.0.0.0 --port=80" 2>>"$LOG" && \
|
||||||
echo "[$(date)] FileBrowser created successfully" >> "$LOG" || \
|
echo "[$(date)] FileBrowser created successfully" >> "$LOG" || \
|
||||||
echo "[$(date)] WARNING: FileBrowser creation failed" >> "$LOG"
|
echo "[$(date)] WARNING: FileBrowser creation failed" >> "$LOG"
|
||||||
|
# Set FileBrowser password to match the stored random password
|
||||||
|
sleep 5
|
||||||
|
FB_PASS=$(cat "$FB_PASS_DIR/password" 2>/dev/null || echo "admin")
|
||||||
|
runuser -u archipelago -- bash -c "export XDG_RUNTIME_DIR=/run/user/1000 && podman exec filebrowser filebrowser users update admin --password '$FB_PASS' --database /data/database.db" 2>>"$LOG" && \
|
||||||
|
echo "[$(date)] FileBrowser admin password set" >> "$LOG" || \
|
||||||
|
echo "[$(date)] WARNING: Could not set FileBrowser password" >> "$LOG"
|
||||||
fi
|
fi
|
||||||
echo "[$(date)] Minimal first-boot complete" >> "$LOG"
|
echo "[$(date)] Minimal first-boot complete" >> "$LOG"
|
||||||
FBUNBUNDLED
|
FBUNBUNDLED
|
||||||
|
|||||||
@ -55,11 +55,17 @@ class FileBrowserClient {
|
|||||||
async login(): Promise<boolean> {
|
async login(): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
// Get a filebrowser JWT via the authenticated backend (no credentials exposed to browser)
|
// Get a filebrowser JWT via the authenticated backend (no credentials exposed to browser)
|
||||||
|
// Use credentials: 'include' and CSRF token for proper auth
|
||||||
|
const csrfMatch = document.cookie.match(/(?:^|;\s*)csrf_token=([^;]+)/)
|
||||||
|
const csrfToken = csrfMatch ? csrfMatch[1]! : ''
|
||||||
|
const headers: Record<string, string> = { 'Content-Type': 'application/json' }
|
||||||
|
if (csrfToken) headers['X-CSRF-Token'] = csrfToken
|
||||||
|
|
||||||
const rpcRes = await fetch('/rpc/v1', {
|
const rpcRes = await fetch('/rpc/v1', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers,
|
||||||
body: JSON.stringify({ method: 'app.filebrowser-token' }),
|
body: JSON.stringify({ method: 'app.filebrowser-token' }),
|
||||||
credentials: 'same-origin',
|
credentials: 'include',
|
||||||
})
|
})
|
||||||
if (!rpcRes.ok) return false
|
if (!rpcRes.ok) return false
|
||||||
const rpcData = await rpcRes.json()
|
const rpcData = await rpcRes.json()
|
||||||
|
|||||||
@ -412,7 +412,7 @@ export function getCuratedAppList(): MarketplaceApp[] {
|
|||||||
description: 'Run your own Nostr relay. Store your events locally, relay for friends, and publish over Tor. A sovereign relay for your sovereign node.',
|
description: 'Run your own Nostr relay. Store your events locally, relay for friends, and publish over Tor. A sovereign relay for your sovereign node.',
|
||||||
icon: '/assets/img/app-icons/nostr-rs-relay.svg',
|
icon: '/assets/img/app-icons/nostr-rs-relay.svg',
|
||||||
author: 'scsiblade',
|
author: 'scsiblade',
|
||||||
dockerImage: `${REGISTRY}/nostr-rs-relay:0.9.0`,
|
dockerImage: 'docker.io/scsibug/nostr-rs-relay:0.9.0',
|
||||||
manifestUrl: undefined,
|
manifestUrl: undefined,
|
||||||
repoUrl: 'https://sr.ht/~gheartsfield/nostr-rs-relay/'
|
repoUrl: 'https://sr.ht/~gheartsfield/nostr-rs-relay/'
|
||||||
},
|
},
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user