Feat(services): id not auth (#55)

This commit is contained in:
Arnaud D. Natali 2023-09-19 18:21:22 +02:00 committed by GitHub
commit 2adc72de41
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 120 additions and 8544 deletions

View File

@ -12,6 +12,7 @@ const nextConfig = {
NEXT_PUBLIC_FRONT_APP_PORT: process.env.NEXT_PUBLIC_FRONT_APP_PORT, NEXT_PUBLIC_FRONT_APP_PORT: process.env.NEXT_PUBLIC_FRONT_APP_PORT,
NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT, NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT: process.env.NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT,
NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID, NEXT_PUBLIC_IDNOT_CLIENT_ID: process.env.NEXT_PUBLIC_IDNOT_CLIENT_ID,
NEXT_PUBLIC_IDNOT_BASE_URL: process.env.NEXT_PUBLIC_IDNOT_BASE_URL,
}, },
// webpack: config => { // webpack: config => {
// config.node = { // config.node = {

8419
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
import BaseApiService from "@Front/Api/BaseApiService"; import BaseApiService from "@Front/Api/BaseApiService";
import { FrontendVariables } from "@Front/Config/VariablesFront"; import { FrontendVariables } from "@Front/Config/VariablesFront";
//import User from "le-coffre-resources/dist/SuperAdmin";
export default class Auth extends BaseApiService { export default class Auth extends BaseApiService {
private static instance: Auth; private static instance: Auth;
@ -12,15 +13,40 @@ export default class Auth extends BaseApiService {
return (this.instance = this.instance ?? new this()); return (this.instance = this.instance ?? new this());
} }
public async getIdnotJwt(autorizationCode: string | string[]): Promise<any> { public async logOutWithIdNot() {
const variables = FrontendVariables.getInstance(); const variables = FrontendVariables.getInstance();
const baseBackUrl = variables.BACK_API_PROTOCOL + variables.BACK_API_HOST; const url = new URL(`${variables.IDNOT_BASE_URL}/user/auth/logout?post_logout_redirect_uri=${variables.FRONT_APP_HOST}`);
const url = new URL(`${baseBackUrl}/api/v1/idnot-user/${autorizationCode}`); console.log(url.toString())
try { try {
return await this.postRequest<any>(url); return await fetch(url);
} catch (err) {
console.log(err);
this.onError(err);
return Promise.reject(err);
}
}
public async loginWithIdNot() {
const variables = FrontendVariables.getInstance();
const url = new URL(`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${variables.FRONT_APP_HOST}/authorized-client&scope=openid,profile&response_type=code`);
try {
return await this.getRequest(url);
} catch (err) { } catch (err) {
this.onError(err); this.onError(err);
return Promise.reject(err); return Promise.reject(err);
} }
} }
public async getIdnotJwt(autorizationCode: string | string[]): Promise<{accessToken: string, refreshToken: string}> {
const variables = FrontendVariables.getInstance();
const baseBackUrl = variables.BACK_API_PROTOCOL + variables.BACK_API_HOST;
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
try {
return await this.postRequest<{accessToken: string, refreshToken: string}>(url);
} catch (err) {
this.onError(err);
return Promise.reject(err);
}
}
} }

View File

@ -3,21 +3,23 @@ import Image from "next/image";
import DisconnectIcon from "@Assets/Icons/disconnect.svg"; import DisconnectIcon from "@Assets/Icons/disconnect.svg";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import Typography, { ITypo } from "../Typography"; import Typography, { ITypo } from "../Typography";
import { useRouter } from "next/router";
import UserStore from "@Front/Stores/UserStore";
import { FrontendVariables } from "@Front/Config/VariablesFront";
type IProps = {}; export default function LogOut() {
type IState = { const router = useRouter();
isLogged: boolean; const variables = FrontendVariables.getInstance();
const disconnect = async() => {
await UserStore.instance.disconnect();
router.push(`https://qual-connexion.idnot.fr/user/auth/logout?post_logout_redirect_uri=${variables.FRONT_APP_HOST}/login`);
}; };
export default class LogOutButton extends React.Component<IProps, IState> {
public override render(): JSX.Element {
return ( return (
<div className={classes["root"]} onClick={this.disconnect}> <div className={classes["root"]} onClick={disconnect}>
<Typography typo={ITypo.NAV_HEADER_18}>Déconnexion</Typography> <Typography typo={ITypo.NAV_HEADER_18}>Déconnexion</Typography>
<Image src={DisconnectIcon} className={classes["disconnect-icon"]} alt="disconnect" /> <Image src={DisconnectIcon} className={classes["disconnect-icon"]} alt="disconnect" />
</div> </div>
); );
} }
private disconnect() {}
}

View File

@ -12,25 +12,14 @@ import { useCallback } from "react";
import classes from "./classes.module.scss"; import classes from "./classes.module.scss";
import LandingImage from "./landing-connect.jpeg"; import LandingImage from "./landing-connect.jpeg";
import { FrontendVariables } from "@Front/Config/VariablesFront";
export default function Login() { export default function Login() {
const router = useRouter(); const router = useRouter();
const redirectUserOnConnection = useCallback(() => { const redirectUserOnConnection = useCallback(() => {
async function getUser() { const variables = FrontendVariables.getInstance();
try { router.push(`${variables.IDNOT_BASE_URL + variables.IDNOT_AUTHORIZE_ENDPOINT}?client_id=${variables.IDNOT_CLIENT_ID}&redirect_uri=${variables.FRONT_APP_HOST}/authorized-client&scope=openid,profile&response_type=code`);
// Super admin
await UserStore.instance.connect("jelkvelknvlkn");
// Notaire
// await UserStore.instance.connect("ljfeflecnmd");
await JwtService.getInstance().checkJwt();
router.push(Module.getInstance().get().modules.pages.Folder.props.path);
} catch (e) {
console.error(e);
}
}
getUser();
}, [router]); }, [router]);
const redirectCustomerOnConnection = useCallback(() => { const redirectCustomerOnConnection = useCallback(() => {

View File

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

View File

@ -1,90 +1,52 @@
// import classes from "./classes.module.scss"; import LandingImage from "../Login/landing-connect.jpeg";
// import LandingImage from "../Login/landing-connect.png"; import Image from "next/image";
// import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; import CoffreIcon from "@Assets/Icons/coffre.svg";
// import Image from "next/image";
// import CoffreIcon from "@Assets/Icons/coffre.svg";
// import Button, { EButtonVariant } from "@Front/Components/DesignSystem/Button";
// import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography";
import { useRouter } from "next/router"; 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 UserStore from "@Front/Stores/UserStore";
//import React, { useEffect, useState } from "react"; export default function LoginCallBack() {
import React from "react";
//import Loader from "@Front/Components/DesignSystem/Loader";
//import Auth from "@Front/Api/Auth/IdNot";
import Folder from "../Folder";
import LoginClass from "../Login";
type IPropsClass = {};
// type IStateClass = {};
// class LoginCallBackClass extends React.Component<IPropsClass, IStateClass> {
// public override render(): JSX.Element {
// return (
// <DefaultDoubleSidePage title={"Login"} image={LandingImage}>
// <div className={classes["root"]}>
// <Image alt="coffre" src={CoffreIcon} />
// <Typography typo={ITypo.H1}>
// <div className={classes["title"]}>
// Connexion espace professionnel
// </div>
// </Typography>
// <Loader />
// <Typography typo={ITypo.P_18}>
// <div className={classes["forget-password"]}>
// Vous n'arrivez pas à vous connecter ?
// </div>
// </Typography>
// <Button variant={EButtonVariant.LINE}>
// Contacter l'administrateur
// </Button>
// </div>
// </DefaultDoubleSidePage>
// );
// }
// }
// TODO: Refacto with functionnal component container of classcomponent
// export default function LoginCallBack(props: IPropsClass) {
// const [user, setUser] = useState(null);
// const [isLoading, setIsLoading] = useState(false);
// const router = useRouter();
// const { code } = router.query;
// if (code) {
// useEffect(() => {
// const getIdNotJwt = async () => {
// setIsLoading(true);
// try {
// const authService = Auth.getInstance();
// const fetchedUser = await authService.getIdnotJwt(code);
// setUser(fetchedUser);
// } catch (error) {
// console.error(error);
// // Router.push('/login');
// }
// };
// getIdNotJwt();
// }, []);
// if (isLoading) return <LoginCallBackClass {... props}/>
// return <Folder {...props} />;
// }
// return <LoginClass {...props}/>
// }
export default function LoginCallBack(props: IPropsClass) {
const router = useRouter(); const router = useRouter();
const { code } = router.query;
if (code) { useEffect(() => {
// const getIdNotJwt = async () => { async function getUser() {
// try { const code = router.query["code"];
// const authService = Auth.getInstance(); if (!code) return;
// await authService.getIdnotJwt(code); try {
// } catch (error) { const token = await Auth.getInstance().getIdnotJwt(code as string);
// console.error(error); await UserStore.instance.connect(token.accessToken, token.refreshToken);
// } return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
// }; } catch (e) {
//getIdNotJwt(); console.error(e);
return <Folder {...props} />; return;
} }
return <LoginClass {...props} />; }
getUser();
}),
[router];
return (
<DefaultDoubleSidePage title={"Login"} image={LandingImage}>
<div className={classes["root"]}>
<Image alt="coffre" src={CoffreIcon} />
<Typography typo={ITypo.H1}>
<div className={classes["title"]}>Connexion espace professionnel</div>
</Typography>
<div className={classes["loader"]}>
<Loader />
</div>
<Typography typo={ITypo.P_18}>
<div className={classes["forget-password"]}>Vous n'arrivez pas à vous connecter ?</div>
</Typography>
<Button variant={EButtonVariant.LINE}>Contacter l'administrateur</Button>
</div>
</DefaultDoubleSidePage>
);
} }

View File

@ -11,6 +11,8 @@ export class FrontendVariables {
public FRONT_APP_HOST!: string; public FRONT_APP_HOST!: string;
public IDNOT_BASE_URL!: string;
public IDNOT_AUTHORIZE_ENDPOINT!: string; public IDNOT_AUTHORIZE_ENDPOINT!: string;
public IDNOT_CLIENT_ID!: string; public IDNOT_CLIENT_ID!: string;

View File

@ -1,6 +1,5 @@
"use client"; "use client";
import User from "@Front/Api/Auth/IdNot/User";
import Customer from "@Front/Api/Auth/franceConnect/Customer"; import Customer from "@Front/Api/Auth/franceConnect/Customer";
import CookieService from "@Front/Services/CookieService/CookieService"; import CookieService from "@Front/Services/CookieService/CookieService";
import EventEmitter from "@Front/Services/EventEmitter"; import EventEmitter from "@Front/Services/EventEmitter";
@ -23,14 +22,11 @@ export default class UserStore {
return decodedPayload?.role; return decodedPayload?.role;
} }
public async connect(idnotUid: string) { public async connect(accessToken: string, refreshToken: string) {
try { try {
//call connection function
const user: any = await User.getInstance().login(idnotUid);
//Save tokens in cookies //Save tokens in cookies
CookieService.getInstance().setCookie("leCoffreAccessToken", user.accessToken); CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken);
CookieService.getInstance().setCookie("leCoffreRefreshToken", user.refreshToken); CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
this.event.emit("connection", this.accessToken); this.event.emit("connection", this.accessToken);
} catch (error) { } catch (error) {

View File

@ -17,6 +17,7 @@ type AppPropsWithLayout = AppProps & {
backApiRootUrl: string; backApiRootUrl: string;
backApiVersion: string; backApiVersion: string;
frontAppHost: string; frontAppHost: string;
idNotBaseUrl: string;
idNotAuthorizeEndpoint: string; idNotAuthorizeEndpoint: string;
idNotClientId: string; idNotClientId: string;
fcAuthorizeEndpoint: string; fcAuthorizeEndpoint: string;
@ -31,6 +32,7 @@ const MyApp = (({
backApiRootUrl, backApiRootUrl,
backApiVersion, backApiVersion,
frontAppHost, frontAppHost,
idNotBaseUrl,
idNotAuthorizeEndpoint, idNotAuthorizeEndpoint,
idNotClientId, idNotClientId,
fcAuthorizeEndpoint, fcAuthorizeEndpoint,
@ -44,7 +46,8 @@ const MyApp = (({
instance.BACK_API_ROOT_URL = backApiRootUrl ?? "/api"; instance.BACK_API_ROOT_URL = backApiRootUrl ?? "/api";
instance.BACK_API_VERSION = backApiVersion ?? "/v1"; instance.BACK_API_VERSION = backApiVersion ?? "/v1";
instance.FRONT_APP_HOST = frontAppHost ?? "app.stg.lecoffre.smart-chain.fr"; instance.FRONT_APP_HOST = frontAppHost ?? "app.stg.lecoffre.smart-chain.fr";
instance.IDNOT_AUTHORIZE_ENDPOINT = idNotAuthorizeEndpoint ?? "https://qual-connexion.idnot.fr/IdPOAuth2/authorize/idnot_idp_v1"; instance.IDNOT_BASE_URL = idNotBaseUrl ?? "https://qual-connexion.idnot.fr";
instance.IDNOT_AUTHORIZE_ENDPOINT = idNotAuthorizeEndpoint ?? "/IdPOAuth2/authorize/idnot_idp_v1";
instance.IDNOT_CLIENT_ID = idNotClientId ?? "4501646203F3EF67"; instance.IDNOT_CLIENT_ID = idNotClientId ?? "4501646203F3EF67";
instance.FC_AUTHORIZE_ENDPOINT= fcAuthorizeEndpoint ?? "https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize"; instance.FC_AUTHORIZE_ENDPOINT= fcAuthorizeEndpoint ?? "https://fcp.integ01.dev-franceconnect.fr/api/v1/authorize";
instance.FC_CLIENT_ID = fcClientId ?? "211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6e"; instance.FC_CLIENT_ID = fcClientId ?? "211286433e39cce01db448d80181bdfd005554b19cd51b3fe7943f6b3b86ab6e";
@ -60,6 +63,7 @@ MyApp.getInitialProps = async () => {
backApiVersion: process.env["NEXT_PUBLIC_BACK_API_VERSION"], backApiVersion: process.env["NEXT_PUBLIC_BACK_API_VERSION"],
frontAppHost: process.env["NEXT_PUBLIC_FRONT_APP_HOST"], frontAppHost: process.env["NEXT_PUBLIC_FRONT_APP_HOST"],
frontAppPort: process.env["NEXT_PUBLIC_FRONT_APP_PORT"], frontAppPort: process.env["NEXT_PUBLIC_FRONT_APP_PORT"],
idNotBaseUrl: process.env["NEXT_PUBLIC_IDNOT_BASE_URL"],
idNotAuthorizeEndpoint: process.env["NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT"], idNotAuthorizeEndpoint: process.env["NEXT_PUBLIC_IDNOT_AUTHORIZE_ENDPOINT"],
idNotClientId: process.env["NEXT_PUBLIC_IDNOT_CLIENT_ID"], idNotClientId: process.env["NEXT_PUBLIC_IDNOT_CLIENT_ID"],
fcAuthorizeEndpoint: process.env["NEXT_PUBLIC_FC_AUTHORIZE_ENDPOINT"], fcAuthorizeEndpoint: process.env["NEXT_PUBLIC_FC_AUTHORIZE_ENDPOINT"],