-เพิ่ม pkg jose ไว้ encrypt secret key
All checks were successful
Build Docker Image / Build Docker Image (push) Successful in 6m5s

-jwt services/jwt.service.ts
-เพิ่ม  เวลา expire jwt token
This commit is contained in:
x2Skyz
2025-11-23 19:30:54 +07:00
parent 0d43286d84
commit 6669399b7e
12 changed files with 166 additions and 14 deletions

View File

@@ -0,0 +1,96 @@
import { Injectable } from '@angular/core';
import { environment } from '../../environments/environment';
import * as jose from 'jose';
import { BehaviorSubject, Observable, timer, Subscription } from 'rxjs';
import { map, takeWhile, finalize } from 'rxjs/operators';
import { Router } from '@angular/router';
import { ToastrService } from 'ngx-toastr';
@Injectable({
providedIn: 'root'
})
export class JwtService {
private secret = new TextEncoder().encode(environment.jwt_secret);
private countdownSub = new BehaviorSubject<string | null>(null);
public countdown$: Observable<string | null> = this.countdownSub.asObservable();
private timerSubscription: Subscription | null = null;
constructor(
private router: Router,
private toastr: ToastrService
) {
this.startTokenCountdown();
}
async decodeToken(token: string): Promise<any> {
try {
const { payload } = await jose.jwtVerify(token, this.secret);
return payload;
} catch (error) {
// console.error('Invalid token:', error);
return null;
}
}
private startTokenCountdown(): void {
if (this.timerSubscription) {
this.timerSubscription.unsubscribe();
}
const token = localStorage.getItem('access_token');
if (!token) {
this.countdownSub.next(null);
return;
}
this.decodeToken(token).then(payload => {
if (payload && payload.exp) {
const expirationTime = payload.exp * 1000;
this.timerSubscription = timer(0, 1000).pipe(
map(() => {
const now = new Date().getTime();
const distance = expirationTime - now;
if (distance < 0) {
this.logout();
return 'Expired';
}
const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((distance % (1000 * 60)) / 1000);
return `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}`;
}),
takeWhile(val => val !== 'Expired', true),
finalize(() => {
if (this.countdownSub.value !== 'Expired') {
this.logout();
}
this.countdownSub.next('Expired');
})
).subscribe(val => this.countdownSub.next(val));
} else {
this.countdownSub.next(null);
}
});
}
private pad(num: number): string {
return num < 10 ? '0' + num : num.toString();
}
public logout(): void {
localStorage.removeItem('access_token');
this.countdownSub.next(null);
if (this.timerSubscription) {
this.timerSubscription.unsubscribe();
}
// this.toastr.info('Your session has expired. Please log in again.', 'Session Expired');
this.router.navigate(['/login']); // Assuming '/login' is your login route
}
public restartCountdown(): void {
this.startTokenCountdown();
}
}