diff --git a/src/UI/Areas/Identity/Pages/Account/ExternalLogin.cshtml b/src/UI/Areas/Identity/Pages/Account/ExternalLogin.cshtml
index 51c9b9264f..ba074852ee 100644
--- a/src/UI/Areas/Identity/Pages/Account/ExternalLogin.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/ExternalLogin.cshtml
@@ -29,5 +29,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/ForgotPassword.cshtml b/src/UI/Areas/Identity/Pages/Account/ForgotPassword.cshtml
index cd8e98cf44..5cdfdc0a89 100644
--- a/src/UI/Areas/Identity/Pages/Account/ForgotPassword.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/ForgotPassword.cshtml
@@ -22,5 +22,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Login.cshtml b/src/UI/Areas/Identity/Pages/Account/Login.cshtml
index a486f27545..da09191ae0 100644
--- a/src/UI/Areas/Identity/Pages/Account/Login.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Login.cshtml
@@ -78,5 +78,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/LoginWith2fa.cshtml b/src/UI/Areas/Identity/Pages/Account/LoginWith2fa.cshtml
index 032ecd98cd..c960eb8b22 100644
--- a/src/UI/Areas/Identity/Pages/Account/LoginWith2fa.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/LoginWith2fa.cshtml
@@ -32,10 +32,10 @@
- Don't have access to your authenticator device? You can
+ Don't have access to your authenticator device? You can
log in with a recovery code.
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
\ No newline at end of file
diff --git a/src/UI/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml b/src/UI/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml
index 4b32c1d8ff..abaad2a4d4 100644
--- a/src/UI/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/LoginWithRecoveryCode.cshtml
@@ -23,7 +23,7 @@
-
- @section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
+@section Scripts {
+
}
\ No newline at end of file
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml
index 6aa47234d1..c35de0c622 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/ChangePassword.cshtml
@@ -31,5 +31,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml
new file mode 100644
index 0000000000..709701fc75
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml
@@ -0,0 +1,34 @@
+@page
+@model DeletePersonalDataModel
+@{
+ ViewData["Title"] = "Delete Personal Data";
+ ViewData["ActivePage"] = ManageNavPages.DeletePersonalData;
+}
+
+@ViewData["Title"]
+
+
+
+
+ Deleting this data will permanently remove your account, and this cannot be recovered.
+
+
+
+
+
+@section Scripts {
+
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs b/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs
new file mode 100644
index 0000000000..12b227de58
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/DeletePersonalData.cshtml.cs
@@ -0,0 +1,84 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.ComponentModel.DataAnnotations;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
+{
+ public class DeletePersonalDataModel : PageModel
+ {
+ private readonly UserManager _userManager;
+ private readonly SignInManager _signInManager;
+ private readonly ILogger _logger;
+
+ public DeletePersonalDataModel(
+ UserManager userManager,
+ SignInManager signInManager,
+ ILogger logger)
+ {
+ _userManager = userManager;
+ _signInManager = signInManager;
+ _logger = logger;
+ }
+
+ [BindProperty]
+ public InputModel Input { get; set; }
+
+ public class InputModel
+ {
+ [Required]
+ [DataType(DataType.Password)]
+ public string Password { get; set; }
+ }
+
+ public bool RequirePassword { get; set; }
+
+ public async Task OnGet()
+ {
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ RequirePassword = await _userManager.HasPasswordAsync(user);
+ return Page();
+ }
+
+ public async Task OnPostAsync()
+ {
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ RequirePassword = await _userManager.HasPasswordAsync(user);
+ if (RequirePassword)
+ {
+ if (!await _userManager.CheckPasswordAsync(user, Input.Password))
+ {
+ ModelState.AddModelError(string.Empty, "Password not correct.");
+ return Page();
+ }
+ }
+
+ var result = await _userManager.DeleteAsync(user);
+ if (!result.Succeeded)
+ {
+ throw new InvalidOperationException($"Unexpected error occurred deleteing user with ID '{user.Id}'.");
+ }
+
+ await _signInManager.SignOutAsync();
+
+ _logger.LogInformation("User with ID '{UserId}' deleted themselves.", _userManager.GetUserId(User));
+
+ return Redirect("~/");
+ }
+ }
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml
index 954093ee3b..28bc1c5add 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/Disable2fa.cshtml
@@ -2,7 +2,7 @@
@model Disable2faModel
@{
ViewData["Title"] = "Disable two-factor authentication (2FA)";
- ViewData["ActivePage"] = "TwoFactorAuthentication";
+ ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
}
@ViewData["Title"]
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml
new file mode 100644
index 0000000000..a4f5ca4814
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml
@@ -0,0 +1,12 @@
+@page
+@model DownloadPersonalDataModel
+@{
+ ViewData["Title"] = "Download Your Data";
+ ViewData["ActivePage"] = ManageNavPages.DownloadPersonalData;
+}
+
+@ViewData["Title"]
+
+@section Scripts {
+
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs b/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs
new file mode 100644
index 0000000000..14cf888d8c
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/DownloadPersonalData.cshtml.cs
@@ -0,0 +1,51 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+using Newtonsoft.Json;
+
+namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
+{
+ public class DownloadPersonalDataModel : PageModel
+ {
+ private readonly UserManager _userManager;
+ private readonly ILogger _logger;
+
+ public DownloadPersonalDataModel(
+ UserManager userManager,
+ ILogger logger)
+ {
+ _userManager = userManager;
+ _logger = logger;
+ }
+
+ public async Task OnPostAsync()
+ {
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ _logger.LogInformation("User with ID '{UserId}' asked for their personal data.", _userManager.GetUserId(User));
+
+ // Only include personal data for download
+ var personalData = new Dictionary();
+ personalData.Add("UserId", await _userManager.GetUserIdAsync(user));
+ personalData.Add("UserName", await _userManager.GetUserNameAsync(user));
+ personalData.Add("Email", await _userManager.GetEmailAsync(user));
+ personalData.Add("EmailConfirmed", (await _userManager.IsEmailConfirmedAsync(user)).ToString());
+ personalData.Add("PhoneNumber", await _userManager.GetPhoneNumberAsync(user));
+ personalData.Add("PhoneNumberConfirmed", (await _userManager.IsEmailConfirmedAsync(user)).ToString());
+
+ Response.Headers.Add("Content-Disposition", "attachment; filename=PersonalData.json");
+ return new FileContentResult(Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(personalData)), "text/json");
+ }
+ }
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml
index 9d1113d779..047c6388cb 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/EnableAuthenticator.cshtml
@@ -2,7 +2,7 @@
@model EnableAuthenticatorModel
@{
ViewData["Title"] = "Configure authenticator app";
- ViewData["ActivePage"] = "TwoFactorAuthentication";
+ ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
}
@ViewData["Title"]
@@ -49,5 +49,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml
index 5966480d05..d6a39d1937 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/GenerateRecoveryCodes.cshtml
@@ -2,7 +2,7 @@
@model GenerateRecoveryCodesModel
@{
ViewData["Title"] = "Generate two-factor authentication (2FA) recovery codes";
- ViewData["ActivePage"] = "TwoFactorAuthentication";
+ ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
}
@ViewData["Title"]
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/Index.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/Index.cshtml
index 78a0383cd3..4fc98a0c14 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/Index.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/Index.cshtml
@@ -41,5 +41,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs b/src/UI/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
index 42e859a203..49a721ac60 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/ManageNavPages.cs
@@ -12,16 +12,28 @@ namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
public static string ChangePassword => "ChangePassword";
+ public static string DownloadPersonalData => "DownloadPersonalData";
+
+ public static string DeletePersonalData => "DeletePersonalData";
+
public static string ExternalLogins => "ExternalLogins";
+ public static string PersonalData => "PersonalData";
+
public static string TwoFactorAuthentication => "TwoFactorAuthentication";
public static string IndexNavClass(ViewContext viewContext) => PageNavClass(viewContext, Index);
public static string ChangePasswordNavClass(ViewContext viewContext) => PageNavClass(viewContext, ChangePassword);
+ public static string DownloadPersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DownloadPersonalData);
+
+ public static string DeletePersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, DeletePersonalData);
+
public static string ExternalLoginsNavClass(ViewContext viewContext) => PageNavClass(viewContext, ExternalLogins);
+ public static string PersonalDataNavClass(ViewContext viewContext) => PageNavClass(viewContext, PersonalData);
+
public static string TwoFactorAuthenticationNavClass(ViewContext viewContext) => PageNavClass(viewContext, TwoFactorAuthentication);
public static string PageNavClass(ViewContext viewContext, string page)
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml
new file mode 100644
index 0000000000..770f044cf0
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml
@@ -0,0 +1,27 @@
+@page
+@model PersonalDataModel
+@{
+ ViewData["Title"] = "Personal Data";
+ ViewData["ActivePage"] = ManageNavPages.PersonalData;
+}
+
+@ViewData["Title"]
+
+
+
+
Your account contains personal data that you have given us. This page allows you to download or delete that data.
+
+ Deleting this data will permanently remove your account, and this cannot be recovered.
+
+
+
+ Delete
+
+
+
+
+@section Scripts {
+
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs b/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs
new file mode 100644
index 0000000000..432371ff6d
--- /dev/null
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/PersonalData.cshtml.cs
@@ -0,0 +1,35 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.RazorPages;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.Identity.UI.Pages.Account.Manage
+{
+ public class PersonalDataModel : PageModel
+ {
+ private readonly UserManager _userManager;
+ private readonly ILogger _logger;
+
+ public PersonalDataModel(
+ UserManager userManager,
+ ILogger logger)
+ {
+ _userManager = userManager;
+ _logger = logger;
+ }
+
+ public async Task OnGet()
+ {
+ var user = await _userManager.GetUserAsync(User);
+ if (user == null)
+ {
+ return NotFound($"Unable to load user with ID '{_userManager.GetUserId(User)}'.");
+ }
+
+ return Page();
+ }
+ }
+}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml
index a9534ae257..0bb89805b7 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/ResetAuthenticator.cshtml
@@ -2,7 +2,7 @@
@model ResetAuthenticatorModel
@{
ViewData["Title"] = "Reset authenticator key";
- ViewData["ActivePage"] = "TwoFactorAuthentication";
+ ViewData["ActivePage"] = ManageNavPages.TwoFactorAuthentication;
}
@ViewData["Title"]
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml
index 3f4544caf4..feeb3c30e4 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/SetPassword.cshtml
@@ -2,7 +2,7 @@
@model SetPasswordModel
@{
ViewData["Title"] = "Set password";
- ViewData["ActivePage"] = "ChangePassword";
+ ViewData["ActivePage"] = ManageNavPages.ChangePassword;
}
Set your password
@@ -31,5 +31,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml
index fabe1999e6..19ba8daacb 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/TwoFactorAuthentication.cshtml
@@ -45,5 +45,5 @@ else
}
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml b/src/UI/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
index 56db638f33..5ba75b6646 100644
--- a/src/UI/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Manage/_ManageNav.cshtml
@@ -11,5 +11,6 @@
External logins
}
Two-factor authentication
+ Personal data
diff --git a/src/UI/Areas/Identity/Pages/Account/Register.cshtml b/src/UI/Areas/Identity/Pages/Account/Register.cshtml
index 64f2151518..d40f55c35c 100644
--- a/src/UI/Areas/Identity/Pages/Account/Register.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/Register.cshtml
@@ -33,5 +33,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}
diff --git a/src/UI/Areas/Identity/Pages/Account/ResetPassword.cshtml b/src/UI/Areas/Identity/Pages/Account/ResetPassword.cshtml
index 85a81b1ef5..5ccb61edcf 100644
--- a/src/UI/Areas/Identity/Pages/Account/ResetPassword.cshtml
+++ b/src/UI/Areas/Identity/Pages/Account/ResetPassword.cshtml
@@ -33,5 +33,5 @@
@section Scripts {
- @await Html.PartialAsync("_ValidationScriptsPartial")
+
}