#!/bin/bash # # Get FoundryVTT download URL using account credentials # Based on felddy/foundryvtt-docker authentication flow # # Usage: get_foundry_download.sh [--url-only] [--version VERSION] # # Required environment variables: # FOUNDRY_USERNAME - FoundryVTT account username/email # FOUNDRY_PASSWORD - FoundryVTT account password # set -euo pipefail # Configuration FOUNDRY_BASE_URL="https://foundryvtt.com" # Check required environment variables if [[ -z "${FOUNDRY_USERNAME:-}" || -z "${FOUNDRY_PASSWORD:-}" ]]; then echo "Error: FOUNDRY_USERNAME and FOUNDRY_PASSWORD environment variables are required" >&2 exit 1 fi # Create temp file for cookies COOKIE_JAR=$(mktemp) trap "rm -f $COOKIE_JAR" EXIT # Step 1: Get CSRF token from the main page (not login page) get_csrf_token() { local main_page main_page=$(curl -fsSL -c "$COOKIE_JAR" -b "$COOKIE_JAR" \ -H "DNT: 1" \ -H "Referer: ${FOUNDRY_BASE_URL}" \ -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "${FOUNDRY_BASE_URL}" 2>/dev/null) # Extract csrfmiddlewaretoken from the form local csrf_token csrf_token=$(echo "$main_page" | grep -oP 'name="csrfmiddlewaretoken" value="\K[^"]+' 2>/dev/null | head -1) echo "$csrf_token" } # Step 2: Authenticate authenticate() { local csrf_token="$1" # POST to login curl -fsSL -b "$COOKIE_JAR" -c "$COOKIE_JAR" \ -X POST "${FOUNDRY_BASE_URL}/auth/login/" \ -H "DNT: 1" \ -H "Referer: ${FOUNDRY_BASE_URL}" \ -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "csrfmiddlewaretoken=${csrf_token}&username=${FOUNDRY_USERNAME}&password=${FOUNDRY_PASSWORD}&next=/" \ -o /dev/null 2>/dev/null || true # Check for sessionid cookie (indicates successful login) if grep -q "sessionid" "$COOKIE_JAR" 2>/dev/null; then return 0 else return 1 fi } # Step 3: Get download URL get_download_url() { local version="$1" # Extract build number from version (e.g., "13.351" -> "351") local build build="${version##*.}" # Fetch presigned URL from API local response response=$(curl -fsSL -b "$COOKIE_JAR" \ -H "DNT: 1" \ -H "Referer: ${FOUNDRY_BASE_URL}" \ -H "User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36" \ "${FOUNDRY_BASE_URL}/releases/download?build=${build}&platform=node&response_type=json" 2>/dev/null) # Extract URL from JSON response local download_url download_url=$(echo "$response" | grep -oP '"url":\s*"\K[^"]+' 2>/dev/null || true) echo "$download_url" } # Main execution main() { local url_only=false local version_override="" # Parse arguments while [[ $# -gt 0 ]]; do case "$1" in --url-only) url_only=true shift ;; --version) version_override="$2" shift 2 ;; *) echo "Unknown option: $1" >&2 exit 1 ;; esac done # Get version local version="${version_override:-}" if [[ -z "$version" ]]; then # Get latest stable version version=$(bash "$(dirname "$0")/get_foundry_version.sh" --version-only 2>/dev/null || echo "") if [[ -z "$version" ]]; then echo "Error: Could not determine FoundryVTT version" >&2 exit 1 fi fi if [[ "$url_only" != true ]]; then echo "Authenticating with FoundryVTT..." >&2 fi local csrf_token csrf_token=$(get_csrf_token) if [[ -z "$csrf_token" ]]; then echo "Error: Could not get CSRF token from FoundryVTT" >&2 exit 1 fi if ! authenticate "$csrf_token"; then echo "Error: Authentication failed. Check your credentials." >&2 exit 1 fi if [[ "$url_only" != true ]]; then echo "Fetching download URL for version ${version}..." >&2 fi local download_url download_url=$(get_download_url "$version") if [[ -z "$download_url" || "$download_url" == "null" ]]; then echo "Error: Could not retrieve download URL. Make sure you have a valid license." >&2 exit 1 fi echo "$download_url" } main "$@"