From 0789fc62d46c55ac80dd34daa5a6277e2b2621b0 Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 23 Feb 2025 18:38:10 +0300 Subject: [PATCH] auth;reg;fortorPassword;resetPassword --- app/build.gradle.kts | 7 +- .../java/com/example/testktor/MainActivity.kt | 15 +- .../com/example/testktor/auth/AuthScreen.kt | 48 +++- .../testktor/auth/ForgotPasswordScreen.kt | 120 ++++++++++ .../testktor/auth/RegistrationScreen.kt | 212 ++++++++++++++--- .../testktor/auth/ResetPasswordScreen.kt | 134 +++++++++++ .../main/java/com/example/testktor/getUser.kt | 225 +++++++++++------- gradle/libs.versions.toml | 2 + 8 files changed, 632 insertions(+), 131 deletions(-) create mode 100644 app/src/main/java/com/example/testktor/auth/ForgotPasswordScreen.kt create mode 100644 app/src/main/java/com/example/testktor/auth/ResetPasswordScreen.kt diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2fae56b..ace528d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -10,6 +10,10 @@ android { namespace = "com.example.testktor" compileSdk = 35 + packagingOptions { + exclude ("META-INF/versions/9/OSGI-INF/MANIFEST.MF") + } + defaultConfig { applicationId = "com.example.testktor" minSdk = 24 @@ -51,6 +55,7 @@ dependencies { implementation(libs.androidx.ui.tooling.preview) implementation(libs.androidx.material3) implementation(libs.androidx.navigation.compose) + implementation(libs.identity.jvm) testImplementation(libs.junit) androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.espresso.core) @@ -77,7 +82,7 @@ dependencies { testImplementation("junit:junit:4.13.2") 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") diff --git a/app/src/main/java/com/example/testktor/MainActivity.kt b/app/src/main/java/com/example/testktor/MainActivity.kt index 21c4783..c6a5cb0 100644 --- a/app/src/main/java/com/example/testktor/MainActivity.kt +++ b/app/src/main/java/com/example/testktor/MainActivity.kt @@ -73,6 +73,9 @@ import androidx.navigation.compose.rememberNavController import com.example.matuletest.ui.auth.FirstScreen import com.example.matuletest.ui.auth.SliderScreen 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.RegistrationScreen import com.example.testktor.ui.theme.TestKtorTheme @@ -132,9 +135,15 @@ class MainActivity : ComponentActivity() { composable("auth_screen") { AuthScreen(navController) } -// composable("registration_screen") { -// RegistrationScreen() -// } + composable("registration_screen") { + RegScreen(navController) + } + composable("resetPassword_screen") { + ResetPasswordScreen(navController) + } + composable("forgotPassword_screen") { + ForgotPasswordScreen(navController) + } } } } diff --git a/app/src/main/java/com/example/testktor/auth/AuthScreen.kt b/app/src/main/java/com/example/testktor/auth/AuthScreen.kt index 29d3772..e6897a0 100644 --- a/app/src/main/java/com/example/testktor/auth/AuthScreen.kt +++ b/app/src/main/java/com/example/testktor/auth/AuthScreen.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.sp import androidx.navigation.NavController import com.example.testktor.authUser -import com.example.testktor.getUser import io.ktor.client.HttpClient import io.ktor.client.engine.android.Android @@ -74,15 +73,26 @@ fun AuthContent( verticalArrangement = Arrangement.Center ) { // Отображение текста "Success" в левом верхнем углу - if (authSuccess == "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) - ) + if (authSuccess != null){ + if (authSuccess == "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( @@ -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 + ), + ) + } } } \ No newline at end of file diff --git a/app/src/main/java/com/example/testktor/auth/ForgotPasswordScreen.kt b/app/src/main/java/com/example/testktor/auth/ForgotPasswordScreen.kt new file mode 100644 index 0000000..8b47f81 --- /dev/null +++ b/app/src/main/java/com/example/testktor/auth/ForgotPasswordScreen.kt @@ -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(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("Отправить") + } + } +} diff --git a/app/src/main/java/com/example/testktor/auth/RegistrationScreen.kt b/app/src/main/java/com/example/testktor/auth/RegistrationScreen.kt index d405fd0..82ea99d 100644 --- a/app/src/main/java/com/example/testktor/auth/RegistrationScreen.kt +++ b/app/src/main/java/com/example/testktor/auth/RegistrationScreen.kt @@ -1,39 +1,179 @@ -//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.collectAsState -//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.lifecycle.viewmodel.compose.viewModel -//import androidx.navigation.NavController -//import com.example.matuletest.ui.auth.AuthScreenViewModel -// -//@Composable -//fun RegistrationScreen(navController: NavController) { -// val viewModel: AuthScreenViewModel = viewModel() -// RegistrationContent(viewModel, navController) -//} -// +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.collectAsState +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.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.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(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 //fun RegistrationContent(viewModel: AuthScreenViewModel, navController: NavController){ // val regState = viewModel.registrationScreenState.collectAsState() diff --git a/app/src/main/java/com/example/testktor/auth/ResetPasswordScreen.kt b/app/src/main/java/com/example/testktor/auth/ResetPasswordScreen.kt new file mode 100644 index 0000000..ec46e4f --- /dev/null +++ b/app/src/main/java/com/example/testktor/auth/ResetPasswordScreen.kt @@ -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(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("Восстановить") + } + } +} diff --git a/app/src/main/java/com/example/testktor/getUser.kt b/app/src/main/java/com/example/testktor/getUser.kt index 772035a..1b04ba9 100644 --- a/app/src/main/java/com/example/testktor/getUser.kt +++ b/app/src/main/java/com/example/testktor/getUser.kt @@ -16,17 +16,18 @@ import com.example.testktor.ui.theme.TestKtorTheme import io.ktor.client.HttpClient import io.ktor.client.engine.android.Android 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.bodyAsText +import io.ktor.client.utils.EmptyContent.contentType import io.ktor.http.ContentType import io.ktor.http.contentType import kotlinx.serialization.Serializable import kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json - - -@Serializable -data class User(val id: Int, val email: String, val password: String) +import java.sql.Time //@Composable //fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) { @@ -89,90 +90,152 @@ data class User(val id: Int, val email: String, val password: String) // } //} -@Composable -fun UserScreen(modifier: Modifier = Modifier, client: HttpClient) { - var user by remember { mutableStateOf(null) } - var isLoading by remember { mutableStateOf(true) } - var errorMessage by remember { mutableStateOf(null) } +@Serializable +data class User( + val id: Int, + val name: String, + 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(null) } +// var isLoading by remember { mutableStateOf(true) } +// var errorMessage by remember { mutableStateOf(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) { - 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.") - } -} - -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(responseBody) // Десериализуем в объект User - Log.d("json", buba.email) - - return try { - json.decodeFromString(responseBody) // Десериализуем в объект User - } catch (e: Exception) { - Log.e("getUser", "Error deserializing response", e) - throw e // Повторно выбрасываем ошибку, чтобы она была обработана в UserScreen - } -} +//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(responseBody) +// Log.d("json", buba.email) +// +// return try { +// json.decodeFromString(responseBody) +// } catch (e: Exception) { +// Log.e("getUser", "Error deserializing response", e) +// throw e +// } +//} suspend fun authUser(client: HttpClient, email: String, password: String): Boolean { - val response: HttpResponse = client.get("http://10.0.2.2:8080/user2?email=$email") { - contentType(ContentType.Application.Json) - } - - val responseBody = response.bodyAsText() - Log.d("authUser", "Response: $responseBody") // Логируем ответ сервера - - val json = Json { ignoreUnknownKeys = true } - - return try { - val user = json.decodeFromString(responseBody) // Десериализуем в объект User - - // Проверяем, совпадает ли пароль - if (user.password == password) { - true // Возвращаем true, если пароль совпадает - } else { - Log.e("authUser", "Incorrect password") - false // Возвращаем false, если пароль неверный + try { + 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 } + val responseMap = json.decodeFromString>(responseBody) + + return responseMap["message"] == "Вход успешен" } catch (e: Exception) { - Log.e("authUser", "Error deserializing response", e) - false // Возвращаем false в случае ошибки + Log.e("authUser", "Error during login request", e) + return false } } -@Preview(showBackground = true) -@Composable -fun UserScreenPreview() { - TestKtorTheme { - UserScreen(client = HttpClient(Android)) +suspend fun regUser(client: HttpClient, email: String, password: String, name: String): Boolean{ + try{ + val response: HttpResponse = client.post("http://10.0.2.2:8080/register"){ + contentType(ContentType.Application.Json) + 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>(responseBody) + + return responseMap["message"] == "Регистрация успешна" + } catch (e: Exception){ + Log.e("regUser", "Error during registration request", e) + return false } -} \ No newline at end of file +} + +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>(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>(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)) +// } +//} \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index aa6c917..5511a4b 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -9,6 +9,7 @@ lifecycleRuntimeKtx = "2.8.7" activityCompose = "1.10.0" composeBom = "2024.04.01" navigationCompose = "2.8.7" +identityJvm = "202411.1" [libraries] 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-material3 = { group = "androidx.compose.material3", name = "material3" } 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] android-application = { id = "com.android.application", version.ref = "agp" }