Closed ajacques closed 7 months ago
Looks like this regressed in a recent release I'm running. 9.9.1 and I'm getting this when it should be redirecting.
@Daniel-dev22 nothing changed on code to cause that AFAIK
@Daniel-dev22 nothing changed on code to cause that AFAIK
This is the only webapp giving me trouble.
I know this was a follow-up to the original pr that fixed this? Not sure if this matters or if anything else could have changed to cause such an error.
https://github.com/zwave-js/zwave-js-ui/commit/366b8dcb056fee10c1d32e9311a8161047f1fe10
@Daniel-dev22 could you try to test the commit before that to see if that is working? If so we should find a way to make both work...
@Daniel-dev22 could you try to test the commit before that to see if that is working? If so we should find a way to make both work...
Hm I tried 9.8.0 and cleared cookies + cache and tried a different browser I never used with zwave js UI to avoid any cache issues and I get the same error which is odd.
It only works if cookies are cleared and I sign in with authelia but once it's time to re-authenticate it fails which is when it needs to be redirected similar to what was happening before the fix was found.
I didn't upgrade authelia either. It's still the same version as before.
Hm I tried 9.8.0 and cleared cookies + cache and tried a different browser I never used with zwave js UI to avoid any cache issues and I get the same error which is odd.
That is odd yeah because I just checked and 9.8.0 version is the right before that commit so I don't think that's the root cause.
@ajacques Is it still working for you?
Hm I tried 9.8.0 and cleared cookies + cache and tried a different browser I never used with zwave js UI to avoid any cache issues and I get the same error which is odd.
That is odd yeah because I just checked and 9.8.0 version is the right before that commit so I don't think that's the root cause.
@ajacques Is it still working for you?
I checked the console and I see
SyntaxError: Unexpected token '<', \"<a href=\"h\"... is not valid JSON
Initially when I loaded the page I saw CORS errors for fetching icons not sure if that's even related as I never touched cors in traefik since we last determined this was working.
Access to font at 'https://authelia.nuc.domain.net/?rd=https%3A%2F%2Fzwave.domain.net%2Fassets%2FMaterialIcons-Regular-5743ed3d.woff2&rm=GET' (redirected from 'https://zwave.domain.net/assets/MaterialIcons-Regular-5743ed3d.woff2') from origin 'https://zwave.domain.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to font at 'https://authelia.nuc.domain.net/?rd=https%3A%2F%2Fzwave.domain.net%2Fassets%2FMaterialIcons-Regular-11ec382a.woff&rm=GET' (redirected from 'https://zwave.domain.net/assets/MaterialIcons-Regular-11ec382a.woff') from origin 'https://zwave.domain.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to font at 'https://authelia.nuc.domain.net/?rd=https%3A%2F%2Fzwave.domain.net%2Fassets%2FMaterialIcons-Regular-29c11fa5.ttf&rm=GET' (redirected from 'https://zwave.domain.net/assets/MaterialIcons-Regular-29c11fa5.ttf') from origin 'https://zwave.domain.net' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
@Daniel-dev22 CORS are enabled on my end because otherwise it wouldn't work even for me when developing, you should check if your proxy actually is blocking cors for some reason?
@Daniel-dev22 CORS are enabled on my end because otherwise it wouldn't work even for me when developing, you should check if your proxy actually is blocking cors for some reason?
Yeah in traefik I only allow using this parameter accesscontrolalloworiginlist
for traefik.domain.net, authelia.domain.net and domain.net
https://doc.traefik.io/traefik/middlewares/http/headers/#accesscontrolalloworiginlist
Shouldn't you allow also zwave.domain.net?
Shouldn't you allow also zwave.domain.net?
I wasn't sure if all app sub domains should be added to that list or it should strictly be authentication/root domain on the list.
I just upgraded to 9.9.1 and the login redirect does not appear to be working correctly. It looks like it tried to follow the redirect which means the max redirect limit wasn't hit. I will have to investigate further in the next few days. CORS is not the fix for this. The JS needs to see the redirect and use that to trigger a full frame redirect. Enabling CORS means that the browser followed the redirect and is going to get an unparseable response payload.
Yeah in traefik I only allow using this parameter accesscontrolalloworiginlist for traefik.domain.net, authelia.domain.net and domain.net
FYI, the CORS list is the source origin, not the destination origin. So if you wanted CORS to work, the list would include zwave.domain.net. CORS may work in some cases but not all.
Plot twist. It is working for me on 9.9.1 correctly. I think the JS was cached from an older version in the service worker cache on the computer I tested on. @Daniel-dev22, if you're saying it's not working, you should be able to hard refresh and get it to login, then does the version in the top right show 9.9.1 or something modern?
It could be the service worker failed to refresh the cache for some reason related to the proxy maybe...
I suppose it is possible that the SW tried to fetch the latest version, then failed because the auth proxy rejected it, but in the above case Daniel-dev22 suggested that it used to work for them, then stopped. In theory, they should have had a version cached. I could see how that could cause my problem if I have a pre-9.8.x cached version, but not post-9.x.x cached JS in the SW cache (which had the new auth check.)
However, that gives me an idea. I'm going to remove /manifest.webmanifest
and /assets/*
from the Auth proxy and then try to test the next upgrade and see what happens. That should enable the service worker to be able to fetch the latest assets at any point... Though I don't think this is going to work since the /index.html
is what actually defines what version of the JS bundle is provided.
I suppose it is possible that the SW tried to fetch the latest version, then failed because the auth proxy rejected it, but in the above case Daniel-dev22 suggested that it used to work for them, then stopped. In theory, they should have had a version cached. I could see how that could cause my problem if I have a pre-9.8.x cached version, but not post-9.x.x cached JS in the SW cache (which had the new auth check.)
However, that gives me an idea. I'm going to remove
/manifest.webmanifest
and/assets/*
from the Auth proxy and then try to test the next upgrade and see what happens. That should enable the service worker to be able to fetch the latest assets at any point... Though I don't think this is going to work since the/index.html
is what actually defines what version of the JS bundle is provided.
@ajacques were you able to test your theories?
Unfortunately, I haven't been able to reproduce the issue since then. I do have /sw.js
and /assets/*
permitted to bypass the auth check and have been able to go through some upgrades without issues and I think this should be enough. But I haven't confirmed that this fixes it with a negative check (i.e. it doesn't work before making this change.) Testing is slow because I'm running out of releases to test on.
👋 I just wanted to chime in and say thanks a bunch to @robertsLando and @ajacques! My setup is Caddy + Auhentik and things seem to work with no errors in network panel after I delete cookies + hard refresh. I didn't test with a stale Authentik session, though.
Here's my config for anyone who drops in:
zwave.mydomain {
reverse_proxy /outpost.goauthentik.io/* http://authentik-server.idp.svc.cluster.local
forward_auth http://authentik-server.idp.svc.cluster.local {
uri /outpost.goauthentik.io/auth/caddy
copy_headers X-Authentik-Username X-Authentik-Groups X-Authentik-Email X-Authentik-Name X-Authentik-Uid X-Authentik-Jwt X-Authentik-Meta-Jwks X-Authentik-Meta-Outpost X-Authentik-Meta-Provider X-Authentik-Meta-App X-Authentik-Meta-Version
trusted_proxies private_ranges
}
reverse_proxy http://zwave.home.svc.cluster.local
}
resource "authentik_provider_proxy" "zwave" {
name = "zwave"
external_host = "https://zwave.mydomain"
mode = "forward_single"
access_token_validity = "days=3"
skip_path_regex = "^/manifest.webmanifest$"
authorization_flow = data.authentik_flow.default-authorization-flow.id
authentication_flow = data.authentik_flow.default-authentication-flow.id
}
resource "authentik_application" "zwave" {
name = "zwave"
slug = "zwave"
meta_icon = "https://zwave-js.github.io/zwave-js-ui/_images/app_logo.svg"
protocol_provider = authentik_provider_proxy.zwave.id
}
resource "authentik_policy_binding" "zwave-access" {
for_each = { 0 : data.authentik_user.sushain }
target = authentik_application.zwave.uuid
user = each.value.pk
order = 0
}
The only interesting bit is really skip_path_regex = "^/manifest.webmanifest$"
which I added after requests there 302'd to Authentik and then failed with CORS errors.
Could someone of you guys confirm me if #3825 could break your setup?
Could someone of you guys confirm me if #3825 could break your setup?
Is there a test build we can run for that pr?
Unfortunately nope as it's on a fork, but I can merge it and then you can use master
to check.
LGTM from an external auth provider perspective.
Thanks for your feedback @ajacques ! :)
Works for me as well!
@Daniel-dev22 🙏🏼
Can reproduce with Traefik and basic auth as well.
Checklist
Deploy method
Docker
Z-Wave JS UI version
9.3.2
ZwaveJS version
12.3.0
Describe the bug
I'm using an external auth provider (nginx + vouch proxy) to protect all of my services with one SSO solution. I choose to do this instead of having separate username and passwords for different services. Effectively how it works is it checks for a cookie on all requests to ZWaveJS and redirects the browser to the login page.
The problem is that ZWaveJS now appears to use a service worker and works as a PWA (I suspect this came in with this commit d409051b9e96939fa0510399e45693b331a34cf1) which intercepts the call to
/
and causes this to fail. When the authorization expires, I have to hard refresh the page to load it.What happens is the
/
page loads from the Service worker, then theGET /api/auth-enabled
call gets a 302 Found to redirect to the login page, the app doesn't know what to do and fails to load the app. The/
request does not hit the backend app (I've checked my logs), so it can't know that/
is failing. The only way to bypass this is to hard refresh the page, but that's not easy on mobile phones.To Reproduce
GET /
and the app will work until the auth token expires.Expected behavior
I expect the ZWaveJS application to be able to handle when there's a separate auth provider and redirect to the login page. ZWaveJS does not have to specifically have to support these providers, just handle the redirects.
I see two options here:
GET /
request, it revalidates with the service to see if the response includes a redirect or not. This can also be used to refresh the cache in the service worker. (basically cache-bust the/
call because the app can't work without internet anyway)GET /api/auth-enabled
, it follows the redirect in a full frame redirect (i.e. browser tab navigates to the new page.) This appears to be the first request that actually gets forwarded to the server so would have to be the first point the app knows there's external auth.It seems like the service worker comes from Vite, which possibly internalizes the cache handling logic. I'm unfamiliar with what knobs it has to know whether 1 would work, but 2 should be doable in the app side. I tried changing the
Cache-Control
onGET /
to bemust-revalidate
, but the service worker does not respect itAdditional context
No response