diff --git a/src/main/kotlin/Application.kt b/src/main/kotlin/Application.kt index 66bd26e..dd6ba14 100644 --- a/src/main/kotlin/Application.kt +++ b/src/main/kotlin/Application.kt @@ -8,7 +8,7 @@ import org.example.auth.authRoutes import io.ktor.server.routing.routing fun main() { - embeddedServer(Netty, port = 8080, host = "0.0.0.0") { + embeddedServer(Netty, port = 8080, host = "localhost") { configureSecurity() configureSerialization() configureRouting() diff --git a/src/main/kotlin/auth/AuthRoutes.kt b/src/main/kotlin/auth/AuthRoutes.kt index 573b37d..916ca13 100644 --- a/src/main/kotlin/auth/AuthRoutes.kt +++ b/src/main/kotlin/auth/AuthRoutes.kt @@ -6,44 +6,82 @@ import org.example.dto.requests.SignUpRequest import org.example.dto.responses.AuthResponse import org.example.data.DataRepository import io.ktor.server.application.* -import io.ktor.server.auth.authenticate -import io.ktor.server.auth.jwt.JWTPrincipal -import io.ktor.server.auth.principal import io.ktor.server.request.* import io.ktor.server.response.* import io.ktor.server.routing.* +import org.example.dto.requests.ForgotPasswordRequest +import org.example.dto.requests.VerifyCodeRequest +import org.example.dto.responses.ForgotPasswordResponse +import org.example.dto.responses.PasswordResponse fun Route.authRoutes() { post("/sign-up") { val request = call.receive() + println("/регистрация: $request") + val user = DataRepository.createUser(request) - call.respond(AuthResponse(token = JwtConfig.makeToken(user.id))) + println("пользователь создан: $user") + + val token = JwtConfig.makeToken(user.id) + println("сгенерированный токен: $token") + + call.respond(AuthResponse(token = token)) } post("/sign-in") { val request = call.receive() + println("/вход: $request") + val user = DataRepository.authenticate(request) - ?: throw IllegalArgumentException("Invalid credentials") - call.respond(AuthResponse(token = JwtConfig.makeToken(user.id))) + if (user == null) { + println("ошибка аутентификации для email: ${request.email}") + throw IllegalArgumentException("Invalid credentials") + } + + val token = JwtConfig.makeToken(user.id) + println("успешный вход для: ${user.email}, токен: $token") + + call.respond(AuthResponse(token = token)) } - authenticate { - get("/me") { - val principal = call.principal() - val userId = principal?.payload?.getClaim("userId")?.asInt() + post("/forgot-password") { + val request = call.receive() + println("запрос на сброс пароля для: ${request.email}") - if (userId == null) { - call.respond(HttpStatusCode.Unauthorized, "Invalid token") - return@get - } + try { + val code = DataRepository.initiatePasswordReset(request.email) + println("код сброса пароля для ${request.email}: $code") - val user = DataRepository.findById(userId) - if (user == null) { - call.respond(HttpStatusCode.NotFound, "User not found") - return@get - } + call.respond( + ForgotPasswordResponse( + message = "Код отправлен на email", + code = code + ) + ) + } catch (e: IllegalArgumentException) { + println("ошибка при сбросе пароля: ${e.message}") + call.respond( + HttpStatusCode.BadRequest, + ForgotPasswordResponse(message = e.message ?: "Ошибка") + ) + } + } - call.respond(user) + post("/verify-reset-code") { + val request = call.receive() + println("проверка кода ${request.code} для ${request.email}") + + try { + val password = DataRepository.verifyResetCode(request.email, request.code) + println("успешная проверка кода для ${request.email}, пароль: $password") + + call.respond(PasswordResponse(password = password)) + } catch (e: IllegalArgumentException) { + println("неверный код для ${request.email}: ${request.code}") + call.respond( + HttpStatusCode.BadRequest, + ForgotPasswordResponse(message = e.message ?: "Неверный код") + ) } } } \ No newline at end of file diff --git a/src/main/kotlin/data/DataRepository.kt b/src/main/kotlin/data/DataRepository.kt index 35050ce..87f32ce 100644 --- a/src/main/kotlin/data/DataRepository.kt +++ b/src/main/kotlin/data/DataRepository.kt @@ -7,13 +7,14 @@ import java.util.concurrent.atomic.AtomicInteger object DataRepository { private val users = mutableListOf() - private val idCounter = AtomicInteger(1) // Автоинкремент ID + private val idCounter = AtomicInteger(1) + private val passwordResetCodes = mutableMapOf() fun createUser(request: SignUpRequest): User { val user = User( id = idCounter.getAndIncrement(), email = request.email, - password = request.password, // В реальном приложении хешируйте пароль! + password = request.password, name = request.name ) users.add(user) @@ -28,6 +29,28 @@ object DataRepository { return users.find { it.id == id } } + fun initiatePasswordReset(email: String): String { + val user = users.find { it.email == email } + ?: throw IllegalArgumentException("User not found") + + val code = (100000..999999).random().toString() + passwordResetCodes[email] = code + + return code + } + + fun verifyResetCode(email: String, code: String): String { + val storedCode = passwordResetCodes[email] + ?: throw IllegalArgumentException("No code requested for this email") + + if (storedCode != code) { + throw IllegalArgumentException("Invalid code") + } + + return users.find { it.email == email }?.password + ?: throw IllegalArgumentException("User not found") + } + init { createUser( SignUpRequest( diff --git a/src/main/kotlin/dto/requests/ForgotPasswordRequest.kt b/src/main/kotlin/dto/requests/ForgotPasswordRequest.kt new file mode 100644 index 0000000..af29d28 --- /dev/null +++ b/src/main/kotlin/dto/requests/ForgotPasswordRequest.kt @@ -0,0 +1,8 @@ +package org.example.dto.requests + +import kotlinx.serialization.Serializable + +@Serializable +data class ForgotPasswordRequest( + val email: String +) \ No newline at end of file diff --git a/src/main/kotlin/dto/requests/VerifyCodeRequest.kt b/src/main/kotlin/dto/requests/VerifyCodeRequest.kt new file mode 100644 index 0000000..ef82070 --- /dev/null +++ b/src/main/kotlin/dto/requests/VerifyCodeRequest.kt @@ -0,0 +1,9 @@ +package org.example.dto.requests + +import kotlinx.serialization.Serializable + +@Serializable +data class VerifyCodeRequest( + val email: String, + val code: String +) \ No newline at end of file diff --git a/src/main/kotlin/dto/responses/ForgotPasswordResponse.kt b/src/main/kotlin/dto/responses/ForgotPasswordResponse.kt new file mode 100644 index 0000000..58efc9a --- /dev/null +++ b/src/main/kotlin/dto/responses/ForgotPasswordResponse.kt @@ -0,0 +1,9 @@ +package org.example.dto.responses + +import kotlinx.serialization.Serializable + +@Serializable +data class ForgotPasswordResponse( + val message: String, + val code: String? = null +) \ No newline at end of file diff --git a/src/main/kotlin/dto/responses/PasswordResponse.kt b/src/main/kotlin/dto/responses/PasswordResponse.kt new file mode 100644 index 0000000..8051295 --- /dev/null +++ b/src/main/kotlin/dto/responses/PasswordResponse.kt @@ -0,0 +1,8 @@ +package org.example.dto.responses + +import kotlinx.serialization.Serializable + +@Serializable +data class PasswordResponse( + val password: String +) \ No newline at end of file