| import { Injectable } from '@angular/core'; |
| import { HttpClient } from '@angular/common/http'; |
| import { BehaviorSubject, Observable, of, throwError } from 'rxjs'; |
| import { tap, catchError } from 'rxjs/operators'; |
| import { Router } from '@angular/router'; |
|
|
|
|
|
|
| @Injectable({ |
| providedIn: 'root' |
| }) |
|
|
| export class AuthService { |
| private apiUrl = location.hostname.endsWith('hf.space') |
| ? 'https://pykara-py-learn-backend.hf.space' |
| : 'http://localhost:5000'; |
| private loggedInSubject = new BehaviorSubject<boolean>(false); |
| public isLoggedIn$ = this.loggedInSubject.asObservable(); |
| private refreshIntervalId: any; |
| constructor(private http: HttpClient, private router: Router) { } |
|
|
| |
| isLoggedIn(): boolean { |
| return this.loggedInSubject.value; |
| } |
|
|
| |
| setLoggedIn(status: boolean): void { |
| this.loggedInSubject.next(status); |
| } |
| |
|
|
|
|
| login(username: string, password: string): Observable<any> { |
| return this.http.post(`${this.apiUrl}/login`, { username, password }, { withCredentials: true }); |
| } |
|
|
|
|
| startAutoRefresh(): void { |
| if (this.refreshIntervalId) return; |
| this.refreshIntervalId = setInterval(() => { |
| this.refreshAccessToken(); |
| }, 12 * 60 * 1000); |
| } |
|
|
| clearAutoRefresh(): void { |
| clearInterval(this.refreshIntervalId); |
| this.refreshIntervalId = null; |
| } |
|
|
| refreshAccessToken(): void { |
| this.http.post(`${this.apiUrl}/refresh`, {}, { withCredentials: true }).subscribe( |
| (response: any) => { |
| console.log("β
Access token refreshed:", response.access_token); |
| |
| }, |
| (error) => { |
| console.error("β Refresh failed:", error); |
|
|
| if ( |
| error.status === 401 && |
| error.error && |
| (error.error.message === 'Refresh token has expired' || error.error.message === 'Invalid refresh token') |
| ) { |
| |
|
|
| |
| this.clearTokens(); |
|
|
| |
| this.router.navigate(['/auth']); |
| } |
| } |
| ); |
| } |
|
|
|
|
| |
|
|
| logout(): Observable<any> { |
| console.log("π§ Sending logout request with credentials"); |
|
|
| return this.http.post(`${this.apiUrl}/logout`, {}, { withCredentials: true }).pipe( |
| tap(response => { |
| console.log('π Response from backend:', response); |
| this.clearTokens(); |
| this.clearAutoRefresh(); |
| }), |
| catchError(error => { |
| console.error('β Error from backend:', error); |
| return throwError(() => error); |
| }) |
| ); |
| } |
|
|
|
|
|
|
| |
|
|
|
|
|
|
| clearTokens(): void { |
| document.cookie = 'access_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; |
| document.cookie = 'refresh_token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;'; |
| this.clearAutoRefresh(); |
| } |
|
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| |
| getAccessToken(): string | null { |
| const cookies = document.cookie.split('; '); |
| for (let cookie of cookies) { |
| if (cookie.startsWith('access_token=')) { |
| return cookie.split('=')[1]; |
| } |
| } |
| return null; |
| } |
|
|
| |
| saveTokens(accessToken: string, refreshToken: string): void { |
| |
| localStorage.setItem('access_token', accessToken); |
| localStorage.setItem('refresh_token', refreshToken); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| checkSession(): Observable<boolean> { |
| return this.http.get(`${this.apiUrl}/check-auth`, { withCredentials: true }).pipe( |
| tap((res: any) => { |
| console.log('β
Session valid:', res); |
| this.setLoggedIn(true); |
| this.startAutoRefresh(); |
| return true; |
| }), |
| catchError((err) => { |
| if (err.status === 401) { |
| |
| console.warn('π Access token expired. Trying to refresh...'); |
|
|
| return this.http.post(`${this.apiUrl}/refresh`, {}, { withCredentials: true }).pipe( |
| tap((refreshRes: any) => { |
| console.log("β
Token refreshed during checkSession."); |
| |
| this.setLoggedIn(true); |
| this.startAutoRefresh(); |
| }), |
| catchError((refreshErr) => { |
| console.error("β Refresh token failed during checkSession.", refreshErr); |
| this.setLoggedIn(false); |
| return of(false); |
| }) |
| ); |
| } else { |
| console.error("β Unknown error during checkSession", err); |
| this.setLoggedIn(false); |
| return of(false); |
| } |
| }) |
| ); |
| } |
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
|
| } |
|
|