Skip to content

Commit

Permalink
Merge pull request #97 from CashAdv/71-Password-Recovery
Browse files Browse the repository at this point in the history
71 password recovery
  • Loading branch information
MajoritySky2496 authored Jun 10, 2024
2 parents 55dcc83 + 1d49e48 commit cc55cf7
Show file tree
Hide file tree
Showing 47 changed files with 2,222 additions and 37 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package app.cashadvisor.authorization.data

import app.cashadvisor.authorization.data.models.response.customError.ErrorWrongConfirmationCodeResponse
import app.cashadvisor.common.data.models.ErrorResponse
import app.cashadvisor.common.utill.exceptions.LoginException
import app.cashadvisor.common.utill.exceptions.NetworkException
import app.cashadvisor.common.utill.exceptions.ResetPasswordException
import javax.inject.Inject
import kotlinx.serialization.json.Json

class NetworkToResetPasswordExceptionMapper @Inject constructor(
private val json: Json
) {
fun handleConfirmResetPasswordWithCode(exception: NetworkException): ResetPasswordException {
return when (exception) {
is NetworkException.BadRequest -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.ConfirmResetPasswordWithCode.BadRequestInvalidCodeOrMissingContentTypeHeader(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

is NetworkException.Unauthorized -> {
val errorResponse =
handleErrorResponse<ErrorWrongConfirmationCodeResponse>(exception.errorBody)
ResetPasswordException.ConfirmResetPasswordWithCode.UnauthorizedWrongConfirmationCode(
remainingAttempts = errorResponse.remainingAttempts,
lockDuration = errorResponse.lockDurationNanoseconds,
message = errorResponse.error,
statusCode = errorResponse.statusCode
)
}

is NetworkException.InternalServerError -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.ConfirmResetPasswordWithCode
.InternalServerErrorFailedToConfirmResetPassword(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

else -> handleCommonException(exception)
}

}

fun handleConfirmEmailToResetPassword(exception: NetworkException): ResetPasswordException {
return when (exception) {
is NetworkException.BadRequest -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.ConfirmEmailToResetPassword.BadRequestInvalidInputOrContentType(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

is NetworkException.InternalServerError -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.ConfirmEmailToResetPassword.InternalServerErrorFailedToGenerateTokenOrSendEmail(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

else -> handleCommonException(exception)
}

}

fun handleSaveNewPassword(exception: NetworkException): ResetPasswordException {
return when (exception) {
is NetworkException.BadRequest -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.SaveNewPassword
.BadRequestInvalidPasswordOrMissingContentTypeHeader(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

is NetworkException.Unauthorized -> {
val errorResponse =
handleErrorResponse<ErrorWrongConfirmationCodeResponse>(exception.errorBody)
ResetPasswordException.SaveNewPassword.UnauthorizedInvalidTokenOrMissingContentTypeHeader(
message = errorResponse.error,
statusCode = errorResponse.statusCode
)
}

is NetworkException.InternalServerError -> {
val errorResponse = handleErrorResponse<ErrorResponse>(exception.errorBody)
ResetPasswordException.SaveNewPassword.InternalServerErrorFailedToResetPassword(
message = errorResponse.message,
statusCode = errorResponse.statusCode
)
}

else -> handleCommonException(exception)
}
}

private fun handleCommonException(exception: NetworkException): ResetPasswordException {
return when (exception) {
is NetworkException.NoInternetConnection -> {
ResetPasswordException.NoConnection(exception.errorBody)
}

is NetworkException.Undefined -> {
ResetPasswordException.Undefined()
}

else -> {
ResetPasswordException.Undefined()
}
}
}

private inline fun <reified T> handleErrorResponse(errorMessage: String): T {
try {
return json.decodeFromString<T>(errorMessage)

} catch (e: Exception) {
throw LoginException.Undefined()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package app.cashadvisor.authorization.data

import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeInputDto
import app.cashadvisor.authorization.data.models.ResetPasswordInputDto
import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeOutputDto
import app.cashadvisor.authorization.data.models.ResetPasswordOutputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordInputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordOutputDto
import app.cashadvisor.authorization.data.models.request.ResetPasswordRequest
import app.cashadvisor.authorization.data.models.request.ResetPasswordWithCodeRequest
import app.cashadvisor.authorization.data.models.request.SaveNewPasswordRequest
import app.cashadvisor.authorization.data.models.response.ConfirmResetPasswordResponse
import app.cashadvisor.authorization.data.models.response.ResetPasswordResponse
import app.cashadvisor.authorization.data.models.response.SaveNewPasswordResponse
import javax.inject.Inject

class ResetDataMapper @Inject constructor() {

fun toResetPasswordRequest(inputDto: ResetPasswordInputDto): ResetPasswordRequest {
return ResetPasswordRequest(
email = inputDto.email

)
}

fun toConfirmResetPasswordWithCodeOutputDto(response: ConfirmResetPasswordResponse):
ConfirmResetPasswordWithCodeOutputDto {
return ConfirmResetPasswordWithCodeOutputDto(
message = response.message,
statusCode = response.statusCode
)
}

fun toResetPasswordWithCodeRequest(inputDto: ConfirmResetPasswordWithCodeInputDto):
ResetPasswordWithCodeRequest {
return ResetPasswordWithCodeRequest(
code = inputDto.code,
token = inputDto.token
)
}

fun toResetPasswordOutputDto(response: ResetPasswordResponse): ResetPasswordOutputDto {
return ResetPasswordOutputDto(
message = response.message,
token = response.token,
statusCode = response.statusCode
)
}

fun toSaveNewPasswordRequest(inputDto: SaveNewPasswordInputDto): SaveNewPasswordRequest {
return SaveNewPasswordRequest(
email = inputDto.email,
password = inputDto.password,
resetToken = inputDto.resetToken
)
}

fun toSaveNewPasswordOutputDto(response: SaveNewPasswordResponse): SaveNewPasswordOutputDto {
return SaveNewPasswordOutputDto(
message = response.message,
statusCode = response.statusCode
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package app.cashadvisor.authorization.data

import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeInputDto
import app.cashadvisor.authorization.data.models.ResetPasswordInputDto
import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeOutputDto
import app.cashadvisor.authorization.data.models.ResetPasswordOutputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordInputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordOutputDto
import app.cashadvisor.authorization.domain.models.ConfirmCode
import app.cashadvisor.authorization.domain.models.ConfirmResetPasswordWithCode
import app.cashadvisor.authorization.domain.models.Email
import app.cashadvisor.authorization.domain.models.Password
import app.cashadvisor.authorization.domain.models.ResetPasswordData
import app.cashadvisor.authorization.domain.models.SaveNewPasswordData
import javax.inject.Inject

class ResetDomainMapper @Inject constructor() {

fun toResetPasswordInputDto(email: Email): ResetPasswordInputDto {
return ResetPasswordInputDto(
email = email.value
)
}

fun toConfirmResetPasswordByEmailWithCodeInputDto(
code: ConfirmCode,
token: String
): ConfirmResetPasswordWithCodeInputDto {
return ConfirmResetPasswordWithCodeInputDto(
code = code.value,
token = token
)
}

fun toSaveNewPasswordInputDto(
email: Email,
password: Password,
resetToken: String
): SaveNewPasswordInputDto {
return SaveNewPasswordInputDto(
email = email.value,
password = password.value,
resetToken = resetToken
)
}

fun toConfirmResetPasswordWithCode(data: ConfirmResetPasswordWithCodeOutputDto): ConfirmResetPasswordWithCode {
return ConfirmResetPasswordWithCode(
message = data.message,
)
}

fun toResetPasswordData(data: ResetPasswordOutputDto): ResetPasswordData {
return ResetPasswordData(
message = data.message,
statusCode = data.statusCode
)
}

fun toSaveNewPasswordData(data: SaveNewPasswordOutputDto): SaveNewPasswordData {
return SaveNewPasswordData(
message = data.message,
statusCode = data.statusCode
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package app.cashadvisor.authorization.data.api

import app.cashadvisor.authorization.data.models.request.ResetPasswordWithCodeRequest
import app.cashadvisor.authorization.data.models.request.ResetPasswordRequest
import app.cashadvisor.authorization.data.models.request.SaveNewPasswordRequest
import app.cashadvisor.authorization.data.models.response.ConfirmResetPasswordResponse
import app.cashadvisor.authorization.data.models.response.ResetPasswordResponse
import app.cashadvisor.authorization.data.models.response.SaveNewPasswordResponse
import retrofit2.http.Body
import retrofit2.http.Headers
import retrofit2.http.POST

interface ResetPasswordApiService {

@Headers("Content-Type: application/json")
@POST("auth/login/reset/password")
suspend fun resetPassword(@Body passwordResetRequest: ResetPasswordRequest ):ResetPasswordResponse

@Headers("Content-Type: application/json")
@POST("auth/login/reset/password/confirm")
suspend fun resetPasswordConfirm(@Body resetPasswordRequest: ResetPasswordWithCodeRequest):ConfirmResetPasswordResponse

@Headers("Content-Type: application/json")
@POST("auth/login/reset/password")
suspend fun saveNewPassword(@Body saveNewPasswordRequest: SaveNewPasswordRequest):SaveNewPasswordResponse

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package app.cashadvisor.authorization.data.api

import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeInputDto
import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeOutputDto
import app.cashadvisor.authorization.data.models.ResetPasswordInputDto
import app.cashadvisor.authorization.data.models.ResetPasswordOutputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordInputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordOutputDto

interface ResetPasswordRemoteDataSource {
suspend fun confirmEmail(inputDto: ResetPasswordInputDto):ResetPasswordOutputDto
suspend fun confirmResetPasswordByEmailWithCode(inputDto: ConfirmResetPasswordWithCodeInputDto):ConfirmResetPasswordWithCodeOutputDto
suspend fun saveNewPassword(inputDto:SaveNewPasswordInputDto):SaveNewPasswordOutputDto
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package app.cashadvisor.authorization.data.impl

import app.cashadvisor.authorization.data.NetworkToResetPasswordExceptionMapper
import app.cashadvisor.authorization.data.ResetDataMapper
import app.cashadvisor.authorization.data.api.ResetPasswordApiService
import app.cashadvisor.authorization.data.api.ResetPasswordRemoteDataSource
import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeInputDto
import app.cashadvisor.authorization.data.models.ResetPasswordInputDto
import app.cashadvisor.authorization.data.models.ConfirmResetPasswordWithCodeOutputDto
import app.cashadvisor.authorization.data.models.ResetPasswordOutputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordInputDto
import app.cashadvisor.authorization.data.models.SaveNewPasswordOutputDto
import app.cashadvisor.common.utill.exceptions.NetworkException
import app.cashadvisor.common.utill.extensions.logDebugMessage
import javax.inject.Inject

class ResetPasswordRemoteDataSourceImpl @Inject constructor(
private val resetDataMapper: ResetDataMapper,
private val resetPasswordApiService: ResetPasswordApiService,
private val networkToResetPasswordExceptionMapper:
NetworkToResetPasswordExceptionMapper
) : ResetPasswordRemoteDataSource {

override suspend fun confirmEmail(inputDto: ResetPasswordInputDto): ResetPasswordOutputDto {
return try {
val response = resetPasswordApiService.resetPassword(
passwordResetRequest = resetDataMapper.toResetPasswordRequest(inputDto)
)
logDebugMessage(resetDataMapper.toResetPasswordRequest(inputDto).toString())
resetDataMapper.toResetPasswordOutputDto(response)
} catch (exception: NetworkException) {
throw networkToResetPasswordExceptionMapper.handleConfirmEmailToResetPassword(exception)
}
}

override suspend fun confirmResetPasswordByEmailWithCode(inputDto: ConfirmResetPasswordWithCodeInputDto):
ConfirmResetPasswordWithCodeOutputDto {
return try {
val response = resetPasswordApiService.resetPasswordConfirm(
resetPasswordRequest = resetDataMapper.toResetPasswordWithCodeRequest(inputDto)
)
resetDataMapper.toConfirmResetPasswordWithCodeOutputDto(response)
} catch (exception: NetworkException) {
throw networkToResetPasswordExceptionMapper.handleConfirmResetPasswordWithCode(exception)
}
}

override suspend fun saveNewPassword(inputDto: SaveNewPasswordInputDto): SaveNewPasswordOutputDto {
return try {
val response = resetPasswordApiService.saveNewPassword(
saveNewPasswordRequest = resetDataMapper.toSaveNewPasswordRequest(inputDto)
)
resetDataMapper.toSaveNewPasswordOutputDto(response)
} catch (exception: NetworkException) {
throw networkToResetPasswordExceptionMapper.handleSaveNewPassword(exception)
}
}
}
Loading

0 comments on commit cc55cf7

Please sign in to comment.