fix(web-app-fider): pass BASE_URL without a trailing slash

Fider v0.39.0 accepts an OAuth redirect only when its origin equals
OAuthBaseURL (isKnownOAuthOrigin compares u.Scheme + "://" + u.Host with
it), and in single-host mode OAuthBaseURL is BASE_URL unchanged. The tls
lookup's url.base ends with "/", so the comparison never matched and
every Keycloak login was rejected. Main run 41925343136 (2df12002c0),
Fider#0 compose clearnet centos/ext4: playwright.spec.js:56 and :88 find
no .c-menu-user after SSO, and the rescue fider.log shows 11x "OAuth
callback state for provider _keycloak points at an unknown origin.
Aborting sign in process." The image is the mirrored getfider/fider
stable, refreshed 35 hours before the run.

The tls lookup now also returns url.origin, the base URL without its
slash (the lookup hunk of 44aaa68924 on feature/store-i18n), and the
Fider env passes it as BASE_URL (d531d35823 there). url.base keeps its
value, so no other consumer changes, and both lines match the
store-i18n side for a conflict-free merge.

| 🎯 Fix | 💥 Break | 🌱 Efficiency | ⚡ Speed | 🛡️ Security | 🏆 Score | Gate |
| --- | --- | --- | --- | --- | --- | --- |
| 88 % | 3 % | – | – | ~100 % | 85 | ⛔ fix 88 % < 90 |

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
kevinveenbirkenbachandClaude Opus 5.5 committed 2026-11-05 11:42:16 +00:00
1 parent 572c69ec56
commit bf1b1f2769
3 files changed
+14 -3

No files matched your search

+3 -2
View File
@@ -99,7 +99,8 @@ class LookupModule(LookupBase):
web_protocol = "https" if enabled else "http"
websocket_protocol = "wss" if enabled else "ws"
web_port = 443 if enabled else 80
base_url = f"{web_protocol}://{primary_domain}/"
origin = f"{web_protocol}://{primary_domain}"
base_url = f"{origin}/"
resolved: dict[str, Any] = {
"application_id": app_id,
@@ -109,7 +110,7 @@ class LookupModule(LookupBase):
"domains": {"primary": primary_domain, "all": all_domains},
"protocols": {"web": web_protocol, "websocket": websocket_protocol},
"ports": {"web": web_port},
"url": {"base": base_url},
"url": {"base": base_url, "origin": origin},
}
if want:
+1 -1
View File
@@ -1,6 +1,6 @@
{% include 'roles/sys-svc-container/templates/env.j2' %}
BASE_URL={{ lookup('tls', application_id, 'url.base') }}
BASE_URL={{ lookup('tls', application_id, 'url.origin') }}
DATABASE_URL=postgresql://{{ lookup('database', application_id, 'username') }}:{{ lookup('database', application_id, 'password') }}@{{ lookup('database', application_id, 'host') }}:{{ lookup('database', application_id, 'port') }}/{{ lookup('database', application_id, 'name') }}?sslmode=disable
JWT_SECRET={{ (application_id ~ lookup('users', 'administrator').password) | hash('sha256') }}
@@ -85,6 +85,16 @@ class TestTlsResolveLookup(unittest.TestCase):
)[0]
self.assertEqual(val, "https://a.example/")
def test_url_origin_is_the_base_url_without_its_trailing_slash(self):
origin, base = (
self.lookup.run(["web-app-a", want], variables=self.base_vars, mode="app")[
0
]
for want in ("url.origin", "url.base")
)
self.assertEqual(origin, "https://a.example")
self.assertEqual(f"{origin}/", base)
def test_protocols_web_path_is_http_for_an_onion_only_app(self):
onion = dict(self.base_vars)
onion["domains"] = {**self.domains, "web-app-onion": "abc123.onion"}