add admin mode to delete message

This commit is contained in:
2023-12-12 16:41:27 +01:00
parent 4418e6d865
commit c2f938f3a2
5 changed files with 61 additions and 5 deletions

5
src/auth.d.ts vendored
View File

@@ -1,9 +1,10 @@
declare module '#auth-utils' { declare module '#auth-utils' {
interface UserSession { interface UserSession {
user: { user: {
email: string, email: string
username: string, username: string
picture: string picture: string
admin: boolean
} }
} }
} }

View File

@@ -6,8 +6,7 @@ useHead({
title: 'Sign my guestbook • Arthur Danjou', title: 'Sign my guestbook • Arthur Danjou',
}) })
const { loggedIn, clear } = useUserSession() const { loggedIn, clear, user } = useUserSession()
const { data: messages, refresh } = useFetch<Array<GuestbookMessage>>('/api/messages', { method: 'get' }) const { data: messages, refresh } = useFetch<Array<GuestbookMessage>>('/api/messages', { method: 'get' })
const toast = useToast() const toast = useToast()
@@ -37,6 +36,30 @@ async function sign() {
}) })
messageContent.value = '' messageContent.value = ''
} }
async function deleteMessage(id: number) {
if (!user.value.admin)
return
await $fetch('/api/message', {
method: 'delete',
body: {
id,
},
}).then(async () => {
toast.add({
title: `Message successfully deleted`,
icon: 'i-material-symbols-check-circle-outline-rounded',
color: 'green',
timeout: 4000,
})
await refresh()
}).catch(() => {
toast.add({
title: 'An error occured when deleting a message!',
color: 'red',
})
})
}
</script> </script>
<template> <template>
@@ -104,7 +127,7 @@ async function sign() {
<div <div
v-for="message in messages" v-for="message in messages"
:key="message.id" :key="message.id"
class="overflow-hidden sm:p-6 px-4 py-5 border border-zinc-100 p-6 dark:border-zinc-700/40 rounded-lg" class="relative overflow-hidden sm:p-6 px-4 py-5 border border-zinc-100 p-6 dark:border-zinc-700/40 rounded-lg"
> >
<p class="text-sm text-subtitle"> <p class="text-sm text-subtitle">
{{ message.message }} {{ message.message }}
@@ -117,6 +140,16 @@ async function sign() {
{{ message.username }} {{ message.username }}
</p> </p>
</div> </div>
<UButton
v-if="user && user.admin"
class="absolute top-1 right-1"
icon="i-material-symbols-delete-forever-outline-rounded"
color="red"
variant="ghost"
:ui="{ rounded: 'rounded-full' }"
size="xs"
@click.prevent="deleteMessage(message.id)"
/>
</div> </div>
</div> </div>
<div v-else class="my-4 text-subtitle"> <div v-else class="my-4 text-subtitle">

View File

@@ -0,0 +1,18 @@
import { z } from 'zod'
const MessageValidator = z.object({
id: z.number(),
}).parse
export default defineEventHandler(async (event) => {
const { id } = await readValidatedBody(event, MessageValidator)
const { user } = await requireUserSession(event)
if (!user.admin)
throw createError({ statusCode: 400, message: 'You need the permission to delete a message!' })
return await usePrisma().guestbookMessage.delete({
where: {
id,
},
})
})

View File

@@ -8,6 +8,8 @@ export default oauth.githubEventHandler({
email: user.email, email: user.email,
picture: user.avatar_url, picture: user.avatar_url,
username: String(user.name).trim(), username: String(user.name).trim(),
// eslint-disable-next-line node/prefer-global/process
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL,
}, },
}) })
return sendRedirect(event, getCookie(event, 'last-route') || '/') return sendRedirect(event, getCookie(event, 'last-route') || '/')

View File

@@ -5,6 +5,8 @@ export default oauth.googleEventHandler({
email: user.email, email: user.email,
picture: user.picture, picture: user.picture,
username: String(user.name).trim(), username: String(user.name).trim(),
// eslint-disable-next-line node/prefer-global/process
admin: user.email === process.env.NUXT_AUTH_ADMIN_EMAIL,
}, },
}) })
return sendRedirect(event, getCookie(event, 'last-route') || '/') return sendRedirect(event, getCookie(event, 'last-route') || '/')