harmonize with coredesktop

This commit is contained in:
David Young
2026-10-28 14:35:07 -06:00
parent 866720c3c1
commit 9b9f1d5fdd
35 changed files with 1445 additions and 8 deletions
+109
View File
@@ -0,0 +1,109 @@
#!/bin/bash
TITLE="Nextcloud files"
DESCRIPTION="Mount your Core's Nextcloud files"
# What you entered last time, so running this again starts from it
FILES_CONF="$HOME/.config/miniserver/files.conf"
DAVFS_SECRETS="/etc/davfs2/secrets"
source "$MINISERVER/configure.d/lib/nextcloud.sh"
[ -f "$FILES_CONF" ] && source "$FILES_CONF"
is_installed() {
command -v mount.davfs
}
# CORE_DOMAIN and CORE_EMAIL come from files.conf; the rest follow
core_names() {
CORE_USER="${CORE_EMAIL%@*}"
NEXTCLOUD="https://nextcloud.$CORE_DOMAIN"
WEBDAV="$NEXTCLOUD/remote.php/dav/files/$CORE_USER"
MOUNT="/mnt/$CORE_DOMAIN"
}
# The fstab line is added last, after the password is saved
is_configured() {
[ -n "$CORE_DOMAIN" ] || return 1
core_names
grep -qs " $MOUNT davfs " /etc/fstab
}
save_conf() {
mkdir -p "$(dirname "$FILES_CONF")"
{
printf 'CORE_DOMAIN=%q\n' "$CORE_DOMAIN"
printf 'CORE_EMAIL=%q\n' "$CORE_EMAIL"
} > "$FILES_CONF"
}
# Mount your Nextcloud files at /mnt/<domain> with davfs2. On a server nobody
# may be logged in, so root mounts it, owned by you, the first time something
# uses it after boot (x-systemd.automount); nofail keeps boot going if
# Nextcloud can't be reached. The password is in davfs2's own secrets file,
# which only root can read, so sandboxed agents can't either.
setup_files() {
local secret unit
secret="${APP_PASSWORD//\\/\\\\}"
secret="${secret//\"/\\\"}"
sudo sed -i "\\#^$MOUNT #d" "$DAVFS_SECRETS" || return 1
printf '%s %s "%s"\n' "$MOUNT" "$CORE_USER" "$secret" | sudo tee -a "$DAVFS_SECRETS" > /dev/null || return 1
sudo chmod 600 "$DAVFS_SECRETS" || return 1
sudo install -d "$MOUNT" || return 1
if ! grep -qs " $MOUNT davfs " /etc/fstab; then
echo "$WEBDAV $MOUNT davfs rw,uid=$(id -u),gid=$(id -g),_netdev,nofail,x-systemd.automount 0 0" \
| sudo tee -a /etc/fstab > /dev/null || return 1
fi
sudo systemctl daemon-reload || return 1
# Start the automount now rather than at the next boot, then use it once so
# a wrong address or password shows up here. Unmount first when running
# again, so a new password is used.
unit="$(systemd-escape --path "$MOUNT")"
if ! sudo systemctl stop "$unit.mount"; then
echo "$MOUNT is in use; close what's using it and run: configure files"
return 1
fi
sudo systemctl restart "$unit.automount" || return 1
if ! ls "$MOUNT" > /dev/null; then
echo "Couldn't mount $WEBDAV; see: journalctl -u $unit.mount"
return 1
fi
echo "Your Nextcloud files are at $MOUNT."
}
run_configure() {
local url tries
read -erp "Your Superpanel's address (e.g. https://superpanel.example.com): " \
-i "${CORE_DOMAIN:+https://superpanel.$CORE_DOMAIN}" url
url="${url#*://}"
url="${url%%/*}"
CORE_DOMAIN="${url#superpanel.}"
[ -n "$CORE_DOMAIN" ] || { echo "That isn't an address."; return 1; }
read -erp "Your Core email: " -i "${CORE_EMAIL:-$USER@$CORE_DOMAIN}" CORE_EMAIL
[[ "$CORE_EMAIL" == *@* ]] || { echo "That isn't an email address."; return 1; }
core_names
save_conf
# The mount gets an app password, not your Core password
for tries in 1 2 3; do
read -rsp "Your Core password: " PASSWORD
echo
nextcloud_app_password "MiniServer on $HOSTNAME"
case $? in
0) break ;;
2) echo "Nextcloud says that password is wrong." ;;
*) echo "Couldn't reach Nextcloud at $NEXTCLOUD."; unset PASSWORD; return 1 ;;
esac
done
unset PASSWORD
[ -n "$APP_PASSWORD" ] || return 1
setup_files
local status=$?
unset APP_PASSWORD
return $status
}
+24
View File
@@ -0,0 +1,24 @@
#!/bin/bash
TITLE="Claude Code"
DESCRIPTION="Sign in to Anthropic"
is_installed() {
command -v claude
}
is_configured() {
claude auth status
}
run_configure() {
echo " 1) Claude subscription (Pro, Max, Team or Enterprise)"
echo " 2) Anthropic Console (pay for API usage)"
local choice
read -rp "How do you pay for Claude? [1] " choice
case "$choice" in
""|1) claude auth login ;;
2) claude auth login --console ;;
*) echo "Choose 1 or 2."; return 1 ;;
esac
}
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
TITLE="opencode"
DESCRIPTION="Sign in to AI providers"
is_installed() {
[ -x /usr/bin/opencode ]
}
# Signed in to at least one provider
is_configured() {
jq -e 'length > 0' "$HOME/.local/share/opencode/auth.json"
}
run_configure() {
echo "Choose a provider and sign in or paste its API key. You can pick the model inside opencode with /models."
unsandboxed opencode auth login || return 1
while confirm "Sign in to another provider?"; do
unsandboxed opencode auth login || return 1
done
}
+25
View File
@@ -0,0 +1,25 @@
#!/bin/bash
TITLE="Hermes Agent"
DESCRIPTION="Choose a model provider and tools"
is_installed() {
[ -x "$HOME/.local/bin/hermes" ]
}
# Signed in with OAuth (e.g. Nous Portal), or an API key is set
is_configured() {
[ -s "$HOME/.hermes/auth.json" ] || grep -qE '^[A-Z_]*API_KEY=.+' "$HOME/.hermes/.env"
}
run_configure() {
echo " 1) Nous Portal (one sign-in covers the model, web search, images and more)"
echo " 2) Another provider (OpenRouter, OpenAI, Anthropic or your own endpoint)"
local choice
read -rp "Which provider? [1] " choice
case "$choice" in
""|1) unsandboxed hermes setup --portal ;;
2) unsandboxed hermes setup ;;
*) echo "Choose 1 or 2."; return 1 ;;
esac
}
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
#
# Purpose : Nextcloud app passwords for configure.d items. Source this file.
# Basic auth header for curl, read from stdin (-H @-) so the password isn't
# in the process list
auth_header() {
printf 'Authorization: Basic %s\n' "$(printf '%s:%s' "$1" "$2" | base64 -w0)"
}
# Create a Nextcloud app password, so what MiniServer sets up doesn't keep
# your Core password. It shows in Nextcloud under Settings > Security with the
# name given, where it can be revoked. Uses CORE_USER, PASSWORD and NEXTCLOUD;
# sets APP_PASSWORD. Returns 2 if Nextcloud says the password is wrong.
nextcloud_app_password() {
local name="$1" response code
response="$(auth_header "$CORE_USER" "$PASSWORD" | curl -s -w '\n%{http_code}' -H @- \
-H 'OCS-APIRequest: true' -A "$name" \
"$NEXTCLOUD/ocs/v2.php/core/getapppassword?format=json")"
code="${response##*$'\n'}"
case "$code" in
200) APP_PASSWORD="$(jq -r '.ocs.data.apppassword // empty' <<< "${response%$'\n'*}")"
[ -n "$APP_PASSWORD" ] ;;
401) return 2 ;;
*) return 1 ;;
esac
}