works with authelia

This commit is contained in:
root
2025-12-25 00:34:26 -08:00
parent 187e2357bd
commit 5b3c70666a

View File

@@ -1,115 +1,109 @@
#!/bin/bash
set -euo pipefail
set -e
# --- 1. Environment Loading ---
IMMICH_ENV="/root/secrets/immich.env"
AUTHELIA_ENV="/root/secrets/authelia.env"
# --- Configuration ---
MAIN_ADMIN_EMAIL="camonroe@poppyglen.cc"
PHOTO_ROOT="/mnt/photos"
BASE="http://localhost:2283/api"
load_env() {
if [ -f "$1" ]; then
# Sourcing the file directly is often more reliable for quoted strings in Bash
# but we wrap it in a subshell to avoid polluting the current shell
set -a
source "$1"
set +a
else
echo "❌ Error: $1 not found"
exit 1
fi
# --- Helper: Hard Delete ---
hard_delete_user() {
sudo -u postgres psql -d immich -c "DELETE FROM \"user\" WHERE email = '$1';" >/dev/null 2>&1
}
echo "🔐 Loading secrets..."
load_env "$IMMICH_ENV"
load_env "$AUTHELIA_ENV"
[ -f "/root/secrets/immich.env" ] && { set -a; source "/root/secrets/immich.env"; set +a; }
[ -f "/root/secrets/authelia.env" ] && { set -a; source "/root/secrets/authelia.env"; set +a; }
BASE="http://localhost:2283/api"
PHOTO_ROOT="/mnt/photos"
# --- 2. Wait for API ---
echo "⏳ Waiting for Immich..."
until curl -s "$BASE/server/ping" | grep -q '"res":"pong"'; do
printf '.'
sleep 3
done
echo -e "\n✅ API Online."
# --- 3. Admin Initialization ---
echo "👤 Ensuring Admin exists..."
curl -s -X POST "$BASE/auth/admin-sign-up" \
-H "Content-Type: application/json" \
-d "{\"email\":\"${IMMICH_INIT_ADMIN_EMAIL}\",\"password\":\"${IMMICH_INIT_ADMIN_PASSWORD}\",\"name\":\"${IMMICH_INIT_ADMIN_NAME}\"}" || echo " Admin already exists."
# --- 4. Login ---
# --- 1. Login ---
echo "🔑 Logging in..."
TOKEN=$(curl -fsS -X POST "$BASE/auth/login" \
-H "Content-Type: application/json" \
-d "{\"email\":\"${IMMICH_INIT_ADMIN_EMAIL}\",\"password\":\"${IMMICH_INIT_ADMIN_PASSWORD}\"}" \
-d "$(jq -n --arg e "$IMMICH_INIT_ADMIN_EMAIL" --arg p "$IMMICH_INIT_ADMIN_PASSWORD" '{email: $e, password: $p}')" \
| jq -r '.accessToken')
if [ -z "$TOKEN" ] || [ "$TOKEN" == "null" ]; then
echo "❌ Login failed! Check IMMICH_INIT_ADMIN_PASSWORD."
exit 1
fi
# --- 5. OIDC & Security ---
echo "🛡️ Configuring OIDC (Authelia)..."
# --- 2. Configure System (Hybrid Mode) ---
echo "⚙️ Enabling OAuth Hybrid Mode..."
CURRENT_CONFIG=$(curl -fsS -H "Authorization: Bearer $TOKEN" "$BASE/system-config")
UPDATED_CONFIG=$(echo "$CURRENT_CONFIG" | jq \
--arg host "${MAIL_SMTPHOST}" \
--arg port "${SMTP_PORT:-587}" \
--arg user "${MAIL_ADMIN_EMAIL:-}" \
--arg pass "${MAIL_ADMIN_PASSWORD:-}" \
--arg from "${MAIL_SENDER_EMAIL:-notify@poppyglen.cc}" \
--arg issuer "$OAUTH_ISSUER_URL" \
--arg secret "$IMMICH_CLIENT_SECRET" \
'.oauth.enabled = true |
.oauth.issuerUrl = $issuer |
.oauth.clientId = "immich" |
.oauth.clientSecret = $secret |
.oauth.scope = "openid profile email" |
.oauth.buttonText = "Login with Authelia" |
.oauth.autoRegister = true |
.passwordLogin.enabled = false')
--argjson secure false \
'
# 1. SMTP
.notifications.smtp.enabled = true |
.notifications.smtp.from = $from |
.notifications.smtp.transport.host = $host |
.notifications.smtp.transport.port = ($port | tonumber) |
.notifications.smtp.transport.username = $user |
.notifications.smtp.transport.password = $pass |
.notifications.smtp.transport.secure = $secure |
# 2. OAuth Configuration
.oauth.enabled = true |
.oauth.issuerUrl = $issuer |
.oauth.clientId = "immich" |
.oauth.clientSecret = $secret |
.oauth.scope = "openid profile email groups" |
.oauth.buttonText = "Login with Authelia" |
.oauth.autoRegister = false |
.oauth.autoLaunch = false |
.oauth.storageLabelClaim = "preferred_username" |
# 3. Password Login (Fallback)
.passwordLogin.enabled = true
')
curl -fsS -X PUT "$BASE/system-config" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "$UPDATED_CONFIG" > /dev/null
echo " ✅ OAuth Enabled (Hybrid Mode)."
# --- 6. Provision Users & Map Libraries ---
# --- 3. Provision Users ---
# (Using the same logic as the last successful run)
if [ -n "${USERS_JSON:-}" ]; then
echo "👥 Processing Users from JSON..."
echo "👥 Processing Users..."
echo "$USERS_JSON" | jq -c '.[]' | while read -r u; do
u_email=$(echo "$u" | jq -r '.email')
u_pass=$(echo "$u" | jq -r '.password')
u_name=$(echo "$u" | jq -r '.name')
# Extract folder name from email (e.g. camonroe from camonroe@poppyglen.cc)
short_name="${u_email%%@*}"
echo " Creating/Checking user: $u_email"
USER_DATA=$(curl -s -X POST "$BASE/admin/users" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"email\":\"$u_email\",\"password\":\"$u_pass\",\"name\":\"$u_name\"}")
USER_ID=$(echo "$USER_DATA" | jq -r '.id // empty')
if [ -z "$USER_ID" ] || [ "$USER_ID" == "null" ]; then
USER_ID=$(curl -s -H "Authorization: Bearer $TOKEN" "$BASE/users" | jq -r --arg email "$u_email" '.[] | select(.email==$email) | .id')
fi
echo "➡️ Processing: $short_name"
if [ -n "$USER_ID" ] && [ "$USER_ID" != "null" ]; then
lib_path="$PHOTO_ROOT/$short_name"
if [ -d "$lib_path" ]; then
echo "✨ Mapping library for $short_name at $lib_path"
LIB_ID=$(curl -fsS -X POST "$BASE/libraries" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"name\":\"External-$short_name\",\"ownerId\":\"$USER_ID\",\"importPaths\":[\"$lib_path\"]}" | jq -r '.id')
curl -fsS -X POST "$BASE/libraries/$LIB_ID/scan" \
-H "Authorization: Bearer $TOKEN" -d "{}" > /dev/null
else
echo "⚠️ Folder not found: $lib_path"
fi
if [ "$u_email" != "${IMMICH_INIT_ADMIN_EMAIL}" ]; then
hard_delete_user "$u_email"
CREATE_PAYLOAD=$(jq -n --arg e "$u_email" --arg p "$u_pass" --arg n "$u_name" '{email: $e, password: $p, name: $n, shouldChangePassword: false}')
USER_DATA=$(curl -s -X POST "$BASE/admin/users" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$CREATE_PAYLOAD")
USER_ID=$(echo "$USER_DATA" | jq -r '.id // empty')
if [ -n "$USER_ID" ] && [ "$USER_ID" != "null" ]; then
IS_ADMIN="false"
[ "$u_email" == "$MAIN_ADMIN_EMAIL" ] && IS_ADMIN="true"
# Update without oauthId to keep local passwords alive
UPDATE_PAYLOAD=$(jq -n --arg e "$u_email" --arg n "$u_name" --arg sl "$short_name" --argjson admin "$IS_ADMIN" \
'{email: $e, name: $n, storageLabel: $sl, isAdmin: $admin, shouldChangePassword: false}')
curl -s -o /dev/null -X PUT "$BASE/admin/users/$USER_ID" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" -d "$UPDATE_PAYLOAD"
# Library Mapping
lib_path="$PHOTO_ROOT/$short_name"
if [ -d "$lib_path" ]; then
LIB_ID=$(curl -fsS -X POST "$BASE/libraries" -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d "{\"name\":\"External-$short_name\",\"ownerId\":\"$USER_ID\",\"importPaths\":[\"$lib_path\"]}" | jq -r '.id // empty')
[ -n "$LIB_ID" ] && curl -s -X POST "$BASE/libraries/$LIB_ID/scan" -H "Authorization: Bearer $TOKEN" -d "{}" > /dev/null
fi
fi
fi
done
fi
echo "🚀 Setup Complete!"
echo "🚀 Hybrid Mode Active. Test the Authelia button now!"