scheduling
This commit is contained in:
@@ -1,19 +1,18 @@
|
|||||||
package space.luminic.budgerapp
|
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.autoconfigure.SpringBootApplication
|
||||||
import org.springframework.boot.runApplication
|
import org.springframework.boot.runApplication
|
||||||
import org.springframework.cache.annotation.EnableCaching
|
import org.springframework.cache.annotation.EnableCaching
|
||||||
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories
|
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories
|
||||||
import org.springframework.scheduling.annotation.EnableAsync
|
import org.springframework.scheduling.annotation.EnableAsync
|
||||||
import org.springframework.web.reactive.config.EnableWebFlux
|
import org.springframework.scheduling.annotation.EnableScheduling
|
||||||
import java.security.Security
|
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
|
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
@EnableAsync
|
@EnableAsync
|
||||||
|
@EnableScheduling
|
||||||
@EnableMongoRepositories(basePackages = ["space.luminic.budgerapp.repos"])
|
@EnableMongoRepositories(basePackages = ["space.luminic.budgerapp.repos"])
|
||||||
class BudgerAppApplication
|
class BudgerAppApplication
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ data class PushMessage(
|
|||||||
val title: String,
|
val title: String,
|
||||||
val body: String,
|
val body: String,
|
||||||
val icon: String? = null,
|
val icon: String? = null,
|
||||||
val budge: String? = null,
|
val badge: String? = null,
|
||||||
val url: String? = null
|
val url: String? = null
|
||||||
|
|
||||||
)
|
)
|
||||||
@@ -5,10 +5,8 @@ import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
|||||||
import org.springframework.stereotype.Service
|
import org.springframework.stereotype.Service
|
||||||
import reactor.core.publisher.Mono
|
import reactor.core.publisher.Mono
|
||||||
import space.luminic.budgerapp.configs.AuthException
|
import space.luminic.budgerapp.configs.AuthException
|
||||||
import space.luminic.budgerapp.models.Token
|
|
||||||
import space.luminic.budgerapp.models.TokenStatus
|
import space.luminic.budgerapp.models.TokenStatus
|
||||||
import space.luminic.budgerapp.models.User
|
import space.luminic.budgerapp.models.User
|
||||||
import space.luminic.budgerapp.repos.TokenRepo
|
|
||||||
import space.luminic.budgerapp.repos.UserRepo
|
import space.luminic.budgerapp.repos.UserRepo
|
||||||
import space.luminic.budgerapp.utils.JWTUtil
|
import space.luminic.budgerapp.utils.JWTUtil
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
@@ -19,7 +17,7 @@ import java.util.Date
|
|||||||
@Service
|
@Service
|
||||||
class AuthService(
|
class AuthService(
|
||||||
private val userRepository: UserRepo,
|
private val userRepository: UserRepo,
|
||||||
private val tokenRepo: TokenRepo,
|
private val tokenService: TokenService,
|
||||||
private val jwtUtil: JWTUtil
|
private val jwtUtil: JWTUtil
|
||||||
|
|
||||||
) {
|
) {
|
||||||
@@ -31,18 +29,14 @@ class AuthService(
|
|||||||
if (passwordEncoder.matches(password, user.password)) {
|
if (passwordEncoder.matches(password, user.password)) {
|
||||||
val token = jwtUtil.generateToken(user.username)
|
val token = jwtUtil.generateToken(user.username)
|
||||||
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
|
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
|
||||||
tokenRepo.save(
|
tokenService.saveToken(
|
||||||
Token(
|
|
||||||
token = token,
|
token = token,
|
||||||
username = username,
|
username = username,
|
||||||
issuedAt = LocalDateTime.now(),
|
|
||||||
expiresAt = LocalDateTime.ofInstant(
|
expiresAt = LocalDateTime.ofInstant(
|
||||||
expireAt.toInstant(),
|
expireAt.toInstant(),
|
||||||
ZoneId.systemDefault()
|
ZoneId.systemDefault()
|
||||||
)
|
)
|
||||||
)
|
).thenReturn(token)
|
||||||
)
|
|
||||||
.thenReturn(token)
|
|
||||||
} else {
|
} else {
|
||||||
Mono.error(AuthException("Invalid credentials"))
|
Mono.error(AuthException("Invalid credentials"))
|
||||||
}
|
}
|
||||||
@@ -51,16 +45,21 @@ class AuthService(
|
|||||||
|
|
||||||
@Cacheable("tokens")
|
@Cacheable("tokens")
|
||||||
fun isTokenValid(token: String): Mono<User> {
|
fun isTokenValid(token: String): Mono<User> {
|
||||||
// print("checking token: $token")
|
return tokenService.getToken(token)
|
||||||
return tokenRepo.findByToken(token)
|
.flatMap { tokenDetails ->
|
||||||
.flatMap {
|
when {
|
||||||
if (it.status == TokenStatus.ACTIVE &&
|
tokenDetails.status == TokenStatus.ACTIVE && tokenDetails.expiresAt.isAfter(LocalDateTime.now()) -> {
|
||||||
it.expiresAt.isAfter(LocalDateTime.now())
|
userRepository.findByUsername(tokenDetails.username)
|
||||||
) {
|
.switchIfEmpty(Mono.error(AuthException("User not found for token")))
|
||||||
userRepository.findByUsername(it.username)
|
|
||||||
} else {
|
|
||||||
Mono.error(AuthException("Token expired"))
|
|
||||||
}
|
}
|
||||||
}.switchIfEmpty(Mono.error(AuthException("User not found")))
|
|
||||||
|
else -> {
|
||||||
|
tokenService.revokeToken(token)
|
||||||
|
.then(Mono.error(AuthException("Token expired or inactive")))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.switchIfEmpty(Mono.error(AuthException("Token not found")))
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -21,6 +21,10 @@ class TokenService(private val tokenRepository: TokenRepo) {
|
|||||||
return tokenRepository.save(newToken)
|
return tokenRepository.save(newToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getToken(token: String): Mono<Token> {
|
||||||
|
return tokenRepository.findByToken(token)
|
||||||
|
}
|
||||||
|
|
||||||
@CacheEvict("tokens", allEntries = true)
|
@CacheEvict("tokens", allEntries = true)
|
||||||
fun revokeToken(token: String): Mono<Void> {
|
fun revokeToken(token: String): Mono<Void> {
|
||||||
return tokenRepository.findByToken(token)
|
return tokenRepository.findByToken(token)
|
||||||
|
|||||||
@@ -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()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user