From 22d74be55876602c6ff04c4433fe19db44ee1d0d Mon Sep 17 00:00:00 2001
From: Sofiane Lasri-Trienpont <alasri250@gmail.com>
Date: Sat, 9 Nov 2024 22:29:53 +0100
Subject: [PATCH] feat: implement admin authentication middleware and API
 endpoint

- Add `auth.ts` middleware for session validation in server.
- Update `auth.ts` in middleware to use async and fetch ping API.
- Modify `admin.vue` to utilize `useAuthStore()` for state management.
- Introduce `ping.ts` API in server for admin route validation.
---
 middleware/auth.ts        | 18 ++++++++++++++++--
 pages/admin.vue           |  5 ++++-
 server/api/admin/ping.ts  |  5 +++++
 server/middleware/auth.ts | 34 ++++++++++++++++++++++++++++++++++
 4 files changed, 59 insertions(+), 3 deletions(-)
 create mode 100644 server/api/admin/ping.ts
 create mode 100644 server/middleware/auth.ts

diff --git a/middleware/auth.ts b/middleware/auth.ts
index 5048b24..53fc7a2 100644
--- a/middleware/auth.ts
+++ b/middleware/auth.ts
@@ -1,6 +1,20 @@
-export default defineNuxtRouteMiddleware((to) => {
+export default defineNuxtRouteMiddleware(async () => {
     const hasToken = useCookie('session_token');
-    if (!hasToken && to.path.startsWith('/admin')) {
+    if (!hasToken) {
+        return navigateTo('/login');
+    }
+
+    let isAuthorized = false;
+    await useFetch('/api/admin/ping', {
+        onResponse({response}) {
+            console.log(response.ok);
+            if (response.ok) {
+                isAuthorized = true;
+            }
+        }
+    });
+
+    if (!isAuthorized) {
         return navigateTo('/login');
     }
 });
\ No newline at end of file
diff --git a/pages/admin.vue b/pages/admin.vue
index 67818b9..bdb76bc 100644
--- a/pages/admin.vue
+++ b/pages/admin.vue
@@ -1,7 +1,10 @@
 <script setup lang="ts">
 definePageMeta({
   middleware: 'auth'
-})
+});
+
+useAuthStore();
+
 </script>
 
 <template>
diff --git a/server/api/admin/ping.ts b/server/api/admin/ping.ts
new file mode 100644
index 0000000..6064d83
--- /dev/null
+++ b/server/api/admin/ping.ts
@@ -0,0 +1,5 @@
+import {EventHandlerRequest, H3Event} from "h3";
+
+export default defineEventHandler(async () => {
+    return "pong";
+});
\ No newline at end of file
diff --git a/server/middleware/auth.ts b/server/middleware/auth.ts
new file mode 100644
index 0000000..3927e0a
--- /dev/null
+++ b/server/middleware/auth.ts
@@ -0,0 +1,34 @@
+import {EventHandlerRequest, H3Event} from "h3";
+import prisma from "~/lib/prisma";
+
+export default defineEventHandler(async (event: H3Event<EventHandlerRequest>) => {
+    if (!event.path.startsWith('/admin/')) {
+        return;
+    }
+
+    const sessionToken = getCookie(event, 'session_token');
+    const sessionUserId = getCookie(event, 'userId');
+    console.log(sessionToken, sessionUserId);
+
+    if (!sessionToken || !sessionUserId) {
+        throw createError({statusCode: 401, statusMessage: 'Unauthorized'});
+    }
+
+    const dateNow = new Date();
+    const session = await prisma.session.findUnique({
+        where: {
+            token: sessionToken,
+            expiresAt: {
+                gte: dateNow,
+            }
+        },
+    });
+
+    if (!session) {
+        throw createError({statusCode: 401, statusMessage: 'Unauthorized'});
+    }
+
+    if (session.userId.toString() !== sessionUserId) {
+        throw createError({statusCode: 401, statusMessage: 'Unauthorized'});
+    }
+});
\ No newline at end of file
-- 
GitLab