Add deletion options (#9)
This commit is contained in:
parent
7c6804c2af
commit
7784ee66ea
|
@ -3,6 +3,6 @@
|
|||
@inject NavigationManager nav
|
||||
@inject AppState state
|
||||
|
||||
<PageTitle Title="Logging in..." />
|
||||
<PageTitle Title="Logging on..." />
|
||||
|
||||
<p>@Message</p>
|
||||
|
|
|
@ -115,4 +115,8 @@
|
|||
<br><a href="/profile/view/@state.User!.Id"><span class="oi oi-file"></span> View Your User Profile</a>
|
||||
</p>
|
||||
}
|
||||
<p>
|
||||
<br>If you want to delete your profile, or your entire account,
|
||||
<a href="/so-long/options">see your deletion options here</a>.
|
||||
</p>
|
||||
</Loading>
|
||||
|
|
39
src/JobsJobsJobs/Client/Pages/SoLong/Options.razor
Normal file
39
src/JobsJobsJobs/Client/Pages/SoLong/Options.razor
Normal file
|
@ -0,0 +1,39 @@
|
|||
@page "/so-long/options"
|
||||
@inject HttpClient http
|
||||
@inject AppState state
|
||||
@inject NavigationManager nav
|
||||
@inject IToastService toast
|
||||
|
||||
<PageTitle Title="Account Deletion Options" />
|
||||
|
||||
<h3>Account Deletion Options</h3>
|
||||
|
||||
<h4>Option 1 – Delete Your Profile</h4>
|
||||
<p>
|
||||
Utilizing this option will remove your current employment profile and skills. This will preserve any success stories
|
||||
you may have written, and preserves this application’s knowledge of you. This is what you want to use if you
|
||||
want to clear out your profile and start again (and remove the current one from others’ view).
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<button class="btn btn-danger" @onclick=@DeleteProfile>Delete Your Profile</button>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
|
||||
<h4>Option 2 – Delete Your Account</h4>
|
||||
<p>
|
||||
This option will make it like you never visited this site. It will delete your profile, skills, success stories, and
|
||||
account. This is what you want to use if you want to disappear from this application. Clicking the button below
|
||||
<strong>will not</strong> affect your No Agenda Social account in any way; its effects are limited to Jobs, Jobs,
|
||||
Jobs.
|
||||
</p>
|
||||
<p>
|
||||
<em>
|
||||
(This will not revoke this application’s permissions on No Agenda Social; you will have to remove this
|
||||
yourself. The confirmation message has a link where you can do this; once the page loads, find the
|
||||
<strong>Jobs, Jobs, Jobs</strong> entry, and click the <strong>× Revoke</strong> link for that entry.)
|
||||
</em>
|
||||
</p>
|
||||
<p class="text-center">
|
||||
<button class="btn btn-danger" @onclick=@DeleteAccount>Delete Your Entire Account</button>
|
||||
</p>
|
54
src/JobsJobsJobs/Client/Pages/SoLong/Options.razor.cs
Normal file
54
src/JobsJobsJobs/Client/Pages/SoLong/Options.razor.cs
Normal file
|
@ -0,0 +1,54 @@
|
|||
using Microsoft.AspNetCore.Components;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Client.Pages.SoLong
|
||||
{
|
||||
public partial class Options : ComponentBase
|
||||
{
|
||||
/// <summary>
|
||||
/// Extract an error phrase from a response similar to <code>404 - Not Found</code>
|
||||
/// </summary>
|
||||
/// <param name="response">The HTTP response</param>
|
||||
/// <returns>The formatted error code</returns>
|
||||
private static string ErrorPhrase(HttpResponseMessage response) =>
|
||||
$"{response.StatusCode}{(string.IsNullOrEmpty(response.ReasonPhrase) ? "" : $" - {response.ReasonPhrase }")}";
|
||||
|
||||
/// <summary>
|
||||
/// Delete the profile only; redirect to home page on success
|
||||
/// </summary>
|
||||
private async Task DeleteProfile()
|
||||
{
|
||||
ServerApi.SetJwt(http, state);
|
||||
var result = await http.DeleteAsync("/api/profile/");
|
||||
if (result.IsSuccessStatusCode)
|
||||
{
|
||||
toast.ShowSuccess("Profile Deleted Successfully");
|
||||
nav.NavigateTo("/citizen/dashboard");
|
||||
}
|
||||
else
|
||||
{
|
||||
toast.ShowError(ErrorPhrase(result));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete everything pertaining to the user's account
|
||||
/// </summary>
|
||||
private async Task DeleteAccount()
|
||||
{
|
||||
ServerApi.SetJwt(http, state);
|
||||
var result = await http.DeleteAsync("/api/citizen/");
|
||||
if (result.IsSuccessStatusCode)
|
||||
{
|
||||
state.Jwt = "";
|
||||
state.User = null;
|
||||
nav.NavigateTo("/so-long/success");
|
||||
}
|
||||
else
|
||||
{
|
||||
toast.ShowError(ErrorPhrase(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
src/JobsJobsJobs/Client/Pages/SoLong/Success.razor
Normal file
15
src/JobsJobsJobs/Client/Pages/SoLong/Success.razor
Normal file
|
@ -0,0 +1,15 @@
|
|||
@page "/so-long/success"
|
||||
|
||||
<PageTitle Title="Account Deletion Success" />
|
||||
|
||||
<h3>Account Deletion Success</h3>
|
||||
|
||||
<p>
|
||||
Your account has been successfully deleted. To revoke the permissions you have previously granted to this
|
||||
application, find it in <a href="https://noagendasocial.com/oauth/authorized_applications">this list</a> and click
|
||||
<strong>× Revoke</strong>. Otherwise, clicking “Log On” will create a new, empty account without
|
||||
prompting you further.
|
||||
</p>
|
||||
<p>
|
||||
Thank you for participating, and thank you for your courage. #GitmoNation
|
||||
</p>
|
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Authorization;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using NodaTime;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
||||
|
@ -44,6 +45,11 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
|||
_db = db;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The current citizen ID
|
||||
/// </summary>
|
||||
private CitizenId CurrentCitizenId => CitizenId.Parse(User.FindFirst(ClaimTypes.NameIdentifier)!.Value);
|
||||
|
||||
[HttpGet("log-on/{authCode}")]
|
||||
public async Task<IActionResult> LogOn([FromRoute] string authCode)
|
||||
{
|
||||
|
@ -87,5 +93,15 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
|||
var citizen = await _db.FindCitizenById(CitizenId.Parse(id));
|
||||
return citizen == null ? NotFound() : Ok(citizen);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
[HttpDelete("")]
|
||||
public async Task<IActionResult> Remove()
|
||||
{
|
||||
await _db.DeleteCitizen(CurrentCitizenId);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,5 +130,13 @@ namespace JobsJobsJobs.Server.Areas.Api.Controllers
|
|||
return Ok();
|
||||
}
|
||||
|
||||
[HttpDelete("")]
|
||||
public async Task<IActionResult> Remove()
|
||||
{
|
||||
await _db.DeleteProfileByCitizen(CurrentCitizenId);
|
||||
await _db.SaveChangesAsync();
|
||||
|
||||
return Ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ namespace JobsJobsJobs.Server.Data
|
|||
/// </summary>
|
||||
/// <param name="citizen">The citizen to be added</param>
|
||||
public static async Task AddCitizen(this JobsDbContext db, Citizen citizen) =>
|
||||
await db.Citizens.AddAsync(citizen);
|
||||
await db.Citizens.AddAsync(citizen).ConfigureAwait(false);
|
||||
|
||||
/// <summary>
|
||||
/// Update a citizen after they have logged on (update last seen, sync display name)
|
||||
|
@ -42,5 +42,20 @@ namespace JobsJobsJobs.Server.Data
|
|||
/// <param name="citizen">The updated citizen</param>
|
||||
public static void UpdateCitizen(this JobsDbContext db, Citizen citizen) =>
|
||||
db.Entry(citizen).State = EntityState.Modified;
|
||||
|
||||
/// <summary>
|
||||
/// Delete a citizen
|
||||
/// </summary>
|
||||
/// <param name="citizenId">The ID of the citizen to be deleted</param>
|
||||
/// <returns></returns>
|
||||
public static async Task DeleteCitizen(this JobsDbContext db, CitizenId citizenId)
|
||||
{
|
||||
var id = citizenId.ToString();
|
||||
await db.DeleteProfileByCitizen(citizenId).ConfigureAwait(false);
|
||||
await db.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM jjj.success WHERE citizen_id = {id}")
|
||||
.ConfigureAwait(false);
|
||||
await db.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM jjj.citizen WHERE id = {id}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -160,5 +160,18 @@ namespace JobsJobsJobs.Server.Data
|
|||
x.Profile.SeekingEmployment, x.Profile.RemoteWork, x.Profile.FullTime, x.Profile.LastUpdatedOn))
|
||||
.ToListAsync().ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Delete skills and profile for the given citizen
|
||||
/// </summary>
|
||||
/// <param name="citizenId">The ID of the citizen whose profile should be deleted</param>
|
||||
public static async Task DeleteProfileByCitizen(this JobsDbContext db, CitizenId citizenId)
|
||||
{
|
||||
var id = citizenId.ToString();
|
||||
await db.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM jjj.skill WHERE citizen_id = {id}")
|
||||
.ConfigureAwait(false);
|
||||
await db.Database.ExecuteSqlInterpolatedAsync($"DELETE FROM jjj.profile WHERE citizen_id = {id}")
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user