#!/usr/bin/env bash set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" env_file="${repo_root}/.env" template_file="${repo_root}/.env.example" if [[ ! -f "${template_file}" ]]; then echo "Missing ${template_file}. Run from the repo root." exit 1 fi if [[ -f "${env_file}" ]]; then read -r -p ".env already exists. Overwrite? (y/N): " overwrite if [[ "${overwrite}" =~ ^[Yy]$ ]]; then cp "${template_file}" "${env_file}" fi else cp "${template_file}" "${env_file}" fi set_kv() { local key="$1" local value="$2" local esc esc="${value//\\/\\\\}" esc="${esc//&/\\&}" esc="${esc//|/\\|}" if grep -q "^${key}=" "${env_file}"; then sed -i -E "s|^${key}=.*|${key}=${esc}|" "${env_file}" else echo "${key}=${value}" >> "${env_file}" fi } read_kv() { local key="$1" local line line="$(grep -m1 -E "^${key}=" "${env_file}" || true)" if [[ -z "${line}" ]]; then return 1 fi echo "${line#*=}" } resolve_path_from_env() { local key="$1" local default_path="$2" local value value="$(read_kv "${key}" || true)" value="${value:-${default_path}}" if [[ "${value}" == /* ]]; then echo "${value}" else echo "${repo_root}/${value}" fi } default_nextcloud_image="nextcloud:34-apache" is_tested_nextcloud_image() { local image="$1" [[ "${image}" =~ (^|[^0-9])(33|34)([^0-9]|$) ]] } prompt_nextcloud_image_selection() { local current_value choice custom_value selected_image current_value="$(read_kv "NEXTCLOUD_IMAGE" || true)" current_value="${current_value:-${default_nextcloud_image}}" while true; do echo "Select Nextcloud Docker image:" echo " 1) nextcloud:34-apache (recommended default)" echo " 2) nextcloud:33-apache (tested fallback)" echo " 3) Keep current (${current_value})" echo " 4) Enter a custom image tag" read -r -p "Choice [1/2/3/4] (default: 1): " choice choice="${choice:-1}" case "${choice}" in 1) selected_image="nextcloud:34-apache" ;; 2) selected_image="nextcloud:33-apache" ;; 3) selected_image="${current_value}" ;; 4) read -r -p "Custom Nextcloud image (for example nextcloud:34.0.1-apache): " custom_value custom_value="${custom_value//[[:space:]]/}" if [[ -z "${custom_value}" ]]; then echo "Custom image cannot be empty." continue fi selected_image="${custom_value}" ;; *) echo "Invalid choice: ${choice}" continue ;; esac if ! is_tested_nextcloud_image "${selected_image}"; then echo "Warning: ${selected_image} has not been tested extensively in this repo." echo "Tested image majors are 33 and 34." read -r -p "Use ${selected_image} anyway? (y/N): " proceed_custom proceed_custom="${proceed_custom:-N}" if [[ ! "${proceed_custom}" =~ ^[Yy]$ ]]; then continue fi fi set_kv "NEXTCLOUD_IMAGE" "${selected_image}" echo "Using NEXTCLOUD_IMAGE=${selected_image}" break done } prompt() { local key="$1" local default="$2" local label="$3" local value read -r -p "${label} [${default}]: " value value="${value:-$default}" set_kv "${key}" "${value}" } echo "Configure local dev settings (press Enter to keep defaults)." prompt_nextcloud_image_selection prompt "NEXTCLOUD_PORT" "8080" "Nextcloud port" prompt "NEXTCLOUD_ADMIN_USER" "admin" "Nextcloud admin user" prompt "NEXTCLOUD_ADMIN_PASSWORD" "admin123" "Nextcloud admin password" prompt "NEXTCLOUD_TRUSTED_DOMAINS" "localhost 127.0.0.1 app" "Nextcloud trusted domains" prompt "BROKER_PORT" "3000" "Broker port" prompt "NEXTCLOUD_PUBLIC_URL" "http://localhost:8080" "Public Nextcloud URL" set_kv "BROKER_CORS_ALLOWED_ORIGINS" "$(grep -E "^NEXTCLOUD_PUBLIC_URL=" "${env_file}" | cut -d= -f2-)" prompt "OIDC_ISSUER" "http://broker:3000" "OIDC issuer (broker URL reachable by Nextcloud + browser)" prompt "OIDC_REDIRECT_URI_ALLOWLIST" "http://localhost:8080/apps/user_oidc/code" "OIDC redirect allowlist" read -r -p "Start bundled External Auth container? (y/N): " start_ext_auth start_ext_auth="${start_ext_auth:-N}" if [[ "${start_ext_auth}" =~ ^[Yy]$ ]]; then set_kv "QORTAL_EXTERNAL_AUTH_BASE_URL" "http://external_auth:3191" set_kv "EXTERNAL_AUTH_CONTEXT" "../Qortal-External-Auth" set_kv "EXTERNAL_AUTH_DOCKERFILE" "Dockerfile" set_kv "EXTERNAL_AUTH_PORT" "3191" read -r -p "Qortal node API key for External Auth (leave blank if not required): " qortal_auth_node_api_key set_kv "QORTAL_AUTH_NODE_API_KEY" "${qortal_auth_node_api_key}" set_kv "QORTAL_AUTH_NODE_API_KEY_MODE" "paths" set_kv "QORTAL_AUTH_NODE_API_KEY_PATHS" "/" mkdir -p "${repo_root}/external-auth/data" else prompt "QORTAL_EXTERNAL_AUTH_BASE_URL" "http://gateway.docker.internal:3191" "External Auth base URL" fi read -r -p "External Auth app ID (leave blank to set later): " app_id set_kv "QORTAL_EXTERNAL_AUTH_APP_ID" "${app_id}" read -r -p "External Auth app secret (leave blank to set later): " app_secret set_kv "QORTAL_EXTERNAL_AUTH_APP_SECRET" "${app_secret}" if [[ -x "${repo_root}/scripts/select-qortal-p2p-port.sh" ]]; then "${repo_root}/scripts/select-qortal-p2p-port.sh" "${env_file}" fi if [[ -f "${repo_root}/scripts/ensure-broker-internal-token.sh" ]]; then bash "${repo_root}/scripts/ensure-broker-internal-token.sh" "${env_file}" fi if [[ -x "${repo_root}/scripts/ensure-oidc-signing-key.sh" ]]; then "${repo_root}/scripts/ensure-oidc-signing-key.sh" "${env_file}" fi broker_internal_api_token="$(read_kv "BROKER_INTERNAL_API_TOKEN" || true)" if [[ -z "${broker_internal_api_token}" ]]; then echo "BROKER_INTERNAL_API_TOKEN is missing in ${env_file}" echo "Run: bash scripts/ensure-broker-internal-token.sh ${env_file}" exit 1 fi export BROKER_INTERNAL_API_TOKEN="${broker_internal_api_token}" broker_cors_allowed_origins="$(read_kv "BROKER_CORS_ALLOWED_ORIGINS" || true)" if [[ -n "${broker_cors_allowed_origins}" ]]; then export BROKER_CORS_ALLOWED_ORIGINS="${broker_cors_allowed_origins}" fi echo "Broker auth env loaded from ${env_file}: token_set=yes cors_origins=${broker_cors_allowed_origins:-}" echo nextcloud_custom_apps_path="$(resolve_path_from_env "NEXTCLOUD_CUSTOM_APPS_PATH" "./nextcloud/custom_apps")" mkdir -p "${repo_root}/nextcloud/html" "${repo_root}/nextcloud/data" "${nextcloud_custom_apps_path}" "${repo_root}/qortal/data" if [[ -x "${repo_root}/scripts/ensure-qortal-settings.sh" ]]; then "${repo_root}/scripts/ensure-qortal-settings.sh" fi echo "Starting local dev stack..." if [[ "${start_ext_auth}" =~ ^[Yy]$ ]]; then (cd "${repo_root}" && COMPOSE_PROFILES=external-auth make up) else (cd "${repo_root}" && make up) fi echo read -r -p "Install/enable user_oidc app now? (y/N): " install_oidc if [[ "${install_oidc}" =~ ^[Yy]$ ]]; then (cd "${repo_root}" && make install-oidc) fi cat <