diff --git a/Aspnet/Controllers/UsuarioController.cs b/Aspnet/Controllers/UsuarioController.cs
index 38ba1bf..3c6678d 100644
--- a/Aspnet/Controllers/UsuarioController.cs
+++ b/Aspnet/Controllers/UsuarioController.cs
@@ -2,6 +2,7 @@ using AlquilaFacil.Builder;
using Microsoft.AspNetCore.Mvc;
using Modelo;
using Entidades;
+using AlquilaFacil.Emailer.Sender;
namespace AlquilaFacil.Controllers;
@@ -51,7 +52,15 @@ public class UsuarioController : ControllerBase
if (!emailrecuperacion.Contains("@")) return BadRequest(new { message = "Tiene que ser un email" });
bool ret = RepositorioUsuarios.Singleton.SetEmailRecuperacion(emailrecuperacion, cli);
- return ret ? Ok(new { message = "Email de recuperación actualizado con éxito" }) : BadRequest(new { message = "No se pudo actualizar el email de recuperación" });
+ if (ret == false) return BadRequest(new { message = "No se pudo actualizar el email de recuperación" });
+
+ Task.Run(() =>
+ {
+ AvisoEmailSender s = new();
+ s.Send(cli.Email, setemail.EmailRecuperacion);
+ });
+
+ return Ok(new { message = "Email de recuperación actualizado con éxito" });
}
public record recuperarusuario(string Email, string EmailRecuperacion);
@@ -61,7 +70,34 @@ public class UsuarioController : ControllerBase
bool check = RepositorioUsuarios.Singleton.CheckEmailRecuperacion(mails.Email, mails.EmailRecuperacion);
if (check == false) return BadRequest(new { message = "El email no corresponde al email de recuperacion" });
- //WIP hacer emailer
+ string pin = "";
+ var ran = new Random();
+ for (int i = 0; i < 6; i++) pin += ran.Next(0, 10);
+ bool ret = RepositorioUsuarios.Singleton.SetF2aPin(pin, mails.Email);
+ if (ret == false) return BadRequest(new { message = "no se pudo generar/guardar el codigo 2fa" });
+
+ OtpEmailSender s = new();
+ s.Send(mails.EmailRecuperacion, mails.Email, pin);
+
+ return Ok(new { message = $"Se envio un email de recuperacion a {mails.EmailRecuperacion}" });
+ }
+
+ public record ingreso2fa(string Pin, string Email);
+ [HttpPost("/api/ingresar2fa")]
+ public IActionResult IngresarUsuario([FromBody] ingreso2fa data)
+ {
+ if (!data.Email.Contains("@")) return BadRequest(new { message = "Tiene que ser un email" });
+ if (data.Pin.Length != 6) return BadRequest(new { message = "el pin tiene que tener 6 digitos" });
+
+ (bool check, long Dni) = RepositorioUsuarios.Singleton.Check2fa(data.Email, data.Pin);
+ if (check == false) return BadRequest(new { message = "El pin es incorrecto" });
+
+ var cli = RepositorioUsuarios.Singleton.ObtenerClientePorDni(Dni);
+
+ //esto literalmente no se puede triggerear pero lo pongo para evitar una warning
+ if (cli == null) return BadRequest(new { message = "El usuario no existe" });
+
+ return Ok(new { token = cli.Token });
}
}
diff --git a/Aspnet/Emailer/Builder/EmailBuilder.cs b/Aspnet/Emailer/Builder/EmailBuilder.cs
index 34777c6..20df36b 100644
--- a/Aspnet/Emailer/Builder/EmailBuilder.cs
+++ b/Aspnet/Emailer/Builder/EmailBuilder.cs
@@ -17,10 +17,20 @@ public class EmailBuilder
return this;
}
- public EmailBuilder Body(string email, string pin)
+ public EmailBuilder Body(string email, string pin, string modo = "2fa")
{
_message.IsBodyHtml = true;
- _message.Body = new HtmlGenerator().GenerarMail2fa(email, pin);
+ switch (modo)
+ {
+ case "2fa":
+ _message.Body = new HtmlGenerator().GenerarMail2fa(email, pin);
+ break;
+ case "aviso":
+ _message.Body = new HtmlGenerator().AvisoSetEmail(email, pin);
+ break;
+ default:
+ break;
+ }
return this;
}
diff --git a/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs b/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs
index bb27711..8475e6c 100644
--- a/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs
+++ b/Aspnet/Emailer/Builder/EmailHtmlGenerator.cs
@@ -55,4 +55,58 @@ public class HtmlGenerator
return msg;
}
+ public string AvisoSetEmail(string emailUsuario, string emailreq)
+ {
+ var msg = $"""
+
+
+
+
+
+
+
+ |
+
+ Aviso:
+
+
+ Se seteo este email : {emailreq}, como email de respaldo
+
+
+
+
+
+ Si no sabes para que es el email, ignoralo.
+
+ |
+
+
+
+
+
+
+
+ """;
+
+ return msg;
+ }
+
}
diff --git a/Aspnet/Emailer/Decorator/AvisoEmailSender.cs b/Aspnet/Emailer/Decorator/AvisoEmailSender.cs
new file mode 100644
index 0000000..94bd831
--- /dev/null
+++ b/Aspnet/Emailer/Decorator/AvisoEmailSender.cs
@@ -0,0 +1,11 @@
+namespace AlquilaFacil.Emailer.Sender;
+using AlquilaFacil.Emailer.Builder;
+
+public class AvisoEmailSender : EmailSender
+{
+ public void Send(string emailusu, string emailreq)
+ {
+ var mail = new EmailBuilder().Body(emailusu, emailreq, "aviso").To(emailreq).Subject("AvisoEmail").Build();
+ base.Send(mail);
+ }
+}
diff --git a/Aspnet/Emailer/Decorator/EmailerSender.cs b/Aspnet/Emailer/Decorator/EmailerSender.cs
new file mode 100644
index 0000000..d3d0f7d
--- /dev/null
+++ b/Aspnet/Emailer/Decorator/EmailerSender.cs
@@ -0,0 +1,50 @@
+using System.Net.Mail;
+using System.Net;
+using System.Text.Json;
+
+namespace AlquilaFacil.Emailer.Sender;
+
+public class EmailSender
+{
+ protected static SmtpClient? smtp = null;
+ protected void configSmtp(MailMessage mail)
+ {
+ var jsonContent = File.ReadAllText("settings.json");
+ var options = JsonSerializer.Deserialize>(jsonContent);
+ if (options == null) return;
+
+
+ bool check = options.ContainsKey("smtpHost");
+ check = options.ContainsKey("smtpPort");
+ check = options.ContainsKey("emailAddr");
+ check = options.ContainsKey("emailPass");
+
+ if (check == false) return;
+ mail.Sender = new MailAddress(options["emailAddr"]);
+ mail.From = new MailAddress(options["emailAddr"]);
+
+ if (null != smtp) return;
+ smtp = new();
+ smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
+ smtp.EnableSsl = true;
+ smtp.Host = options["smtpHost"];
+ smtp.Port = int.Parse(options["smtpPort"].ToString());
+ smtp.Credentials = new NetworkCredential(options["emailAddr"], options["emailPass"]);
+ }
+
+ public virtual void Send(MailMessage message)
+ {
+ configSmtp(message);
+ if (smtp == null) return;
+ try
+ {
+ smtp.Send(message);
+ message.Dispose();
+ }
+ catch (Exception)
+ {
+ throw;
+ }
+ }
+
+}
diff --git a/Aspnet/Emailer/Decorator/IEmailerSender.cs b/Aspnet/Emailer/Decorator/IEmailerSender.cs
deleted file mode 100644
index a5007a4..0000000
--- a/Aspnet/Emailer/Decorator/IEmailerSender.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Net.Mail;
-
-namespace AlquilaFacil.Emailer.Sender;
-
-public interface IEmailSender
-{
- public void Send(MailMessage message, SmtpClient smtp);
-
-}
diff --git a/Aspnet/Emailer/Decorator/OtpEmailSender.cs b/Aspnet/Emailer/Decorator/OtpEmailSender.cs
new file mode 100644
index 0000000..c0a20b0
--- /dev/null
+++ b/Aspnet/Emailer/Decorator/OtpEmailSender.cs
@@ -0,0 +1,13 @@
+namespace AlquilaFacil.Emailer.Sender;
+using AlquilaFacil.Emailer.Builder;
+public class OtpEmailSender : EmailSender
+{
+
+ public void Send(string To, string email, string pin)
+ {
+ var mail = new EmailBuilder().To(To).Body(email, pin).Subject("Mail de Recuperacion").Build();
+
+ base.Send(mail);
+
+ }
+}
diff --git a/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs b/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs
deleted file mode 100644
index e6615f5..0000000
--- a/Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs
+++ /dev/null
@@ -1,25 +0,0 @@
-namespace AlquilaFacil.Emailer.Sender;
-using System.Net.Mail;
-public class OtpEmailSender : IEmailSender
-{
- private readonly int _codigoLength;
-
- public OtpEmailSenderDecorator(int codigoLength = 6)
- {
- _codigoLength = codigoLength;
- }
-
- public void Send(MailMessage message, SmtpClient? smtp = null)
- {
- if (smtp == null)
- {
- smtp = new();
- //WIP
- smtp.DeliveryMethod = SmtpDeliveryMethod.Network;
-
- }
-
-
- // 4.2 Construir HTML de verificación
-
- }
diff --git a/Aspnet/bin/Debug/net8.0/settings.json b/Aspnet/bin/Debug/net8.0/settings.json
index f44d236..b3fc1c9 100644
--- a/Aspnet/bin/Debug/net8.0/settings.json
+++ b/Aspnet/bin/Debug/net8.0/settings.json
@@ -1,5 +1,9 @@
{
"usr": "nwFNMLJcn5m0owbzeXMs",
"scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
- "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none"
+ "connectiondb": "Server=127.0.0.1;Port=3306;Database=AlquilaFacil;Uid=AlquilaFacil;Pwd=.n@9c2ve*0,b1ETv].Kipa/~pR~V;Connection Timeout=5;SslMode=none",
+ "smtpHost": "smtp.gmail.com",
+ "smtpPort": "587",
+ "emailAddr": "emailerpasillo@gmail.com",
+ "emailPass": "hgwa mznx xuff exws"
}
diff --git a/Entidades/AlquilaFacilContext.cs b/Entidades/Alquilafacilcontext.cs
similarity index 99%
rename from Entidades/AlquilaFacilContext.cs
rename to Entidades/Alquilafacilcontext.cs
index 64cf8b5..d0fb684 100644
--- a/Entidades/AlquilaFacilContext.cs
+++ b/Entidades/Alquilafacilcontext.cs
@@ -136,6 +136,9 @@ public partial class AlquilaFacilContext : DbContext
entity.Property(e => e.EmailRecuperacion)
.HasMaxLength(50)
.HasColumnName("emailRecuperacion");
+ entity.Property(e => e.F2a)
+ .HasMaxLength(6)
+ .HasColumnName("f2a");
entity.Property(e => e.Habilitado)
.HasDefaultValueSql("b'1'")
.HasColumnType("bit(1)")
diff --git a/Entidades/Cliente.cs b/Entidades/Cliente.cs
index fc67897..8bb00d0 100644
--- a/Entidades/Cliente.cs
+++ b/Entidades/Cliente.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace Entidades;
@@ -25,6 +25,9 @@ public partial class Cliente
public string? EmailRecuperacion { get; set; }
+ public string? F2a { get; set; }
+
+
public virtual ICollection ContratoDniinquilinoNavigations { get; set; } = new List();
public virtual ICollection ContratoDnipropietarioNavigations { get; set; } = new List();
diff --git a/Entidades/EstadoPropiedad.cs b/Entidades/EstadoPropiedad.cs
deleted file mode 100644
index ed87dfa..0000000
--- a/Entidades/EstadoPropiedad.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Entidades;
-
-public partial class EstadoPropiedad
-{
- public int Id { get; set; }
-
- public string Descripcion { get; set; } = null!;
-
- public virtual ICollection Propiedades { get; set; } = new List();
-}
diff --git a/Entidades/Estadopropiedad.cs b/Entidades/Estadopropiedad.cs
index a220579..ed87dfa 100644
--- a/Entidades/Estadopropiedad.cs
+++ b/Entidades/Estadopropiedad.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace Entidades;
diff --git a/Entidades/LogDetalle.cs b/Entidades/LogDetalle.cs
deleted file mode 100644
index 9b3b469..0000000
--- a/Entidades/LogDetalle.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Entidades;
-
-public partial class LogDetalle
-{
- public DateTime Fecha { get; set; }
-
- public long Dniusuario { get; set; }
-
- public string NombreTabla { get; set; } = null!;
-
- public string Columna { get; set; } = null!;
-
- public string? ValorAnterior { get; set; }
-
- public string? ValorNuevo { get; set; }
-
- public int Id { get; set; }
-
- public virtual Log Log { get; set; } = null!;
-}
diff --git a/Entidades/Logdetalle.cs b/Entidades/Logdetalle.cs
index db3946f..9b3b469 100644
--- a/Entidades/Logdetalle.cs
+++ b/Entidades/Logdetalle.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace Entidades;
diff --git a/Entidades/TipoPropiedad.cs b/Entidades/TipoPropiedad.cs
deleted file mode 100644
index c842eec..0000000
--- a/Entidades/TipoPropiedad.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace Entidades;
-
-public partial class TipoPropiedad
-{
- public int Id { get; set; }
-
- public string Descripcion { get; set; } = null!;
-
- public virtual ICollection Propiedades { get; set; } = new List();
-}
diff --git a/Entidades/Tipopropiedad.cs b/Entidades/Tipopropiedad.cs
index c0235cb..c842eec 100644
--- a/Entidades/Tipopropiedad.cs
+++ b/Entidades/Tipopropiedad.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
namespace Entidades;
diff --git a/Front/src/Componentes/LoginPanel.svelte b/Front/src/Componentes/LoginPanel.svelte
index b9a8769..6678c44 100644
--- a/Front/src/Componentes/LoginPanel.svelte
+++ b/Front/src/Componentes/LoginPanel.svelte
@@ -50,15 +50,73 @@
let showrecuperarmodal = $state(false);
let modaldata = $state("");
+
+ let emailr = $state("");
+ let emailrecovery = $state("");
async function SubmitRecuperarContraseñaEmail(e) {
e.preventDefault();
- return;
try {
- const req = await fetch($urlG + "");
+ const req = await fetch($urlG + "/api/recuperarUsuario", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ Email: emailr,
+ EmailRecuperacion: emailrecovery,
+ }),
+ });
+ const data = await req.json();
+ showrecuperarmodal = false;
+ if (req.ok) {
+ showf2amodal = true;
+ return;
+ }
+
+ //hago esto para que no puedan haber errores en caso de que intente recuperar 1 cuenta, aborte y intente recuperar una segunda
+ emailr = "";
+ emailrecovery = "";
+ //
+ modaldata = data.message;
} catch {
modaldata = "Fallo al hacer la request";
}
- } //WIP
+ }
+
+ let showf2amodal = $state(false);
+ async function submitf2a(e) {
+ e.preventDefault();
+
+ const inputs = document.querySelectorAll(".otp-input");
+
+ let otppin = "";
+
+ inputs.forEach((x) => {
+ otppin += x.value.trim();
+ });
+ if (otppin.length != 6) {
+ modaldata = "la longitud del pin es incorrecta";
+ return;
+ }
+ if (emailr == "") {
+ modaldata = "Fallo vuelva a intentar";
+ return;
+ }
+ try {
+ const req = await fetch($urlG + "/api/ingresar2fa", {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({ Pin: otppin, Email: emailr }),
+ });
+ const data = await req.json();
+ if (req.ok) {
+ sessionStorage.setItem("token", data.token);
+ localStorage.setItem("email", emailr);
+ showf2amodal = false;
+ navigate("/usuario");
+ }
+ } catch {
+ modaldata = "Fallo al hacer la request";
+ }
+ }
{#if modaldata}
@@ -116,6 +174,86 @@
>
+{#if showf2amodal}
+
+{/if}
{#if showrecuperarmodal}