tg login
This commit is contained in:
@@ -1,23 +1,67 @@
|
||||
package space.luminic.finance.api
|
||||
|
||||
|
||||
import org.apache.commons.codec.digest.DigestUtils.sha256
|
||||
import org.apache.commons.codec.digest.HmacUtils.hmacSha256
|
||||
import org.slf4j.LoggerFactory
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.security.core.context.SecurityContextHolder
|
||||
import org.springframework.web.bind.annotation.*
|
||||
import space.luminic.finance.dtos.UserDTO
|
||||
import space.luminic.finance.dtos.UserDTO.AuthUserDTO
|
||||
import space.luminic.finance.dtos.UserDTO.RegisterUserDTO
|
||||
import space.luminic.finance.mappers.UserMapper.toDto
|
||||
import space.luminic.finance.mappers.UserMapper.toTelegramMap
|
||||
import space.luminic.finance.services.AuthService
|
||||
import java.security.MessageDigest
|
||||
import java.time.Instant
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/auth")
|
||||
class AuthController(
|
||||
private val authService: AuthService
|
||||
private val authService: AuthService,
|
||||
@Value("\${telegram.bot.token}") private val botToken: String
|
||||
) {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(javaClass)
|
||||
|
||||
fun verifyTelegramAuth(data: Map<String, String>, botToken: String): Boolean {
|
||||
val hash = data["hash"] ?: return false
|
||||
|
||||
val dataCheckString = data
|
||||
.filterKeys { it != "hash" }
|
||||
.toSortedMap()
|
||||
.map { "${it.key}=${it.value}" }
|
||||
.joinToString("\n")
|
||||
|
||||
val secretKey = sha256(botToken)
|
||||
val hmacHex = hmacSha256(secretKey, dataCheckString)
|
||||
|
||||
if (hmacHex != hash) return false
|
||||
|
||||
val authDate = data["auth_date"]?.toLongOrNull() ?: return false
|
||||
val now = Instant.now().epochSecond
|
||||
|
||||
// Опционально — запрет старых ответов (например, старше 1 часа)
|
||||
val maxAgeSeconds = 3600
|
||||
if (now - authDate > maxAgeSeconds) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
private fun sha256(input: String): ByteArray =
|
||||
MessageDigest.getInstance("SHA-256").digest(input.toByteArray())
|
||||
|
||||
private fun hmacSha256(secret: ByteArray, message: String): String {
|
||||
val key = SecretKeySpec(secret, "HmacSHA256")
|
||||
val mac = Mac.getInstance("HmacSHA256")
|
||||
mac.init(key)
|
||||
val hashBytes = mac.doFinal(message.toByteArray())
|
||||
return hashBytes.joinToString("") { "%02x".format(it) }
|
||||
}
|
||||
|
||||
@GetMapping("/test")
|
||||
fun test(): String {
|
||||
val authentication = SecurityContextHolder.getContext().authentication
|
||||
@@ -26,23 +70,26 @@ class AuthController(
|
||||
}
|
||||
|
||||
@PostMapping("/login")
|
||||
fun login(@RequestBody request: AuthUserDTO): Map<String, String> {
|
||||
fun login(@RequestBody request: AuthUserDTO): Map<String, String> {
|
||||
val token = authService.login(request.username.lowercase(), request.password)
|
||||
return mapOf("token" to token)
|
||||
}
|
||||
|
||||
@PostMapping("/register")
|
||||
fun register(@RequestBody request: RegisterUserDTO): UserDTO {
|
||||
fun register(@RequestBody request: RegisterUserDTO): UserDTO {
|
||||
return authService.register(request.username, request.password, request.firstName).toDto()
|
||||
}
|
||||
|
||||
@PostMapping("/tgLogin")
|
||||
fun tgLogin(@RequestHeader("X-Tg-Id") tgId: String): Map<String, String> {
|
||||
val token = authService.tgLogin(tgId)
|
||||
return mapOf("token" to token)
|
||||
@PostMapping("/tg-login")
|
||||
fun tgLogin(@RequestBody tgUser: UserDTO.TelegramAuthDTO): String {
|
||||
val ok = verifyTelegramAuth(tgUser.toTelegramMap(), botToken)
|
||||
if (!ok) throw IllegalArgumentException("Invalid Telegram login")
|
||||
return authService.tgAuth(tgUser)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@GetMapping("/me")
|
||||
fun getMe(): UserDTO {
|
||||
logger.info("Get Me")
|
||||
|
||||
Reference in New Issue
Block a user