Page verrouilée

This commit is contained in:
Maxime Lalo 2023-09-14 16:43:06 +02:00
parent 03dfacee1e
commit 581d50d26e
6 changed files with 113 additions and 2 deletions

View File

@ -9,6 +9,7 @@ import Image from "next/image";
export type IProps = IBaseFieldProps & { export type IProps = IBaseFieldProps & {
canCopy?: boolean; canCopy?: boolean;
password?: boolean;
}; };
export default class TextField extends BaseField<IProps> { export default class TextField extends BaseField<IProps> {
@ -32,6 +33,7 @@ export default class TextField extends BaseField<IProps> {
onBlur={this.onBlur} onBlur={this.onBlur}
name={this.props.name} name={this.props.name}
disabled={this.props.disabled} disabled={this.props.disabled}
type={this.props.password ? "password" : "text"}
/> />
<div className={classes["fake-placeholder"]}> <div className={classes["fake-placeholder"]}>
{this.props.placeholder} {!this.props.required && " (Facultatif)"} {this.props.placeholder} {!this.props.required && " (Facultatif)"}

View File

@ -0,0 +1,29 @@
@import "@Themes/constants.scss";
.root {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
height: 100%;
max-width: 530px;
margin: auto;
.title {
margin: 32px 0;
text-align: center;
@media (max-width: $screen-s) {
font-family: 48px;
}
}
.forget-password {
margin-top: 32px;
margin-bottom: 8px;
}
.form {
display: flex;
}
}

View File

@ -0,0 +1,57 @@
import Module from "@Front/Config/Module";
import { useRouter } from "next/router";
import { useState } from "react";
import Image from "next/image";
import classes from "./classes.module.scss";
import LandingImage from "./landing-connect.jpeg";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import CoffreIcon from "@Assets/Icons/coffre.svg";
import TextField from "@Front/Components/DesignSystem/Form/TextField";
import Button from "@Front/Components/DesignSystem/Button";
export default function Protect() {
const [password, setPassword] = useState("");
const router = useRouter();
const setPasswordFromInput = (event: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
setPassword(event.target.value);
};
const submitAuth = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (password === "team-fullstack") {
console.log("ok");
setCookie("protect_staging", Date.now().toString());
router.push(Module.getInstance().get().modules.pages.Login.props.path);
} else {
console.log("pas ok");
}
};
const setCookie = (name: string, value: string) => {
if (!name || !value) throw new Error("Cookie name or value is empty");
const date = new Date();
// Set it expire in 7 days
date.setTime(date.getTime() + 7 * 24 * 60 * 60 * 1000);
// Set it
document.cookie = name + "=" + value + "; expires=" + date.toUTCString() + "; path=/";
};
return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}>
<div className={classes["root"]}>
<Image alt="coffre" src={CoffreIcon} />
<Typography typo={ITypo.H1}>
<div className={classes["title"]}>Le site est verrouillé</div>
</Typography>
<form onSubmit={submitAuth} className={classes["form"]}>
<TextField placeholder="Password" onChange={setPasswordFromInput} password />
<Button type="submit">Submit</Button>
</form>
</div>
</DefaultDoubleSidePage>
);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

View File

@ -4,11 +4,28 @@ import { NextResponse } from "next/server";
import type { NextRequest } from "next/server"; import type { NextRequest } from "next/server";
export async function middleware(request: NextRequest) { export async function middleware(request: NextRequest) {
const cookieStaging = request.cookies.get("protect_staging");
console.log(cookieStaging);
if (!cookieStaging) return NextResponse.redirect(new URL("/protect", request.url));
// Get the JWT from the cookies
const cookies = request.cookies.get("leCoffreAccessToken"); const cookies = request.cookies.get("leCoffreAccessToken");
if (!cookies) return NextResponse.redirect(new URL("/login", request.url)); if (!cookies) return NextResponse.redirect(new URL("/login", request.url));
// Decode it
const userDecodedToken = jwt_decode(cookies.value) as IUserJwtPayload; const userDecodedToken = jwt_decode(cookies.value) as IUserJwtPayload;
const customerDecodedToken = jwt_decode(cookies.value) as ICustomerJwtPayload; const customerDecodedToken = jwt_decode(cookies.value) as ICustomerJwtPayload;
// If no JWT provided, redirect to login page
if (!userDecodedToken && !customerDecodedToken) return NextResponse.redirect(new URL("/login", request.url)); if (!userDecodedToken && !customerDecodedToken) return NextResponse.redirect(new URL("/login", request.url));
// If JWT expired, redirect to login page
const token = userDecodedToken ?? customerDecodedToken;
const now = Math.floor(Date.now() / 1000);
if (token.exp < now) {
return NextResponse.redirect(new URL("/login", request.url));
}
const requestUrlPath = request.nextUrl.pathname; const requestUrlPath = request.nextUrl.pathname;
if ( if (
requestUrlPath.startsWith("/collaborators") || requestUrlPath.startsWith("/collaborators") ||
@ -21,7 +38,8 @@ export async function middleware(request: NextRequest) {
if (userDecodedToken.role !== "admin" && userDecodedToken.role !== "super-admin") if (userDecodedToken.role !== "admin" && userDecodedToken.role !== "super-admin")
return NextResponse.redirect(new URL("/404", request.url)); return NextResponse.redirect(new URL("/404", request.url));
} }
if ((requestUrlPath.startsWith("/my-account") || requestUrlPath.startsWith("/document-types")) && !userDecodedToken) return NextResponse.redirect(new URL("/404", request.url)); if ((requestUrlPath.startsWith("/my-account") || requestUrlPath.startsWith("/document-types")) && !userDecodedToken)
return NextResponse.redirect(new URL("/404", request.url));
if (requestUrlPath.startsWith("/client-dashboard") && !customerDecodedToken) return NextResponse.redirect(new URL("/404", request.url)); if (requestUrlPath.startsWith("/client-dashboard") && !customerDecodedToken) return NextResponse.redirect(new URL("/404", request.url));
return NextResponse.next(); return NextResponse.next();
@ -33,7 +51,7 @@ export const config = {
"/collaborators/:path*", "/collaborators/:path*",
"/customer/:path*", "/customer/:path*",
"/document-types/:path*", "/document-types/:path*",
"/deed-types/:path*", "/deed-types/:path*",
"/folders/:path*", "/folders/:path*",
"/my-account/:path*", "/my-account/:path*",
"/offices/:path*", "/offices/:path*",

5
src/pages/protect.tsx Normal file
View File

@ -0,0 +1,5 @@
import Protect from "@Front/Components/Layouts/Protect";
export default function Route() {
return <Protect />;
}