diff --git a/Aspnet/AlquilaFacil.csproj b/Aspnet/AlquilaFacil.csproj index 9f40be9..842f7c7 100644 --- a/Aspnet/AlquilaFacil.csproj +++ b/Aspnet/AlquilaFacil.csproj @@ -7,7 +7,10 @@ - + + + + diff --git a/Aspnet/Controllers/InquilinoController.cs b/Aspnet/Controllers/InquilinoController.cs index ad68fcf..c7f5391 100644 --- a/Aspnet/Controllers/InquilinoController.cs +++ b/Aspnet/Controllers/InquilinoController.cs @@ -27,7 +27,8 @@ public class InquilinoController: Controller if (inq.Dni < 0 ) return BadRequest("Dni Invalido"); - return Redirect("/Inquilino"); +// no recuerdo porque esto existe +// return Redirect("/Inquilino"); return Content($"

Inquilino {inq.Nombre} agregado exitosamente.

", "text/html"); } @@ -38,4 +39,4 @@ public class InquilinoController: Controller public IActionResult FormAdd(){ return View(); } -} \ No newline at end of file +} diff --git a/Aspnet/Controllers/LoginController.cs b/Aspnet/Controllers/LoginController.cs index ea9c3d9..4ba34a8 100644 --- a/Aspnet/Controllers/LoginController.cs +++ b/Aspnet/Controllers/LoginController.cs @@ -1,30 +1,41 @@ +using Entidades.Dto; +using Modelo; +using Microsoft.AspNetCore.Mvc; +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using Microsoft.IdentityModel.Tokens; +namespace AlquilaFacil.Controllers; - using Entidades.Dto; - using Modelo; - using Microsoft.AspNetCore.Mvc; - namespace AlquilaFacil.Controllers; +[ApiController] +public class LoginController: ControllerBase +{ + [HttpPost("api/login")] + public IActionResult Login([FromBody] LoginDto loginDto) { + + if (loginDto.Email == String.Empty || loginDto.Contraseña == String.Empty) return Unauthorized(new {message = "Los Datos no llegaron correctamente o faltan"}); + + var usuario = RepositorioUsuarios.Singleton.CheckUsuario(loginDto); + if (usuario == null) return Unauthorized(new {message = "El usuario no existe o la contraseña es incorrecta"}); - public class LoginController: Controller - { - public IActionResult Index(){ - return View(); - } + string tokenString = GenerarToken(loginDto); + return Ok( new {Token = tokenString, Redirect = "/Menu"}); + } - [HttpPost("api/login")] - public IActionResult Login([FromForm] LoginDto loginDto) { - - var usuario = RepositorioUsuarios.Singleton.CheckUsuario(loginDto); - if (usuario == null){ - return Content(errorAlert); - } - else { - Response.Headers["HX-Redirect"] = "/Home"; - return Ok(); - } - } - - private const string errorAlert = @" - "; - } \ No newline at end of file + + private string GenerarToken(LoginDto loginDto){ + var tokenHandler = new JwtSecurityTokenHandler(); + var key = Encoding.ASCII.GetBytes("ffb2cdc15d472e41a5b626e294c45020"); + var tokenDescriptor = new SecurityTokenDescriptor + { + Subject = new ClaimsIdentity(new Claim[] + { + new Claim(ClaimTypes.Name, loginDto.Email) + }), + Expires = DateTime.UtcNow.AddHours(1), + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature) + }; + var token = tokenHandler.CreateToken(tokenDescriptor); + return tokenHandler.WriteToken(token); + } +} diff --git a/Aspnet/Program.cs b/Aspnet/Program.cs index 0bfdf53..f08a8c6 100644 --- a/Aspnet/Program.cs +++ b/Aspnet/Program.cs @@ -1,30 +1,41 @@ + var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddControllers(); -builder.Services.AddControllersWithViews(); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); + +builder.Services.AddCors(options => + { + options.AddPolicy("AllowSvelteApp", + builder => + { + builder.WithOrigins("*") + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); var app = builder.Build(); // Configure the HTTP request pipeline. -if (!app.Environment.IsDevelopment()) +if (app.Environment.IsDevelopment()) { - app.UseExceptionHandler("/Home/Error"); - // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. - app.UseHsts(); + app.UseSwagger(); + app.UseSwaggerUI(); } -app.UseHttpsRedirection(); -app.UseStaticFiles(); - app.UseRouting(); +app.UseAuthentication(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Login}/{action=Index}/{id?}"); +app.UseCors("AllowSvelteApp"); app.UseEndpoints(endpoints => { // Mapea los controladores a las rutas predeterminadas. diff --git a/Aspnet/Views/Login/ErrorPopup.cshtml b/Aspnet/Views/Login/ErrorPopup.cshtml index 58d7d87..0a591f6 100644 --- a/Aspnet/Views/Login/ErrorPopup.cshtml +++ b/Aspnet/Views/Login/ErrorPopup.cshtml @@ -1,5 +1,5 @@ @model Entidades.Dto.LoginDto; diff --git a/Entidades/Dto/LoginDto.cs b/Entidades/Dto/LoginDto.cs index a276135..17f707c 100644 --- a/Entidades/Dto/LoginDto.cs +++ b/Entidades/Dto/LoginDto.cs @@ -5,6 +5,6 @@ namespace Entidades.Dto; [NotMapped] public class LoginDto { - public string Usuario {get; set;} = string.Empty; - public string Contrasena {get; set;} = string.Empty; -} \ No newline at end of file + public string Email {get; set;} = string.Empty; + public string Contraseña {get; set;} = string.Empty; +} diff --git a/Entidades/Dto/TokenDto.cs b/Entidades/Dto/TokenDto.cs new file mode 100644 index 0000000..e23f2e4 --- /dev/null +++ b/Entidades/Dto/TokenDto.cs @@ -0,0 +1,6 @@ +namespace Entidades.Dto; + +public class TokenDto{ + public string Token {get; set;} = String.Empty; + public string Redirect { get; set; } = String.Empty; +} diff --git a/Front/.gitignore b/Front/.gitignore new file mode 100644 index 0000000..a547bf3 --- /dev/null +++ b/Front/.gitignore @@ -0,0 +1,24 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/Front/.vscode/extensions.json b/Front/.vscode/extensions.json new file mode 100644 index 0000000..bdef820 --- /dev/null +++ b/Front/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["svelte.svelte-vscode"] +} diff --git a/Front/README.md b/Front/README.md new file mode 100644 index 0000000..e6cd94f --- /dev/null +++ b/Front/README.md @@ -0,0 +1,47 @@ +# Svelte + TS + Vite + +This template should help get you started developing with Svelte and TypeScript in Vite. + +## Recommended IDE Setup + +[VS Code](https://code.visualstudio.com/) + [Svelte](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode). + +## Need an official Svelte framework? + +Check out [SvelteKit](https://github.com/sveltejs/kit#readme), which is also powered by Vite. Deploy anywhere with its serverless-first approach and adapt to various platforms, with out of the box support for TypeScript, SCSS, and Less, and easily-added support for mdsvex, GraphQL, PostCSS, Tailwind CSS, and more. + +## Technical considerations + +**Why use this over SvelteKit?** + +- It brings its own routing solution which might not be preferable for some users. +- It is first and foremost a framework that just happens to use Vite under the hood, not a Vite app. + +This template contains as little as possible to get started with Vite + TypeScript + Svelte, while taking into account the developer experience with regards to HMR and intellisense. It demonstrates capabilities on par with the other `create-vite` templates and is a good starting point for beginners dipping their toes into a Vite + Svelte project. + +Should you later need the extended capabilities and extensibility provided by SvelteKit, the template has been structured similarly to SvelteKit so that it is easy to migrate. + +**Why `global.d.ts` instead of `compilerOptions.types` inside `jsconfig.json` or `tsconfig.json`?** + +Setting `compilerOptions.types` shuts out all other types not explicitly listed in the configuration. Using triple-slash references keeps the default TypeScript setting of accepting type information from the entire workspace, while also adding `svelte` and `vite/client` type information. + +**Why include `.vscode/extensions.json`?** + +Other templates indirectly recommend extensions via the README, but this file allows VS Code to prompt the user to install the recommended extension upon opening the project. + +**Why enable `allowJs` in the TS template?** + +While `allowJs: false` would indeed prevent the use of `.js` files in the project, it does not prevent the use of JavaScript syntax in `.svelte` files. In addition, it would force `checkJs: false`, bringing the worst of both worlds: not being able to guarantee the entire codebase is TypeScript, and also having worse typechecking for the existing JavaScript. In addition, there are valid use cases in which a mixed codebase may be relevant. + +**Why is HMR not preserving my local component state?** + +HMR state preservation comes with a number of gotchas! It has been disabled by default in both `svelte-hmr` and `@sveltejs/vite-plugin-svelte` due to its often surprising behavior. You can read the details [here](https://github.com/rixo/svelte-hmr#svelte-hmr). + +If you have state that's important to retain within a component, consider creating an external store which would not be replaced by HMR. + +```ts +// store.ts +// An extremely simple external store +import { writable } from 'svelte/store' +export default writable(0) +``` diff --git a/Front/bun.lockb b/Front/bun.lockb new file mode 100755 index 0000000..f4cbd75 Binary files /dev/null and b/Front/bun.lockb differ diff --git a/Front/index.html b/Front/index.html new file mode 100644 index 0000000..2719e02 --- /dev/null +++ b/Front/index.html @@ -0,0 +1,14 @@ + + + + + + + + AlquilaFacil + + +
+ + + diff --git a/Front/package.json b/Front/package.json new file mode 100644 index 0000000..f7518bb --- /dev/null +++ b/Front/package.json @@ -0,0 +1,26 @@ +{ + "name": "front", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "check": "svelte-check --tsconfig ./tsconfig.json && tsc -p tsconfig.node.json" + }, + "devDependencies": { + "@sveltejs/vite-plugin-svelte": "^3.1.2", + "@tsconfig/svelte": "^5.0.4", + "svelte": "^4.2.19", + "svelte-check": "^4.0.4", + "tslib": "^2.7.0", + "typescript": "^5.5.3", + "vite": "^5.4.8" + }, + "dependencies": { + "@sveltejs/kit": "^2.7.1", + "@sveltestrap/sveltestrap": "^6.2.7", + "svelte-routing": "^2.13.0" + } +} diff --git a/Front/public/favicon.png b/Front/public/favicon.png new file mode 100644 index 0000000..bc2d027 Binary files /dev/null and b/Front/public/favicon.png differ diff --git a/Front/src/App.svelte b/Front/src/App.svelte new file mode 100644 index 0000000..52b77ea --- /dev/null +++ b/Front/src/App.svelte @@ -0,0 +1,11 @@ + + + + + + + diff --git a/Front/src/Menu/page.svelte b/Front/src/Menu/page.svelte new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/Front/src/Menu/page.svelte @@ -0,0 +1 @@ + diff --git a/Front/src/app.css b/Front/src/app.css new file mode 100644 index 0000000..617f5e9 --- /dev/null +++ b/Front/src/app.css @@ -0,0 +1,79 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +.card { + padding: 2em; +} + +#app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/Front/src/assets/svelte.svg b/Front/src/assets/svelte.svg new file mode 100644 index 0000000..c5e0848 --- /dev/null +++ b/Front/src/assets/svelte.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/Front/src/lib/Counter.svelte b/Front/src/lib/Counter.svelte new file mode 100644 index 0000000..979b4df --- /dev/null +++ b/Front/src/lib/Counter.svelte @@ -0,0 +1,10 @@ + + + diff --git a/Front/src/lib/NavBarLogin.svelte b/Front/src/lib/NavBarLogin.svelte new file mode 100644 index 0000000..0da5cc3 --- /dev/null +++ b/Front/src/lib/NavBarLogin.svelte @@ -0,0 +1,8 @@ + + + + + AlquilaFacil + diff --git a/Front/src/lib/login.svelte b/Front/src/lib/login.svelte new file mode 100644 index 0000000..ae625cd --- /dev/null +++ b/Front/src/lib/login.svelte @@ -0,0 +1,66 @@ + + + + + Iniciar Sesión + + +
+ + + + + + + + + +
+{#if errorMessage} + +{/if} +
+
diff --git a/Front/src/login/loginPage.svelte b/Front/src/login/loginPage.svelte new file mode 100644 index 0000000..56e4174 --- /dev/null +++ b/Front/src/login/loginPage.svelte @@ -0,0 +1,10 @@ + + + +
+
+ +
diff --git a/Front/src/main.ts b/Front/src/main.ts new file mode 100644 index 0000000..2619336 --- /dev/null +++ b/Front/src/main.ts @@ -0,0 +1,8 @@ +//import './app.css' +import App from './App.svelte' + +const app = new App({ + target: document.getElementById('app')!, +}) + +export default app diff --git a/Front/src/vite-env.d.ts b/Front/src/vite-env.d.ts new file mode 100644 index 0000000..4078e74 --- /dev/null +++ b/Front/src/vite-env.d.ts @@ -0,0 +1,2 @@ +/// +/// diff --git a/Front/svelte.config.js b/Front/svelte.config.js new file mode 100644 index 0000000..b0683fd --- /dev/null +++ b/Front/svelte.config.js @@ -0,0 +1,7 @@ +import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' + +export default { + // Consult https://svelte.dev/docs#compile-time-svelte-preprocess + // for more information about preprocessors + preprocess: vitePreprocess(), +} diff --git a/Front/tsconfig.json b/Front/tsconfig.json new file mode 100644 index 0000000..df56300 --- /dev/null +++ b/Front/tsconfig.json @@ -0,0 +1,21 @@ +{ + "extends": "@tsconfig/svelte/tsconfig.json", + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "resolveJsonModule": true, + /** + * Typecheck JS in `.svelte` and `.js` files by default. + * Disable checkJs if you'd like to use dynamic types in JS. + * Note that setting allowJs false does not prevent the use + * of JS in `.svelte` files. + */ + "allowJs": true, + "checkJs": true, + "isolatedModules": true, + "moduleDetection": "force" + }, + "include": ["src/**/*.ts", "src/**/*.js", "src/**/*.svelte"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/Front/tsconfig.node.json b/Front/tsconfig.node.json new file mode 100644 index 0000000..6c2d870 --- /dev/null +++ b/Front/tsconfig.node.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "composite": true, + "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "noEmit": true + }, + "include": ["vite.config.ts"] +} diff --git a/Front/vite.config.ts b/Front/vite.config.ts new file mode 100644 index 0000000..d701969 --- /dev/null +++ b/Front/vite.config.ts @@ -0,0 +1,7 @@ +import { defineConfig } from 'vite' +import { svelte } from '@sveltejs/vite-plugin-svelte' + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [svelte()], +}) diff --git a/Modelo/RepositorioUsuarios.cs b/Modelo/RepositorioUsuarios.cs index cc1f5c6..0aa74fe 100644 --- a/Modelo/RepositorioUsuarios.cs +++ b/Modelo/RepositorioUsuarios.cs @@ -1,9 +1,7 @@ using System.Collections.ObjectModel; -using System.Runtime.Intrinsics.Arm; using System.Security.Cryptography; using System.Text; using Entidades.Dto; -using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; namespace Modelo; @@ -12,15 +10,15 @@ public class RepositorioUsuarios: RepositorioBase public static RepositorioUsuarios Singleton = new(); public Usuario? CheckUsuario(LoginDto logindto) { - byte[] Contraseña = HacerHash(logindto.Contrasena); + byte[] Contraseña = HacerHash(logindto.Contraseña); - bool usu = Context.Inquilinos.Any(x=>x.Email == logindto.Usuario && x.Contrasena == Contraseña); + bool usu = Context.Inquilinos.Any(x=>x.Email == logindto.Email && x.Contrasena == Contraseña); if (usu){ - return Context.Inquilinos.FirstOrDefault(x=>x.Email == logindto.Usuario); + return Context.Inquilinos.FirstOrDefault(x=>x.Email == logindto.Email); } - usu = Context.Propietarios.Any(x=>x.Email == logindto.Usuario && x.Contrasena == Contraseña); + usu = Context.Propietarios.Any(x=>x.Email == logindto.Email && x.Contrasena == Contraseña); if (usu){ - return Context.Propietarios.FirstOrDefault(x=>x.Email == logindto.Usuario); + return Context.Propietarios.FirstOrDefault(x=>x.Email == logindto.Email); } return null; } @@ -34,4 +32,4 @@ public class RepositorioUsuarios: RepositorioBase return Encoding.UTF8.GetBytes(BitConverter.ToString(buf).Replace("-","").ToLower()); } -} \ No newline at end of file +}