Merge Dev in Staging
This commit is contained in:
commit
66b9a632b5
@ -7,6 +7,11 @@ export interface IConnectionUrlResponse {
|
||||
}
|
||||
}
|
||||
|
||||
export interface ICustomerTokens {
|
||||
accessToken: string;
|
||||
refreshToken: string;
|
||||
}
|
||||
|
||||
export default class Customers extends BaseId360 {
|
||||
private static instance: Customers;
|
||||
private readonly baseURl = this.namespaceUrl.concat("/customers");
|
||||
@ -33,10 +38,10 @@ export default class Customers extends BaseId360 {
|
||||
}
|
||||
}
|
||||
|
||||
public async loginCallback(callbackToken: string | string[]): Promise<any> {
|
||||
public async loginCallback(callbackToken: string | string[]): Promise<ICustomerTokens> {
|
||||
const url = new URL(this.baseURl.concat(`/login-callback/${callbackToken}`));
|
||||
try {
|
||||
return await this.postRequest<any>(url);
|
||||
return await this.postRequest<ICustomerTokens>(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
@ -35,14 +35,4 @@ export default class User extends BaseApiService {
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshToken(refreshToken: string): Promise<{ accessToken: string }> {
|
||||
const url = new URL(`${this.baseURl}/refresh-token`);
|
||||
try {
|
||||
return await this.postRequest(url, {}, refreshToken);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
import BaseApiService from "@Front/Api/BaseApiService";
|
||||
|
||||
export default class Customer extends BaseApiService {
|
||||
private static instance: Customer;
|
||||
private readonly baseURl = this.getBaseUrl().concat("/france-connect/customer");
|
||||
|
||||
private constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
public static getInstance() {
|
||||
if (!this.instance) {
|
||||
return new Customer();
|
||||
} else {
|
||||
return this.instance;
|
||||
}
|
||||
}
|
||||
|
||||
public async login(email: string) {
|
||||
const url = new URL(this.baseURl.concat("/login/").concat(email));
|
||||
try {
|
||||
return await this.postRequest(url);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
|
||||
public async refreshToken(refreshToken: string): Promise<{ accessToken: string }> {
|
||||
const url = new URL(this.baseURl.concat("/refresh-token"));
|
||||
try {
|
||||
return await this.postRequest(url, {}, refreshToken);
|
||||
} catch (err) {
|
||||
this.onError(err);
|
||||
return Promise.reject(err);
|
||||
}
|
||||
}
|
||||
}
|
@ -31,7 +31,6 @@ export default function ClientDashboard(props: IProps) {
|
||||
}
|
||||
|
||||
const folder = await Folders.getInstance().getByUid(folderUid as string, { q: { office: true, customers: true } });
|
||||
console.log(folder);
|
||||
const actualCustomer = folder?.customers?.find((customer) => customer.uid === jwt?.customerId);
|
||||
if (!actualCustomer) throw new Error("Customer not found");
|
||||
|
||||
|
@ -259,7 +259,6 @@ class AddClientToFolderClass extends BasePage<IPropsClass, IState> {
|
||||
return Customer.hydrate<Customer>(customer);
|
||||
}),
|
||||
});
|
||||
console.log(body);
|
||||
await Folders.getInstance().put(this.props.selectedFolderUid, body);
|
||||
this.props.router.push(`/folders/${this.props.selectedFolderUid}`);
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Loader from "@Front/Components/DesignSystem/Loader";
|
||||
import UserStore from "@Front/Stores/UserStore";
|
||||
import Link from "next/link";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
|
||||
export default function LoginCallBack() {
|
||||
const router = useRouter();
|
||||
@ -19,16 +20,22 @@ export default function LoginCallBack() {
|
||||
useEffect(() => {
|
||||
async function getUser() {
|
||||
const code = router.query["code"];
|
||||
if (!code) return;
|
||||
try {
|
||||
const token = await Auth.getInstance().getIdnotJwt(code as string);
|
||||
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
|
||||
await UserStore.instance.connect(token.accessToken, token.refreshToken);
|
||||
const refreshedTokens = await JwtService.getInstance().refreshToken();
|
||||
if (refreshedTokens) {
|
||||
return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||
} catch (e) {
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
if (code) {
|
||||
try {
|
||||
const token = await Auth.getInstance().getIdnotJwt(code as string);
|
||||
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
|
||||
await UserStore.instance.connect(token.accessToken, token.refreshToken);
|
||||
return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
|
||||
} catch (e) {
|
||||
router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
}
|
||||
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
|
||||
}
|
||||
getUser();
|
||||
}),
|
||||
|
@ -4,33 +4,39 @@ import CoffreIcon from "@Assets/Icons/coffre.svg";
|
||||
import { useRouter } from "next/router";
|
||||
import React, { useEffect } from "react";
|
||||
import classes from "./classes.module.scss";
|
||||
//import Module from "@Front/Config/Module";
|
||||
//import Auth from "@Front/Api/Auth/IdNot";
|
||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||
import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
|
||||
import Loader from "@Front/Components/DesignSystem/Loader";
|
||||
// import { FrontendVariables } from "@Front/Config/VariablesFront";
|
||||
// import CustomerStore from "@Front/Stores/CustomerStore";
|
||||
import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers";
|
||||
import Customers, { ICustomerTokens } from "@Front/Api/Auth/Id360/Customers/Customers";
|
||||
import CustomerStore from "@Front/Stores/CustomerStore";
|
||||
import Module from "@Front/Config/Module";
|
||||
import Link from "next/link";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
|
||||
export default function LoginCallBack() {
|
||||
export default function LoginCallBackCustomer() {
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
const getReport = async () => {
|
||||
const tokenid360 = router.query["token"];
|
||||
if (!tokenid360) return;
|
||||
// const variables = FrontendVariables.getInstance();
|
||||
// console.log(`${variables.DOCAPOST_API_URL}/enrollment/status/${tokenid360}/`)
|
||||
// const reportRes = await fetch(`${variables.DOCAPOST_API_URL}/enrollment/status/${tokenid360}`, { method: "GET"});
|
||||
// const report = await reportRes.json() as id360ProcessResponse;
|
||||
const token = await Customers.getInstance().loginCallback(tokenid360);
|
||||
CustomerStore.instance.connect(token.accessToken, token.refreshToken);
|
||||
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
|
||||
const refreshedTokens = await JwtService.getInstance().refreshToken();
|
||||
if (refreshedTokens) {
|
||||
return router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
|
||||
}
|
||||
if (tokenid360) {
|
||||
let token: ICustomerTokens | undefined;
|
||||
try {
|
||||
token = await Customers.getInstance().loginCallback(tokenid360);
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
router.push(Module.getInstance().get().modules.pages.CustomersLogin.props.path + "?error=1");
|
||||
return;
|
||||
}
|
||||
CustomerStore.instance.connect(token.accessToken, token.refreshToken);
|
||||
router.push(Module.getInstance().get().modules.pages.Folder.pages.Select.props.path);
|
||||
}
|
||||
return router.push(Module.getInstance().get().modules.pages.CustomersLogin.props.path + "?error=1");
|
||||
};
|
||||
getReport();
|
||||
}),
|
||||
|
@ -5,14 +5,18 @@ import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
|
||||
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
|
||||
import Image from "next/image";
|
||||
import { useRouter } from "next/router";
|
||||
import { useCallback } from "react";
|
||||
import Customers from "@Front/Api/LeCoffreApi/Id360/Customers/Customers";
|
||||
import { useCallback, useEffect, useState } from "react";
|
||||
import Customers from "@Front/Api/Auth/Id360/Customers/Customers";
|
||||
import classes from "./classes.module.scss";
|
||||
import LandingImage from "./landing-connect.jpeg";
|
||||
import Link from "next/link";
|
||||
import Confirm from "@Front/Components/DesignSystem/Modal/Confirm";
|
||||
|
||||
export default function Login() {
|
||||
const router = useRouter();
|
||||
const error = router.query["error"];
|
||||
|
||||
const [isErrorModalOpen, setIsErrorModalOpen] = useState(false);
|
||||
|
||||
const redirectCustomerOnConnection = useCallback(() => {
|
||||
async function getCustomer() {
|
||||
@ -26,6 +30,18 @@ export default function Login() {
|
||||
getCustomer();
|
||||
}, [router]);
|
||||
|
||||
const openErrorModal = useCallback(() => {
|
||||
setIsErrorModalOpen(true);
|
||||
}, []);
|
||||
|
||||
const closeErrorModal = useCallback(() => {
|
||||
setIsErrorModalOpen(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (error === "1") openErrorModal();
|
||||
}, [error, openErrorModal]);
|
||||
|
||||
return (
|
||||
<DefaultDoubleSidePage title={"Login"} image={LandingImage}>
|
||||
<div className={classes["root"]}>
|
||||
@ -41,6 +57,20 @@ export default function Login() {
|
||||
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
|
||||
</Link>
|
||||
</div>
|
||||
<Confirm
|
||||
isOpen={isErrorModalOpen}
|
||||
onClose={closeErrorModal}
|
||||
showCancelButton={false}
|
||||
onAccept={closeErrorModal}
|
||||
closeBtn
|
||||
header={"Erreur"}
|
||||
confirmText={"OK"}>
|
||||
<div className={classes["modal-content"]}>
|
||||
<Typography typo={ITypo.P_16} className={classes["text"]}>
|
||||
Une erreur est survenue lors de la connexion. Veuillez réessayer.
|
||||
</Typography>
|
||||
</div>
|
||||
</Confirm>
|
||||
</DefaultDoubleSidePage>
|
||||
);
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ export default function SelectFolder() {
|
||||
async function getFolders() {
|
||||
const jwt = JwtService.getInstance().decodeCustomerJwt();
|
||||
if (!jwt) return;
|
||||
console.log(jwt);
|
||||
|
||||
const folders = await Folders.getInstance().get({
|
||||
q: {
|
||||
|
@ -1,6 +1,8 @@
|
||||
import jwt_decode from "jwt-decode";
|
||||
import CookieService from "../CookieService/CookieService";
|
||||
import User from "@Front/Api/Auth/IdNot/User";
|
||||
import UserStore from "@Front/Stores/CustomerStore";
|
||||
import CustomerStore from "@Front/Stores/CustomerStore";
|
||||
import { FrontendVariables } from "@Front/Config/VariablesFront";
|
||||
|
||||
enum PROVIDER_OPENID {
|
||||
idNot = "idNot",
|
||||
@ -22,6 +24,7 @@ export interface IUserJwtPayload {
|
||||
export interface ICustomerJwtPayload {
|
||||
customerId: string;
|
||||
email: string;
|
||||
exp: number;
|
||||
}
|
||||
|
||||
export default class JwtService {
|
||||
@ -48,23 +51,55 @@ export default class JwtService {
|
||||
* @description : set a cookie with a name and a value that expire in 7 days
|
||||
* @throws {Error} If the name or the value is empty
|
||||
*/
|
||||
public async checkJwt() {
|
||||
const decodedToken = this.decodeJwt();
|
||||
public async refreshToken() {
|
||||
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
||||
const variables = await FrontendVariables.getInstance();
|
||||
if (!refreshToken) return false;
|
||||
const userToken = jwt_decode(refreshToken) as IUserJwtPayload;
|
||||
const customerToken = jwt_decode(refreshToken) as ICustomerJwtPayload;
|
||||
|
||||
if (!decodedToken) return;
|
||||
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
|
||||
if (decodedToken.exp < now) {
|
||||
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
||||
|
||||
if (!refreshToken) return;
|
||||
const newAccessToken: { accessToken: string } = await User.getInstance().refreshToken(refreshToken);
|
||||
|
||||
if (newAccessToken) {
|
||||
CookieService.getInstance().setCookie("leCoffreAccessToken", newAccessToken.accessToken);
|
||||
if (userToken?.exp && userToken.exp > Math.floor(Date.now() / 1000)) {
|
||||
if (userToken?.userId) {
|
||||
try {
|
||||
const headers = new Headers();
|
||||
headers.append("Authorization", `Bearer ${refreshToken}`);
|
||||
const response = await fetch(
|
||||
`${
|
||||
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
|
||||
}/idnot/user/auth/refresh-token`,
|
||||
{ method: 'POST', headers: headers },
|
||||
);
|
||||
const newAccessToken: { accessToken: string } = await response.json();
|
||||
if (newAccessToken) {
|
||||
await UserStore.instance.connect(newAccessToken.accessToken, refreshToken);
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return false;
|
||||
}
|
||||
} else if (customerToken?.customerId) {
|
||||
try {
|
||||
const headers = new Headers();
|
||||
headers.append("Authorization", `Bearer ${refreshToken}`);
|
||||
const response = await fetch(
|
||||
`${
|
||||
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
|
||||
}/id360/customers/refresh-token`,
|
||||
{ method: 'POST', headers: headers },
|
||||
);
|
||||
const newAccessToken: { accessToken: string } = await response.json();
|
||||
if (newAccessToken) {
|
||||
await CustomerStore.instance.connect(newAccessToken.accessToken, refreshToken);
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public hasRule(name: string, action: string) {
|
||||
|
@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import Customer from "@Front/Api/Auth/franceConnect/Customer";
|
||||
import CookieService from "@Front/Services/CookieService/CookieService";
|
||||
import EventEmitter from "@Front/Services/EventEmitter";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
@ -36,23 +35,6 @@ export default class UserStore {
|
||||
return true;
|
||||
}
|
||||
|
||||
public async connectCustomer(email: string) {
|
||||
try {
|
||||
//call connection function
|
||||
const customer: any = await Customer.getInstance().login(email);
|
||||
|
||||
//Save tokens in cookies
|
||||
CookieService.getInstance().setCookie("leCoffreAccessToken", customer.accessToken);
|
||||
CookieService.getInstance().setCookie("leCoffreRefreshToken", customer.refreshToken);
|
||||
|
||||
this.event.emit("connection", this.accessToken);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async disconnect() {
|
||||
try {
|
||||
//Remove tokens from cookies
|
||||
|
@ -1,6 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import Customer from "@Front/Api/Auth/franceConnect/Customer";
|
||||
import CookieService from "@Front/Services/CookieService/CookieService";
|
||||
import EventEmitter from "@Front/Services/EventEmitter";
|
||||
import JwtService from "@Front/Services/JwtService/JwtService";
|
||||
@ -36,23 +35,6 @@ export default class UserStore {
|
||||
return true;
|
||||
}
|
||||
|
||||
public async connectCustomer(email: string) {
|
||||
try {
|
||||
//call connection function
|
||||
const customer: any = await Customer.getInstance().login(email);
|
||||
|
||||
//Save tokens in cookies
|
||||
CookieService.getInstance().setCookie("leCoffreAccessToken", customer.accessToken);
|
||||
CookieService.getInstance().setCookie("leCoffreRefreshToken", customer.refreshToken);
|
||||
|
||||
this.event.emit("connection", this.accessToken);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public async disconnect() {
|
||||
try {
|
||||
//Remove tokens from cookies
|
||||
|
@ -15,14 +15,13 @@ export async function middleware(request: NextRequest) {
|
||||
// If no JWT provided, redirect to login page
|
||||
if (!userDecodedToken && !customerDecodedToken) return NextResponse.redirect(new URL("/login", request.url));
|
||||
|
||||
// If JWT expired, redirect to login page
|
||||
const token = userDecodedToken ?? customerDecodedToken;
|
||||
const currentDate = new Date();
|
||||
const time = currentDate.getTime();
|
||||
const now = Math.floor(time / 1000);
|
||||
if (token.exp < now) {
|
||||
console.log("token expired");
|
||||
return NextResponse.redirect(new URL("/login", request.url));
|
||||
// If JWT expired, redirect to login callback page to refresh tokens
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
if (userDecodedToken.userId && userDecodedToken.exp < now) {
|
||||
return NextResponse.redirect(new URL("/authorized-client", request.url));
|
||||
}
|
||||
if (customerDecodedToken.customerId && customerDecodedToken.exp < now) {
|
||||
return NextResponse.redirect(new URL("/id360/customer-callback", request.url));
|
||||
}
|
||||
|
||||
return NextResponse.next();
|
||||
|
Loading…
x
Reference in New Issue
Block a user