From 84f61532d0e8f8c3554cec94acb6e6653a706300 Mon Sep 17 00:00:00 2001 From: Vladimir Voronin Date: Tue, 7 Jan 2025 13:31:08 +0300 Subject: [PATCH] scheduling --- .../luminic/budgerapp/BudgerAppApplication.kt | 7 ++- .../luminic/budgerapp/models/PushMessage.kt | 2 +- .../luminic/budgerapp/services/AuthService.kt | 47 +++++++++---------- .../budgerapp/services/TokenService.kt | 4 ++ .../luminic/budgerapp/utils/ScheduledTasks.kt | 42 +++++++++++++++++ 5 files changed, 73 insertions(+), 29 deletions(-) create mode 100644 src/main/kotlin/space/luminic/budgerapp/utils/ScheduledTasks.kt diff --git a/src/main/kotlin/space/luminic/budgerapp/BudgerAppApplication.kt b/src/main/kotlin/space/luminic/budgerapp/BudgerAppApplication.kt index 8fac966..2b8d7c1 100644 --- a/src/main/kotlin/space/luminic/budgerapp/BudgerAppApplication.kt +++ b/src/main/kotlin/space/luminic/budgerapp/BudgerAppApplication.kt @@ -1,19 +1,18 @@ package space.luminic.budgerapp -import com.interaso.webpush.VapidKeys -//import org.apache.tomcat.util.codec.binary.Base64.encodeBase64 + import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication import org.springframework.cache.annotation.EnableCaching import org.springframework.data.mongodb.repository.config.EnableMongoRepositories import org.springframework.scheduling.annotation.EnableAsync -import org.springframework.web.reactive.config.EnableWebFlux -import java.security.Security +import org.springframework.scheduling.annotation.EnableScheduling import java.util.TimeZone @SpringBootApplication @EnableCaching @EnableAsync +@EnableScheduling @EnableMongoRepositories(basePackages = ["space.luminic.budgerapp.repos"]) class BudgerAppApplication diff --git a/src/main/kotlin/space/luminic/budgerapp/models/PushMessage.kt b/src/main/kotlin/space/luminic/budgerapp/models/PushMessage.kt index 11af81c..bb14e72 100644 --- a/src/main/kotlin/space/luminic/budgerapp/models/PushMessage.kt +++ b/src/main/kotlin/space/luminic/budgerapp/models/PushMessage.kt @@ -14,7 +14,7 @@ data class PushMessage( val title: String, val body: String, val icon: String? = null, - val budge: String? = null, + val badge: String? = null, val url: String? = null ) \ No newline at end of file diff --git a/src/main/kotlin/space/luminic/budgerapp/services/AuthService.kt b/src/main/kotlin/space/luminic/budgerapp/services/AuthService.kt index 59f3b00..2f4104e 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/AuthService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/AuthService.kt @@ -5,10 +5,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.stereotype.Service import reactor.core.publisher.Mono import space.luminic.budgerapp.configs.AuthException -import space.luminic.budgerapp.models.Token import space.luminic.budgerapp.models.TokenStatus import space.luminic.budgerapp.models.User -import space.luminic.budgerapp.repos.TokenRepo import space.luminic.budgerapp.repos.UserRepo import space.luminic.budgerapp.utils.JWTUtil import java.time.LocalDateTime @@ -19,7 +17,7 @@ import java.util.Date @Service class AuthService( private val userRepository: UserRepo, - private val tokenRepo: TokenRepo, + private val tokenService: TokenService, private val jwtUtil: JWTUtil ) { @@ -31,18 +29,14 @@ class AuthService( if (passwordEncoder.matches(password, user.password)) { val token = jwtUtil.generateToken(user.username) val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10) - tokenRepo.save( - Token( - token = token, - username = username, - issuedAt = LocalDateTime.now(), - expiresAt = LocalDateTime.ofInstant( - expireAt.toInstant(), - ZoneId.systemDefault() - ) + tokenService.saveToken( + token = token, + username = username, + expiresAt = LocalDateTime.ofInstant( + expireAt.toInstant(), + ZoneId.systemDefault() ) - ) - .thenReturn(token) + ).thenReturn(token) } else { Mono.error(AuthException("Invalid credentials")) } @@ -51,16 +45,21 @@ class AuthService( @Cacheable("tokens") fun isTokenValid(token: String): Mono { -// print("checking token: $token") - return tokenRepo.findByToken(token) - .flatMap { - if (it.status == TokenStatus.ACTIVE && - it.expiresAt.isAfter(LocalDateTime.now()) - ) { - userRepository.findByUsername(it.username) - } else { - Mono.error(AuthException("Token expired")) + return tokenService.getToken(token) + .flatMap { tokenDetails -> + when { + tokenDetails.status == TokenStatus.ACTIVE && tokenDetails.expiresAt.isAfter(LocalDateTime.now()) -> { + userRepository.findByUsername(tokenDetails.username) + .switchIfEmpty(Mono.error(AuthException("User not found for token"))) + } + + else -> { + tokenService.revokeToken(token) + .then(Mono.error(AuthException("Token expired or inactive"))) + } } - }.switchIfEmpty(Mono.error(AuthException("User not found"))) + } + .switchIfEmpty(Mono.error(AuthException("Token not found"))) } + } \ No newline at end of file diff --git a/src/main/kotlin/space/luminic/budgerapp/services/TokenService.kt b/src/main/kotlin/space/luminic/budgerapp/services/TokenService.kt index fce0afb..48f2a5f 100644 --- a/src/main/kotlin/space/luminic/budgerapp/services/TokenService.kt +++ b/src/main/kotlin/space/luminic/budgerapp/services/TokenService.kt @@ -21,6 +21,10 @@ class TokenService(private val tokenRepository: TokenRepo) { return tokenRepository.save(newToken) } + fun getToken(token: String): Mono { + return tokenRepository.findByToken(token) + } + @CacheEvict("tokens", allEntries = true) fun revokeToken(token: String): Mono { return tokenRepository.findByToken(token) diff --git a/src/main/kotlin/space/luminic/budgerapp/utils/ScheduledTasks.kt b/src/main/kotlin/space/luminic/budgerapp/utils/ScheduledTasks.kt new file mode 100644 index 0000000..f67dc94 --- /dev/null +++ b/src/main/kotlin/space/luminic/budgerapp/utils/ScheduledTasks.kt @@ -0,0 +1,42 @@ +package space.luminic.budgerapp.utils + +import org.slf4j.LoggerFactory +import org.springframework.scheduling.annotation.Scheduled +import org.springframework.stereotype.Component +import space.luminic.budgerapp.models.PushMessage +import space.luminic.budgerapp.services.SubscriptionService +import space.luminic.budgerapp.services.TokenService + + +@Component +class ScheduledTasks(private val subscriptionService: SubscriptionService, + private val tokenService: TokenService) { + private val logger = LoggerFactory.getLogger(ScheduledTasks::class.java) + + @Scheduled(cron = "0 30 19 * * *") + fun sendNotificationOfMoneyFilling() { + subscriptionService.sendToAll( + PushMessage( + title = "Время заполнять траты!🤑", + body = "Проверь все ли траты внесены!", + icon = "/apple-touch-icon.png", + badge = "/apple-touch-icon.png", + url = "https://luminic.space/transactions/create" + ) + ).doOnNext { responses -> + responses.forEach { response -> + logger.info("Уведомление отправлено: $response") + } + }.subscribe( + { logger.info("Все уведомления отправлены.") }, + { error -> logger.error("Ошибка при отправке уведомлений: ${error.message}", error) } + ) + } + + @Scheduled(cron = "0 0 0 * * *") + fun deleteExpiredTokens() { + tokenService.deleteExpiredTokens() + } + + +} \ No newline at end of file