FlowFuse / FlowFuse/node-red-dashboard
Infinite loop when express-openid-connect middleware is used
- Dominant language
- HTML
- Stars
- 355
- Forks
- 82
- Avg merge
- 4d 23h
- Merged PRs (30d)
- 24
Description
### Current Behavior
When a custom middleware based on "express-openid-connect" is used during the time of the first session everything operates normally but once it expires and new one needs to be established an infinite loop is created. This is because "callback" route critical for this middleware is served by PWA's service worker from its cache instead of the middleware itself which needs to return a session in form of a cookie. A simple solution for this particular case is provided by below patch, more generic one could consist of configuration variable for excluded routes for example.
```diff
--- a/ui/src/sw.js
+++ b/ui/src/sw.js
@@ -22,6 +22,8 @@ if (import.meta.env.DEV) {
// this permits the request to be handled by the server which will do a redirect as required
const configPath = self.location.pathname.split('/')[1]
denylist.push(new RegExp(`/${configPath}/[^?]*/(\\?.*)*$`))
+ // don't precache the callback route which is handled by express-openid-connect middleware
+ denylist.push(new RegExp(`/${configPath}/callback\\?`))
}
// to allow work offline for allowed routes only
```
### Expected Behavior
_No response_
### Steps To Reproduce
1. Configure custom OIDC middleware in settings.js, example configuration used with Hashicorp Vault:
```javascript
dashboard: {
middleware: (req, res, next) => {
const issuerBaseURL = "";
const baseURL = "";
const clientID = "";
const clientSecret = "";
const secret = "";
const group ="";
// Workaround for double middleware call bug
if (req.hasOwnProperty("oidc") && req.oidc.isAuthenticated()) return next();
const { auth } = require("express-openid-connect");
const jose = require("jose");
const oidcAuth = auth({
issuerBaseURL: issuerBaseURL,
baseURL: baseURL,
clientID: clientID,
clientSecret: clientSecret,
secret: secret,
authorizationParams: {
response_type: "code",
scope: "openid security"
},
afterCallback: async (request, response, session) => {
const claims = jose.JWT.decode(session.id_token);
if (!(claims.hasOwnProperty("groups") && claims.groups.includes(group)))
return response.sendStatus(401);
return session;
}
});
oidcAuth(req, res, next);
}
}
```
2. Logon to the dashboard
3. Close browser tab and delete "appSession" cookie to simulate expired session
4. Try to logon to the dashboard again
### Environment
- Dashboard version: 1.24.2
- Node-RED version: 4.0.9
- Node.js version: 20.19.0
- npm version:
- Platform/OS: Linux 6.1.0-34-armmp arm LE
- Browser: Edge/Firefox
### Have you provided an initial effort estimate for this issue?
I am not a FlowFuse team member
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.