diff --git a/src/services/token.ts b/src/services/token.ts index d7e7333..223ee52 100644 --- a/src/services/token.ts +++ b/src/services/token.ts @@ -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 { private static instance: TokenService; - public tokens: Map = new Map(); - private readonly STORAGE_KEY = 'ihm_tokens'; - - private constructor() { - this.loadTokensFromStorage(); - // Nettoyer les tokens expirés toutes les minutes - setInterval(() => this.cleanExpiredTokens(), 60 * 1000); - } + private readonly SECRET_KEY = import.meta.env.VITE_JWT_SECRET_KEY; + private readonly ACCESS_TOKEN_EXPIRATION = '10s'; + private readonly REFRESH_TOKEN_EXPIRATION = '7d'; + private readonly encoder = new TextEncoder(); + + private constructor() {} static async getInstance(): Promise { if (!TokenService.instance) { @@ -18,50 +21,43 @@ export default class TokenService { return TokenService.instance; } - private loadTokensFromStorage(): void { - const storedTokens = localStorage.getItem(this.STORAGE_KEY); - if (storedTokens) { - const tokenArray = JSON.parse(storedTokens); - this.tokens = new Map(tokenArray); - console.log('Tokens loaded from storage:', this.tokens); - } + async generateSessionToken(origin: string): Promise { + const secret = new Uint8Array(this.encoder.encode(this.SECRET_KEY)); + + const accessToken = await new jose.SignJWT({ origin, type: 'access' }) + .setProtectedHeader({ alg: 'HS256' }) + .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 { - const tokenArray = Array.from(this.tokens.entries()); - localStorage.setItem(this.STORAGE_KEY, JSON.stringify(tokenArray)); - } - - generateSessionToken(origin: string): string { - 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}`); + async validateToken(token: string, origin: string): Promise { + try { + 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; + } + + console.error('Erreur de validation du token:', error); return false; }