From a2e299a75923596f3f0c836a21b8d2019d10068d Mon Sep 17 00:00:00 2001 From: WardPearce Date: Sat, 14 Feb 2026 22:09:23 +1300 Subject: [PATCH] Added account deletion --- .../settings/InternalAccount.svelte | 38 ++++++++++ .../lib/components/settings/Settings.svelte | 73 +++++++++++++------ materialious/src/lib/i18n/locales/en.json | 3 + .../src/routes/api/user/delete/+server.ts | 8 ++ 4 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 materialious/src/lib/components/settings/InternalAccount.svelte create mode 100644 materialious/src/routes/api/user/delete/+server.ts diff --git a/materialious/src/lib/components/settings/InternalAccount.svelte b/materialious/src/lib/components/settings/InternalAccount.svelte new file mode 100644 index 00000000..08596043 --- /dev/null +++ b/materialious/src/lib/components/settings/InternalAccount.svelte @@ -0,0 +1,38 @@ + + +
Passsword reset
+ +
Delete account
+
+ diff --git a/materialious/src/lib/components/settings/Settings.svelte b/materialious/src/lib/components/settings/Settings.svelte index 37c4d82d..facadeb2 100644 --- a/materialious/src/lib/components/settings/Settings.svelte +++ b/materialious/src/lib/components/settings/Settings.svelte @@ -7,15 +7,17 @@ import Player from './Player.svelte'; import Ryd from './RYD.svelte'; import SponsorBlock from './SponsorBlock.svelte'; - import { isAndroidTvStore } from '$lib/store'; + import { isAndroidTvStore, rawMasterKeyStore } from '$lib/store'; import About from './About.svelte'; import Engine from './Engine.svelte'; import { isUnrestrictedPlatform } from '$lib/misc'; + import { isOwnBackend } from '$lib/shared'; + import InternalAccount from './InternalAccount.svelte'; let activeTab = $state('interface'); const isActive = (id: string) => activeTab === id; - const tabs: { id: string; label: string; icon: string; component: Component }[] = [ + let tabs: { id: string; label: string; icon: string; component: Component }[] = $state([ { id: 'interface', label: $_('layout.interface'), icon: 'grid_view', component: Interface }, { id: 'player', label: $_('layout.player.title'), icon: 'smart_display', component: Player }, { id: 'ryd', label: 'Return YT Dislike', icon: 'thumb_down', component: Ryd }, @@ -33,7 +35,11 @@ icon: 'info', component: About } - ]; + ]); + + let tabIds: string[] = $state([]); + + setTabIds(); if (isUnrestrictedPlatform()) { tabs.splice(1, 0, { @@ -44,7 +50,28 @@ }); } - const tabIds = tabs.map((tab) => tab.id); + function setTabIds() { + tabs.forEach((tab) => { + tabIds.push(tab.id); + }); + } + + rawMasterKeyStore.subscribe((value) => { + if (isOwnBackend()?.internalAuth && value) { + tabs.splice(1, 0, { + id: 'account', + label: $_('layout.materialiousAccount'), + icon: 'person', + component: InternalAccount + }); + } else { + tabs = tabs.filter((tab) => { + return tab.id !== 'account'; + }); + } + + setTabIds(); + }); let dialogType = $state(''); @@ -102,24 +129,26 @@
diff --git a/materialious/src/lib/i18n/locales/en.json b/materialious/src/lib/i18n/locales/en.json index b8080665..2c9bb3f0 100644 --- a/materialious/src/lib/i18n/locales/en.json +++ b/materialious/src/lib/i18n/locales/en.json @@ -170,6 +170,7 @@ "engine": "Backend engine", "syncParty": "Sync party", "about": "About", + "materialiousAccount": "Account", "syncPartyWarning": "Please note your IP will be visible to users you invite.", "startSyncParty": "Start sync party", "endSyncParty": "End sync party", @@ -185,6 +186,8 @@ "displayThumbnailAvatars": "Thumbnail avatars (Slow)", "searchHistory": "Search history", "companionUrl": "Companion URL", + "deleteAccount": "Delete account", + "clickXmoreTimesToDelete": "Click {{clicksTillDelete}} more time(s) to delete", "theme": { "theme": "Theme", "darkMode": "Dark mode", diff --git a/materialious/src/routes/api/user/delete/+server.ts b/materialious/src/routes/api/user/delete/+server.ts new file mode 100644 index 00000000..6ef59e22 --- /dev/null +++ b/materialious/src/routes/api/user/delete/+server.ts @@ -0,0 +1,8 @@ +import { getUser } from '$lib/server/user'; + +export async function DELETE({ locals }) { + const user = await getUser(locals.userId); + await user.delete(); + + return new Response(); +}