Files

214 lines
6.8 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
if [[ "${EUID:-$(id -u)}" -ne 0 ]]; then
echo "Run this installer as root (sudo)."
exit 1
fi
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/.." && pwd)"
default_nc_path="/var/www/nextcloud"
read -r -p "Nextcloud path [${default_nc_path}]: " nc_path
nc_path="${nc_path:-$default_nc_path}"
if [[ ! -f "${nc_path}/occ" ]]; then
echo "Could not find occ at ${nc_path}/occ. Please check the Nextcloud path."
exit 1
fi
occ() {
if command -v sudo >/dev/null 2>&1; then
sudo -u www-data php "${nc_path}/occ" "$@"
else
runuser -u www-data -- php "${nc_path}/occ" "$@"
fi
}
detect_nc_url() {
local url
set +e
url="$(occ config:system:get overwrite.cli.url 2>/dev/null)"
if [[ -z "$url" ]]; then
url="$(occ config:system:get trusted_domains 0 2>/dev/null)"
if [[ -n "$url" && "$url" != http* ]]; then
url="https://${url}"
fi
fi
set -e
echo "$url"
}
nc_url="$(detect_nc_url)"
read -r -p "Nextcloud URL [${nc_url:-https://cloud.example.com}]: " nc_url_input
nc_url="${nc_url_input:-$nc_url}"
if [[ -z "$nc_url" ]]; then
echo "Nextcloud URL is required."
exit 1
fi
nc_host="${nc_url#*://}"
nc_host="${nc_host%%/*}"
base_domain="$nc_host"
if [[ "$nc_host" == *.* ]]; then
base_domain="${nc_host#*.}"
fi
default_broker_host="qortalbroker.${base_domain}"
read -r -p "Broker hostname [${default_broker_host}]: " broker_host
broker_host="${broker_host:-$default_broker_host}"
read -r -p "Broker external URL [https://${broker_host}]: " broker_url
broker_url="${broker_url:-https://${broker_host}}"
read -r -p "Nextcloud service user [admin]: " nc_service_user
nc_service_user="${nc_service_user:-admin}"
read -r -p "Nextcloud service password [admin123]: " nc_service_password
nc_service_password="${nc_service_password:-admin123}"
read -r -p "External Auth base URL [http://127.0.0.1:3191]: " ext_auth_url
ext_auth_url="${ext_auth_url:-http://127.0.0.1:3191}"
read -r -p "External Auth app ID: " ext_auth_app_id
read -r -p "External Auth app secret: " ext_auth_app_secret
if [[ ! "${ext_auth_url}" =~ ^https?://(127\.0\.0\.1|localhost) ]]; then
echo "Warning: External Auth is not local. Ensure secondary wallet encryption is enabled."
fi
gen_secret() {
tr -dc 'a-zA-Z0-9' </dev/urandom | head -c 32
}
default_db_pass="$(gen_secret)"
read -r -p "Broker DB password [${default_db_pass}]: " broker_db_password
broker_db_password="${broker_db_password:-$default_db_pass}"
default_oidc_secret="$(gen_secret)"
read -r -p "OIDC client secret [${default_oidc_secret}]: " oidc_secret
oidc_secret="${oidc_secret:-$default_oidc_secret}"
default_broker_internal_token="$(gen_secret)"
read -r -p "Broker internal API token [${default_broker_internal_token}]: " broker_internal_token
broker_internal_token="${broker_internal_token:-$default_broker_internal_token}"
broker_dir="/opt/qortal-broker"
mkdir -p "${broker_dir}"
compose_src="${repo_root}/deploy/docker-compose.broker.yml"
compose_dst="${broker_dir}/docker-compose.yml"
cp "${compose_src}" "${compose_dst}"
cat > "${broker_dir}/.env" <<EOF
BROKER_BUILD_CONTEXT=${repo_root}/services/qortal-oidc-broker
BROKER_PORT=3000
BROKER_DB_NAME=qortal_broker
BROKER_DB_USER=qortal_broker
BROKER_DB_PASSWORD=${broker_db_password}
BROKER_DATABASE_URL=postgresql://qortal_broker:${broker_db_password}@broker_db:5432/qortal_broker
NEXTCLOUD_BASE_URL=${nc_url}
NEXTCLOUD_PUBLIC_URL=${nc_url}
NEXTCLOUD_SERVICE_USER=${nc_service_user}
NEXTCLOUD_SERVICE_PASSWORD=${nc_service_password}
QORTAL_EXTERNAL_AUTH_BASE_URL=${ext_auth_url}
QORTAL_EXTERNAL_AUTH_APP_ID=${ext_auth_app_id}
QORTAL_EXTERNAL_AUTH_APP_SECRET=${ext_auth_app_secret}
BROKER_INTERNAL_API_TOKEN=${broker_internal_token}
# Optional comma-separated browser origins for CORS.
BROKER_CORS_ALLOWED_ORIGINS=${nc_url}
OIDC_ISSUER=${broker_url}
OIDC_CLIENT_ID=nextcloud-local
OIDC_CLIENT_SECRET=${oidc_secret}
OIDC_REDIRECT_URI_ALLOWLIST=${nc_url}/apps/user_oidc/code
OIDC_POLICY_MODE=link_only
OIDC_AUTO_PROVISION_GUARD=invite_or_allowlist
OIDC_INVITE_TTL_SECONDS=604800
OIDC_AUTH_REQUEST_TTL_SECONDS=600
OIDC_AUTH_CODE_TTL_SECONDS=120
OIDC_ACCESS_TOKEN_TTL_SECONDS=600
OIDC_ID_TOKEN_TTL_SECONDS=600
EOF
echo "Copying Nextcloud app..."
mkdir -p "${nc_path}/custom_apps"
if command -v rsync >/dev/null 2>&1; then
rsync -a "${repo_root}/nextcloud/custom_apps/qortal_integration/" "${nc_path}/custom_apps/qortal_integration/"
else
rm -rf "${nc_path}/custom_apps/qortal_integration"
cp -R "${repo_root}/nextcloud/custom_apps/qortal_integration" "${nc_path}/custom_apps/qortal_integration"
fi
echo "Enabling Nextcloud apps..."
occ app:enable qortal_integration || true
occ app:enable user_oidc || true
occ config:app:set qortal_integration broker_internal_api_token --value="${broker_internal_token}" || true
echo "Configuring user_oidc provider..."
set +e
occ user_oidc:provider qortal \
-c nextcloud-local \
-s "${oidc_secret}" \
-d "${broker_url}/.well-known/openid-configuration" \
--scope="openid profile email" \
--mapping-uid=sub \
--mapping-display-name=name \
--mapping-email=email
set -e
if ! command -v docker >/dev/null 2>&1; then
echo "Docker is required but not installed. Install Docker and re-run docker compose manually."
exit 1
fi
if docker compose version >/dev/null 2>&1; then
docker_compose="docker compose"
elif command -v docker-compose >/dev/null 2>&1; then
docker_compose="docker-compose"
else
echo "Docker Compose not found."
exit 1
fi
echo "Starting broker containers..."
${docker_compose} -f "${compose_dst}" --env-file "${broker_dir}/.env" up -d
echo "Configuring Apache reverse proxy..."
if ! a2enmod proxy proxy_http headers ssl >/dev/null 2>&1; then
echo "Warning: failed to enable Apache modules (proxy/proxy_http/headers/ssl)."
fi
apache_site="/etc/apache2/sites-available/qortalbroker.conf"
cat > "${apache_site}" <<EOF
<VirtualHost *:80>
ServerName ${broker_host}
ProxyPreserveHost On
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
RequestHeader set X-Forwarded-Proto "https"
ErrorLog \${APACHE_LOG_DIR}/qortalbroker_error.log
CustomLog \${APACHE_LOG_DIR}/qortalbroker_access.log combined
</VirtualHost>
EOF
a2ensite qortalbroker.conf >/dev/null 2>&1 || true
systemctl reload apache2 || true
read -r -p "Run certbot for ${broker_host}? (y/N): " run_certbot
if [[ "${run_certbot}" == "y" || "${run_certbot}" == "Y" ]]; then
read -r -p "Let's Encrypt email: " le_email
if command -v certbot >/dev/null 2>&1; then
certbot --apache -d "${broker_host}" -m "${le_email}" --agree-tos --redirect --non-interactive
else
echo "certbot is not installed. Install it and rerun manually."
fi
fi
echo "Install complete."
echo "Broker URL: ${broker_url}"
echo "Nextcloud URL: ${nc_url}"
echo "OIDC provider configured with client_id=nextcloud-local"
echo "If login fails, verify DNS for ${broker_host} and Apache proxy."