refactor(user): clean up comments and rename variables
All checks were successful
All checks were successful
This commit is contained in:
parent
25c68e230d
commit
02453449cd
5 changed files with 4 additions and 41 deletions
|
@ -19,7 +19,7 @@ public class UserEntity {
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
private Long id;
|
private Long id;
|
||||||
@Column(unique = true)
|
@Column(unique = true)
|
||||||
private String authentikId; // Changed from keycloakId to authentikId
|
private String authentikId;
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
@Column(precision = 19, scale = 2)
|
@Column(precision = 19, scale = 2)
|
||||||
|
|
|
@ -10,8 +10,6 @@ import lombok.Setter;
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
public class KeycloakUserDto {
|
public class KeycloakUserDto {
|
||||||
// Renamed class but kept for backward compatibility
|
|
||||||
// This now contains Authentik user info
|
|
||||||
private String sub;
|
private String sub;
|
||||||
private String preferred_username;
|
private String preferred_username;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,11 +18,9 @@ export default class LoginSuccessComponent implements OnInit {
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
try {
|
try {
|
||||||
// Check if we're authenticated
|
|
||||||
if (this.oauthService.hasValidAccessToken()) {
|
if (this.oauthService.hasValidAccessToken()) {
|
||||||
this.router.navigate(['/home']);
|
this.router.navigate(['/home']);
|
||||||
} else {
|
} else {
|
||||||
// Wait a bit and check if we've been authenticated in the meantime
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.oauthService.hasValidAccessToken() || this.authService.getUser()) {
|
if (this.oauthService.hasValidAccessToken() || this.authService.getUser()) {
|
||||||
this.router.navigate(['/home']);
|
this.router.navigate(['/home']);
|
||||||
|
@ -33,7 +31,6 @@ export default class LoginSuccessComponent implements OnInit {
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error during login callback:', err);
|
console.error('Error during login callback:', err);
|
||||||
// Wait a bit in case token processing is happening elsewhere
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (this.authService.isLoggedIn()) {
|
if (this.authService.isLoggedIn()) {
|
||||||
this.router.navigate(['/home']);
|
this.router.navigate(['/home']);
|
||||||
|
|
|
@ -17,16 +17,12 @@ 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: '',
|
postLogoutRedirectUri: '',
|
||||||
// Don't use redirect URI as fallback for post logout
|
|
||||||
redirectUriAsPostLogoutRedirectUriFallback: false,
|
redirectUriAsPostLogoutRedirectUriFallback: false,
|
||||||
oidc: true,
|
oidc: true,
|
||||||
requestAccessToken: true,
|
requestAccessToken: true,
|
||||||
// Explicitly set token endpoint since discovery is failing
|
|
||||||
tokenEndpoint: 'https://oauth.simonis.lol/application/o/token/',
|
tokenEndpoint: 'https://oauth.simonis.lol/application/o/token/',
|
||||||
userinfoEndpoint: 'https://oauth.simonis.lol/application/o/userinfo/',
|
userinfoEndpoint: 'https://oauth.simonis.lol/application/o/userinfo/',
|
||||||
// Loosen validation since Authentik might not fully conform to the spec
|
|
||||||
strictDiscoveryDocumentValidation: false,
|
strictDiscoveryDocumentValidation: false,
|
||||||
skipIssuerCheck: true,
|
skipIssuerCheck: true,
|
||||||
disableAtHashCheck: true,
|
disableAtHashCheck: true,
|
||||||
|
@ -45,27 +41,22 @@ export class AuthService {
|
||||||
this.oauthService.configure(this.authConfig);
|
this.oauthService.configure(this.authConfig);
|
||||||
this.setupEventHandling();
|
this.setupEventHandling();
|
||||||
|
|
||||||
// Check if we're on the callback page
|
|
||||||
const hasAuthParams =
|
const hasAuthParams =
|
||||||
window.location.search.includes('code=') ||
|
window.location.search.includes('code=') ||
|
||||||
window.location.search.includes('token=') ||
|
window.location.search.includes('token=') ||
|
||||||
window.location.search.includes('id_token=');
|
window.location.search.includes('id_token=');
|
||||||
|
|
||||||
if (hasAuthParams) {
|
if (hasAuthParams) {
|
||||||
// We're in the OAuth callback
|
|
||||||
this.processCodeFlow();
|
this.processCodeFlow();
|
||||||
} else {
|
} else {
|
||||||
// Normal app startup
|
|
||||||
this.checkExistingSession();
|
this.checkExistingSession();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private processCodeFlow() {
|
private processCodeFlow() {
|
||||||
// Try to exchange the authorization code for tokens
|
|
||||||
this.oauthService
|
this.oauthService
|
||||||
.tryLogin({
|
.tryLogin({
|
||||||
onTokenReceived: () => {
|
onTokenReceived: () => {
|
||||||
// Manually create a token_received event
|
|
||||||
this.handleSuccessfulLogin();
|
this.handleSuccessfulLogin();
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -75,7 +66,6 @@ export class AuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private checkExistingSession() {
|
private checkExistingSession() {
|
||||||
// Try login on startup
|
|
||||||
this.oauthService
|
this.oauthService
|
||||||
.loadDiscoveryDocumentAndTryLogin()
|
.loadDiscoveryDocumentAndTryLogin()
|
||||||
.then((isLoggedIn) => {
|
.then((isLoggedIn) => {
|
||||||
|
@ -97,25 +87,20 @@ export class AuthService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private handleSuccessfulLogin() {
|
private handleSuccessfulLogin() {
|
||||||
// Extract claims from id token if available
|
|
||||||
const claims = this.oauthService.getIdentityClaims();
|
const claims = this.oauthService.getIdentityClaims();
|
||||||
|
|
||||||
// If we have claims, use that as profile
|
|
||||||
if (claims && (claims['sub'] || claims['email'])) {
|
if (claims && (claims['sub'] || claims['email'])) {
|
||||||
this.processUserProfile(claims);
|
this.processUserProfile(claims);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise try to load user profile
|
|
||||||
try {
|
try {
|
||||||
from(this.oauthService.loadUserProfile())
|
from(this.oauthService.loadUserProfile())
|
||||||
.pipe(
|
.pipe(
|
||||||
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 (this.oauthService.hasValidAccessToken()) {
|
if (this.oauthService.hasValidAccessToken()) {
|
||||||
this.oauthService.getAccessToken(); // Get token but don't use it directly
|
this.oauthService.getAccessToken();
|
||||||
// Create a basic profile from the token
|
|
||||||
const minimalProfile = {
|
const minimalProfile = {
|
||||||
sub: 'user-' + Math.random().toString(36).substring(2, 10),
|
sub: 'user-' + Math.random().toString(36).substring(2, 10),
|
||||||
preferred_username: 'user' + Date.now(),
|
preferred_username: 'user' + Date.now(),
|
||||||
|
@ -134,7 +119,6 @@ export class AuthService {
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Exception in handleSuccessfulLogin:', err);
|
console.error('Exception in handleSuccessfulLogin:', err);
|
||||||
// Try to navigate to home if we have a token anyway
|
|
||||||
if (this.oauthService.hasValidAccessToken()) {
|
if (this.oauthService.hasValidAccessToken()) {
|
||||||
this.router.navigate(['/home']);
|
this.router.navigate(['/home']);
|
||||||
} else {
|
} else {
|
||||||
|
@ -151,7 +135,6 @@ export class AuthService {
|
||||||
},
|
},
|
||||||
error: (err) => {
|
error: (err) => {
|
||||||
console.error('Error creating/retrieving user:', err);
|
console.error('Error creating/retrieving user:', err);
|
||||||
// Navigate to home if we have a token anyway - the backend will need to handle auth
|
|
||||||
if (this.oauthService.hasValidAccessToken()) {
|
if (this.oauthService.hasValidAccessToken()) {
|
||||||
this.router.navigate(['/home']);
|
this.router.navigate(['/home']);
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,7 +146,6 @@ export class AuthService {
|
||||||
|
|
||||||
login() {
|
login() {
|
||||||
try {
|
try {
|
||||||
// First ensure discovery document is loaded
|
|
||||||
this.oauthService
|
this.oauthService
|
||||||
.loadDiscoveryDocument()
|
.loadDiscoveryDocument()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -171,12 +153,10 @@ export class AuthService {
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error('Error loading discovery document:', err);
|
console.error('Error loading discovery document:', err);
|
||||||
// Try login anyway with configured endpoints
|
|
||||||
this.oauthService.initLoginFlow();
|
this.oauthService.initLoginFlow();
|
||||||
});
|
});
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Exception in login:', err);
|
console.error('Exception in login:', err);
|
||||||
// Try direct login as a fallback
|
|
||||||
const redirectUri = this.authConfig.redirectUri || window.location.origin + '/auth/callback';
|
const redirectUri = this.authConfig.redirectUri || window.location.origin + '/auth/callback';
|
||||||
const scope = this.authConfig.scope || 'openid email profile';
|
const scope = this.authConfig.scope || 'openid email profile';
|
||||||
const authUrl = `${this.authConfig.issuer}authorize?client_id=${this.authConfig.clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${encodeURIComponent(scope)}`;
|
const authUrl = `${this.authConfig.issuer}authorize?client_id=${this.authConfig.clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&response_type=code&scope=${encodeURIComponent(scope)}`;
|
||||||
|
@ -188,20 +168,12 @@ export class AuthService {
|
||||||
try {
|
try {
|
||||||
this.user = null;
|
this.user = null;
|
||||||
|
|
||||||
// Prevent redirect to Authentik by doing a local logout only
|
this.oauthService.logOut(true);
|
||||||
// Instead of using oauthService.logOut() which redirects to the provider
|
|
||||||
|
|
||||||
// Clear tokens from storage without redirecting
|
|
||||||
// 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 (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;
|
window.location.href = window.location.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear any lingering tokens manually
|
|
||||||
localStorage.removeItem('access_token');
|
localStorage.removeItem('access_token');
|
||||||
localStorage.removeItem('id_token');
|
localStorage.removeItem('id_token');
|
||||||
localStorage.removeItem('refresh_token');
|
localStorage.removeItem('refresh_token');
|
||||||
|
@ -209,12 +181,10 @@ export class AuthService {
|
||||||
sessionStorage.removeItem('id_token');
|
sessionStorage.removeItem('id_token');
|
||||||
sessionStorage.removeItem('refresh_token');
|
sessionStorage.removeItem('refresh_token');
|
||||||
|
|
||||||
// Navigate to landing page
|
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Exception in logout:', err);
|
console.error('Exception in logout:', err);
|
||||||
// Force clear tokens locally
|
localStorage.clear();
|
||||||
localStorage.clear(); // Clear all local storage as a last resort
|
|
||||||
sessionStorage.clear();
|
sessionStorage.clear();
|
||||||
this.router.navigate(['/']);
|
this.router.navigate(['/']);
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,8 +43,6 @@ export class UserService {
|
||||||
}
|
}
|
||||||
|
|
||||||
public getOrCreateUser(profile: Record<string, unknown>): Observable<User> {
|
public getOrCreateUser(profile: Record<string, unknown>): Observable<User> {
|
||||||
// Authentik format might differ from Keycloak
|
|
||||||
// Check different possible locations for the ID and username
|
|
||||||
const info = profile['info'] as Record<string, unknown> | undefined;
|
const info = profile['info'] as Record<string, unknown> | undefined;
|
||||||
const id = (info?.['sub'] as string) || (profile['sub'] as string);
|
const id = (info?.['sub'] as string) || (profile['sub'] as string);
|
||||||
const username =
|
const username =
|
||||||
|
|
Reference in a new issue