package space.luminic.finance.services import org.springframework.cache.annotation.Cacheable import org.springframework.security.core.context.SecurityContextHolder import org.springframework.security.core.userdetails.UsernameNotFoundException import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder import org.springframework.stereotype.Service import space.luminic.finance.configs.AuthException import space.luminic.finance.models.Token import space.luminic.finance.models.User import space.luminic.finance.repos.UserRepo import space.luminic.finance.utils.JWTUtil import java.time.Instant import java.util.* @Service class AuthService( private val userRepo: UserRepo, private val tokenService: TokenService, private val jwtUtil: JWTUtil, private val userService: UserService, ) { private val passwordEncoder = BCryptPasswordEncoder() fun getSecurityUser(): User { val securityContextHolder = SecurityContextHolder.getContext() ?: throw AuthException("Authentication failed") val authentication = securityContextHolder.authentication val username = authentication.name // Получаем пользователя по имени return userService.getById(username.toInt()) } fun getSecurityUserId(): Int { val securityContextHolder = SecurityContextHolder.getContext() ?: throw AuthException("Authentication failed") val authentication = securityContextHolder.authentication val username = authentication.name // Получаем пользователя по имени return username.toInt() } fun login(username: String, password: String): String { val user = userRepo.findByUsername(username) ?: 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( token = token, username = username, expiresAt = expireAt.toInstant() ) token } else { throw IllegalArgumentException("Ошибка логина или пароля") } } fun tgLogin(tgId: String): String { val user = userRepo.findByTgId(tgId) ?: throw UsernameNotFoundException("Пользователь не найден") val token = jwtUtil.generateToken(user.username) val expireAt = Date(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 10) tokenService.saveToken( token = token, username = user.username, expiresAt = expireAt.toInstant() ) return token } fun register(username: String, password: String, firstName: String): User { val user = userRepo.findByUsername(username) if (user == null) { var newUser = User( username = username, password = passwordEncoder.encode(password), // Шифрование пароля firstName = firstName, roles = mutableListOf("USER") ) newUser = userRepo.save(newUser) return newUser } else throw IllegalArgumentException("Пользователь уже зарегистрирован") } @Cacheable(cacheNames = ["tokens"], key = "#token") fun isTokenValid(token: String): User { val tokenDetails = tokenService.getToken(token) when { tokenDetails.status == Token.TokenStatus.ACTIVE && tokenDetails.expiresAt.isAfter(Instant.now()) -> { return tokenDetails.user } else -> { tokenService.revokeToken(tokenDetails.token) throw AuthException("Токен истек или не валиден") } } } }