Wire Authelia SSO into Immich, Audiobookshelf, and Beszel
_authelia_provision_oidc_client gains an optional PKCE flag (new 5th positional arg; every existing caller updated to pass "n", producing an identical client block to before) — Audiobookshelf and Beszel's own Authelia integration docs both require require_pkce/pkce_challenge_method, which Authelia doesn't turn on by default. immich.sh: _immich_offer_authelia_oidc() is real server-side automation, not just paste-in instructions — confirmed the exact system-config "oauth" JSON field names against Immich's own config-file.md and source (not guessed, closing out the "needs one more verification pass" note this repo's own CLAUDE.md already had on file). GET/PUT exchange the whole config object, so it round-trips everything else unchanged. Needs an admin API key that doesn't exist until first web-UI visit, so it's wired into both the fresh-install path and the "update" rerun path. audiobookshelf.sh, beszel.sh: both apps' OIDC config is UI-only (checked against audiobookshelf.org and beszel.dev directly — no config API or env var for the provider fields), so their new offers automate the Authelia side and print exact paste-in values. Beszel also gets a real, separate DISABLE_PASSWORD_AUTH/USER_CREATION toggle to fully replace its login, gated behind a warning to register a working account first. Also adds Audiobookshelf and Beszel as presets in authelia.sh's own generic "Register another app" menu, and updates CLAUDE.md's OIDC verification table to match reality (Immich now wired, Audiobookshelf was wrongly listed as "high-confidence no", Beszel added).
This commit is contained in:
+63
-5
@@ -2746,7 +2746,7 @@ _authelia_remove_oidc_client() {
|
||||
# that's already registered is NOT a failure — it gets replaced (see the
|
||||
# comment at that check below).
|
||||
_authelia_provision_oidc_client() {
|
||||
local APP_NAME="$1" CLIENT_ID="$2" AUTH_POLICY="$3" RESTART_AUTH="$4"; shift 4
|
||||
local APP_NAME="$1" CLIENT_ID="$2" AUTH_POLICY="$3" RESTART_AUTH="$4" REQUIRE_PKCE="$5"; shift 5
|
||||
local -a REDIRECT_URIS=("$@")
|
||||
|
||||
OIDC_CLIENT_SECRET_PLAIN=""
|
||||
@@ -2841,11 +2841,27 @@ _authelia_provision_oidc_client() {
|
||||
REDIRECT_URIS_YAML="$(printf " - '%s'\n" "${REDIRECT_URIS[@]}")"
|
||||
REDIRECT_URIS_YAML="${REDIRECT_URIS_YAML%$'\n'}"
|
||||
|
||||
# PKCE lines are opt-in, not default — Authelia's own defaults for every
|
||||
# other field here (client_secret_basic auth method for a confidential
|
||||
# client, access_token_signed_response_alg: none) already match what
|
||||
# Audiobookshelf/Beszel's own Authelia integration docs specify, but
|
||||
# require_pkce defaults to false and has to be set explicitly for the
|
||||
# apps that need it. Checked against authelia.com's own per-client
|
||||
# integration pages for those two, not assumed — every existing caller
|
||||
# (Mealie/ActualBudget/Vaultwarden/Gitea/Immich) passes "n" here and
|
||||
# gets byte-for-byte the same client block as before this was added.
|
||||
local PKCE_YAML=""
|
||||
if [[ "$REQUIRE_PKCE" =~ ^[Yy]$ ]]; then
|
||||
PKCE_YAML="
|
||||
require_pkce: true
|
||||
pkce_challenge_method: 'S256'"
|
||||
fi
|
||||
|
||||
local CLIENT_BLOCK=" - client_id: '${CLIENT_ID}'
|
||||
client_name: '${APP_NAME}'
|
||||
client_secret: '${CLIENT_SECRET_HASH}'
|
||||
public: false
|
||||
authorization_policy: '${AUTH_POLICY}'
|
||||
authorization_policy: '${AUTH_POLICY}'${PKCE_YAML}
|
||||
redirect_uris:
|
||||
${REDIRECT_URIS_YAML}
|
||||
scopes:
|
||||
@@ -2922,13 +2938,17 @@ _authelia_add_oidc_client() {
|
||||
echo " 2) Vaultwarden"
|
||||
echo " 3) Immich (needs multiple redirect URIs — web login, account-linking,"
|
||||
echo " and the mobile app's custom-scheme callback — all registered here)"
|
||||
echo " 5) Audiobookshelf (needs PKCE — checked against its own Authelia"
|
||||
echo " integration docs, registered here automatically)"
|
||||
echo " 6) Beszel (PocketBase-based — also needs PKCE; its own side is"
|
||||
echo " configured in its Settings -> Auth providers page, not an API)"
|
||||
echo " 4) Other / custom app"
|
||||
echo " 0) Cancel"
|
||||
echo ""
|
||||
local APP_CHOICE=""
|
||||
prompt_text " Choice [1-4, 0 to cancel]:" "0" APP_CHOICE
|
||||
prompt_text " Choice [1-6, 0 to cancel]:" "0" APP_CHOICE
|
||||
|
||||
local APP_NAME="" CLIENT_ID=""
|
||||
local APP_NAME="" CLIENT_ID="" REQUIRE_PKCE="n"
|
||||
local -a REDIRECT_PATHS=() EXTRA_REDIRECT_URIS=()
|
||||
case "$APP_CHOICE" in
|
||||
1) APP_NAME="ActualBudget"; CLIENT_ID="actualbudget"; REDIRECT_PATHS=("/openid/callback") ;;
|
||||
@@ -2938,6 +2958,15 @@ _authelia_add_oidc_client() {
|
||||
REDIRECT_PATHS=("/auth/login" "/user-settings")
|
||||
EXTRA_REDIRECT_URIS=("app.immich:///oauth-callback")
|
||||
;;
|
||||
5)
|
||||
APP_NAME="Audiobookshelf"; CLIENT_ID="audiobookshelf"; REQUIRE_PKCE="y"
|
||||
REDIRECT_PATHS=("/auth/openid/callback" "/auth/openid/mobile-redirect")
|
||||
EXTRA_REDIRECT_URIS=("audiobookshelf://oauth")
|
||||
;;
|
||||
6)
|
||||
APP_NAME="Beszel"; CLIENT_ID="beszel"; REQUIRE_PKCE="y"
|
||||
REDIRECT_PATHS=("/api/oauth2-redirect")
|
||||
;;
|
||||
4)
|
||||
prompt_text " App name (for your reference):" "" APP_NAME
|
||||
[ -z "$APP_NAME" ] && { log_warning "No app name entered — nothing to do."; return 0; }
|
||||
@@ -2994,7 +3023,7 @@ _authelia_add_oidc_client() {
|
||||
local RESTART_AUTH=""
|
||||
prompt_yn " Restart Authelia to apply? (y/n):" "y" RESTART_AUTH
|
||||
|
||||
_authelia_provision_oidc_client "$APP_NAME" "$CLIENT_ID" "$AUTH_POLICY" "$RESTART_AUTH" "${REDIRECT_URIS[@]}" \
|
||||
_authelia_provision_oidc_client "$APP_NAME" "$CLIENT_ID" "$AUTH_POLICY" "$RESTART_AUTH" "$REQUIRE_PKCE" "${REDIRECT_URIS[@]}" \
|
||||
|| return 1
|
||||
local CLIENT_SECRET_PLAIN="$OIDC_CLIENT_SECRET_PLAIN"
|
||||
|
||||
@@ -3047,6 +3076,35 @@ _authelia_add_oidc_client() {
|
||||
echo " for OAuth to work in both the browser and the Immich mobile app."
|
||||
echo ""
|
||||
;;
|
||||
5)
|
||||
echo " Audiobookshelf -> Settings -> Authentication -> enable OpenID Connect"
|
||||
echo " Authentication, then fill in (checked against audiobookshelf.org's own"
|
||||
echo " OIDC docs — it wants individual endpoints, not a discovery URL):"
|
||||
echo " Issuer URL: https://${AUTHELIA_PORTAL_DOMAIN}"
|
||||
echo " Authorize URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/authorization"
|
||||
echo " Token URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/token"
|
||||
echo " Userinfo URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/userinfo"
|
||||
echo " JWKS URL: https://${AUTHELIA_PORTAL_DOMAIN}/jwks.json"
|
||||
echo " Client ID: ${CLIENT_ID}"
|
||||
echo " Client Secret: ${CLIENT_SECRET_PLAIN}"
|
||||
echo " Signing Algorithm: RS256"
|
||||
echo " Allowed Mobile Redirect URIs: audiobookshelf://oauth"
|
||||
echo ""
|
||||
;;
|
||||
6)
|
||||
echo " Beszel is PocketBase-based — its OAuth2 provider is a PocketBase admin"
|
||||
echo " setting, not an API this script can write (checked against beszel.dev's"
|
||||
echo " own docs). In the hub: Settings -> Auth providers -> OpenID Connect:"
|
||||
echo " Client ID: ${CLIENT_ID}"
|
||||
echo " Client Secret: ${CLIENT_SECRET_PLAIN}"
|
||||
echo " Auth URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/authorization"
|
||||
echo " Token URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/token"
|
||||
echo " User Info URL: https://${AUTHELIA_PORTAL_DOMAIN}/api/oidc/userinfo"
|
||||
echo " Register your first Beszel account with a password BEFORE touching"
|
||||
echo " DISABLE_PASSWORD_AUTH/USER_CREATION in its .env — flipping those before"
|
||||
echo " a working login exists risks locking the hub's UI out entirely."
|
||||
echo ""
|
||||
;;
|
||||
esac
|
||||
log_warning "The Client Secret above is shown once — it isn't stored in plaintext anywhere. Save it now."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user