using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using WebVentaCoche.Helpers;
using WebVentaCoche.Enums;
using WebVentaCoche.Models;
using WebVentaCoche.Services;
using WebVentaCoche.ViewModels;
using static System.Runtime.InteropServices.JavaScript.JSType;
using WebVentaCoche.DataBase;
using Microsoft.EntityFrameworkCore;
namespace WebVentaCoche.Controllers
{
public class UserController : Controller
{
private readonly IUserHelper _userHelper;
private readonly IConfiguration _configuration;
private readonly EmailService _emailService;
private readonly VerificationService _verificationService;
private readonly ApplicationDbContext _context;
public UserController(IUserHelper userHelper, IConfiguration configuration, EmailService emailService, VerificationService verificationService, ApplicationDbContext context)
{
_userHelper = userHelper;
_configuration = configuration;
_emailService = emailService;
_verificationService = verificationService;
_context = context;
}
private async Task SenConfirmationEmail(User user, string token, string confirmationLink)
{
await _emailService.SendEmailAsync(user.Email, "Verifica tu Email",
$"
¡Hola {user.Name}!
" +
$"Gracias por registrarte en WebVentaCoche. Para completar tu registro, verifica tu correo electrónico haciendo clic en el siguiente enlace:
" +
$"Verificar mi Correo
" +
$"Si no has solicitado esto, puedes ignorar este mensaje.
" +
$"¡Gracias!
");
}
[HttpGet]
public IActionResult Register()
{
return View();
}
[HttpPost]
public async Task Register(RegisterViewModel model)
{
if (ModelState.IsValid)
{
User existingUser = await _userHelper.GetUserAsync(model.Email);
if (existingUser != null)
{
return BadRequest("El correo electrónico ya está en uso.");
}
var user = new User
{
Name = model.Email,
Surname = model.Surname,
Email = model.Email,
PhoneNumber = model.PhoneNumber,
UserName = model.Email,
UserType = UserType.Usuario,
};
//Name = nombre,
// Surname = apellidos,
// Email = email,
// PhoneNumber = phoneNumber,
// Password = password,
// PasswordConfirm = passwordConfirm,
// UserName = email,
// UserType = UserType.Usuario
var result = await _userHelper.AddUserAsync(user, model.Password);
if (result.Succeeded)
{
await _userHelper.AddUserRoleAsync(user, user.UserType.ToString());
//return Ok(BuildToken(user));
var token = await _userHelper.GenerateEmailConfirmationTokenAsync(user);
// Crea el enlace de verificación
var confirmationLink = Url.Action(
"VerifyEmail",
"User",
new { token, email = user.Email },
Request.Scheme);
SenConfirmationEmail(user, token, confirmationLink);
TempData["Message"] = "Registro exitoso. Revisa tu correo para confirmar tu email.";
return RedirectToAction("Login");
}
foreach (var error in result.Errors)
{
ModelState.AddModelError(string.Empty, error.Description);
}
}
return View(model);
}
[HttpGet]
public IActionResult Login()
{
return View();
}
[HttpPost]
public async Task Login(LoginViewModel model)
{
if (ModelState.IsValid)
{
var user = await _userHelper.GetUserAsync(model.Email);
if (user == null)
{
TempData["Error"] = "Email o contraseña incorrectos.";
return View(model); // Redirige de nuevo al formulario de login con un mensaje de error
}
if (!await _userHelper.IsEmailConfirmedAsync(user))
{
var token = await _userHelper.GenerateEmailConfirmationTokenAsync(user);
// Crea el enlace de verificación
var confirmationLink = Url.Action(
"VerifyEmail",
"User",
new { token, email = user.Email },
Request.Scheme);
SenConfirmationEmail(user, token, confirmationLink);
// Redirige al usuario a la página de verificación de email
TempData["Error"] = "Debes confirmar tu email antes de iniciar sesión.";
return RedirectToAction("Index", "Home");
}
var result = await _userHelper.LoginAsync(model);
if (result.Succeeded)
{
// Redirige al usuario al home o al lugar correspondiente
return RedirectToAction("Index", "Home");
}
TempData["Error"] = "Email o contraseña incorrectos.";
return View(model);
}
return View(model);
}
[HttpPost]
public async Task Logout()
{
await _userHelper.LogoutAsync();
return RedirectToAction("Login");
}
//[HttpGet]
//public IActionResult VerifyEmail()
//{
// return View();
//}
[HttpGet]
public async Task VerifyEmail(string token, string email)
{
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(email))
{
TempData["Error"] = "El enlace de verificación no es válido.";
return View();
}
var user = await _userHelper.GetUserAsync(email);
if (user == null)
{
TempData["Error"] = "Usuario no encontrado.";
return View();
}
var result = await _userHelper.ConfirmEmailAsync(user, token);
if (result.Succeeded)
{
TempData["Message"] = "¡Tu correo ha sido verificado correctamente!";
}
else
{
TempData["Error"] = "El enlace de verificación es inválido o ha expirado.";
}
return View();
}
public async Task Index()
{
var users = await _context.Users.ToListAsync();
return View(users);
}
//GET:/Users/Edit/{id}
[HttpGet]
public async Task Edit(string id)
{
if (string.IsNullOrEmpty(id))
return NotFound();
var user = await _context.Users.FindAsync(id);
if (user == null)
return NotFound();
var vm = new UserViewModel
{
Id = user.Id,
Name = user.Name,
Surname = user.Surname,
Email = user.Email,
PhoneNumber = user.PhoneNumber,
UserType = user.UserType
};
return View(vm);
}
//POST:/Users/Edit
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Edit(UserViewModel vm)
{
if (!ModelState.IsValid)
return View(vm);
var user = await _context.Users.FindAsync(vm.Id);
if (user == null)
return NotFound();
// Actualiza campos
user.Name = vm.Name;
user.Surname = vm.Surname;
user.Email = vm.Email;
user.UserName = vm.Email; // si cambias email conviene actualizar UserName
user.PhoneNumber = vm.PhoneNumber;
user.UserType = vm.UserType;
_context.Update(user);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
//GET:/Users/Create
public IActionResult Create()
{
return View();
}
//POST:/Users/Create
[HttpPost]
[ValidateAntiForgeryToken]
public async Task Create(RegisterViewModel model)
{
if (!ModelState.IsValid) return View(model);
// Valida y crea el usuario
var user = new User
{
Name = model.Name,
Surname = model.Surname,
Email = model.Email,
PhoneNumber = model.PhoneNumber,
UserName = model.Email,
UserType = Enums.UserType.Usuario
};
var result = await _userHelper.AddUserAsync(user, model.Password);
if (result.Succeeded)
return RedirectToAction(nameof(Index));
foreach (var e in result.Errors)
ModelState.AddModelError("", e.Description);
return View(model);
}
private TokenAuth BuildToken(User user)
{
var claims = new List
{
new Claim(ClaimTypes.Name, user.Email!),
new Claim(ClaimTypes.Role, user.UserType.ToString()),
new Claim("Nombre", user.Name),
new Claim("Apellido", user.Surname),
};
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JWT:SecretToken"]!));
var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
var expiration = DateTime.UtcNow.AddDays(15);
var token = new JwtSecurityToken(
issuer: null,
audience: null,
claims: claims,
expires: expiration,
signingCredentials: credentials
);
return new TokenAuth
{
Token = new JwtSecurityTokenHandler().WriteToken(token),
Expiration = expiration
};
}
}
}