From 6d4ad293796a031d8e67028e478830bdd9f81bd1 Mon Sep 17 00:00:00 2001
From: bytedream <bytedream@protonmail.com>
Date: Mon, 28 Aug 2023 18:46:41 +0200
Subject: [PATCH] add more responsiveness when updating self admin

---
 src/lib/components/Input/Badges.svelte | 21 +++++++++-------
 src/lib/server/database.ts             |  2 +-
 src/routes/admin/admin/+page.server.ts | 11 +++++++--
 src/routes/admin/admin/+page.svelte    | 33 ++++++++++++++++++--------
 src/routes/admin/admin/+server.ts      | 13 +++++-----
 5 files changed, 51 insertions(+), 29 deletions(-)

diff --git a/src/lib/components/Input/Badges.svelte b/src/lib/components/Input/Badges.svelte
index fd5e789..1163c1c 100644
--- a/src/lib/components/Input/Badges.svelte
+++ b/src/lib/components/Input/Badges.svelte
@@ -4,7 +4,7 @@
 
 	export let id: string | null = null;
 	export let name: string | null = null;
-	export let disabled = true;
+	export let disabled = false;
 	export let available: string[] | { [key: string]: T } = {};
 	export let value: T[] = [];
 </script>
@@ -37,14 +37,17 @@
 	<div class="flex flow flex-wrap gap-2">
 		{#each value as badge, i}
 			{#if Object.values(available).indexOf(badge) !== -1}
-				<div class="badge badge-outline gap-1">
-					<button
-						{disabled}
-						on:click={() => {
-							value.splice(i, 1);
-							value = value;
-						}}>✕</button
-					>
+				<div class="badge badge-outline gap-1" class:brightness-[60%]={disabled}>
+					<span class:cursor-not-allowed={disabled}>
+						<button
+							{disabled}
+							class:pointer-events-none={disabled}
+							on:click={() => {
+								value.splice(i, 1);
+								value = value;
+							}}>✕</button
+						>
+					</span>
 					{Object.keys(available)[Object.values(available).indexOf(badge)]}
 				</div>
 			{/if}
diff --git a/src/lib/server/database.ts b/src/lib/server/database.ts
index dc0b1ad..1108d53 100644
--- a/src/lib/server/database.ts
+++ b/src/lib/server/database.ts
@@ -55,7 +55,7 @@ export class Admin extends Model {
 	@BeforeCreate
 	@BeforeUpdate
 	static hashPassword(instance: Admin) {
-		if (instance.password != null) {
+		if ((instance.changed() || []).indexOf('password') != -1) {
 			instance.password = bcrypt.hashSync(instance.password, 10);
 		}
 	}
diff --git a/src/routes/admin/admin/+page.server.ts b/src/routes/admin/admin/+page.server.ts
index 112bf62..0c359bb 100644
--- a/src/routes/admin/admin/+page.server.ts
+++ b/src/routes/admin/admin/+page.server.ts
@@ -9,8 +9,15 @@ export const load: PageServerLoad = async ({ cookies }) => {
 		admins = await Admin.findAll({ attributes: { exclude: ['password'] } });
 	}
 
+	const session = getSession(cookies);
 	return {
-		admins: JSON.parse(JSON.stringify(admins)),
-		permissions: getSession(cookies.get('session') || '')!.permissions.value
+		admins: admins.map((v) => {
+			const vv = JSON.parse(JSON.stringify(v));
+			vv.permissions = v.permissions.asArray();
+
+			return vv;
+		}) as (Admin & { [key: string]: any })[],
+		id: session?.userId,
+		permissions: session?.permissions.value || 0
 	};
 };
diff --git a/src/routes/admin/admin/+page.svelte b/src/routes/admin/admin/+page.svelte
index 7d6c24c..afd0b13 100644
--- a/src/routes/admin/admin/+page.svelte
+++ b/src/routes/admin/admin/+page.svelte
@@ -7,6 +7,7 @@
 	import { env } from '$env/dynamic/public';
 	import ErrorToast from '$lib/components/Toast/ErrorToast.svelte';
 	import { buttonTriggeredRequest } from '$lib/components/utils';
+	import { goto } from '$app/navigation';
 
 	let allPermissionBadges = {
 		'Admin Read': Permissions.AdminRead,
@@ -40,7 +41,7 @@
 		id: number,
 		username: string | null,
 		password: string | null,
-		permissions: Permissions | null
+		updatePermissions: Permissions | null
 	) {
 		const response = await fetch(`${env.PUBLIC_BASE_PATH}/admin/admin`, {
 			method: 'PATCH',
@@ -48,10 +49,14 @@
 				id: id,
 				username: username,
 				password: password,
-				permissions: permissions?.value
+				permissions: updatePermissions?.value
 			})
 		});
-		if (!response.ok) {
+		if (response.ok) {
+			if (id === data.id && updatePermissions) {
+				permissions = updatePermissions;
+			}
+		} else {
 			throw new Error();
 		}
 	}
@@ -64,11 +69,15 @@
 			})
 		});
 		if (response.ok) {
-			data.admins.splice(
-				data.admins.find((v: typeof data.admins) => v.id == id),
-				1
-			);
-			data.admins = data.admins;
+			if (id === data.id) {
+				await goto(`${env.PUBLIC_BASE_PATH}/`);
+			} else {
+				data.admins.splice(
+					data.admins.findIndex((v) => v.id == id),
+					1
+				);
+				data.admins = data.admins;
+			}
 		} else {
 			throw new Error();
 		}
@@ -104,20 +113,21 @@
 				<td
 					><Input
 						type="text"
-						value={admin.username}
+						bind:value={admin.username}
 						disabled={!permissions.adminWrite() || !admin.edit}
 					/></td
 				>
 				<td
 					><Input
 						type="password"
+						bind:value={admin.password}
 						placeholder="Neues Passwort..."
 						disabled={!permissions.adminWrite() || !admin.edit}
 					/></td
 				>
 				<td
 					><Badges
-						value={new Permissions(admin.permissions).asArray()}
+						bind:value={admin.permissions}
 						available={allPermissionBadges}
 						disabled={!permissions.adminWrite() || !admin.edit}
 					/></td
@@ -139,6 +149,7 @@
 												new Permissions(admin.permissions)
 											)
 										);
+										admin.password = '';
 										admin.edit = false;
 									}}
 								>
@@ -151,6 +162,7 @@
 									disabled={!permissions.adminWrite()}
 									on:click={() => {
 										admin.username = admin.before.username;
+										admin.password = admin.before.password;
 										admin.permissions = admin.before.permissions;
 										admin.edit = false;
 									}}
@@ -167,6 +179,7 @@
 										admin.edit = true;
 										admin.before = {
 											username: admin.username,
+											password: admin.password,
 											permissions: admin.permissions
 										};
 									}}
diff --git a/src/routes/admin/admin/+server.ts b/src/routes/admin/admin/+server.ts
index b73caca..7f0cb19 100644
--- a/src/routes/admin/admin/+server.ts
+++ b/src/routes/admin/admin/+server.ts
@@ -55,18 +55,17 @@ export const PATCH = (async ({ request, cookies }) => {
 		});
 	}
 
-	const updatePayload: { [key: string]: any } = {};
-	if (data['username']) updatePayload.username = data['username'];
-	if (data['password']) updatePayload.password = data['password'];
-	if (data['permissions']) updatePayload.permissions = new Permissions(data['permissions']);
-
-	let user = await Admin.findOne({ where: { id: id } });
+	const user = await Admin.findOne({ where: { id: id } });
 	if (!user) {
 		return new Response(null, {
 			status: 400
 		});
 	}
-	user = await user.update(updatePayload);
+
+	if (data['username']) user.username = data['username'];
+	if (data['password']) user.password = data['password'];
+	if (data['permissions']) user.permissions = new Permissions(data['permissions']);
+	await user.save();
 
 	updateAllUserSessions(user.id, { permissions: user.permissions });