auth;reg;fortorPassword;resetPassword

This commit is contained in:
Your Name 2025-02-23 18:38:10 +03:00
parent 42e0bc865c
commit 0789fc62d4
8 changed files with 632 additions and 131 deletions

View File

@ -10,6 +10,10 @@ android {
namespace = "com.example.testktor" namespace = "com.example.testktor"
compileSdk = 35 compileSdk = 35
packagingOptions {
exclude ("META-INF/versions/9/OSGI-INF/MANIFEST.MF")
}
defaultConfig { defaultConfig {
applicationId = "com.example.testktor" applicationId = "com.example.testktor"
minSdk = 24 minSdk = 24
@ -51,6 +55,7 @@ dependencies {
implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3) implementation(libs.androidx.material3)
implementation(libs.androidx.navigation.compose) implementation(libs.androidx.navigation.compose)
implementation(libs.identity.jvm)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)
@ -77,7 +82,7 @@ dependencies {
testImplementation("junit:junit:4.13.2") testImplementation("junit:junit:4.13.2")
testImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0") testImplementation ("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.8.0")
implementation("com.auth0:java-jwt:4.4.0") // Версия актуальна на 2024 год
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1") implementation("androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1")

View File

@ -73,6 +73,9 @@ import androidx.navigation.compose.rememberNavController
import com.example.matuletest.ui.auth.FirstScreen import com.example.matuletest.ui.auth.FirstScreen
import com.example.matuletest.ui.auth.SliderScreen import com.example.matuletest.ui.auth.SliderScreen
import com.example.testktor.auth.AuthScreen import com.example.testktor.auth.AuthScreen
import com.example.testktor.auth.ForgotPasswordScreen
import com.example.testktor.auth.RegScreen
import com.example.testktor.auth.ResetPasswordScreen
//import com.example.testktor.auth.AuthScreen //import com.example.testktor.auth.AuthScreen
//import com.example.testktor.auth.RegistrationScreen //import com.example.testktor.auth.RegistrationScreen
import com.example.testktor.ui.theme.TestKtorTheme import com.example.testktor.ui.theme.TestKtorTheme
@ -132,9 +135,15 @@ class MainActivity : ComponentActivity() {
composable("auth_screen") { composable("auth_screen") {
AuthScreen(navController) AuthScreen(navController)
} }
// composable("registration_screen") { composable("registration_screen") {
// RegistrationScreen() RegScreen(navController)
// } }
composable("resetPassword_screen") {
ResetPasswordScreen(navController)
}
composable("forgotPassword_screen") {
ForgotPasswordScreen(navController)
}
} }
} }
} }

View File

@ -32,7 +32,6 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
import androidx.navigation.NavController import androidx.navigation.NavController
import com.example.testktor.authUser import com.example.testktor.authUser
import com.example.testktor.getUser
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android import io.ktor.client.engine.android.Android
@ -74,15 +73,26 @@ fun AuthContent(
verticalArrangement = Arrangement.Center verticalArrangement = Arrangement.Center
) { ) {
// Отображение текста "Success" в левом верхнем углу // Отображение текста "Success" в левом верхнем углу
if (authSuccess == "Success") { if (authSuccess != null){
Text( if (authSuccess == "Success") {
text = "Success", Text(
modifier = Modifier text = "Success",
.padding(start = 16.dp, top = 16.dp) modifier = Modifier
.align(Alignment.Start), .padding(start = 16.dp, top = 16.dp)
color = Color.Green, .align(Alignment.Start),
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold) color = Color.Green,
) style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
} else{
Text(
text = "Error",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
}
} }
Text( Text(
@ -149,5 +159,23 @@ fun AuthContent(
), ),
) )
} }
Row(
modifier = Modifier
.padding(top = 8.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
ClickableText(
text = buildAnnotatedString { append("Восстановить") },
onClick = {
navController.navigate("forgotPassword_screen")
},
style = TextStyle(
fontSize = 16.sp,
color = Color.LightGray
),
)
}
} }
} }

View File

@ -0,0 +1,120 @@
package com.example.testktor.auth
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.PasswordVisualTransformation
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.testktor.forgotPassword
import com.example.testktor.resetPassword
import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
@Composable
fun ForgotPasswordScreen(navController: NavController) {
var forgotSuccess by remember { mutableStateOf<String?>(null) }
var email by remember { mutableStateOf("") }
val client = HttpClient(Android)
LaunchedEffect(email) {
if (email.isNotEmpty()) {
val result = forgotPassword(client, email)
forgotSuccess = if (result) "Success" else "Failed"
}
}
ForgotPasswordContent(navController, forgotSuccess, email) { newEmail ->
email = newEmail
}
}
@Composable
fun ForgotPasswordContent(
navController: NavController,
forgotSuccess: String?,
email: String,
onForgot: (String) -> Unit
) {
var emailIn by remember { mutableStateOf(email) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// Отображение текста "Success" в левом верхнем углу
if (forgotSuccess != null){
if (forgotSuccess == "Success") {
navController.navigate("resetPassword_screen")
} else{
Text(
text = "Error",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
}
}
Text(
text = "Забыл Пароль",
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
)
Text(
text = "Введите свою учетную запись для сброса",
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 20.dp),
style = TextStyle(fontSize = 16.sp),
textAlign = TextAlign.Center,
maxLines = 2
)
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = emailIn,
onValueChange = { emailIn = it }
)
Button(
modifier = Modifier.width(350.dp).height(50.dp),
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
containerColor = Color(0xFF48B2E7),
contentColor = Color.White
),
onClick = { onForgot(emailIn) }
) {
Text("Отправить")
}
}
}

View File

@ -1,39 +1,179 @@
//package com.example.testktor.auth package com.example.testktor.auth
//
//import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
//import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
//import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
//import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
//import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
//import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
//import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
//import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
//import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.ClickableText
//import androidx.compose.material3.Button import androidx.compose.material3.Button
//import androidx.compose.material3.Text import androidx.compose.material3.Text
//import androidx.compose.material3.TextField import androidx.compose.material3.TextField
//import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
//import androidx.compose.runtime.collectAsState import androidx.compose.runtime.LaunchedEffect
//import androidx.compose.ui.Alignment import androidx.compose.runtime.collectAsState
//import androidx.compose.ui.Modifier import androidx.compose.runtime.getValue
//import androidx.compose.ui.graphics.Color import androidx.compose.runtime.mutableStateOf
//import androidx.compose.ui.text.TextStyle import androidx.compose.runtime.remember
//import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.runtime.setValue
//import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.Alignment
//import androidx.compose.ui.text.input.PasswordVisualTransformation import androidx.compose.ui.Modifier
//import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.graphics.Color
//import androidx.compose.ui.unit.dp import androidx.compose.ui.text.TextStyle
//import androidx.compose.ui.unit.sp import androidx.compose.ui.text.buildAnnotatedString
//import androidx.lifecycle.viewmodel.compose.viewModel import androidx.compose.ui.text.font.FontWeight
//import androidx.navigation.NavController import androidx.compose.ui.text.input.PasswordVisualTransformation
//import com.example.matuletest.ui.auth.AuthScreenViewModel import androidx.compose.ui.text.style.TextAlign
// import androidx.compose.ui.unit.dp
//@Composable import androidx.compose.ui.unit.sp
//fun RegistrationScreen(navController: NavController) { import androidx.lifecycle.viewmodel.compose.viewModel
// val viewModel: AuthScreenViewModel = viewModel() import androidx.navigation.NavController
// RegistrationContent(viewModel, navController) import com.example.testktor.authUser
//} import com.example.testktor.regUser
// import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
@Composable
fun RegScreen(navController: NavController) {
var regSuccess by remember { mutableStateOf<String?>(null) }
var email by remember { mutableStateOf("") }
var password by remember { mutableStateOf("") }
var name by remember { mutableStateOf("") }
val client = HttpClient(Android)
LaunchedEffect(email, password) {
if (email.isNotEmpty() && password.isNotEmpty()) {
val result = regUser(client, email, password, name)
regSuccess = if (result) "Success" else "Failed"
}
}
RegContent(navController, regSuccess, email, password, name) { newEmail, newPassword, newName ->
email = newEmail
password = newPassword
name = newName
}
}
@Composable
fun RegContent(
navController: NavController,
regSuccess: String?,
email: String,
password: String,
name: String,
onReg: (String, String, String) -> Unit
) {
var emailIn by remember { mutableStateOf(email) }
var passwordIn by remember { mutableStateOf(password) }
var nameIn by remember { mutableStateOf(name) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// Отображение текста "Success" в левом верхнем углу
if (regSuccess != null){
if (regSuccess == "Success") {
Text(
text = "Success",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
} else{
Text(
text = "Error",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
}
}
Text(
text = "Регистрация!",
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
)
Text(
text = "Заполните Свои данные или продолжите через социальные медиа",
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 20.dp),
style = TextStyle(fontSize = 16.sp),
textAlign = TextAlign.Center,
maxLines = 2
)
Text(text = "Ваше имя", modifier = Modifier.padding(end = 255.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = nameIn,
onValueChange = { nameIn = it }
)
Text(text = "Email", modifier = Modifier.padding(end = 255.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = emailIn,
onValueChange = { emailIn = it }
)
Text(text = "Password", modifier = Modifier.padding(end = 225.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = passwordIn,
onValueChange = { passwordIn = it }
)
Button(
modifier = Modifier.width(350.dp).height(50.dp),
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
containerColor = Color(0xFF48B2E7),
contentColor = Color.White
),
onClick = { onReg(emailIn, passwordIn, nameIn) }
) {
Text("Зарегистрироваться")
}
Row(
modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Center
) {
Text(
text = "Есть аккаунт? ",
style = TextStyle(fontSize = 16.sp, color = Color.Black)
)
ClickableText(
text = buildAnnotatedString { append("Войти") },
onClick = {
navController.navigate("auth_screen")
},
style = TextStyle(
fontSize = 16.sp,
color = Color.Black
),
)
}
}
}
//@Composable //@Composable
//fun RegistrationContent(viewModel: AuthScreenViewModel, navController: NavController){ //fun RegistrationContent(viewModel: AuthScreenViewModel, navController: NavController){
// val regState = viewModel.registrationScreenState.collectAsState() // val regState = viewModel.registrationScreenState.collectAsState()

View File

@ -0,0 +1,134 @@
package com.example.testktor.auth
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.navigation.NavController
import com.example.testktor.authUser
import com.example.testktor.resetPassword
import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
@Composable
fun ResetPasswordScreen(navController: NavController) {
var resetSuccess by remember { mutableStateOf<String?>(null) }
var code by remember { mutableStateOf("") }
var newPassword by remember { mutableStateOf("") }
val client = HttpClient(Android)
LaunchedEffect(code, newPassword) {
if (code.isNotEmpty() && newPassword.isNotEmpty()) {
val result = resetPassword(client, code, newPassword)
resetSuccess = if (result) "Success" else "Failed"
}
}
ResetPasswordContent(navController, resetSuccess, code, newPassword) { newCode, newNewPassword ->
code = newCode
newPassword = newNewPassword
}
}
@Composable
fun ResetPasswordContent(
navController: NavController,
resetSuccess: String?,
code: String,
newPassword: String,
onReset: (String, String) -> Unit
) {
var codeIn by remember { mutableStateOf(code) }
var newPasswordIn by remember { mutableStateOf(newPassword) }
Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
// Отображение текста "Success" в левом верхнем углу
if (resetSuccess != null){
if (resetSuccess == "Success") {
Text(
text = "Success",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
} else{
Text(
text = "Error",
modifier = Modifier
.padding(start = 16.dp, top = 16.dp)
.align(Alignment.Start),
color = Color.Green,
style = TextStyle(fontSize = 18.sp, fontWeight = FontWeight.Bold)
)
}
}
Text(
text = "ОТР Проверка",
style = TextStyle(fontSize = 32.sp, fontWeight = FontWeight.Bold),
modifier = Modifier.height(60.dp).padding(bottom = 20.dp)
)
Text(
text = "Пожалуйста, проверьте свою электронную почту, чтобы увидеть код подтверждения",
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 20.dp),
style = TextStyle(fontSize = 16.sp),
textAlign = TextAlign.Center,
maxLines = 3
)
Text(text = "OTP Code", modifier = Modifier.padding(end = 255.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = codeIn,
onValueChange = { codeIn = it }
)
Text(text = "New Password", modifier = Modifier.padding(end = 255.dp))
TextField(
modifier = Modifier.width(300.dp).height(70.dp).padding(bottom = 16.dp),
value = newPasswordIn,
onValueChange = { newPasswordIn = it }
)
Button(
modifier = Modifier.width(350.dp).height(50.dp),
colors = androidx.compose.material3.ButtonDefaults.buttonColors(
containerColor = Color(0xFF48B2E7),
contentColor = Color.White
),
onClick = { onReset(codeIn, newPasswordIn) }
) {
Text("Восстановить")
}
}
}

View File

@ -16,17 +16,18 @@ import com.example.testktor.ui.theme.TestKtorTheme
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android import io.ktor.client.engine.android.Android
import io.ktor.client.request.get import io.ktor.client.request.get
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsText import io.ktor.client.statement.bodyAsText
import io.ktor.client.utils.EmptyContent.contentType
import io.ktor.http.ContentType import io.ktor.http.ContentType
import io.ktor.http.contentType import io.ktor.http.contentType
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
import java.sql.Time
@Serializable
data class User(val id: Int, val email: String, val password: String)
//@Composable //@Composable
//fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) { //fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) {
@ -89,90 +90,152 @@ data class User(val id: Int, val email: String, val password: String)
// } // }
//} //}
@Composable @Serializable
fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) { data class User(
var user by remember { mutableStateOf<User?>(null) } val id: Int,
var isLoading by remember { mutableStateOf(true) } val name: String,
var errorMessage by remember { mutableStateOf<String?>(null) } val email: String,
val password: String,
val resetToken: String)
val scope = rememberCoroutineScope() //@Composable
//fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) {
// var user by remember { mutableStateOf<User?>(null) }
// var isLoading by remember { mutableStateOf(true) }
// var errorMessage by remember { mutableStateOf<String?>(null) }
//
// val scope = rememberCoroutineScope()
//
// LaunchedEffect(Unit) {
// try {
// val fetchedUser = getUser(client)
// user = fetchedUser
// } catch (e: Exception) {
// errorMessage = "Error fetching user: ${e.localizedMessage}"
// Log.e("UserScreen", "Error: ${e.localizedMessage}", e)
// }
// isLoading = false
// }
//
// if (isLoading) {
// CircularProgressIndicator()
// }
//
// errorMessage?.let {
// Text(text = it)
// }
//
// user?.let {
// Text(text = "User: ${it.email}, ID: ${it.id}")
// } ?: run {
// Text(text = "No user found or failed to load.")
// }
//}
LaunchedEffect(Unit) { //suspend fun getUser(client: HttpClient): User {
try { // val response: HttpResponse = client.get("http://10.0.2.2:8080/user") {
val fetchedUser = getUser(client) // Получаем одного пользователя // contentType(ContentType.Application.Json)
user = fetchedUser // }
} catch (e: Exception) { // val responseBody = response.bodyAsText()
errorMessage = "Error fetching user: ${e.localizedMessage}" // Log.d("getUser", "Response: $responseBody")
Log.e("UserScreen", "Error: ${e.localizedMessage}", e) //
} // val json = Json { ignoreUnknownKeys = true }
isLoading = false //
} // val buba = json.decodeFromString<User>(responseBody)
// Log.d("json", buba.email)
if (isLoading) { //
CircularProgressIndicator() // return try {
} // json.decodeFromString<User>(responseBody)
// } catch (e: Exception) {
errorMessage?.let { // Log.e("getUser", "Error deserializing response", e)
Text(text = it) // throw e
} // }
//}
user?.let {
Text(text = "User: ${it.email}, ID: ${it.id}") // Отображаем имя пользователя
} ?: run {
Text(text = "No user found or failed to load.")
}
}
suspend fun getUser(client: HttpClient): User {
val response: HttpResponse = client.get("http://10.0.2.2:8080/user") {
contentType(ContentType.Application.Json)
}
val responseBody = response.bodyAsText()
Log.d("getUser", "Response: $responseBody") // Логируем ответ сервера
val json = Json { ignoreUnknownKeys = true }
val buba = json.decodeFromString<User>(responseBody) // Десериализуем в объект User
Log.d("json", buba.email)
return try {
json.decodeFromString<User>(responseBody) // Десериализуем в объект User
} catch (e: Exception) {
Log.e("getUser", "Error deserializing response", e)
throw e // Повторно выбрасываем ошибку, чтобы она была обработана в UserScreen
}
}
suspend fun authUser(client: HttpClient, email: String, password: String): Boolean { suspend fun authUser(client: HttpClient, email: String, password: String): Boolean {
val response: HttpResponse = client.get("http://10.0.2.2:8080/user2?email=$email") { try {
contentType(ContentType.Application.Json) val response: HttpResponse = client.post("http://10.0.2.2:8080/login") {
} contentType(ContentType.Application.Json)
setBody(Json.encodeToString(mapOf("email" to email, "password" to password)))
val responseBody = response.bodyAsText()
Log.d("authUser", "Response: $responseBody") // Логируем ответ сервера
val json = Json { ignoreUnknownKeys = true }
return try {
val user = json.decodeFromString<User>(responseBody) // Десериализуем в объект User
// Проверяем, совпадает ли пароль
if (user.password == password) {
true // Возвращаем true, если пароль совпадает
} else {
Log.e("authUser", "Incorrect password")
false // Возвращаем false, если пароль неверный
} }
val responseBody = response.bodyAsText()
Log.d("authUser", "Response: $responseBody")
val json = Json { ignoreUnknownKeys = true }
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
return responseMap["message"] == "Вход успешен"
} catch (e: Exception) { } catch (e: Exception) {
Log.e("authUser", "Error deserializing response", e) Log.e("authUser", "Error during login request", e)
false // Возвращаем false в случае ошибки return false
} }
} }
@Preview(showBackground = true) suspend fun regUser(client: HttpClient, email: String, password: String, name: String): Boolean{
@Composable try{
fun UserScreenPreview() { val response: HttpResponse = client.post("http://10.0.2.2:8080/register"){
TestKtorTheme { contentType(ContentType.Application.Json)
UserScreen(client = HttpClient(Android)) setBody(Json.encodeToString(mapOf("name" to name, "email" to email, "password" to password)))
}
val responseBody = response.bodyAsText()
Log.d("regUser", "Response: $responseBody")
val json = Json { ignoreUnknownKeys = true }
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
return responseMap["message"] == "Регистрация успешна"
} catch (e: Exception){
Log.e("regUser", "Error during registration request", e)
return false
} }
} }
suspend fun forgotPassword(client: HttpClient, email: String): Boolean{
try{
val response: HttpResponse = client.post("http://10.0.2.2:8080/forgot-password"){
contentType(ContentType.Application.Json)
setBody(Json.encodeToString(mapOf("email" to email)))
}
val responseBody = response.bodyAsText()
Log.d("forgotPassword", "Response: $responseBody")
val json = Json { ignoreUnknownKeys = true }
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
return responseMap["message"] == "Код на восстановление пароля отправлен"
} catch (e: Exception){
Log.e("forgotPassword", "Error during forgotting password", e)
return false
}
}
suspend fun resetPassword(client: HttpClient, code: String, newPassword: String): Boolean{
try{
val response: HttpResponse = client.post("http://10.0.2.2:8080/reset-password"){
contentType(ContentType.Application.Json)
setBody(Json.encodeToString(mapOf("code" to code, "newPassword" to newPassword)))
}
val responseBody = response.bodyAsText()
Log.d("resetPassword", "Response: $responseBody")
val json = Json { ignoreUnknownKeys = true }
val responseMap = json.decodeFromString<Map<String, String>>(responseBody)
return responseMap["message"] == "Пароль успешно изменён"
} catch (e: Exception){
Log.e("resetPassword", "Error during resetting password", e)
return false
}
}
//@Preview(showBackground = true)
//@Composable
//fun UserScreenPreview() {
// TestKtorTheme {
// UserScreen(client = HttpClient(Android))
// }
//}

View File

@ -9,6 +9,7 @@ lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.10.0" activityCompose = "1.10.0"
composeBom = "2024.04.01" composeBom = "2024.04.01"
navigationCompose = "2.8.7" navigationCompose = "2.8.7"
identityJvm = "202411.1"
[libraries] [libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
@ -26,6 +27,7 @@ androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-man
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
androidx-material3 = { group = "androidx.compose.material3", name = "material3" } androidx-material3 = { group = "androidx.compose.material3", name = "material3" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" } androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
identity-jvm = { group = "com.android.identity", name = "identity-jvm", version.ref = "identityJvm" }
[plugins] [plugins]
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }