(core) Delete my account button

Summary:
Adding new "Delete my account" button to the profile page that allows users to remove completely
their accounts as long as they don't own any team site.

Test Plan: Added

Reviewers: georgegevoian, paulfitz

Reviewed By: georgegevoian, paulfitz

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D4037
This commit is contained in:
Jarosław Sadziński
2023-09-26 10:09:06 +02:00
parent e033889b6a
commit cce185956c
19 changed files with 205 additions and 34 deletions

View File

@@ -29,6 +29,7 @@ export const ThemeColors = t.iface([], {
"text-light": "string",
"text-dark": "string",
"text-error": "string",
"text-error-hover": "string",
"text-danger": "string",
"text-disabled": "string",
"page-bg": "string",

View File

@@ -27,6 +27,7 @@ export interface ThemeColors {
'text-light': string;
'text-dark': string;
'text-error': string;
'text-error-hover': string;
'text-danger': string;
'text-disabled': string;

View File

@@ -405,6 +405,20 @@ export interface UserAPI {
getBaseUrl(): string; // Get the prefix for all the endpoints this object wraps.
forRemoved(): UserAPI; // Get a version of the API that works on removed resources.
getWidgets(): Promise<ICustomWidget[]>;
/**
* Deletes account and personal org with all documents. Note: deleteUser doesn't clear documents, and this method
* is specific to Grist installation, and might not be supported. Pass current user's id so that we can verify
* that the user is deleting their own account. This is just to prevent accidental deletion from multiple tabs.
*
* @returns true if the account was deleted, false if there was a mismatch with the current user's id, and the
* account was probably already deleted.
*/
closeAccount(userId: number): Promise<boolean>;
/**
* Deletes current non personal org with all documents. Note: deleteOrg doesn't clear documents, and this method
* is specific to Grist installation, and might not be supported.
*/
closeOrg(): Promise<void>;
}
/**
@@ -813,6 +827,14 @@ export class UserAPIImpl extends BaseAPI implements UserAPI {
body: JSON.stringify({name})});
}
public async closeAccount(userId: number): Promise<boolean> {
return await this.requestJson(`${this._url}/api/doom/account?userid=` + userId, {method: 'DELETE'});
}
public async closeOrg() {
await this.request(`${this._url}/api/doom/org`, {method: 'DELETE'});
}
public getBaseUrl(): string { return this._url; }
// Recomputes the URL on every call to pick up changes in the URL when switching orgs.
@@ -1047,7 +1069,7 @@ export class DocAPIImpl extends BaseAPI implements DocAPI {
public async uploadAttachment(value: string | Blob, filename?: string): Promise<number> {
const formData = this.newFormData();
formData.append('upload', value, filename);
formData.append('upload', value as Blob, filename);
const response = await this.requestAxios(`${this._url}/attachments`, {
method: 'POST',
data: formData,

View File

@@ -694,6 +694,9 @@ export interface GristLoadConfig {
// The org containing public templates and tutorials.
templateOrg?: string|null;
// Whether to show the "Delete Account" button in the account page.
canCloseAccount?: boolean;
}
export const Features = StringUnion(

View File

@@ -5,7 +5,8 @@ export const GristDark: ThemeColors = {
'text': '#EFEFEF',
'text-light': '#A4A4B1',
'text-dark': '#FFFFFF',
'text-error': '#FF6666',
'text-error': '#E63946',
'text-error-hover': '#FF5C5C',
'text-danger': '#FFA500',
'text-disabled': '#A4A4B1',

View File

@@ -6,6 +6,7 @@ export const GristLight: ThemeColors = {
'text-light': '#929299',
'text-dark': 'black',
'text-error': '#D0021B',
'text-error-hover': '#A10000',
'text-danger': '#FFA500',
'text-disabled': '#929299',