login fix and spaces creation
This commit is contained in:
@@ -30,18 +30,19 @@ class AuthController(
|
||||
|
||||
@PostMapping("/login")
|
||||
suspend fun login(@RequestBody request: AuthRequest): Map<String, String> {
|
||||
return authService.login(request.username, request.password)
|
||||
.map { token -> mapOf("token" to token) }.awaitFirst()
|
||||
val token = authService.login(request.username, request.password)
|
||||
return mapOf("token" to token)
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
fun register(@RequestBody request: RegisterRequest): Mono<User> {
|
||||
suspend fun register(@RequestBody request: RegisterRequest): User {
|
||||
return authService.register(request.username, request.password, request.firstName)
|
||||
}
|
||||
|
||||
@PostMapping("/tgLogin")
|
||||
fun tgLogin(@RequestHeader("X-Tg-Id") tgId: String): Mono<Map<String, String>> {
|
||||
return authService.tgLogin(tgId).map { token -> mapOf("token" to token) }
|
||||
suspend fun tgLogin(@RequestHeader("X-Tg-Id") tgId: String): Map<String, String> {
|
||||
val token = authService.tgLogin(tgId)
|
||||
return mapOf("token" to token)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
package space.luminic.budgerapp.services
|
||||
|
||||
import kotlinx.coroutines.reactive.awaitFirstOrNull
|
||||
import kotlinx.coroutines.reactor.awaitSingle
|
||||
import kotlinx.coroutines.reactor.awaitSingleOrNull
|
||||
import org.springframework.cache.annotation.Cacheable
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -25,10 +28,10 @@ class AuthService(
|
||||
) {
|
||||
private val passwordEncoder = BCryptPasswordEncoder()
|
||||
|
||||
fun login(username: String, password: String): Mono<String> {
|
||||
return userRepository.findByUsername(username)
|
||||
.flatMap { user ->
|
||||
if (passwordEncoder.matches(password, user.password)) {
|
||||
suspend fun login(username: String, password: String): String {
|
||||
val user = userRepository.findByUsername(username).awaitFirstOrNull()
|
||||
?: throw UsernameNotFoundException("Пользователь не найден")
|
||||
return if (passwordEncoder.matches(password, user.password)) {
|
||||
val token = jwtUtil.generateToken(user.username!!)
|
||||
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
|
||||
tokenService.saveToken(
|
||||
@@ -38,18 +41,17 @@ class AuthService(
|
||||
expireAt.toInstant(),
|
||||
ZoneId.systemDefault()
|
||||
)
|
||||
).thenReturn(token)
|
||||
)
|
||||
token
|
||||
} else {
|
||||
Mono.error(AuthException("Invalid credentials"))
|
||||
}
|
||||
throw IllegalArgumentException("Ошибка логина или пароля")
|
||||
}
|
||||
}
|
||||
|
||||
fun tgLogin(tgId: String): Mono<String> {
|
||||
return userRepository.findByTgId(tgId)
|
||||
.switchIfEmpty(Mono.error(AuthException("Invalid credentials")))
|
||||
.flatMap { user ->
|
||||
println("here")
|
||||
suspend fun tgLogin(tgId: String): String {
|
||||
val user =
|
||||
userRepository.findByTgId(tgId).awaitSingleOrNull() ?: throw UsernameNotFoundException("Пользователь не найден")
|
||||
|
||||
val token = jwtUtil.generateToken(user.username!!)
|
||||
val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10)
|
||||
tokenService.saveToken(
|
||||
@@ -59,35 +61,30 @@ class AuthService(
|
||||
expireAt.toInstant(),
|
||||
ZoneId.systemDefault()
|
||||
)
|
||||
).thenReturn(token)
|
||||
)
|
||||
return token
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun register(username: String, password: String, firstName: String): Mono<User> {
|
||||
return userRepository.findByUsername(username)
|
||||
.flatMap<User> { Mono.error(IllegalArgumentException("User with username '$username' already exists")) } // Ошибка, если пользователь уже существует
|
||||
.switchIfEmpty(
|
||||
Mono.defer {
|
||||
val newUser = User(
|
||||
suspend fun register(username: String, password: String, firstName: String): User {
|
||||
val user = userRepository.findByUsername(username).awaitSingleOrNull()
|
||||
if (user == null) {
|
||||
var newUser = User(
|
||||
username = username,
|
||||
password = passwordEncoder.encode(password), // Шифрование пароля
|
||||
firstName = firstName,
|
||||
roles = mutableListOf("USER")
|
||||
)
|
||||
userRepository.save(newUser).map { user ->
|
||||
user.password = null
|
||||
user
|
||||
} // Сохранение нового пользователя
|
||||
|
||||
}
|
||||
)
|
||||
newUser = userRepository.save(newUser).awaitSingle()
|
||||
newUser.password = null
|
||||
return newUser
|
||||
} else throw IllegalArgumentException("Пользователь уже зарегистрирован")
|
||||
}
|
||||
|
||||
|
||||
@Cacheable(cacheNames = ["tokens"], key = "#token")
|
||||
suspend fun isTokenValid(token: String): User {
|
||||
val tokenDetails = tokenService.getToken(token).awaitFirstOrNull() ?: throw AuthException("Invalid token")
|
||||
val tokenDetails = tokenService.getToken(token).awaitFirstOrNull() ?: throw AuthException("Токен не валиден")
|
||||
when {
|
||||
tokenDetails.status == TokenStatus.ACTIVE && tokenDetails.expiresAt.isAfter(LocalDateTime.now()) -> {
|
||||
return userService.getByUserNameWoPass(tokenDetails.username)
|
||||
@@ -95,7 +92,7 @@ class AuthService(
|
||||
|
||||
else -> {
|
||||
tokenService.revokeToken(tokenDetails.token)
|
||||
throw AuthException("Token expired or inactive")
|
||||
throw AuthException("Токен истек или не валиден")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.reactive.awaitFirst
|
||||
import kotlinx.coroutines.reactive.awaitFirstOrNull
|
||||
import kotlinx.coroutines.reactive.awaitLast
|
||||
import kotlinx.coroutines.reactive.awaitSingle
|
||||
import kotlinx.coroutines.reactor.awaitSingleOrNull
|
||||
import org.bson.Document
|
||||
@@ -18,6 +19,7 @@ import space.luminic.budgerapp.configs.AuthException
|
||||
import space.luminic.budgerapp.models.*
|
||||
import space.luminic.budgerapp.repos.*
|
||||
import java.time.LocalDateTime
|
||||
import java.time.ZoneId
|
||||
import java.util.UUID
|
||||
|
||||
@Service
|
||||
@@ -92,7 +94,8 @@ class SpaceService(
|
||||
username = userDoc.getString("username"),
|
||||
firstName = userDoc.getString("firstName")
|
||||
)
|
||||
}.toMutableList()
|
||||
}.toMutableList(),
|
||||
createdAt = doc.getDate("createdAt").toInstant().atZone(ZoneId.systemDefault()).toLocalDate()
|
||||
)
|
||||
}
|
||||
}.awaitFirst()
|
||||
@@ -120,7 +123,7 @@ class SpaceService(
|
||||
.map { category ->
|
||||
category.copy(id = null, space = savedSpace) // Создаем новую копию
|
||||
}
|
||||
categoryRepo.saveAll(categories).awaitSingle()
|
||||
categoryRepo.saveAll(categories).awaitLast()
|
||||
savedSpace
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package space.luminic.budgerapp.services
|
||||
|
||||
import kotlinx.coroutines.reactor.awaitSingle
|
||||
import org.springframework.cache.annotation.CacheEvict
|
||||
import org.springframework.stereotype.Service
|
||||
import reactor.core.publisher.Mono
|
||||
@@ -12,14 +13,14 @@ import java.time.LocalDateTime
|
||||
class TokenService(private val tokenRepository: TokenRepo) {
|
||||
|
||||
@CacheEvict("tokens", allEntries = true)
|
||||
fun saveToken(token: String, username: String, expiresAt: LocalDateTime): Mono<Token> {
|
||||
suspend fun saveToken(token: String, username: String, expiresAt: LocalDateTime): Token {
|
||||
val newToken = Token(
|
||||
token = token,
|
||||
username = username,
|
||||
issuedAt = LocalDateTime.now(),
|
||||
expiresAt = expiresAt
|
||||
)
|
||||
return tokenRepository.save(newToken)
|
||||
return tokenRepository.save(newToken).awaitSingle()
|
||||
}
|
||||
|
||||
fun getToken(token: String): Mono<Token> {
|
||||
|
||||
@@ -24,14 +24,6 @@ class JWTUtil(private val tokenService: TokenService) {
|
||||
.setExpiration(expireAt) // 10 дней
|
||||
.signWith(key)
|
||||
.compact()
|
||||
tokenService.saveToken(
|
||||
token,
|
||||
username,
|
||||
LocalDateTime.from(
|
||||
expireAt.toInstant().atZone(ZoneId.systemDefault())
|
||||
.toLocalDateTime()
|
||||
)
|
||||
)
|
||||
return token
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user