diff --git a/backend/src/StamAcasa.IdentityServer/Quickstart/Account/AccountController.cs b/backend/src/StamAcasa.IdentityServer/Quickstart/Account/AccountController.cs index 59bbc9be..01d8139d 100644 --- a/backend/src/StamAcasa.IdentityServer/Quickstart/Account/AccountController.cs +++ b/backend/src/StamAcasa.IdentityServer/Quickstart/Account/AccountController.cs @@ -18,6 +18,7 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Hosting; +using StamAcasa.IdentityServer.Quickstart.Account; namespace IdentityServer.Quickstart.Account { @@ -212,6 +213,32 @@ public IActionResult AccessDenied() return View(); } + [Route("account/delete")] + [HttpPost] + public async Task DeleteAccountAsync([FromBody] DeleteAccountModel model) + { + var user = await _userManager.FindByNameAsync(model.Email); + if (user == null) + { + return Problem("Utilizatorul nu a fost sters"); + } + + if (!await _userManager.CheckPasswordAsync(user, model.Password)) + { + return Problem("Utilizatorul nu a fost sters"); + } + + var result = await _userManager.DeleteAsync(user); + var userId = await _userManager.GetUserIdAsync(user); + if (!result.Succeeded) + { + throw new InvalidOperationException($"Unexpected error occurred deleting user with ID '{userId}'."); + } + + await _signInManager.SignOutAsync(); + + return Ok(); + } /*****************************************/ /* helper APIs for the AccountController */ diff --git a/backend/src/StamAcasa.IdentityServer/Quickstart/Account/DeleteAccountModel.cs b/backend/src/StamAcasa.IdentityServer/Quickstart/Account/DeleteAccountModel.cs new file mode 100644 index 00000000..095d566d --- /dev/null +++ b/backend/src/StamAcasa.IdentityServer/Quickstart/Account/DeleteAccountModel.cs @@ -0,0 +1,14 @@ + +using System.ComponentModel.DataAnnotations; + +namespace StamAcasa.IdentityServer.Quickstart.Account +{ + public class DeleteAccountModel + { + [Required] + public string Email { get; set; } + + [Required] + public string Password { get; set; } + } +} diff --git a/backend/src/StamAcasa.IdentityServer/Startup.cs b/backend/src/StamAcasa.IdentityServer/Startup.cs index 662a9541..3f4ad467 100644 --- a/backend/src/StamAcasa.IdentityServer/Startup.cs +++ b/backend/src/StamAcasa.IdentityServer/Startup.cs @@ -116,6 +116,19 @@ public void ConfigureServices(IServiceCollection services) )); services.AddSingleton(); services.AddSingleton(); + + services.AddCors(options => + { + // this defines a CORS policy called "default" + options.AddPolicy("default", policy => + { + policy = _identityConfiguration.Clients.SelectMany(x => x.AllowedCorsOrigins) + .Aggregate(policy, (current, url) => current.WithOrigins(url)); + + policy.AllowAnyHeader() + .AllowAnyMethod(); + }); + }); } private X509Certificate2 LoadCertificate(string base64EncodedCertificate, string password) @@ -140,6 +153,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) app.UseHttpsRedirection(); } + app.UseCors("default"); app.UseRouting(); app.UseStaticFiles(); var cookiePolicyOptions = new CookiePolicyOptions diff --git a/frontend/src/api/accountApi.js b/frontend/src/api/accountApi.js new file mode 100644 index 00000000..4eaa721b --- /dev/null +++ b/frontend/src/api/accountApi.js @@ -0,0 +1,12 @@ +import axios from "axios"; +import { Constants } from "../config/constants"; + +const api = axios.create({ + baseURL: `${Constants.idpUrl}/account/` +}); + +const AccountApi = { + deleteAccount: (email, password) => api.post("delete", { email, password }) +}; + +export default AccountApi; diff --git a/frontend/src/api/auth.js b/frontend/src/api/auth.js index d1baef87..814cb19a 100644 --- a/frontend/src/api/auth.js +++ b/frontend/src/api/auth.js @@ -56,3 +56,5 @@ export const getUserToken = async () => { } return user.access_token; }; + +export const removeUser = () => userManager.removeUser(); diff --git a/frontend/src/components/DeleteAccount/index.js b/frontend/src/components/DeleteAccount/index.js new file mode 100644 index 00000000..ed77bb72 --- /dev/null +++ b/frontend/src/components/DeleteAccount/index.js @@ -0,0 +1,69 @@ +import React, { useState } from "react"; +import SidebarLayout from "../SidebarLayout"; +import AccountApi from "../../api/accountApi"; +import "./style.scss"; +import { removeUser, getUser } from "../../api/auth"; +const DeleteAccount = () => { + const [password, setPassword] = useState(""); + const [loading, setLoading] = useState(false); + const [errorDeleting, setErrorDeleting] = useState(false); + + const fieldsFilled = password; + + const updatePassword = event => setPassword(event.target.value); + + const deleteProfile = async () => { + try { + setLoading(true); + const user = await getUser(); + await AccountApi.deleteAccount(user.profile.email, password); + setLoading(false); + await removeUser(); + } catch { + setErrorDeleting(true); + setLoading(false); + } + }; + + const buttonClasses = "button is-danger" + (loading ? " is-loading" : ""); + return ( + +
+ Contul tău va fi șters. Pentru a putea reutiliza această aplicație va + trebui să îți refaci contul de utilizator. Informațiile pe care le-ai + transmis până acum prin intermediul aplicației vor rămâne stocate în + baza de date. Dacă dorești ca toate informațiile să fie eliminate din + baza de date te rugăm să adresezi această cerere către: +

Adresa: Strada Italiană, nr. 22, Sector 2, 020976, București

+

E-mail: jurnalmedical@adr.gov.ro

+
+
{}}> +
+ + +
+
+ +
+
+ +
+ ); +}; + +export default DeleteAccount; diff --git a/frontend/src/components/DeleteAccount/style.scss b/frontend/src/components/DeleteAccount/style.scss new file mode 100644 index 00000000..75e84143 --- /dev/null +++ b/frontend/src/components/DeleteAccount/style.scss @@ -0,0 +1,3 @@ +.notification { + margin-top: 1em; +} \ No newline at end of file diff --git a/frontend/src/components/Header/ProfileItems.js b/frontend/src/components/Header/ProfileItems.js index e6a5a285..8aea36d1 100644 --- a/frontend/src/components/Header/ProfileItems.js +++ b/frontend/src/components/Header/ProfileItems.js @@ -17,6 +17,7 @@ const ProfileItems = () => { Contul meu
+ Ștergere cont ) : ( <> diff --git a/frontend/src/routes.js b/frontend/src/routes.js index 20543abb..3c9efa27 100644 --- a/frontend/src/routes.js +++ b/frontend/src/routes.js @@ -5,6 +5,7 @@ import UpdateProfile from "./components/UpdateProfile"; import Evaluation from "./components/Evaluation"; import Account from "./components/Account"; import TermsAndConditions from "./components/TermsAndConditions"; +import DeleteAccount from "./components/DeleteAccount"; import { redirectSilentSignin, @@ -75,6 +76,10 @@ export const ROUTES = { updateprofile: { path: "/update-profile", component: UpdateProfile + }, + deleteaccount: { + path: "/delete-account", + component: DeleteAccount } } };