fix(node-player): add offline_access scope and server-side token refresh
Publish Metadata Agent Image (dev) / build-and-push-image (push) Has been cancelled
Publish Node Player Image (dev) / build-and-push-image (push) Successful in 36s
Publish Web Player Image (dev) / build-and-push-image (push) Successful in 1m50s

- Add offline_access to OIDC scope so Authentik issues a refresh token
- /auth/token now checks if access token is expired and refreshes it
  server-side before returning to the client

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ultradesu
2026-04-08 16:01:16 +01:00
parent 7bc7de44cf
commit 1ea5f66ea3
+17 -7
View File
@@ -24,7 +24,7 @@ const oidcConfig = {
clientSecret: process.env.OIDC_CLIENT_SECRET ?? '', clientSecret: process.env.OIDC_CLIENT_SECRET ?? '',
authorizationParams: { authorizationParams: {
response_type: 'code', response_type: 'code',
scope: process.env.OIDC_SCOPE ?? 'openid profile email', scope: process.env.OIDC_SCOPE ?? 'openid profile email offline_access',
}, },
}; };
@@ -74,7 +74,7 @@ app.get('/auth/me', (req, res) => {
}); });
}); });
app.get('/auth/token', (req, res) => { app.get('/auth/token', async (req, res) => {
if (disableAuth) { if (disableAuth) {
res.status(204).end(); res.status(204).end();
return; return;
@@ -85,17 +85,27 @@ app.get('/auth/token', (req, res) => {
return; return;
} }
const accessToken = req.oidc.accessToken?.access_token; let accessToken = req.oidc.accessToken;
const expiresAt = req.oidc.accessToken?.expires_in; if (!accessToken?.access_token) {
if (!accessToken) {
res.status(500).json({ error: 'no access token in session' }); res.status(500).json({ error: 'no access token in session' });
return; return;
} }
// Refresh if expired
if (accessToken.isExpired()) {
try {
accessToken = await accessToken.refresh();
} catch (e) {
console.error('Token refresh failed:', e);
res.status(401).json({ error: 'token refresh failed' });
return;
}
}
res.json({ res.json({
access_token: accessToken, access_token: accessToken.access_token,
token_type: 'Bearer', token_type: 'Bearer',
expires_in: expiresAt, expires_in: accessToken.expires_in,
}); });
}); });