diff --git a/src/backend/sign-in.ts b/src/backend/sign-in.ts new file mode 100644 index 0000000..5e45eae --- /dev/null +++ b/src/backend/sign-in.ts @@ -0,0 +1,7 @@ +export async function backendSignIn(email: string, password: string): Promise { + // Simulate 1 second fetch + return new Promise((resolve) => { + const ok = email === 'asdf@asdf.de' && password === 'asdfasdf' + setTimeout(() => resolve(ok), 1000) + }) +} diff --git a/src/components/header.astro b/src/components/header.astro new file mode 100644 index 0000000..c5bd93f --- /dev/null +++ b/src/components/header.astro @@ -0,0 +1,39 @@ +--- +import { isLoggedIn } from "../utils/auth"; + +const loggedIn = isLoggedIn(Astro.cookies) +--- + + \ No newline at end of file diff --git a/src/layouts/layout.astro b/src/layouts/layout.astro index fad8e34..1914f5a 100644 --- a/src/layouts/layout.astro +++ b/src/layouts/layout.astro @@ -1,17 +1,19 @@ --- -import "../assets/app.css"; +import '../assets/app.css' +import Header from '../components/header.astro' --- - + - - - - - + + + + + Astro +
diff --git a/src/middleware.ts b/src/middleware.ts new file mode 100644 index 0000000..2e0a871 --- /dev/null +++ b/src/middleware.ts @@ -0,0 +1,20 @@ +import { defineMiddleware } from 'astro:middleware' +import { isLoggedIn } from './utils/auth' + +const guestUrls = ['/'] +const publicUrls = ['/sign-in', '/sign-up'] + +export const onRequest = defineMiddleware((context, next) => { + const pathname = context.url.pathname.replace(/\/+$/, '') || '/' + const loggedIn = isLoggedIn(context.cookies) + + if (guestUrls.includes(pathname)) { + return next() + } + + if (publicUrls.includes(pathname)) { + return loggedIn ? context.redirect('/dashboard', 303) : next() + } + + return loggedIn ? next() : context.redirect('/sign-in', 303) +}) diff --git a/src/pages/dashboard.astro b/src/pages/dashboard.astro new file mode 100644 index 0000000..0ca7b33 --- /dev/null +++ b/src/pages/dashboard.astro @@ -0,0 +1,7 @@ +--- +import Layout from '../layouts/layout.astro' +--- + + +

Dashboard

+
diff --git a/src/pages/sign-in.astro b/src/pages/sign-in.astro index f8b69a5..485ec4a 100644 --- a/src/pages/sign-in.astro +++ b/src/pages/sign-in.astro @@ -1,11 +1,17 @@ --- +import { backendSignIn } from '../backend/sign-in' import LoginForm from '../islands/LoginForm.vue' import Layout from '../layouts/layout.astro' import { loginSchema } from '../schemas/login' +import { isLoggedIn, setAuthCookie } from '../utils/auth' let email = '' let error = '' +if (isLoggedIn(Astro.cookies)) { + return Astro.redirect('/dashboard', 303) +} + if (Astro.request.method === 'POST') { const formData = await Astro.request.formData() const input = { @@ -20,7 +26,14 @@ if (Astro.request.method === 'POST') { error = result.error.issues[0]?.message ?? 'Invalid form data.' } else { email = result.data.email - console.log('POST DATA', result.data) + + const ok = await backendSignIn(email, input.password?.toString() ?? '') + if (ok) { + setAuthCookie(Astro.cookies) + return Astro.redirect('/dashboard', 303) + } else { + error = 'E-Mail or password wrong' + } } } --- diff --git a/src/pages/sign-out.ts b/src/pages/sign-out.ts new file mode 100644 index 0000000..49d4e89 --- /dev/null +++ b/src/pages/sign-out.ts @@ -0,0 +1,7 @@ +import type { APIRoute } from 'astro' +import { clearAuthCookie } from '../utils/auth' + +export const POST: APIRoute = ({ cookies, redirect }) => { + clearAuthCookie(cookies) + return redirect('/sign-in', 303) +} diff --git a/src/utils/auth.ts b/src/utils/auth.ts new file mode 100644 index 0000000..8d0b2ca --- /dev/null +++ b/src/utils/auth.ts @@ -0,0 +1,24 @@ +import type { AstroCookies } from 'astro' + +export function setAuthCookie(cookies: AstroCookies) { + cookies.set('auth', 'ok', { + maxAge: 60 * 60, + sameSite: 'lax', + path: '/', + secure: true, + httpOnly: true, + }) +} + +export function clearAuthCookie(cookies: AstroCookies) { + cookies.delete('auth', { path: '/' }) +} + +export function isLoggedIn(cookies: AstroCookies): boolean { + const cookie = cookies.get('auth') + console.log('cookie', cookie) + if (cookie) { + return cookie.value == 'ok' + } + return false +}