refactor(auth): clean up login and logout logic
Some checks failed
CI / Get Changed Files (pull_request) Successful in 7s
CI / eslint (pull_request) Successful in 25s
CI / test-build (pull_request) Successful in 32s
CI / prettier (pull_request) Failing after 59s
CI / Checkstyle Main (pull_request) Successful in 1m29s

This commit is contained in:
Jan K9f 2025-04-02 16:33:28 +02:00
parent 9de08ab233
commit 0e1946d190
Signed by: jank
GPG key ID: B9F475106B20F144
2 changed files with 19 additions and 19 deletions

View file

@ -17,13 +17,7 @@ export default class LoginSuccessComponent implements OnInit {
private router: Router = inject(Router); private router: Router = inject(Router);
async ngOnInit() { async ngOnInit() {
try { try {
// Handle code flow without throwing errors
const success = await this.oauthService.loadDiscoveryDocumentAndTryLogin();
// If we have a valid access token, the user should be loaded in AuthService
const user = this.authService.getUser();
// Check if we're authenticated // Check if we're authenticated
if (this.oauthService.hasValidAccessToken()) { if (this.oauthService.hasValidAccessToken()) {

View file

@ -4,7 +4,7 @@ import { UserService } from './user.service';
import { User } from '../model/User'; import { User } from '../model/User';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { environment } from '../../environments/environment'; import { environment } from '../../environments/environment';
import { catchError, from, of, tap } from 'rxjs'; import { catchError, from, of } from 'rxjs';
@Injectable({ @Injectable({
providedIn: 'root', providedIn: 'root',
@ -17,6 +17,10 @@ export class AuthService {
scope: `openid email profile ${environment.OAUTH_CLIENT_ID}`, scope: `openid email profile ${environment.OAUTH_CLIENT_ID}`,
responseType: 'code', responseType: 'code',
redirectUri: window.location.origin + '/auth/callback', redirectUri: window.location.origin + '/auth/callback',
// Important - use empty post logout redirect URI to prevent auto-redirect
postLogoutRedirectUri: '',
// Don't use redirect URI as fallback for post logout
redirectUriAsPostLogoutRedirectUriFallback: false,
oidc: true, oidc: true,
requestAccessToken: true, requestAccessToken: true,
// Explicitly set token endpoint since discovery is failing // Explicitly set token endpoint since discovery is failing
@ -60,7 +64,7 @@ export class AuthService {
// Try to exchange the authorization code for tokens // Try to exchange the authorization code for tokens
this.oauthService this.oauthService
.tryLogin({ .tryLogin({
onTokenReceived: (context) => { onTokenReceived: () => {
// Manually create a token_received event // Manually create a token_received event
this.handleSuccessfulLogin(); this.handleSuccessfulLogin();
}, },
@ -75,7 +79,6 @@ export class AuthService {
this.oauthService this.oauthService
.loadDiscoveryDocumentAndTryLogin() .loadDiscoveryDocumentAndTryLogin()
.then((isLoggedIn) => { .then((isLoggedIn) => {
if (isLoggedIn && !this.user) { if (isLoggedIn && !this.user) {
this.handleSuccessfulLogin(); this.handleSuccessfulLogin();
} }
@ -87,16 +90,13 @@ export class AuthService {
private setupEventHandling() { private setupEventHandling() {
this.oauthService.events.subscribe((event: OAuthEvent) => { this.oauthService.events.subscribe((event: OAuthEvent) => {
if (event.type === 'token_received') { if (event.type === 'token_received') {
this.handleSuccessfulLogin(); this.handleSuccessfulLogin();
} else if (event.type === 'token_refresh_error' || event.type === 'token_expires') {
} }
}); });
} }
private handleSuccessfulLogin() { private handleSuccessfulLogin() {
// Extract claims from id token if available // Extract claims from id token if available
const claims = this.oauthService.getIdentityClaims(); const claims = this.oauthService.getIdentityClaims();
@ -110,7 +110,6 @@ export class AuthService {
try { try {
from(this.oauthService.loadUserProfile()) from(this.oauthService.loadUserProfile())
.pipe( .pipe(
tap((profile) => {}),
catchError((error) => { catchError((error) => {
console.error('Error loading user profile:', error); console.error('Error loading user profile:', error);
// If we can't load the profile but have a token, create a minimal profile // If we can't load the profile but have a token, create a minimal profile
@ -192,8 +191,15 @@ export class AuthService {
// Prevent redirect to Authentik by doing a local logout only // Prevent redirect to Authentik by doing a local logout only
// Instead of using oauthService.logOut() which redirects to the provider // Instead of using oauthService.logOut() which redirects to the provider
// Clear tokens from storage // Clear tokens from storage without redirecting
this.oauthService.logOut(false); // logOut(false) prevents redirect // The parameter noRedirectToLogoutUrl=true prevents redirect to the identity provider
this.oauthService.logOut(true); // true means: don't redirect to Authentik logout page
// Override any post-logout redirect URI that might be configured
if (window.location.href.includes('id_token') || window.location.href.includes('logout')) {
// If we somehow ended up at a logout URL, redirect back to the app
window.location.href = window.location.origin;
}
// Clear any lingering tokens manually // Clear any lingering tokens manually
localStorage.removeItem('access_token'); localStorage.removeItem('access_token');