Esta todo a medio hacerse pero quiero versionar esto ya para no perder
nada
This commit is contained in:
@@ -54,4 +54,14 @@ public class UsuarioController : ControllerBase
|
|||||||
return ret ? Ok(new { message = "Email de recuperación actualizado con éxito" }) : BadRequest(new { message = "No se pudo actualizar el email de recuperación" });
|
return ret ? Ok(new { message = "Email de recuperación actualizado con éxito" }) : BadRequest(new { message = "No se pudo actualizar el email de recuperación" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public record recuperarusuario(string Email, string EmailRecuperacion);
|
||||||
|
[HttpPost("/api/recuperarUsuario")]
|
||||||
|
public IActionResult RecuperarUsuario([FromBody] recuperarusuario mails)
|
||||||
|
{
|
||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
28
Aspnet/Emailer/Builder/EmailBuilder.cs
Normal file
28
Aspnet/Emailer/Builder/EmailBuilder.cs
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
using System.Net.Mail;
|
||||||
|
namespace AlquilaFacil.Emailer.Builder;
|
||||||
|
|
||||||
|
public class EmailBuilder
|
||||||
|
{
|
||||||
|
private MailMessage _message = new();
|
||||||
|
|
||||||
|
public EmailBuilder To(string to)
|
||||||
|
{
|
||||||
|
_message.To.Add(to);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmailBuilder Subject(string subject)
|
||||||
|
{
|
||||||
|
_message.Subject = subject;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EmailBuilder Body(string email, string pin)
|
||||||
|
{
|
||||||
|
_message.IsBodyHtml = true;
|
||||||
|
_message.Body = new HtmlGenerator().GenerarMail2fa(email, pin);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MailMessage Build() => _message;
|
||||||
|
}
|
||||||
58
Aspnet/Emailer/Builder/EmailHtmlGenerator.cs
Normal file
58
Aspnet/Emailer/Builder/EmailHtmlGenerator.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
namespace AlquilaFacil.Emailer.Builder;
|
||||||
|
|
||||||
|
public class HtmlGenerator
|
||||||
|
{
|
||||||
|
public string GenerarMail2fa(string emailUsuario, string pin)
|
||||||
|
{
|
||||||
|
var msg = $"""
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div
|
||||||
|
style='background-color:#000000;color:#FFFFFF;font-family:"Iowan Old Style", "Palatino Linotype", "URW Palladio L", P052, serif;font-size:16px;font-weight:400;letter-spacing:0.15008px;line-height:1.5;margin:0;padding:32px 0;min-height:100%;width:100%'
|
||||||
|
>
|
||||||
|
<table
|
||||||
|
align="center"
|
||||||
|
width="100%"
|
||||||
|
style="margin:0 auto;max-width:600px;background-color:#000000"
|
||||||
|
role="presentation"
|
||||||
|
cellspacing="0"
|
||||||
|
cellpadding="0"
|
||||||
|
border="0"
|
||||||
|
>
|
||||||
|
<tbody>
|
||||||
|
<tr style="width:100%">
|
||||||
|
<td>
|
||||||
|
<div
|
||||||
|
style="color:#ffffff;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
|
||||||
|
>
|
||||||
|
Aqui esta su codigo OTP:
|
||||||
|
</div>
|
||||||
|
<h1
|
||||||
|
style='font-weight:bold;text-align:center;margin:0;font-family:"Nimbus Mono PS", "Courier New", "Cutive Mono", monospace;font-size:32px;padding:16px 24px 16px 24px'
|
||||||
|
>
|
||||||
|
{pin}
|
||||||
|
</h1>
|
||||||
|
<div
|
||||||
|
style="color:#868686;font-size:16px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
|
||||||
|
>
|
||||||
|
Este codigo es del usuario con email:{emailUsuario}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
style="color:#868686;font-size:14px;font-weight:normal;text-align:center;padding:16px 24px 16px 24px"
|
||||||
|
>
|
||||||
|
Si no sabes para que es el email, ignoralo.
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
}
|
||||||
9
Aspnet/Emailer/Decorator/IEmailerSender.cs
Normal file
9
Aspnet/Emailer/Decorator/IEmailerSender.cs
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
using System.Net.Mail;
|
||||||
|
|
||||||
|
namespace AlquilaFacil.Emailer.Sender;
|
||||||
|
|
||||||
|
public interface IEmailSender
|
||||||
|
{
|
||||||
|
public void Send(MailMessage message, SmtpClient smtp);
|
||||||
|
|
||||||
|
}
|
||||||
25
Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs
Normal file
25
Aspnet/Emailer/Decorator/OtpEmailSenderDecorator.cs
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"usr": "nwFNMLJcn5m0owbzeXMs",
|
"usr": "nwFNMLJcn5m0owbzeXMs",
|
||||||
"scrt": "Mf9HxTir5mIGwWSBtQXd6DRK2k00V0EyXk7QTu70",
|
"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"
|
||||||
}
|
}
|
||||||
|
|||||||
13
Entidades/EstadoPropiedad.cs
Normal file
13
Entidades/EstadoPropiedad.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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<Propiedade> Propiedades { get; set; } = new List<Propiedade>();
|
||||||
|
}
|
||||||
23
Entidades/LogDetalle.cs
Normal file
23
Entidades/LogDetalle.cs
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
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!;
|
||||||
|
}
|
||||||
13
Entidades/TipoPropiedad.cs
Normal file
13
Entidades/TipoPropiedad.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
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<Propiedade> Propiedades { get; set; } = new List<Propiedade>();
|
||||||
|
}
|
||||||
@@ -1,11 +1,23 @@
|
|||||||
<script>
|
<script>
|
||||||
import { CardHeader, CardTitle, Button, Card, Input, Form, CardBody, FormGroup } from '@sveltestrap/sveltestrap';
|
import {
|
||||||
import { navigate } from 'svelte-routing';
|
CardHeader,
|
||||||
|
CardTitle,
|
||||||
|
Button,
|
||||||
|
Card,
|
||||||
|
Input,
|
||||||
|
Form,
|
||||||
|
CardBody,
|
||||||
|
FormGroup,
|
||||||
|
Modal,
|
||||||
|
} from "@sveltestrap/sveltestrap";
|
||||||
|
import { navigate } from "svelte-routing";
|
||||||
import { urlG } from "../stores/urlStore";
|
import { urlG } from "../stores/urlStore";
|
||||||
|
import ModalEstatico from "./ModalEstatico.svelte";
|
||||||
|
import { parse } from "svelte/compiler";
|
||||||
|
|
||||||
let email = $state("")
|
let email = $state("");
|
||||||
let contraseña = $state("")
|
let contraseña = $state("");
|
||||||
let errorMessage = $state("")
|
let errorMessage = $state("");
|
||||||
|
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
async function submitForm(event) {
|
async function submitForm(event) {
|
||||||
@@ -14,53 +26,136 @@
|
|||||||
const data = { email, contraseña };
|
const data = { email, contraseña };
|
||||||
try {
|
try {
|
||||||
const response = await fetch(String($urlG) + "/api/login", {
|
const response = await fetch(String($urlG) + "/api/login", {
|
||||||
method: 'POST',
|
method: "POST",
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
credentials: "include"
|
credentials: "include",
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorData = await response.json()
|
const errorData = await response.json();
|
||||||
errorMessage = errorData.message;
|
errorMessage = errorData.message;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const ret = await response.json();
|
const ret = await response.json();
|
||||||
localStorage.setItem('email', ret.email);
|
localStorage.setItem("email", ret.email);
|
||||||
sessionStorage.setItem('token', ret.token);
|
sessionStorage.setItem("token", ret.token);
|
||||||
//setTimeout(() => console.log("50ms") ,50);
|
//setTimeout(() => console.log("50ms") ,50);
|
||||||
navigate(ret.redirect);
|
navigate(ret.redirect);
|
||||||
} catch (e) {
|
} catch (e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let showrecuperarmodal = $state(false);
|
||||||
|
let modaldata = $state("");
|
||||||
|
async function SubmitRecuperarContraseñaEmail(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
try {
|
||||||
|
const req = await fetch($urlG + "");
|
||||||
|
} catch {
|
||||||
|
modaldata = "Fallo al hacer la request";
|
||||||
}
|
}
|
||||||
|
} //WIP
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Card class="position-sticky top-50 start-50 translate-middle-x border border-success" style="width: 20rem; height: auto;" theme="auto" outline>
|
{#if modaldata}
|
||||||
|
<ModalEstatico close={() => !!(modaldata = "")} payload={modaldata} />
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<Card
|
||||||
|
class="position-sticky top-50 start-50 translate-middle-x border border-success"
|
||||||
|
style="width: 20rem; height: auto;"
|
||||||
|
theme="auto"
|
||||||
|
outline
|
||||||
|
>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
<CardTitle>Iniciar Sesión</CardTitle>
|
<CardTitle>Iniciar Sesión</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardBody>
|
<CardBody>
|
||||||
<Form on:submit={submitForm}>
|
<Form onsubmit={(e) => submitForm(e)}>
|
||||||
<FormGroup floating label="Email">
|
<FormGroup floating label="Email">
|
||||||
<Input type="email" placeholder="ejemplo@mail.com" bind:value={email} required/>
|
<Input
|
||||||
|
type="email"
|
||||||
|
placeholder="ejemplo@mail.com"
|
||||||
|
bind:value={email}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup floating label="Contraseña">
|
<FormGroup floating label="Contraseña">
|
||||||
<Input type="password" placeholder="*********" bind:value={contraseña} required/>
|
<Input
|
||||||
|
type="password"
|
||||||
|
placeholder="*********"
|
||||||
|
bind:value={contraseña}
|
||||||
|
required
|
||||||
|
/>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
<FormGroup>
|
<FormGroup>
|
||||||
<Button color="primary" type="submit">Ingresar</Button>
|
<Button color="primary" type="submit">Ingresar</Button>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
</Form>
|
</Form>
|
||||||
{#if errorMessage}
|
{#if errorMessage}
|
||||||
<div class='alert alert-warning alert-dismissible fade show' role='alert'>
|
<div
|
||||||
|
class="alert alert-warning alert-dismissible fade show"
|
||||||
|
role="alert"
|
||||||
|
>
|
||||||
<strong>{errorMessage}</strong>
|
<strong>{errorMessage}</strong>
|
||||||
<button type="button" class="btn-close close" aria-label="Close" data-bs-dismiss="alert"></button>
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close close"
|
||||||
|
aria-label="Close"
|
||||||
|
data-bs-dismiss="alert"
|
||||||
|
></button>
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
<hr />
|
||||||
|
<a href="#" onclick={() => (showrecuperarmodal = true)}
|
||||||
|
>Recuperar Contraseña</a
|
||||||
|
>
|
||||||
</CardBody>
|
</CardBody>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
|
{#if showrecuperarmodal}
|
||||||
|
<div
|
||||||
|
class="modal"
|
||||||
|
tabindex="-1"
|
||||||
|
style="display: block; background-color: rgba(0, 0, 0, 0.3);"
|
||||||
|
>
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">Recuperar Contraseña</h5>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
aria-label="Close"
|
||||||
|
onclick={() => (showrecuperarmodal = false)}
|
||||||
|
></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<form onsubmit={SubmitRecuperarContraseñaEmail}>
|
||||||
|
<div class="mb-3">
|
||||||
|
<label for="recoveryEmail" class="form-label"
|
||||||
|
>Email</label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="email"
|
||||||
|
class="form-control"
|
||||||
|
id="recoveryEmail"
|
||||||
|
placeholder="Ingresa tu email"
|
||||||
|
required
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="d-grid gap-2">
|
||||||
|
<button type="submit" class="btn btn-primary"
|
||||||
|
>Enviar</button
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|||||||
@@ -11,6 +11,18 @@ namespace Modelo;
|
|||||||
|
|
||||||
public class RepositorioUsuarios : RepositorioBase<RepositorioUsuarios>
|
public class RepositorioUsuarios : RepositorioBase<RepositorioUsuarios>
|
||||||
{
|
{
|
||||||
|
public bool CheckEmailRecuperacion(string Email, string EmailRecuperacion)
|
||||||
|
{
|
||||||
|
var con = Context;
|
||||||
|
Cliente cli = con.Clientes.FirstOrDefault(x => x.Email == Email);
|
||||||
|
if (cli == null) return false;
|
||||||
|
if (cli.EmailRecuperacion == EmailRecuperacion)
|
||||||
|
{
|
||||||
|
base.GenerarLog(con, cli.Dni, "Intento de recuperar Usuario");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public bool SetEmailRecuperacion(string emailrecuperacion, Cliente cli)
|
public bool SetEmailRecuperacion(string emailrecuperacion, Cliente cli)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user