package com.openisle.service; import com.openisle.model.PushSubscription; import com.openisle.model.User; import com.openisle.repository.PushSubscriptionRepository; import lombok.extern.slf4j.Slf4j; import nl.martijndwars.webpush.Notification; import nl.martijndwars.webpush.PushService; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.jose4j.lang.JoseException; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.io.IOException; import java.security.GeneralSecurityException; import java.security.Security; import java.util.List; @Slf4j @Service public class PushNotificationService { private final PushSubscriptionRepository subscriptionRepository; private final PushService pushService; public PushNotificationService(PushSubscriptionRepository subscriptionRepository, @Value("${app.webpush.public-key:}") String publicKey, @Value("${app.webpush.private-key:}") String privateKey) throws GeneralSecurityException { this.subscriptionRepository = subscriptionRepository; if (publicKey != null && !publicKey.isBlank() && privateKey != null && !privateKey.isBlank()) { Security.addProvider(new BouncyCastleProvider()); this.pushService = new PushService(publicKey, privateKey); } else { this.pushService = null; } } public void sendNotification(User user, String payload) { if (pushService == null) { log.warn("Push notifications are disabled because VAPID keys are not configured."); return; } List subs = subscriptionRepository.findByUser(user); for (PushSubscription sub : subs) { try { Notification notification = new Notification(sub.getEndpoint(), sub.getP256dh(), sub.getAuth(), payload); pushService.send(notification); } catch (GeneralSecurityException | IOException | JoseException | InterruptedException | java.util.concurrent.ExecutionException e) { log.error(e.getMessage()); } } } }