perbaikan master dan ngecek token jika ada kegiatan

This commit is contained in:
2024-07-16 11:39:44 +07:00
parent 751c36209e
commit dd1deb0812
10 changed files with 501 additions and 240 deletions

View File

@@ -1,8 +1,10 @@
import { Injectable } from "@angular/core";
// src/app/services/login.service.ts
import { Injectable, NgZone } from "@angular/core";
import { HttpClient, HttpHeaders } from "@angular/common/http";
import { BehaviorSubject, Observable } from "rxjs";
import { jwtDecode } from "jwt-decode";
import { BehaviorSubject, Observable, of, Subject, timer, fromEvent, merge } from "rxjs";
import {jwtDecode} from "jwt-decode";
import { Router } from "@angular/router";
import { switchMap, debounceTime, mapTo, startWith } from "rxjs/operators";
import { AuthService } from "src/app/_services/auth.service";
const BASE_URL = "https://kapi.absys.ninja/hemat";
@@ -23,17 +25,29 @@ interface CustomJwtPayload {
})
export class LoginService {
private readonly tokenKey = "currentUser";
private tabSelected = new BehaviorSubject(null);
private tabSelected = new BehaviorSubject<string | null>(null);
public _tabSelected = this.tabSelected.asObservable();
private activitySubject = new Subject<boolean>();
public activity$: Observable<boolean> = this.activitySubject.asObservable();
currentUser: any;
constructor(
private http: HttpClient,
private router: Router,
public logoutService: AuthService
) {}
private authService: AuthService,
private ngZone: NgZone
) {
this.startTrackingActivity();
this.startTokenCheck();
this.currentUser = JSON.parse(localStorage.getItem("currentUser"));
}
setTabsSelected(e: string){
setTabsSelected(e: string) {
this.tabSelected.next(e);
}
updatePassword(data: any): Observable<any> {
const endpoint = `/users`;
const url = `${BASE_URL}${endpoint}/reset-password`;
@@ -44,7 +58,7 @@ export class LoginService {
return this.http.put<any>(url, data, { headers });
}
getDataProfil(id): Observable<any> {
getDataProfil(id: string): Observable<any> {
const endpoint = `/users`;
const url = `${BASE_URL}${endpoint}/byUserid/${id}`;
const headers = new HttpHeaders({
@@ -61,7 +75,7 @@ export class LoginService {
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
});
return this.http.post(`${url}`, data, { headers });
return this.http.post<any>(`${url}`, data, { headers });
}
updateUserProfile(data: any): Observable<any> {
@@ -72,36 +86,92 @@ export class LoginService {
"x-api-key": "j2yaYvPSQcsEEmHh3NEobfiXyyXmmnHT",
});
return this.http.post(`${url}`, body, { headers });
return this.http.post<any>(`${url}`, body, { headers });
}
isTokenExpired(): boolean {
isTokenExpired(): Observable<boolean> {
const tokenData = localStorage.getItem(this.tokenKey);
if (tokenData) {
const tokenInfo = JSON.parse(tokenData);
const decodedToken = jwtDecode<CustomJwtPayload>(tokenInfo.refresh_token);
const expiryDate = decodedToken.exp * 1000;
const now = new Date().getTime();
return now > expiryDate;
const timeLeft = expiryDate - now;
return of(timeLeft <= 5 * 60 * 1000);
}
return true;
return of(true);
}
checkTokenAndRedirect(): void {
if (this.isTokenExpired()) {
// Token sudah kedaluwarsa, arahkan ke halaman login
// console.log("Token expired, redirecting to login page...");
this.logoutService.doLogout().then(
(res) => {
this.router.navigate(["/login"]);
},
(err) => {
console.log(err);
this.isTokenExpired().subscribe((isExpired) => {
if (isExpired) {
this.authService.doLogout().then(
() => {
this.router.navigate(["/login"]);
},
(err) => {
console.log(err);
}
);
this.router.navigate(["/login"]);
} else {
console.log("Token is valid, continuing...");
}
});
}
startTokenCheck(): void {
timer(0, 2 * 60 * 1000) // Check every 5 minutes
.pipe(
switchMap(() => this.isTokenExpired())
)
.subscribe((isExpired) => {
if (isExpired) {
this.activity$.subscribe(isActive => {
if (!isActive) {
this.checkTokenAndRedirect();
} else {
console.log("Token expired but user is active. Refresh token not implemented.");
this.updateUserProfile(this.currentUser.refresh_token)
.subscribe((resp) => {
const decodedToken = jwtDecode<CustomJwtPayload>(resp.access_token);
localStorage.setItem("account_info", JSON.stringify(decodedToken));
const userProfile = {
access_token: resp.access_token,
refresh_token: resp.refresh_token,
displayName: decodedToken.name,
buildingId: 4,
};
localStorage.setItem("currentUser", JSON.stringify(userProfile));
// window.location.reload();
});
}
});
}
});
}
startTrackingActivity(): void {
this.ngZone.runOutsideAngular(() => {
const activityEvents$ = merge(
fromEvent(window, 'mousemove'),
fromEvent(window, 'click'),
fromEvent(window, 'keypress'),
fromEvent(window, 'scroll')
);
this.router.navigate(["/login"]);
} else {
console.log("Token is valid, continuing...");
}
activityEvents$
.pipe(
startWith(null),
switchMap(() => merge(
timer(0).pipe(mapTo(true)),
timer(5 * 60 * 1000).pipe(mapTo(false)) // 5 minutes of inactivity
)),
debounceTime(300)
)
.subscribe(active => {
this.ngZone.run(() => this.activitySubject.next(active));
});
});
}
}

View File

@@ -0,0 +1,33 @@
import { Injectable, NgZone } from '@angular/core';
import { Observable, Subject } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserActivityService {
private activitySubject = new Subject<boolean>();
private timeoutId: any;
constructor(private ngZone: NgZone) {
this.setupActivityListeners();
}
private setupActivityListeners(): void {
const events = ['click', 'mousemove', 'keypress'];
events.forEach(event => {
window.addEventListener(event, () => this.resetTimeout(), true);
});
}
private resetTimeout(): void {
this.ngZone.runOutsideAngular(() => {
clearTimeout(this.timeoutId);
this.timeoutId = setTimeout(() => this.activitySubject.next(false), 300000); // 5 minutes
this.activitySubject.next(true);
});
}
get activity$(): Observable<boolean> {
return this.activitySubject.asObservable();
}
}