se agrega los requerimientos de la LODPD con firma de documentos
This commit is contained in:
@@ -16,8 +16,15 @@ interface LinkedSignApiService {
|
||||
@POST("auth/login")
|
||||
suspend fun login(@Body body: LoginRequest): ApiEnvelope<LoginData>
|
||||
|
||||
@Multipart
|
||||
@POST("auth/register")
|
||||
suspend fun register(@Body body: RegisterRequest): ApiEnvelope<RegisterData>
|
||||
suspend fun register(
|
||||
@Part("email") email: RequestBody,
|
||||
@Part("password") password: RequestBody,
|
||||
@Part("certPassword") certPassword: RequestBody,
|
||||
@Part("consentAccepted") consentAccepted: RequestBody,
|
||||
@Part certificateFile: MultipartBody.Part
|
||||
): ApiEnvelope<RegisterData>
|
||||
|
||||
@POST("auth/refresh")
|
||||
suspend fun refresh(@Body body: RefreshRequest): ApiEnvelope<RefreshData>
|
||||
|
||||
@@ -79,9 +79,16 @@ class LinkedSignRepository(private val context: Context) {
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun register(email: String, password: String): RegisterData {
|
||||
suspend fun register(email: String, password: String, certPassword: String, certificateUri: Uri, certificateName: String): RegisterData {
|
||||
return execute {
|
||||
unwrap(service.register(RegisterRequest(email.trim(), password)))
|
||||
val filePart = withContext(Dispatchers.IO) {
|
||||
createFilePart(certificateUri, certificateName, "application/octet-stream", "certificateFile")
|
||||
}
|
||||
val emailBody = email.trim().toRequestBody("text/plain".toMediaType())
|
||||
val passwordBody = password.toRequestBody("text/plain".toMediaType())
|
||||
val certPasswordBody = certPassword.toRequestBody("text/plain".toMediaType())
|
||||
val consentBody = "true".toRequestBody("text/plain".toMediaType())
|
||||
unwrap(service.register(emailBody, passwordBody, certPasswordBody, consentBody, filePart))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,11 +43,6 @@ data class LoginData(
|
||||
val user: SessionUser
|
||||
)
|
||||
|
||||
data class RegisterRequest(
|
||||
val email: String,
|
||||
val password: String
|
||||
)
|
||||
|
||||
data class RegisterData(
|
||||
val message: String?,
|
||||
val userId: Int?
|
||||
|
||||
@@ -368,9 +368,9 @@ fun LinkedSignApp(viewModel: MainViewModel, appContext: Context, activity: Compo
|
||||
}
|
||||
}
|
||||
},
|
||||
onRegister = { email, password ->
|
||||
onRegister = { email, password, certPassword, certificateUri, certificateName ->
|
||||
scope.launch {
|
||||
runCatching { viewModel.register(email, password) }
|
||||
runCatching { viewModel.register(email, password, certPassword, certificateUri, certificateName) }
|
||||
.onSuccess {
|
||||
authMode = AuthMode.VerifyNotice
|
||||
}
|
||||
@@ -529,7 +529,7 @@ private fun AuthFlow(
|
||||
verifyEmail: String?,
|
||||
onConsumeVerifyNotice: () -> Unit,
|
||||
onLogin: (String, String) -> Unit,
|
||||
onRegister: (String, String) -> Unit,
|
||||
onRegister: (String, String, String, Uri, String) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
Column(
|
||||
@@ -780,11 +780,25 @@ private fun LoginCard(onSubmit: (String, String) -> Unit, onGoRegister: () -> Un
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RegisterCard(onSubmit: (String, String) -> Unit, onGoLogin: () -> Unit) {
|
||||
private fun RegisterCard(onSubmit: (String, String, String, Uri, String) -> Unit, onGoLogin: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
var email by rememberSaveable { mutableStateOf("") }
|
||||
var password by rememberSaveable { mutableStateOf("") }
|
||||
var confirmPassword by rememberSaveable { mutableStateOf("") }
|
||||
var certPassword by rememberSaveable { mutableStateOf("") }
|
||||
var consentAccepted by rememberSaveable { mutableStateOf(false) }
|
||||
var certificateUri by rememberSaveable { mutableStateOf<Uri?>(null) }
|
||||
var certificateName by rememberSaveable { mutableStateOf("") }
|
||||
val passwordProblems = passwordIssues(password)
|
||||
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
|
||||
uri ?: return@rememberLauncherForActivityResult
|
||||
try {
|
||||
context.contentResolver.takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
} catch (_: Exception) {
|
||||
}
|
||||
certificateUri = uri
|
||||
certificateName = queryFileName(context, uri) ?: "certificado.p12"
|
||||
}
|
||||
|
||||
ElevatedCard(
|
||||
shape = RoundedCornerShape(24.dp),
|
||||
@@ -810,7 +824,7 @@ private fun RegisterCard(onSubmit: (String, String) -> Unit, onGoLogin: () -> Un
|
||||
}
|
||||
Column {
|
||||
Text("Alta protegida", color = BrandDark, fontWeight = FontWeight.SemiBold, fontSize = AppFontSizes.base)
|
||||
Text("Usa un correo válido y una clave fuerte", color = TextMuted, fontSize = AppFontSizes.sm)
|
||||
Text("Correo válido, clave fuerte y certificado para el consentimiento legal", color = TextMuted, fontSize = AppFontSizes.sm)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -822,6 +836,38 @@ private fun RegisterCard(onSubmit: (String, String) -> Unit, onGoLogin: () -> Un
|
||||
AppTextField(value = password, onValueChange = { password = it }, label = "Contraseña", isPassword = true)
|
||||
PasswordChecklist(password = password)
|
||||
AppTextField(value = confirmPassword, onValueChange = { confirmPassword = it }, label = "Confirmar contraseña", isPassword = true)
|
||||
AppTextField(value = certPassword, onValueChange = { certPassword = it }, label = "Contraseña del certificado", isPassword = true)
|
||||
Surface(color = SurfaceAlt, shape = RoundedCornerShape(14.dp), border = BorderStroke(1.dp, StrokeSoft)) {
|
||||
Column(modifier = Modifier.padding(14.dp), verticalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
Text("Registro legal inicial", color = BrandDark, fontWeight = FontWeight.SemiBold, fontSize = AppFontSizes.base)
|
||||
Text(
|
||||
"Debes cargar tu P12/PFX. La contraseña del certificado solo se usará para firmar los documentos legales del primer registro y no se guardará.",
|
||||
color = TextMuted,
|
||||
fontSize = AppFontSizes.sm
|
||||
)
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(10.dp), verticalAlignment = Alignment.CenterVertically) {
|
||||
OutlinedActionButton(
|
||||
label = if (certificateName.isBlank()) "Seleccionar P12/PFX" else certificateName,
|
||||
icon = Icons.Outlined.Badge,
|
||||
modifier = Modifier.weight(1f)
|
||||
) {
|
||||
launcher.launch(arrayOf("*/*"))
|
||||
}
|
||||
}
|
||||
Row(verticalAlignment = Alignment.Top, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
||||
androidx.compose.material3.Checkbox(
|
||||
checked = consentAccepted,
|
||||
onCheckedChange = { consentAccepted = it }
|
||||
)
|
||||
Text(
|
||||
"Acepto los términos de uso, la política de privacidad y el consentimiento expreso para tratamiento de datos y uso de firma electrónica.",
|
||||
color = TextMuted,
|
||||
fontSize = AppFontSizes.sm,
|
||||
modifier = Modifier.weight(1f)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (passwordProblems.isNotEmpty() && password.isNotBlank()) {
|
||||
Surface(color = WarningBg, shape = RoundedCornerShape(10.dp)) {
|
||||
Text("La contraseña aún no cumple todos los requisitos.", color = Warning, modifier = Modifier.padding(10.dp), fontSize = AppFontSizes.md)
|
||||
@@ -838,7 +884,10 @@ private fun RegisterCard(onSubmit: (String, String) -> Unit, onGoLogin: () -> Un
|
||||
when {
|
||||
passwordProblems.isNotEmpty() -> Unit
|
||||
password != confirmPassword -> Unit
|
||||
else -> onSubmit(email, password)
|
||||
certPassword.isBlank() -> Unit
|
||||
certificateUri == null -> Unit
|
||||
!consentAccepted -> Unit
|
||||
else -> onSubmit(email, password, certPassword, certificateUri!!, certificateName.ifBlank { "certificado.p12" })
|
||||
}
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth().height(50.dp),
|
||||
|
||||
@@ -63,8 +63,8 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
uiState = buildState(session, cache, loading = false)
|
||||
}
|
||||
|
||||
suspend fun register(email: String, password: String) {
|
||||
repository.register(email, password)
|
||||
suspend fun register(email: String, password: String, certPassword: String, certificateUri: Uri, certificateName: String) {
|
||||
repository.register(email, password, certPassword, certificateUri, certificateName)
|
||||
uiState = uiState.copy(emailForVerificationNotice = email)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user