feat(caddy): give Audiobookshelf a guarded abs.franksdank.cloud address #130
@@ -11,12 +11,15 @@
|
||||
# dist-server/server/auth/OidcAuthStrategy.js + objects/settings/ServerSettings.js)
|
||||
# rather than a forum, because each of these is a dead-login trap:
|
||||
#
|
||||
# * TWO redirect URIs on the provider: <base>/auth/openid/callback (browser) and
|
||||
# <base>/auth/openid/mobile-redirect (mobile). ABS SWAPS the app's own
|
||||
# audiobookshelf://oauth for the mobile-redirect URL before the IdP ever sees a
|
||||
# redirect_uri, so registering the app scheme with authentik — the obvious move —
|
||||
# is what makes phone logins fail. The app scheme belongs in ABS's
|
||||
# authOpenIDMobileRedirectURIs list (its built-in default), not here.
|
||||
# * The browser callback URI <base>/auth/openid/callback for EVERY origin ABS is
|
||||
# reached at, plus <base>/auth/openid/mobile-redirect on ABS_BASE only. ABS SWAPS
|
||||
# the app's own audiobookshelf://oauth for the mobile-redirect URL before the IdP
|
||||
# ever sees a redirect_uri, so registering the app scheme with authentik — the
|
||||
# obvious move — is what makes phone logins fail. The app scheme belongs in ABS's
|
||||
# authOpenIDMobileRedirectURIs list (its built-in default), not here. The mobile
|
||||
# URI is registered on the LAN origin only because the phone is configured with
|
||||
# the LAN address: it is a non-browser client and cannot solve the guard
|
||||
# challenge that sits in front of the vhost.
|
||||
# * <base> CARRIES THE BASE PATH. ABS builds redirect_uri as
|
||||
# <origin><authOpenIDSubfolderForRedirectURLs>/auth/openid/callback, and that subfolder is
|
||||
# the ROUTER_BASE_PATH the container is mounted at — /audiobookshelf, which is also the only
|
||||
@@ -72,8 +75,17 @@
|
||||
# (qa-e2e-admin — tests/e2e/specs/23-audiobookshelf-sso.spec.ts
|
||||
# signs in as this identity, so a re-run restores the fixture)
|
||||
# ABS_BASE ABS URL as the browser sees it, base path included
|
||||
# (http://192.168.0.235:8000/audiobookshelf — LAN-only by policy:
|
||||
# no vhost, no reverse proxy in front)
|
||||
# (http://192.168.0.235:8000/audiobookshelf — the LAN
|
||||
# origin, reached directly, which is also what the phone
|
||||
# app is configured with)
|
||||
# ABS_EXTRA_BASES space-separated additional origins, base path included
|
||||
# (default: https://abs.franksdank.cloud/audiobookshelf —
|
||||
# the guarded vhost, dankclaw/Caddyfile).
|
||||
# ABS builds its redirect_uri from the ORIGIN of the
|
||||
# request, so each origin the app is served at needs its
|
||||
# own registered URI — an unregistered origin is a
|
||||
# redirect_uri_mismatch at the IdP, before any credential.
|
||||
# Set it empty to register the LAN origin alone.
|
||||
# AUTHENTIK_HOST ssh target (dankclaw)
|
||||
set -euo pipefail
|
||||
|
||||
@@ -88,6 +100,7 @@ SSO_USER="${ABS_OIDC_USERNAME:-akadmin}"
|
||||
MEMBERS="${ABS_OIDC_USERS:-}"
|
||||
E2E_ADMIN="${ABS_E2E_ADMIN:-qa-e2e-admin}"
|
||||
BASE="${ABS_BASE:-http://192.168.0.235:8000/audiobookshelf}"
|
||||
EXTRA_BASES="${ABS_EXTRA_BASES:-https://abs.franksdank.cloud/audiobookshelf}"
|
||||
HOST="${AUTHENTIK_HOST:-dankclaw}"
|
||||
|
||||
# The claim expression: translate group membership into ABS role names. It is stored
|
||||
@@ -110,6 +123,7 @@ from authentik.providers.oauth2.models import (
|
||||
|
||||
ADMIN_GROUP, USER_GROUP = "$ADMIN_GROUP", "$USER_GROUP"
|
||||
CLAIM, CLIENT_ID, SECRET, BASE = "$CLAIM", "$CLIENT_ID", "$SECRET", "$BASE"
|
||||
BASES = [BASE] + """$EXTRA_BASES""".split()
|
||||
SSO_USER, E2E_ADMIN = "$SSO_USER", "$E2E_ADMIN"
|
||||
MEMBERS = """$MEMBERS""".split()
|
||||
EXPR = '''$EXPR'''
|
||||
@@ -143,10 +157,12 @@ _ns = {}
|
||||
exec(_src, _ns)
|
||||
|
||||
# --- provider --------------------------------------------------------------------
|
||||
# One browser callback per origin (LAN address and the guarded vhost), because ABS
|
||||
# derives redirect_uri from the request origin; the mobile URI stays on the LAN origin.
|
||||
uris = [RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT,
|
||||
url="%s/auth/openid/callback" % BASE),
|
||||
RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT,
|
||||
url="%s/auth/openid/mobile-redirect" % BASE)]
|
||||
url="%s/auth/openid/callback" % b) for b in BASES]
|
||||
uris.append(RedirectURI(matching_mode=RedirectURIMatchingMode.STRICT,
|
||||
url="%s/auth/openid/mobile-redirect" % BASE))
|
||||
authz_flow = Flow.objects.get(slug="default-provider-authorization-implicit-consent")
|
||||
|
||||
# Three things beyond the name, each one a silent dead login: the grant-type list (2026.8
|
||||
|
||||
Reference in new issue
Block a user