diff --git a/.gitignore b/.gitignore index b83d222..e89d4af 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target/ +.DS_Store diff --git a/AI_AGENT_REPORT.md b/AI_AGENT_REPORT.md deleted file mode 100644 index 0897059..0000000 --- a/AI_AGENT_REPORT.md +++ /dev/null @@ -1,46 +0,0 @@ -# AI Agent Report — uberspace-cli - -## Status - -Phase 1 + 2 of the Rust rewrite are complete. The `uc` binary compiles and all 24 unit tests pass. - -## What was done - -- Created Rust project (`Cargo.toml`, binary name `uc`, CalVer `2026.3.3`) -- Implemented all Phase 1 + 2 modules: - - `registry.rs` — TOML-based asteroid CRUD (`~/.config/uc/registry.toml`) - - `ssh.rs` — passthrough (`ssh -t`) and capture (for status collection) - - `cache.rs` — per-asteroid TOML status cache (`~/.config/uc/cache/*.toml`) - - `translate.rs` — v7/v8 command translation (mail, port, tools, web backend) - - `status.rs` — remote status collection via SSH, colored display, age/staleness - - `cli.rs` — clap-derived CLI with fallback to asteroid passthrough -- `uc import ` migrates legacy `asteroids.list` + cache files - -## CLI command tree - -``` -uc add # register asteroid -uc list # list registered -uc remove # deregister -uc status [--refresh] # aggregate from cache (or refresh all) -uc status # refresh + show one asteroid -uc # passthrough → SSH with v7/v8 translation -uc import # migrate from asteroids.list -``` - -## Architecture notes - -- Clap `try_parse()` + manual fallback handles the `uc ` passthrough pattern -- SSH passthrough preserves the user's SSH config/keys — no Rust SSH library needed -- Remote status script is the same bash heredoc from the original, embedded as a const -- v8 Rich-table box-drawing chrome is stripped by the remote script before parsing - -## What's next (Phase 3) - -- Dashboard HTTP API: `reqwest` + `serde_json` for login, create-asteroid, add-ssh-key, delete -- Session management: cookies + CSRF token in `~/.config/uc/session.toml` - -## Known considerations - -- The `cache::load()` function exists but is currently only used transitively via `load_all()` — produces a dead-code warning -- Edition 2024 requires Rust 1.85+; current toolchain is 1.93 diff --git a/asteroids/asteroids b/asteroids/asteroids deleted file mode 100755 index bfb83fe..0000000 --- a/asteroids/asteroids +++ /dev/null @@ -1,452 +0,0 @@ -#!/usr/bin/env bash -# asteroids — Uberspace account inventory, status, SSH passthrough -# Lives in tools/asteroids/. Symlink to ~/.bin/asteroids via Ansible bin role. -set -euo pipefail - -# --- Resolve repo root (follows symlinks) --- -_src="${BASH_SOURCE[0]}" -while [ -L "$_src" ]; do - _dir="$(cd "$(dirname "$_src")" && pwd -P)" - _src="$(readlink "$_src")" - [[ "$_src" != /* ]] && _src="$_dir/$_src" -done -_TOOL_DIR="$(cd "$(dirname "$_src")" && pwd -P)" -_REPO_DIR="$(cd "$_TOOL_DIR/../.." && pwd -P)" -unset _src _dir - -# --- Config paths --- -UBERSPACES_REGISTRY="$_TOOL_DIR/asteroids.list" -UBERSPACE_CACHE_DIR="$_TOOL_DIR/cache" - -# --- Colors --- -if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then - C_RESET=$'\033[0m' - C_BOLD=$'\033[1m' - C_DIM=$'\033[2m' - C_CYAN=$'\033[36m' - C_BLUE=$'\033[34m' - C_GREEN=$'\033[32m' - C_YELLOW=$'\033[33m' - C_RED=$'\033[31m' -else - C_RESET="" C_BOLD="" C_DIM="" C_CYAN="" C_BLUE="" C_GREEN="" C_YELLOW="" C_RED="" -fi - -# --- Print helpers --- -_info() { printf "%b==>%b %s\n" "$C_CYAN" "$C_RESET" "$*"; } -_ok() { printf "%b[ok]%b %s\n" "$C_GREEN" "$C_RESET" "$*"; } -_warn() { printf "%b[warn]%b %s\n" "$C_YELLOW" "$C_RESET" "$*" >&2; } -_error() { printf "%b[error]%b %s\n" "$C_RED" "$C_RESET" "$*" >&2; } - -# --- Labeled field with tree formatting for multi-value (comma-separated) fields --- -_print_field() { - local label="$1" value="$2" - local -a items=() - - [[ -n "$value" ]] && IFS=',' read -ra items <<< "$value" - - local n="${#items[@]}" - - if [[ "$n" -eq 0 ]]; then - printf " %b%-9s%b (none)\n" "$C_DIM" "$label" "$C_RESET" - elif [[ "$n" -eq 1 ]]; then - printf " %b%-9s%b %s\n" "$C_DIM" "$label" "$C_RESET" "${items[0]}" - else - printf " %b%-9s%b ├── %s\n" "$C_DIM" "$label" "$C_RESET" "${items[0]}" - local i - for (( i=1; i "$tmp_file" - mv "$tmp_file" "$file" -} - -# --- Registry bootstrap --- -_ensure_registry() { - mkdir -p "$(dirname "$UBERSPACES_REGISTRY")" - touch "$UBERSPACES_REGISTRY" - mkdir -p "$UBERSPACE_CACHE_DIR" -} - -# --- Usage --- -usage() { - cat <<-EOF - asteroids — Uberspace account manager - - Usage: asteroids [args] - - Inventory: - add Register an account (version: 7 or 8) - list|ls Show all registered accounts - remove|rm Deregister an account - - Status: - status Aggregate overview from local cache - status --refresh Refresh all accounts via SSH, then show summary - status Refresh + show status for one account (SSH) - - Passthrough: - Run any uberspace subcommand via SSH - - Examples: - asteroids add danger cetus.uberspace.de 7 - asteroids add impstr pandora.uberspace.de 8 - asteroids list - asteroids danger status - asteroids danger mail domain list - asteroids danger web backend list - asteroids danger port add - EOF -} - -# --- Inventory commands --- -cmd_add() { - local name="$1" - local server="$2" - local version="${3:-}" - _ensure_registry - _file_remove_where_first_field_equals "$UBERSPACES_REGISTRY" "$name" - printf "%s %s %s\n" "$name" "$server" "$version" >> "$UBERSPACES_REGISTRY" - local ver_info="" - [[ -n "$version" ]] && ver_info=" (u${version})" - _ok "Registered: $name @ $server${ver_info}" -} - -cmd_list() { - _ensure_registry - if ! awk '!/^[[:space:]]*#/ && NF >= 2 { found=1; exit } END { exit !found }' "$UBERSPACES_REGISTRY"; then - _warn "No accounts registered. Use: asteroids add " - return 0 - fi - printf " %b%-12s %-28s %s%b\n" "$C_BOLD" "NAME" "SERVER" "VER" "$C_RESET" - printf "%b%s%b\n" "$C_DIM" "$(printf '─%.0s' $(seq 1 49))" "$C_RESET" - awk '!/^[[:space:]]*#/ && NF >= 2 { printf " %-12s %-28s %s\n", $1, $2, ($3 ? "u"$3 : "?") }' "$UBERSPACES_REGISTRY" -} - -cmd_remove() { - local name="$1" - _ensure_registry - if ! awk -v n="$name" '$1 == n { found=1; exit } END { exit !found }' "$UBERSPACES_REGISTRY"; then - _error "'$name' not found in registry." - return 1 - fi - _file_remove_where_first_field_equals "$UBERSPACES_REGISTRY" "$name" - rm -f "$UBERSPACE_CACHE_DIR/$name" - _ok "Removed: $name" -} - -# --- Lookup --- -_lookup() { - local name="$1" - local server - server=$(awk -v n="$name" '!/^[[:space:]]*#/ && $1 == n { print $2; exit }' "$UBERSPACES_REGISTRY") - if [[ -z "$server" ]]; then - _error "'$name' not found in registry." - return 1 - fi - printf '%s\n' "$server" -} - -_lookup_version() { - local name="$1" - awk -v n="$name" '!/^[[:space:]]*#/ && $1 == n { print ($3 ? $3 : "?"); exit }' "$UBERSPACES_REGISTRY" -} - -# --- SSH passthrough --- -_ssh_passthrough() { - local name="$1" - shift - local server - server=$(_lookup "$name") || return 1 - ssh -t -o BatchMode=no "$name@$server" "$@" -} - -# --- Per-account status (live SSH refresh) --- -cmd_status_one() { - local name="$1" - local server - server=$(_lookup "$name") || return 1 - _info "Refreshing status for $name @ $server ..." - - local updated version - updated=$(date -u '+%Y-%m-%dT%H:%M:%S') - version=$(_lookup_version "$name") - - local raw="" - if ! raw=$(ssh -o BatchMode=no "$name@$server" bash -s "$version" <<'ENDSSH' -version="$1" -set +e +u -tmpdir=$(mktemp -d) -trap 'rm -rf "$tmpdir"' EXIT - -# bash -s is non-interactive, non-login: .bashrc/.profile are not sourced, -# so PATH may be minimal. Extend it to cover all standard system locations. -export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$HOME/bin:$HOME/.local/bin:$PATH" - -# All data fetched in parallel. Each job gets stdin from /dev/null to prevent -# them from racing on the shared heredoc stdin (which causes silent failures -# when the uberspace CLI reads from stdin for config/token checks). -if [[ "$version" == "8" ]]; then - uberspace web backend list "$tmpdir/ports" 2>"$tmpdir/e.ports" & -else - uberspace port list "$tmpdir/ports" 2>"$tmpdir/e.ports" & -fi -uberspace web domain list "$tmpdir/web" 2>"$tmpdir/e.web" & -uberspace mail domain list "$tmpdir/mdom" 2>"$tmpdir/e.mdom" & -if [[ "$version" == "8" ]]; then - uberspace mail address list "$tmpdir/musr" 2>"$tmpdir/e.musr" & -else - uberspace mail user list "$tmpdir/musr" 2>"$tmpdir/e.musr" & -fi -wait - -# Emit any command errors to stderr — they flow to the user's terminal. -for _ef in "$tmpdir"/e.*; do - [ -s "$_ef" ] && cat "$_ef" >&2 -done - -# parse_list: strips v8 Rich-table chrome (box-drawing separator rows + -# column header) while leaving v7 plain-text output untouched. -# Uses the 2-byte UTF-8 prefix of U+25xx box-drawing chars (\xe2\x94) -# instead of a literal char to avoid locale issues on the remote host. -parse_list() { - local f="$1" - [ -s "$f" ] || return 0 - if grep -q $'\xe2\x94' "$f" 2>/dev/null; then - grep -v $'\xe2\x94' "$f" \ - | awk 'NR==1{next} /^[[:space:]]*$/{next} {gsub(/^[[:space:]]+|[[:space:]]+$/,""); print}' - else - grep -v '^[[:space:]]*$' "$f" - fi -} - -ports=$(parse_list "$tmpdir/ports" | tr '\n' ',' | sed 's/,$//') -web=$(parse_list "$tmpdir/web" | tr '\n' ',' | sed 's/,$//') -mdom=$(parse_list "$tmpdir/mdom" | tr '\n' ',' | sed 's/,$//') -musr=$(parse_list "$tmpdir/musr" | tr '\n' ',' | sed 's/,$//') - -printf 'VERSION=%s\n' "${version:-?}" -printf 'PORTS=%s\n' "$ports" -printf 'WEB=%s\n' "$web" -printf 'MDOM=%s\n' "$mdom" -printf 'MUSR=%s\n' "$musr" -ENDSSH -); then - _error "SSH connection to $name @ $server failed." - return 1 - fi - - local ports web mdom musr - ports=$(printf '%s\n' "$raw" | awk '/^PORTS=/{sub(/^PORTS=/,""); print; exit}' | tr -d '\r') - web=$(printf '%s\n' "$raw" | awk '/^WEB=/{sub(/^WEB=/,""); print; exit}' | tr -d '\r') - mdom=$(printf '%s\n' "$raw" | awk '/^MDOM=/{sub(/^MDOM=/,""); print; exit}' | tr -d '\r') - musr=$(printf '%s\n' "$raw" | awk '/^MUSR=/{sub(/^MUSR=/,""); print; exit}' | tr -d '\r') - - # If nothing came back at all, the remote commands likely couldn't run. - if [[ -z "$ports" && -z "$web" && -z "$mdom" && -z "$musr" ]]; then - _warn "No data from $name — check stderr above, or run manually:" - printf " ssh %s@%s 'which uberspace && uberspace --version'\n" "$name" "$server" >&2 - fi - - mkdir -p "$UBERSPACE_CACHE_DIR" - { - printf 'UPDATED=%s\n' "$updated" - printf 'NAME=%s\n' "$name" - printf 'SERVER=%s\n' "$server" - printf 'VERSION=%s\n' "$version" - printf 'PORTS=%s\n' "$ports" - printf 'WEB_DOMAINS=%s\n' "$web" - printf 'MAIL_DOMAINS=%s\n' "$mdom" - printf 'MAIL_USERS=%s\n' "$musr" - } > "$UBERSPACE_CACHE_DIR/$name" - - printf '\n' - _print_account_block "$name" "$server" "$version" \ - "$ports" "$web" "$mdom" "$musr" \ - "$updated" "${C_DIM}${updated}${C_RESET}" -} - -# --- Aggregate status (from cache, or --refresh to repopulate) --- -cmd_status_all() { - local refresh=false - while [[ $# -gt 0 ]]; do - case "$1" in - --refresh) refresh=true ;; - *) _error "Unknown option: $1"; return 1 ;; - esac - shift - done - - _ensure_registry - - if $refresh; then - local names=() - while IFS= read -r line; do - [[ "$line" =~ ^[[:space:]]*# || -z "${line// }" ]] && continue - names+=("${line%% *}") - done < "$UBERSPACES_REGISTRY" - if [[ "${#names[@]}" -eq 0 ]]; then - _warn "No accounts registered. Use: asteroids add " - return 0 - fi - for n in "${names[@]}"; do - cmd_status_one "$n" || true - done - return 0 - fi - - local found=0 - for f in "$UBERSPACE_CACHE_DIR"/*; do [[ -f "$f" ]] && found=1 && break; done - if [[ "$found" -eq 0 ]]; then - _warn "No cached status — last refresh: never" - printf " Run: %basteroids status --refresh%b\n" "$C_BLUE" "$C_RESET" >&2 - return 0 - fi - - local now stale_count=0 first=1 - now=$(date -u '+%s') - - for cache in "$UBERSPACE_CACHE_DIR"/*; do - [[ -f "$cache" ]] || continue - local name="" server="" version="" ports="" web="" mdom="" musr="" updated="" - while IFS= read -r line; do - case "$line" in - NAME=*) name="${line#NAME=}" ;; - SERVER=*) server="${line#SERVER=}" ;; - VERSION=*) version="${line#VERSION=}" ;; - PORTS=*) ports="${line#PORTS=}" ;; - WEB_DOMAINS=*) web="${line#WEB_DOMAINS=}" ;; - MAIL_DOMAINS=*) mdom="${line#MAIL_DOMAINS=}" ;; - MAIL_USERS=*) musr="${line#MAIL_USERS=}" ;; - UPDATED=*) updated="${line#UPDATED=}" ;; - esac - done < "$cache" - - local age_str="unknown" age_secs=0 - if [[ -n "$updated" ]]; then - local epoch="" - epoch=$(date -u -d "$updated" '+%s' 2>/dev/null \ - || date -u -j -f '%Y-%m-%dT%H:%M:%S' "$updated" '+%s' 2>/dev/null \ - || true) - if [[ -n "$epoch" ]]; then - age_secs=$(( now - epoch )) - if (( age_secs < 60 )); then age_str="${age_secs}s ago" - elif (( age_secs < 3600 )); then age_str="$(( age_secs / 60 ))m ago" - elif (( age_secs < 86400 )); then age_str="$(( age_secs / 3600 ))h ago" - else age_str="$(( age_secs / 86400 ))d ago" - fi - (( age_secs >= 86400 )) && (( stale_count++ )) || true - else - age_str="$updated" - fi - fi - - local time_plain="$age_str" time_display="${C_DIM}${age_str}${C_RESET}" - if (( age_secs >= 86400 )); then - time_plain="${age_str} !" - time_display="${C_DIM}${age_str} ${C_RESET}${C_YELLOW}!${C_RESET}" - fi - - [[ "$first" -eq 0 ]] && printf '\n' - first=0 - _print_account_block "$name" "$server" "$version" \ - "$ports" "$web" "$mdom" "$musr" \ - "$time_plain" "$time_display" - done - - if (( stale_count > 0 )); then - printf '\n' - _warn "${stale_count} account(s) have stale cache (>24h) — run: asteroids status --refresh" - fi -} - -# --- Dispatch --- -if [[ $# -eq 0 ]]; then - usage; exit 0 -fi - -case "$1" in - add) - shift - if [[ $# -lt 3 ]]; then - printf "%bUsage:%b asteroids add \n" "$C_BLUE" "$C_RESET" >&2 - printf " Example: asteroids add danger cetus.uberspace.de 7\n" >&2 - exit 1 - fi - cmd_add "$1" "$2" "$3" - ;; - list|ls) - cmd_list - ;; - remove|rm) - shift - if [[ $# -lt 1 ]]; then - printf "%bUsage:%b asteroids remove \n" "$C_BLUE" "$C_RESET" >&2 - exit 1 - fi - cmd_remove "$1" - ;; - status) - shift - cmd_status_all "$@" - ;; - help|-h|--help) - usage - ;; - *) - # Named account: asteroids [status | ] - _name="$1"; shift - _ensure_registry - _lookup "$_name" > /dev/null || exit 1 - if [[ "${1:-}" == "status" ]]; then - cmd_status_one "$_name" - else - _ssh_passthrough "$_name" uberspace "$@" - fi - ;; -esac diff --git a/asteroids/asteroids.list b/asteroids/asteroids.list deleted file mode 100644 index 04b007c..0000000 --- a/asteroids/asteroids.list +++ /dev/null @@ -1,9 +0,0 @@ -# name server -danger cetus.uberspace.de 7 -serve prospero.uberspace.de 8 -impstr pandora.uberspace.de 8 -foertsch cressida.uberspace.de 7 -jef caliban.uberspace.de 7 -kristina tucana.uberspace.de 7 -suprblox vega.uberspace.de 7 -wtp larissa.uberspace.de 8 diff --git a/asteroids/cache/.gitkeep b/asteroids/cache/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/asteroids/cache/danger b/asteroids/cache/danger deleted file mode 100644 index 8d17a9d..0000000 --- a/asteroids/cache/danger +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:31:06 -NAME=danger -SERVER=cetus.uberspace.de -VERSION=7 -QUOTA= -PORTS= -WEB_DOMAINS=danger.uber.space,rhqq2.de,ws.rhqq2.de -MAIL_DOMAINS=danger.uber.space,rhqq2.de -MAIL_USERS=No mailboxes found. diff --git a/asteroids/cache/foertsch b/asteroids/cache/foertsch deleted file mode 100644 index ec8a01e..0000000 --- a/asteroids/cache/foertsch +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:31:26 -NAME=foertsch -SERVER=cressida.uberspace.de -VERSION=7 -QUOTA= -PORTS= -WEB_DOMAINS=ampelkarten.de,arctic-law.com,doedde.de,foertsch.uber.space,juicyshop.de,newvendo.de,shop.juicyshop.de,themenundtexte.de,tomis-motorradshop.de,undrowear.de,www.juicyshop.de,www.undrowear.de,xn--ddde-5qa.de,xn--frtsch-wxa.de -MAIL_DOMAINS=ampelkarten.de,arctic-law.com,foertsch.uber.space,netfelix.jetzt,themenundtexte.de,xn--frtsch-wxa.de -MAIL_USERS=conrad,felix,hermes,hermine,juicy,paul,support,vmunde diff --git a/asteroids/cache/impstr b/asteroids/cache/impstr deleted file mode 100644 index bf87132..0000000 --- a/asteroids/cache/impstr +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:31:24 -NAME=impstr -SERVER=pandora.uberspace.de -VERSION=8 -QUOTA= -PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /StiggerDLBot PORT 8001 remove,* /movie APACHE None keep -WEB_DOMAINS=Domain,impstr.uber.space -MAIL_DOMAINS=Domain Alias of DNS state,impstr.uber.space VALID -MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse impstr.u… no no yes sysmail@i…,hostmaster impstr.u… no no yes sysmail@i…,postmaster impstr.u… no no yes sysmail@i…,sysmail impstr.u… yes no no uberspac… diff --git a/asteroids/cache/jef b/asteroids/cache/jef deleted file mode 100644 index 6854707..0000000 --- a/asteroids/cache/jef +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:31:42 -NAME=jef -SERVER=caliban.uberspace.de -VERSION=7 -QUOTA= -PORTS= -WEB_DOMAINS=bitwarden.jef-sachsen.de,email.jef-sachsen.de,eud-sachsen.de,eurom.at,jef-leipzig.de,jef-sachsen.de,jef.uber.space,mail.jef-sachsen.de,newsletter.jef-sachsen.de -MAIL_DOMAINS=eud-sachsen.de,eurom.at,jef-leipzig.de,jef-sachsen.de,jef.uber.space,mail.jef-sachsen.de -MAIL_USERS=+,abuse,admin,annika.fleischer,anton.hussing,bitwarden,bjoern.donath,catchall,emely.schaefer,fabian.brueder,felix.foertsch,finnja.klinger,hannes.lauter,hostmaster,info,johannes.kropp,klaas.wibker,kontakt,kristina.oertel,laura.greiff,laurenz.frenzel,maria-teresa.roelke,natalie.semin,no-reply,nora.sandner,paula.kirchner,postmaster,susan.wolf,tanja.schmidt,tim.meglitsch,vincent.kaienburg,vorstand diff --git a/asteroids/cache/kristina b/asteroids/cache/kristina deleted file mode 100644 index abe2c42..0000000 --- a/asteroids/cache/kristina +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:32:10 -NAME=kristina -SERVER=tucana.uberspace.de -VERSION=7 -QUOTA= -PORTS= -WEB_DOMAINS=kristina.uber.space,kristinaschoenfeldt.de -MAIL_DOMAINS=kristina.uber.space,kristinaschoenfeldt.de -MAIL_USERS=mail,noreply diff --git a/asteroids/cache/serve b/asteroids/cache/serve deleted file mode 100644 index f858a03..0000000 --- a/asteroids/cache/serve +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:31:22 -NAME=serve -SERVER=prospero.uberspace.de -VERSION=8 -QUOTA= -PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /sticker-cloner PORT 8080 remove -WEB_DOMAINS=Domain,serve.uber.space -MAIL_DOMAINS=Domain Alias of DNS state,serve.uber.space VALID -MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse serve.ub… no no yes sysmail@s…,hostmaster serve.ub… no no yes sysmail@s…,postmaster serve.ub… no no yes sysmail@s…,sysmail serve.ub… yes no no uberspac… diff --git a/asteroids/cache/suprblox b/asteroids/cache/suprblox deleted file mode 100644 index af5ddc2..0000000 --- a/asteroids/cache/suprblox +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:32:28 -NAME=suprblox -SERVER=vega.uberspace.de -VERSION=7 -QUOTA= -PORTS= -WEB_DOMAINS=superblocks-leipzig.de,suprblox.de,suprblox.uber.space,www.superblocks-leipzig.de -MAIL_DOMAINS=suprblox.de,suprblox.uber.space -MAIL_USERS=No mailboxes found. diff --git a/asteroids/cache/wtp b/asteroids/cache/wtp deleted file mode 100644 index e456198..0000000 --- a/asteroids/cache/wtp +++ /dev/null @@ -1,9 +0,0 @@ -UPDATED=2026-02-25T17:32:45 -NAME=wtp -SERVER=larissa.uberspace.de -VERSION=8 -QUOTA= -PORTS=Domain Path Destination Port Prefix,* / APACHE None keep,* /api PORT 3000 remove -WEB_DOMAINS=Domain,wtp.uber.space -MAIL_DOMAINS=Domain Alias of DNS state,wtp.uber.space VALID -MAIL_USERS=Name Domain sysmail catchall alias Alias of Forwards,abuse wtp.uber… no no yes sysmail@w…,hostmaster wtp.uber… no no yes sysmail@w…,postmaster wtp.uber… no no yes sysmail@w…,sysmail wtp.uber… yes no no uberspac…