feat: silent OIDC auth with JWT Bearer tokens for web
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 3m0s

- Add prompt=none to silently obtain JWT when Authentik session exists
- Flutter sends Bearer token to core-api instead of forward auth cookies
- Fixes cross-subdomain cookie issues between home/api.schweitz.net
- Callback syncs with /auth/sync for user profile and roles
- API interceptor now adds Bearer token on web

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jeroen Schweitzer
2026-01-04 16:11:07 +01:00
co-authored by Claude Opus 4.5
parent f0b32ff68b
commit 3fa97bb0b0
6 changed files with 91 additions and 73 deletions
+9 -10
View File
@@ -46,14 +46,7 @@ class _AppScaffoldState extends ConsumerState<AppScaffold> {
return _buildScaffold(context);
}
// On web, NPM forward auth handles authentication at the proxy level.
// If we reach this point, the user is already authenticated by NPM.
// No need for Flutter's OIDC flow - just show the app.
if (kIsWeb) {
return _buildScaffold(context);
}
// Mobile: Use Flutter's OIDC flow
// Watch auth state (works for both web and mobile)
final authAsync = ref.watch(authProvider);
return authAsync.when(
@@ -64,7 +57,13 @@ class _AppScaffoldState extends ConsumerState<AppScaffold> {
return _buildScaffold(context);
}
// Not authenticated - auto-initiate OIDC
// On web, NPM handles auth - if we're here without auth, something is wrong
// (NPM should have redirected to Authentik before we loaded)
if (kIsWeb) {
return _buildAuthErrorScreen(context, 'Authentication required');
}
// Mobile: Not authenticated - auto-initiate OIDC
if (!_authInitiated) {
_authInitiated = true;
WidgetsBinding.instance.addPostFrameCallback((_) {
@@ -75,7 +74,7 @@ class _AppScaffoldState extends ConsumerState<AppScaffold> {
// Show loading while redirecting to Authentik
return _buildAuthLoadingScreen(context, 'Redirecting to sign in...');
},
loading: () => _buildAuthLoadingScreen(context, 'Checking authentication...'),
loading: () => _buildAuthLoadingScreen(context, 'Loading user info...'),
error: (error, _) => _buildAuthErrorScreen(context, error),
);
}