#!/usr/bin/env bash set -euo pipefail script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" repo_root="$(cd "${script_dir}/.." && pwd)" custom_apps_root="${NEXTCLOUD_CUSTOM_APPS_PATH:-${repo_root}/nextcloud/custom_apps}" if [[ "${custom_apps_root}" != /* ]]; then custom_apps_root="${repo_root}/${custom_apps_root}" fi target_dir="${custom_apps_root}/user_oidc" source_dir="${USER_OIDC_SOURCE_PATH:-}" version="${USER_OIDC_VERSION:-v8.10.1}" download_url="${USER_OIDC_DOWNLOAD_URL:-}" version_no_v="${version#v}" app_version_from_info() { local dir="$1" local info_file="${dir%/}/appinfo/info.xml" if [[ -z "${dir}" || ! -f "${info_file}" ]]; then return 1 fi sed -n 's#.*\([^<]*\).*#\1#p' "${info_file}" | head -n1 } has_valid_app() { local dir="$1" [[ -f "${dir}/appinfo/info.xml" && -f "${dir}/vendor/autoload.php" ]] } patch_invite_flow() { if [[ -x "${script_dir}/patch-user-oidc-invite-flow.sh" ]]; then USER_OIDC_APP_PATH="${target_dir}" "${script_dir}/patch-user-oidc-invite-flow.sh" fi } copy_from_source() { local src="$1" mkdir -p "${target_dir}" if command -v rsync >/dev/null 2>&1; then rsync -a --delete "${src}/" "${target_dir}/" else rm -rf "${target_dir}" mkdir -p "${target_dir}" cp -R "${src}/." "${target_dir}/" fi } find_app_root_with_vendor() { local base="$1" find "${base}" -type f -path "*/appinfo/info.xml" | while read -r info_file; do app_dir="$(dirname "$(dirname "${info_file}")")" if [[ -f "${app_dir}/vendor/autoload.php" ]]; then echo "${app_dir}" return 0 fi done } find_app_root_info_only() { local base="$1" find "${base}" -type f -path "*/appinfo/info.xml" | while read -r info_file; do app_dir="$(dirname "$(dirname "${info_file}")")" echo "${app_dir}" return 0 done } download_and_extract_candidate() { local url="$1" local tmp_dir="$2" local archive_path="${tmp_dir}/user_oidc.tar.gz" if ! curl -fsSL "${url}" -o "${archive_path}"; then return 1 fi if ! tar -xzf "${archive_path}" -C "${tmp_dir}"; then return 1 fi local extracted_with_vendor extracted_with_vendor="$(find_app_root_with_vendor "${tmp_dir}" | head -n1 || true)" if [[ -n "${extracted_with_vendor}" ]]; then copy_from_source "${extracted_with_vendor}" return 0 fi return 2 } if has_valid_app "${target_dir}"; then current_version="$(app_version_from_info "${target_dir}" 2>/dev/null || true)" if [[ "${current_version}" == "${version_no_v}" ]]; then echo "user_oidc app already present: ${target_dir} (v${current_version})" patch_invite_flow exit 0 fi echo "Existing user_oidc app version ${current_version:-unknown} does not match requested ${version}; refreshing..." elif [[ -d "${target_dir}" ]]; then echo "Existing user_oidc app is incomplete (missing vendor/autoload.php); repairing..." fi if [[ -n "${source_dir}" && -d "${source_dir}" ]] && has_valid_app "${source_dir}"; then source_version="$(app_version_from_info "${source_dir}" 2>/dev/null || true)" echo "Syncing user_oidc app from USER_OIDC_SOURCE_PATH=${source_dir}" if [[ -n "${source_version}" ]]; then echo "Source user_oidc version: ${source_version}" fi copy_from_source "${source_dir}" if has_valid_app "${target_dir}"; then echo "user_oidc app synced to ${target_dir}" patch_invite_flow exit 0 fi fi tmp_dir="$(mktemp -d)" cleanup() { rm -rf "${tmp_dir}" } trap cleanup EXIT candidate_urls=() if [[ -n "${download_url}" ]]; then candidate_urls+=("${download_url}") else candidate_urls+=( "https://github.com/nextcloud-releases/user_oidc/releases/download/v${version_no_v}/user_oidc-v${version_no_v}.tar.gz" "https://github.com/nextcloud-releases/user_oidc/releases/download/${version_no_v}/user_oidc-v${version_no_v}.tar.gz" "https://github.com/nextcloud/user_oidc/releases/download/${version}/user_oidc-v${version_no_v}.tar.gz" "https://github.com/nextcloud/user_oidc/releases/download/${version}/user_oidc-${version_no_v}.tar.gz" "https://github.com/nextcloud/user_oidc/archive/refs/tags/${version}.tar.gz" ) fi download_success="0" saw_source_only_archive="0" for candidate in "${candidate_urls[@]}"; do echo "user_oidc app missing; downloading ${candidate}" rm -rf "${tmp_dir:?}/"* set +e download_and_extract_candidate "${candidate}" "${tmp_dir}" rc=$? set -e if [[ "${rc}" -eq 0 ]]; then download_success="1" break fi if [[ "${rc}" -eq 2 ]]; then saw_source_only_archive="1" echo "Downloaded archive appears to be source-only (missing vendor/autoload.php), trying next source..." fi done if [[ "${download_success}" != "1" || ! -f "${target_dir}/vendor/autoload.php" ]]; then if [[ "${saw_source_only_archive}" == "1" ]]; then echo "Failed to obtain a packaged user_oidc app with vendor dependencies." echo "Set USER_OIDC_DOWNLOAD_URL to a packaged release tarball, or USER_OIDC_SOURCE_PATH to a full local app dir." else echo "Failed to download a valid user_oidc app archive." fi exit 1 fi patch_invite_flow echo "user_oidc app prepared at ${target_dir}"