Update to use jose tokens library

This commit is contained in:
NicolasCantu 2025-05-06 16:43:51 +02:00
parent ee7c79a7d5
commit 0f364c7c6e

View File

@ -1,15 +1,18 @@
import { TokenData } from '../models/process.model'; import * as jose from 'jose';
interface TokenPair {
accessToken: string;
refreshToken: string;
}
export default class TokenService { export default class TokenService {
private static instance: TokenService; private static instance: TokenService;
public tokens: Map<string, TokenData> = new Map(); private readonly SECRET_KEY = import.meta.env.VITE_JWT_SECRET_KEY;
private readonly STORAGE_KEY = 'ihm_tokens'; private readonly ACCESS_TOKEN_EXPIRATION = '10s';
private readonly REFRESH_TOKEN_EXPIRATION = '7d';
private readonly encoder = new TextEncoder();
private constructor() { private constructor() {}
this.loadTokensFromStorage();
// Nettoyer les tokens expirés toutes les minutes
setInterval(() => this.cleanExpiredTokens(), 60 * 1000);
}
static async getInstance(): Promise<TokenService> { static async getInstance(): Promise<TokenService> {
if (!TokenService.instance) { if (!TokenService.instance) {
@ -18,50 +21,43 @@ export default class TokenService {
return TokenService.instance; return TokenService.instance;
} }
private loadTokensFromStorage(): void { async generateSessionToken(origin: string): Promise<TokenPair> {
const storedTokens = localStorage.getItem(this.STORAGE_KEY); const secret = new Uint8Array(this.encoder.encode(this.SECRET_KEY));
if (storedTokens) {
const tokenArray = JSON.parse(storedTokens); const accessToken = await new jose.SignJWT({ origin, type: 'access' })
this.tokens = new Map(tokenArray); .setProtectedHeader({ alg: 'HS256' })
console.log('Tokens loaded from storage:', this.tokens); .setIssuedAt()
} .setExpirationTime(this.ACCESS_TOKEN_EXPIRATION)
.sign(secret);
const refreshToken = await new jose.SignJWT({ origin, type: 'refresh' })
.setProtectedHeader({ alg: 'HS256' })
.setIssuedAt()
.setExpirationTime(this.REFRESH_TOKEN_EXPIRATION)
.sign(secret);
console.log('Tokens JWT générés - Access:', accessToken);
console.log('Tokens JWT générés - Refresh:', refreshToken);
return { accessToken, refreshToken };
} }
private saveTokensToStorage(): void { async validateToken(token: string, origin: string): Promise<boolean> {
const tokenArray = Array.from(this.tokens.entries()); try {
localStorage.setItem(this.STORAGE_KEY, JSON.stringify(tokenArray)); const secret = new Uint8Array(this.encoder.encode(this.SECRET_KEY));
const { payload } = await jose.jwtVerify(token, secret);
console.log('Validation du token JWT:', token);
console.log('Données décodées:', payload);
return payload.origin === origin;
} catch (error: any) {
if (error?.code === 'ERR_JWT_EXPIRED') {
console.log('Token expiré');
return false;
} }
generateSessionToken(origin: string): string { console.error('Erreur de validation du token:', error);
const token = crypto.randomUUID();
const expiration = Date.now() + (30 * 60 * 1000); // 30 minutes
this.tokens.set(token, {
token,
origin,
expiration,
createdAt: Date.now()
});
this.saveTokensToStorage();
console.log('Token generated:', token);
console.log('Tokens map:', this.tokens);
return token;
}
validateToken(token: string, origin: string): boolean {
this.loadTokensFromStorage(); // Recharger les tokens avant validation
const tokenData = this.tokens.get(token);
console.log('Validating token:', token);
console.log('Current tokens:', this.tokens);
console.log('Token data found:', tokenData);
if (!tokenData) return false;
if (tokenData.origin !== origin) return false;
if (tokenData.expiration < Date.now()) {
console.log(`Token expired: ${token}`);
return false; return false;
} }