add middleware
This commit is contained in:
parent
c4d902c276
commit
abad2cec96
10 changed files with 181 additions and 49 deletions
BIN
bun.lockb
BIN
bun.lockb
Binary file not shown.
|
@ -12,10 +12,10 @@
|
|||
"dependencies": {
|
||||
"@astrojs/check": "^0.7.0",
|
||||
"@astrojs/node": "^8.2.5",
|
||||
"@astrojs/react": "^3.3.4",
|
||||
"@astrojs/react": "^3.4.0",
|
||||
"@types/react": "^18.3.2",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"astro": "^4.8.4",
|
||||
"astro": "^4.9.1",
|
||||
"bootstrap": "^5.3.3",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
|
|
|
@ -1,23 +1,71 @@
|
|||
export default function LoginForm() {
|
||||
import { useState } from "react";
|
||||
|
||||
export interface LoginFormValue {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
|
||||
interface LoginFormProps {
|
||||
onSubmit: (data: LoginFormValue) => void;
|
||||
}
|
||||
|
||||
export default function LoginForm(props: LoginFormProps) {
|
||||
const [form, setForm] = useState<LoginFormValue>({
|
||||
username: "",
|
||||
password: "",
|
||||
});
|
||||
|
||||
function handleInputChange(event: React.ChangeEvent<HTMLInputElement>) {
|
||||
const target = event.target;
|
||||
const name = target.name;
|
||||
const value = target.value;
|
||||
|
||||
setForm({
|
||||
...form,
|
||||
[name]: value,
|
||||
});
|
||||
}
|
||||
|
||||
function handleBtnClick() {
|
||||
props.onSubmit({ ...form });
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="card">
|
||||
<div className="card-body">
|
||||
<form>
|
||||
<div className="form-floating mb-3">
|
||||
<input type="text" className="form-control" id="username" />
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
id="username"
|
||||
name="username"
|
||||
value={form.username}
|
||||
onChange={handleInputChange}
|
||||
/>
|
||||
<label className="form-label">Nom d'utilisateur</label>
|
||||
</div>
|
||||
<div className="form-floating mb-3">
|
||||
<input type="password" className="form-control" id="password" />
|
||||
<input
|
||||
type="password"
|
||||
className="form-control"
|
||||
id="password"
|
||||
name="password"
|
||||
onChange={handleInputChange}
|
||||
value={form.password}
|
||||
/>
|
||||
<label className="form-label">Mot de passe</label>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
<div className="d-grid">
|
||||
<button type="submit" className="btn btn-primary">
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleBtnClick}
|
||||
className="btn btn-primary"
|
||||
>
|
||||
Connexion
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
22
src/components/forms/LoginFormData.tsx
Normal file
22
src/components/forms/LoginFormData.tsx
Normal file
|
@ -0,0 +1,22 @@
|
|||
import LoginForm, { type LoginFormValue } from "./LoginForm";
|
||||
|
||||
export default function LoginFormData() {
|
||||
function handleOnFormSubmit(data: LoginFormValue) {
|
||||
fetch(`${import.meta.env.PUBLIC_API_URL}/accounts/login`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify(data),
|
||||
credentials: "include",
|
||||
headers: {
|
||||
Accept: "application/json",
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
})
|
||||
.then((res) => res.json())
|
||||
.then((json) => {
|
||||
window.location.href = "/home";
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
|
||||
return <LoginForm onSubmit={handleOnFormSubmit} />;
|
||||
}
|
10
src/env.d.ts
vendored
10
src/env.d.ts
vendored
|
@ -1 +1,11 @@
|
|||
/// <reference types="astro/client" />
|
||||
|
||||
declare namespace App {
|
||||
interface Locals {
|
||||
account?: {
|
||||
id: number;
|
||||
username: string;
|
||||
role_id: number;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
25
src/layouts/HomeLayout.astro
Normal file
25
src/layouts/HomeLayout.astro
Normal file
|
@ -0,0 +1,25 @@
|
|||
---
|
||||
import RootLayout from "./RootLayout.astro";
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
}
|
||||
|
||||
const { title } = Astro.props;
|
||||
---
|
||||
|
||||
<RootLayout title={title}>
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-auto">Films</div>
|
||||
<div class="col-auto">Compte</div>
|
||||
<div class="col-auto">Deconnexion</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
</RootLayout>
|
||||
|
||||
<script></script>
|
29
src/middleware.ts
Normal file
29
src/middleware.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
import { defineMiddleware, sequence } from "astro:middleware";
|
||||
|
||||
const protectedRoutes = defineMiddleware(async (ctx, next) => {
|
||||
const pathname = ctx.url.pathname;
|
||||
if (!["/", "/register"].includes(pathname)) {
|
||||
const jwt = ctx.cookies.get("token");
|
||||
if (!jwt) {
|
||||
return ctx.redirect("/");
|
||||
}
|
||||
|
||||
const res = await fetch(
|
||||
`${import.meta.env.PUBLIC_API_URL}/accounts/recovery`,
|
||||
{
|
||||
credentials: "include",
|
||||
headers: ctx.request.headers,
|
||||
},
|
||||
);
|
||||
|
||||
if (res.status !== 201) {
|
||||
return ctx.redirect("/");
|
||||
}
|
||||
|
||||
ctx.locals.account = JSON.parse(await res.text()).account;
|
||||
}
|
||||
|
||||
return await next();
|
||||
});
|
||||
|
||||
export const onRequest = sequence(defineMiddleware(protectedRoutes));
|
9
src/pages/home/index.astro
Normal file
9
src/pages/home/index.astro
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
import HomeLayout from "../../layouts/HomeLayout.astro";
|
||||
|
||||
const account = Astro.locals.account;
|
||||
---
|
||||
|
||||
<HomeLayout title="Trepa">
|
||||
Hello {account?.username}
|
||||
</HomeLayout>
|
|
@ -1,10 +1,8 @@
|
|||
---
|
||||
import LoginFormData from "../components/forms/LoginFormData";
|
||||
import EmptyLayout from "../layouts/EmptyLayout.astro";
|
||||
|
||||
const jwt = Astro.cookies.get("jwt");
|
||||
if (!jwt) {
|
||||
Astro.redirect("/login");
|
||||
}
|
||||
---
|
||||
|
||||
<EmptyLayout title="Welcome to Astro." />
|
||||
<EmptyLayout title="Trepa - Connexion">
|
||||
<LoginFormData client:load />
|
||||
</EmptyLayout>
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
import RootLayout from "../layouts/RootLayout.astro";
|
||||
import LoginForm from "../components/forms/LoginForm";
|
||||
import EmptyLayout from "../layouts/EmptyLayout.astro";
|
||||
---
|
||||
|
||||
<EmptyLayout title="Welcome to Astro.">
|
||||
<LoginForm />
|
||||
</EmptyLayout>
|
Loading…
Reference in a new issue