package dev.dinauer.oidcproxy.session; import dev.dinauer.oidcproxy.proxy.exception.TokenNotFoundException; import io.quarkus.narayana.jta.QuarkusTransaction; import io.quarkus.runtime.Startup; import jakarta.enterprise.context.ApplicationScoped; import jakarta.enterprise.context.control.ActivateRequestContext; import jakarta.inject.Inject; import org.jboss.logging.Logger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.time.ZonedDateTime; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; @ApplicationScoped public class SessionCache { private final Map tokens = new ConcurrentHashMap<>(); @Inject SessionService sessionService; public String add(String accessToken, String refreshToken) { String sessionId = UUID.randomUUID().toString(); sessionService.create(toHash(sessionId), new AccessToken(accessToken), new RefreshToken(refreshToken)); return sessionId; } public String get(String sessionId) throws TokenNotFoundException { String sessionHash = toHash(sessionId); Optional token = getFromCache(sessionHash); if (token.isPresent()) { return token.get(); } AccessToken fromDB = sessionService.provide(sessionHash); tokens.put(sessionHash, fromDB); return fromDB.getToken(); } public void remove(String sessionId) { String sessionHash = toHash(sessionId); tokens.remove(sessionHash); sessionService.remove(sessionHash); } public Optional getFromCache(String sessionHash) { AccessToken token = tokens.get(sessionHash); if (token != null && ZonedDateTime.now().isBefore(token.getExpiresAt())) { return Optional.of(token.getToken()); } else { tokens.remove(sessionHash); return Optional.empty(); } } private String toHash(String sessionId) { try { return Base64.getEncoder().encodeToString( MessageDigest.getInstance("SHA-256").digest(sessionId.getBytes())); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } } }