Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ fun DesktopApp(
selectColorTheme: (ColorThemeOption) -> Unit,
toggleMaxScreen: () -> Unit,
navigateToRegister: () -> Unit,
navigateToResetPassword: () -> Unit,
startDestination: String = startDestination(),
) {
if (writeopiaDb != null) {
Expand Down Expand Up @@ -231,6 +232,7 @@ fun DesktopApp(
},
deleteModel = globalShellViewModel::deleteModel,
signIn = navigateToRegister,
resetPassword = navigateToResetPassword,
logout = globalShellViewModel::logout,
showDeleteConfirm = globalShellViewModel::showDeleteConfirm,
dismissDeleteConfirm = globalShellViewModel::dismissDeleteConfirm,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ fun ComposeUiTest.startApp(
selectionState = MutableStateFlow(false),
keyboardEventFlow = MutableStateFlow(KeyboardEvent.IDLE),
toggleMaxScreen = {},
navigateToRegister = {}
navigateToRegister = {},
navigateToResetPassword = {}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,11 @@ private fun ApplicationScope.App(onCloseRequest: () -> Unit = ::exitApplication)
navigationController.navigate(
Destinations.AUTH_MENU_INNER_NAVIGATION.id
)
},
navigateToResetPassword = {
navigationController.navigate(
Destinations.AUTH_RESET_PASSWORD.id
)
}
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ import io.ktor.client.call.body
import io.ktor.client.request.delete
import io.ktor.client.request.header
import io.ktor.client.request.post
import io.ktor.client.request.put
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.HttpHeaders
import io.ktor.http.contentType
import io.ktor.http.isSuccess
import io.writeopia.common.utils.ResultData
import io.writeopia.sdk.serialization.data.auth.AuthResponse
import io.writeopia.sdk.serialization.data.auth.DeleteAccountResponse
import io.writeopia.sdk.serialization.data.auth.LoginRequest
import io.writeopia.sdk.serialization.data.auth.RegisterRequest
import io.writeopia.sdk.serialization.data.auth.ResetPasswordRequest

class AuthApi(private val client: HttpClient, private val baseUrl: String) {

Expand All @@ -30,11 +33,16 @@ class AuthApi(private val client: HttpClient, private val baseUrl: String) {
}
}

suspend fun register(name: String, email: String, password: String): ResultData<AuthResponse> {
suspend fun register(
name: String,
email: String,
company: String,
password: String
): ResultData<AuthResponse> {
return try {
val response = client.post("$baseUrl/api/register") {
contentType(ContentType.Application.Json)
setBody(RegisterRequest(name, email, password))
setBody(RegisterRequest(name, email, company, password))
}.body<AuthResponse>()

ResultData.Complete(response)
Expand All @@ -43,6 +51,25 @@ class AuthApi(private val client: HttpClient, private val baseUrl: String) {
}
}

suspend fun resetPassword(newPassword: String, token: String): ResultData<Unit> {
return try {
val response = client.put("$baseUrl/api/password/reset") {
contentType(ContentType.Application.Json)
setBody(ResetPasswordRequest(newPassword))
header(HttpHeaders.Authorization, "Bearer $token")
}

if (response.status.isSuccess()) {
ResultData.Complete(Unit)
} else {
ResultData.Error()
}
} catch (e: Exception) {
e.printStackTrace()
ResultData.Error(e)
}
}

suspend fun deleteAccount(token: String): ResultData<Boolean> {
return try {
val response = client.delete("$baseUrl/api/account") {
Expand Down
6,471 changes: 3,342 additions & 3,129 deletions application/core/resources/config/ktlint/baseline.xml

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,9 @@
<string name="start_now">Let's start now!</string>
<string name="sign_in_account">Sign in to your account at Writeopia.</string>
<string name="or_word">OR</string>
<string name="reset_password">Reset your password</string>
<string name="type_new_password">Type the new password</string>
<string name="new_password">New password</string>
<string name="repeat_password">Repeat password</string>
<string name="company">Company</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,9 @@
<string name="start_now">Comece agora!</string>
<string name="sign_in_account">Entre em sua conta no Writeopia</string>
<string name="or_word">OU</string>
<string name="reset_password">Mudar a senha</string>
<string name="type_new_password">Digite a nova senha</string>
<string name="new_password">Senha nova</string>
<string name="repeat_password">Repita a senha</string>
<string name="company">Empresa</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,9 @@
<string name="start_now">Let's start now!</string>
<string name="sign_in_account">Sign in to your account at Writeopia.</string>
<string name="or_word">OR</string>
<string name="reset_password">Reset your password</string>
<string name="type_new_password">Type the new password</string>
<string name="new_password">New password</string>
<string name="repeat_password">Repeat password</string>
<string name="company">Company</string>
</resources>
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import writeopia.application.core.resources.generated.resources.box
import writeopia.application.core.resources.generated.resources.cancel
import writeopia.application.core.resources.generated.resources.close
import writeopia.application.core.resources.generated.resources.color_theme
import writeopia.application.core.resources.generated.resources.company
import writeopia.application.core.resources.generated.resources.confirmation_delete_multiple_items
import writeopia.application.core.resources.generated.resources.content
import writeopia.application.core.resources.generated.resources.copy_note
Expand All @@ -25,6 +26,7 @@ import writeopia.application.core.resources.generated.resources.delete
import writeopia.application.core.resources.generated.resources.document
import writeopia.application.core.resources.generated.resources.download_models
import writeopia.application.core.resources.generated.resources.download_ollama
import writeopia.application.core.resources.generated.resources.email
import writeopia.application.core.resources.generated.resources.error_model_download
import writeopia.application.core.resources.generated.resources.error_requesting_models
import writeopia.application.core.resources.generated.resources.export
Expand Down Expand Up @@ -53,6 +55,7 @@ import writeopia.application.core.resources.generated.resources.markdown
import writeopia.application.core.resources.generated.resources.move_to
import writeopia.application.core.resources.generated.resources.move_to_home
import writeopia.application.core.resources.generated.resources.name
import writeopia.application.core.resources.generated.resources.new_password
import writeopia.application.core.resources.generated.resources.no_models
import writeopia.application.core.resources.generated.resources.ok
import writeopia.application.core.resources.generated.resources.ollama
Expand All @@ -63,8 +66,10 @@ import writeopia.application.core.resources.generated.resources.onboarding_selec
import writeopia.application.core.resources.generated.resources.or_word
import writeopia.application.core.resources.generated.resources.page
import writeopia.application.core.resources.generated.resources.password
import writeopia.application.core.resources.generated.resources.reset_password
import writeopia.application.core.resources.generated.resources.private_ai_enabled
import writeopia.application.core.resources.generated.resources.recent
import writeopia.application.core.resources.generated.resources.repeat_password
import writeopia.application.core.resources.generated.resources.retry
import writeopia.application.core.resources.generated.resources.search
import writeopia.application.core.resources.generated.resources.settings
Expand All @@ -81,6 +86,7 @@ import writeopia.application.core.resources.generated.resources.summarize
import writeopia.application.core.resources.generated.resources.system_theme
import writeopia.application.core.resources.generated.resources.tap_to_start
import writeopia.application.core.resources.generated.resources.text
import writeopia.application.core.resources.generated.resources.type_new_password
import writeopia.application.core.resources.generated.resources.url
import writeopia.application.core.resources.generated.resources.version
import writeopia.application.core.resources.generated.resources.workspaceName
Expand Down Expand Up @@ -336,4 +342,22 @@ object WrStrings {

@Composable
fun password() = stringResource(Res.string.password)

@Composable
fun resetPassword() = stringResource(Res.string.reset_password)

@Composable
fun typeNewPassword() = stringResource(Res.string.type_new_password)

@Composable
fun newPassword() = stringResource(Res.string.new_password)

@Composable
fun repeatPassword() = stringResource(Res.string.repeat_password)

@Composable
fun email() = stringResource(Res.string.email)

@Composable
fun company() = stringResource(Res.string.company)
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum class Destinations(val id: String, val root: String) {

AUTH_MENU_INNER_NAVIGATION("auth_menu_inner_navigation", "Home"),
AUTH_REGISTER("auth_register", "Home"),
AUTH_RESET_PASSWORD("auth_reset_password", "Home"),
AUTH_MENU("auth_menu", "Home"),
AUTH_LOGIN("auth_login", "Home"),

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ fun SettingsDialog(
downloadModel: (String) -> Unit,
deleteModel: (String) -> Unit,
signIn: () -> Unit,
resetPassword: () -> Unit,
logout: () -> Unit,
showDeleteConfirm: () -> Unit,
dismissDeleteConfirm: () -> Unit,
Expand All @@ -116,6 +117,7 @@ fun SettingsDialog(
userOnlineState,
showDeleteConfirmation,
signIn,
resetPassword,
logout,
dismissDeleteConfirm,
showDeleteConfirm,
Expand Down Expand Up @@ -204,6 +206,7 @@ private fun AccountScreen(
userOnlineState: StateFlow<WriteopiaUser>,
showDeleteConfirmation: StateFlow<Boolean>,
signIn: () -> Unit,
resetPassword: () -> Unit,
logout: () -> Unit,
dismissDeleteConfirm: () -> Unit,
showDeleteConfirm: () -> Unit,
Expand Down Expand Up @@ -236,6 +239,12 @@ private fun AccountScreen(

Spacer(modifier = Modifier.height(4.dp))

CommonTextButton(text = "Reset Password", modifier = Modifier.fillMaxWidth()) {
resetPassword()
}

Spacer(modifier = Modifier.height(4.dp))

CommonTextButton(text = "Logout", modifier = Modifier.fillMaxWidth()) {
logout()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import io.writeopia.auth.core.di.AuthCoreInjectionNeo
import io.writeopia.auth.core.manager.AuthRepository
import io.writeopia.auth.menu.AuthMenuViewModel
import io.writeopia.auth.register.RegisterViewModel
import io.writeopia.auth.register.ResetPasswordViewModel

class AuthInjection(
private val authCoreInjection: AuthCoreInjectionNeo = AuthCoreInjectionNeo.singleton()
Expand All @@ -18,6 +19,12 @@ class AuthInjection(
authApi: AuthApi = authCoreInjection.provideAuthApi()
): RegisterViewModel = viewModel { RegisterViewModel(authRepository, authApi) }

@Composable
internal fun provideResetPasswordViewModel(
authApi: AuthApi = authCoreInjection.provideAuthApi(),
authRepository: AuthRepository = authCoreInjection.provideAuthRepository(),
): ResetPasswordViewModel = viewModel { ResetPasswordViewModel(authApi, authRepository) }

@Composable
internal fun provideAuthMenuViewModel(
authManager: AuthRepository = authCoreInjection.provideAuthRepository(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ private fun AuthMenuContentScreen(
modifier = Modifier.fillMaxWidth().padding(horizontal = 24.dp),
singleLine = true,
placeholder = {
Text("Email")
Text(WrStrings.email())
},
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Email),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import androidx.navigation.navigation
import io.writeopia.auth.di.AuthInjection
import io.writeopia.auth.menu.AuthMenuScreen
import io.writeopia.auth.menu.AuthMenuViewModel
import io.writeopia.auth.register.RegisterPasswordScreen
import io.writeopia.auth.register.RegisterScreen
import io.writeopia.common.utils.Destinations
import io.writeopia.model.ColorThemeOption
Expand All @@ -25,6 +26,29 @@ fun NavGraphBuilder.authNavigation(
colorThemeOption: StateFlow<ColorThemeOption?>,
toAppNavigation: () -> Unit
) {
composable(Destinations.AUTH_RESET_PASSWORD.id) {
val viewModel = authInjection.provideResetPasswordViewModel()
val colorTheme by colorThemeOption.collectAsState()

WrieopiaTheme(darkTheme = colorTheme.isDarkTheme()) {
RegisterPasswordScreen(
modifier = Modifier.background(WriteopiaTheme.colorScheme.globalBackground),
passwordState = viewModel.password,
repeatPasswordState = viewModel.repeatPassword,
resetPasswordState = viewModel.resetPassword,
passwordChanged = viewModel::passwordChanged,
repeatPasswordChanged = viewModel::repeatPasswordChanged,
onPasswordResetRequest = viewModel::onResetPassword,
onPasswordResetSuccess = {
toAppNavigation()
},
navigateBack = {
navController.navigateUp()
}
)
}
}

navigation(
startDestination = Destinations.AUTH_MENU.id,
route = Destinations.AUTH_MENU_INNER_NAVIGATION.id
Expand Down Expand Up @@ -58,10 +82,37 @@ fun NavGraphBuilder.authNavigation(
RegisterScreen(
modifier = Modifier.background(WriteopiaTheme.colorScheme.globalBackground),
nameState = registerViewModel.name,
companyState = registerViewModel.company,
emailState = registerViewModel.email,
passwordState = registerViewModel.password,
registerState = registerViewModel.register,
nameChanged = registerViewModel::nameChanged,
companyChanged = registerViewModel::companyChanged,
emailChanged = registerViewModel::emailChanged,
passwordChanged = registerViewModel::passwordChanged,
onRegisterRequest = registerViewModel::onRegister,
onRegisterSuccess = toAppNavigation,
navigateBack = {
navController.navigateUp()
}
)
}
}

composable(Destinations.AUTH_REGISTER.id) {
val registerViewModel = authInjection.provideRegisterViewModel()
val colorTheme by colorThemeOption.collectAsState()

WrieopiaTheme(darkTheme = colorTheme.isDarkTheme()) {
RegisterScreen(
modifier = Modifier.background(WriteopiaTheme.colorScheme.globalBackground),
nameState = registerViewModel.name,
companyState = registerViewModel.company,
emailState = registerViewModel.email,
passwordState = registerViewModel.password,
registerState = registerViewModel.register,
nameChanged = registerViewModel::nameChanged,
companyChanged = registerViewModel::companyChanged,
emailChanged = registerViewModel::emailChanged,
passwordChanged = registerViewModel::passwordChanged,
onRegisterRequest = registerViewModel::onRegister,
Expand Down
Loading