feat: impl user account deletion

This commit is contained in:
thecodrr
2020-12-10 15:40:55 +05:00
parent 686e20e691
commit bfc5bb01ac
6 changed files with 92 additions and 21 deletions

View File

@@ -19,6 +19,7 @@ import { EV } from "notes-core/common";
import useTablet from "./utils/use-tablet";
import { showBuyDialog } from "./components/dialogs/buy-dialog";
import Banner from "./components/banner";
import { showAccountDeletedNotice } from "./components/dialogs/confirm";
function App() {
const [show, setShow] = useState(true);
@@ -58,6 +59,9 @@ function App() {
return { type, result: false };
}
});
EV.subscribe("user:deleted", async () => {
await showAccountDeletedNotice();
});
}, []);
useEffect(() => {

View File

@@ -1,9 +1,12 @@
import React from "react";
import React, { useState } from "react";
import { Box, Text } from "rebass";
import Dialog, { showDialog } from "./dialog";
import * as Icon from "../icons";
import Field from "../field";
function Confirm(props) {
const [isButtonEnabled, setIsButtonEnabled] = useState(!props.confirmWith);
return (
<Dialog
isOpen={true}
@@ -14,6 +17,7 @@ function Confirm(props) {
positiveButton={{
text: props.yesText,
onClick: props.onYes,
disabled: !isButtonEnabled,
}}
negativeButton={{ text: props.noText, onClick: props.onNo }}
>
@@ -21,12 +25,36 @@ function Confirm(props) {
<Text as="span" variant="body">
{props.message}
</Text>
{props.confirmWith && (
<Field
autoFocus
sx={{ mt: 2 }}
label={
<>
Please type
<Text as="span" color="error" mx={1}>
{`${props.confirmWith}`}
</Text>
to confirm
</>
}
id="confirm"
name="confirm"
onChange={(e) => {
if (e.target.value === props.confirmWith)
setIsButtonEnabled(true);
}}
/>
)}
</Box>
</Dialog>
);
}
export function confirm(icon, { title, subtitle, message, yesText, noText }) {
export function confirm(
icon,
{ title, subtitle, message, yesText, noText, confirmWith }
) {
return showDialog((perform) => (
<Confirm
title={title}
@@ -34,6 +62,7 @@ export function confirm(icon, { title, subtitle, message, yesText, noText }) {
message={message}
yesText={yesText}
noText={noText}
confirmWith={confirmWith}
icon={icon}
onNo={() => perform(false)}
onYes={() => perform(true)}
@@ -96,3 +125,28 @@ export function showLogoutConfirmation() {
noText: "No",
});
}
export function showAccountDeleteConfirmation(username) {
return confirm(Icon.Logout, {
title: `Delete Account?`,
message: (
<>
This action is <b>IRREVERSIBLE</b>. All your data (notes, notebooks,
tags, pins, favorites) will be <b>permanently deleted</b> with no way of
recovery.
</>
),
confirmWith: username,
yesText: `I understand, delete my account`,
noText: "Cancel",
});
}
export function showAccountDeletedNotice() {
return confirm(Icon.Logout, {
title: `Your account was deleted.`,
message:
"You deleted your account from another device. You have been logged out.",
yesText: `Okay`,
});
}

View File

@@ -22,6 +22,7 @@ class AppStore extends BaseStore {
menuPins = [];
refresh = async () => {
await resetReminders();
noteStore.refresh();
notebookStore.refresh();
trashStore.refresh();
@@ -29,7 +30,6 @@ class AppStore extends BaseStore {
editorStore.openLastSession();
this.refreshColors();
this.refreshMenuPins();
await resetReminders();
};
refreshColors = () => {

View File

@@ -33,6 +33,13 @@ class UserStore extends BaseStore {
});
EV.subscribe("db:sync", () => this.sync(false));
EV.subscribe("user:loggedOut", async () => {
this.set((state) => {
state.user = {};
state.isLoggedIn = false;
});
config.clear();
await appStore.refresh();
if (window.PasswordCredential) {
await navigator.credentials.preventSilentAccess();
if (navigator.credentials.requireUserMediation)
@@ -95,17 +102,6 @@ class UserStore extends BaseStore {
this.set((state) => (state.isSyncing = false));
});
};
logout = () => {
return db.user.logout().then(async () => {
this.set((state) => {
state.user = {};
state.isLoggedIn = false;
});
config.clear();
await appStore.refresh();
});
};
}
/**

View File

@@ -7,7 +7,10 @@ import { useStore as useSettingStore } from "../stores/setting-store";
import AccentItem from "../components/accent-item";
import accents from "../theme/accents";
import { showLogInDialog } from "../components/dialogs/logindialog";
import { showLogoutConfirmation } from "../components/dialogs/confirm";
import {
showAccountDeleteConfirmation,
showLogoutConfirmation,
} from "../components/dialogs/confirm";
import useSystemTheme from "../utils/use-system-theme";
import {
createBackup,
@@ -67,7 +70,6 @@ function Settings(props) {
);
const user = useUserStore((store) => store.user);
const isLoggedIn = useUserStore((store) => store.isLoggedIn);
const logout = useUserStore((store) => store.logout);
const [backupReminderOffset, setBackupReminderOffset] = usePersistentState(
"backupReminderOffset",
0
@@ -191,7 +193,7 @@ function Settings(props) {
variant="list"
onClick={async () => {
if (await showLogoutConfirmation()) {
await logout();
await db.user.logout();
}
}}
>
@@ -200,6 +202,21 @@ function Settings(props) {
tip="Log out of your account and clear all data."
/>
</Button>
<Button
sx={{ borderColor: "error" }}
variant="list"
onClick={async () => {
if (await showAccountDeleteConfirmation(user.username)) {
await db.user.delete();
}
}}
>
<TextWithTip
color="error"
text="Delete account"
tip="Permanently delete account and logout from all devices."
/>
</Button>
</>
)}
<Text
@@ -376,11 +393,11 @@ function Settings(props) {
export default Settings;
function TextWithTip({ text, tip, sx }) {
function TextWithTip({ text, tip, sx, color }) {
return (
<Text color="text" fontSize="body" sx={sx}>
<Text color={color || "text"} fontSize="body" sx={sx}>
{text}
<Text color="fontTertiary" fontSize="subBody">
<Text color={color || "fontTertiary"} fontSize="subBody">
{tip}
</Text>
</Text>

View File

@@ -8959,7 +8959,7 @@ normalize-url@^3.0.0, normalize-url@^3.0.1:
"notes-core@git+ssh://git@github.com:streetwriters/notesnook-core.git":
version "4.3.1"
resolved "git+ssh://git@github.com:streetwriters/notesnook-core.git#81188213c112d4ba421854bb4879f0527b4a814d"
resolved "git+ssh://git@github.com:streetwriters/notesnook-core.git#1d1e86e59a3f149c97cf4dafb39ffe555981d528"
dependencies:
fast-sort "^2.0.1"
fuzzysearch "^1.0.3"