#!/bin/bash set -euo pipefail KC_BASE="${KC_BASE:?}" KC_REALM="${KC_REALM:?}" KC_ADMIN_USER="${KC_ADMIN_USER:?}" KC_ADMIN_PASS="${KC_ADMIN_PASS:?}" if ! command -v jq >/dev/null 2>&1; then apt-get update && apt-get install -y jq curl >/dev/null fi account_exists() { local user_id="${1}" local email="${2}" # Nextcloud Mail does not provide a list command; export is safe (does not print passwords). local export if ! export=$(/usr/sbin/runuser -u www-data -- php occ mail:account:export "${user_id}" 2>/dev/null); then echo "WARN: unable to export mail accounts for ${user_id}; skipping sync for safety" >&2 return 0 fi # Output formatting varies by Nextcloud/Mail versions and locale; match by email address. grep -Fq -- "${email}" <<<"${export}" } token=$( curl -s -d "grant_type=password" \ -d "client_id=admin-cli" \ -d "username=${KC_ADMIN_USER}" \ -d "password=${KC_ADMIN_PASS}" \ "${KC_BASE}/realms/master/protocol/openid-connect/token" | jq -r '.access_token' ) if [[ -z "${token}" || "${token}" == "null" ]]; then echo "Failed to obtain admin token" exit 1 fi cd /var/www/html users=$(curl -s -H "Authorization: Bearer ${token}" \ "${KC_BASE}/admin/realms/${KC_REALM}/users?max=2000") echo "${users}" | jq -c '.[]' | while read -r user; do username=$(echo "${user}" | jq -r '.username') email=$(echo "${user}" | jq -r '.email // empty') app_pw=$(echo "${user}" | jq -r '(.attributes.mailu_app_password[0] // .attributes.mailu_app_password // empty)') [[ -z "${email}" || -z "${app_pw}" ]] && continue if account_exists "${username}" "${email}"; then echo "Skipping ${email}, already exists" continue fi echo "Syncing ${email}" /usr/sbin/runuser -u www-data -- php occ mail:account:create \ "${username}" "${username}" "${email}" \ mail.bstein.dev 993 ssl "${email}" "${app_pw}" \ mail.bstein.dev 587 tls "${email}" "${app_pw}" || true done