ajanin #5

Merged
ajanin merged 2 commits from ajanin into cicd 2025-07-09 18:36:28 +00:00
12 changed files with 594 additions and 136 deletions
Showing only changes of commit c8f6d625f8 - Show all commits

View File

@ -0,0 +1,152 @@
import { v4 as uuidv4 } from 'uuid';
import User from 'src/sdk/User';
import AbstractService from './AbstractService';
export default class CollaboratorService extends AbstractService {
private constructor() {
super();
}
public static createCollaborator(collaboratorData: any, validatorId: string): Promise<any> {
const ownerId = User.getInstance().getPairingId()!;
const processData: any = {
uid: uuidv4(),
utype: 'collaborator',
isDeleted: 'false',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
...collaboratorData,
};
const privateFields: string[] = Object.keys(processData);
privateFields.splice(privateFields.indexOf('uid'), 1);
privateFields.splice(privateFields.indexOf('utype'), 1);
privateFields.splice(privateFields.indexOf('isDeleted'), 1);
const roles: any = {
demiurge: {
members: [...[ownerId], validatorId],
validation_rules: [],
storages: []
},
owner: {
members: [ownerId],
validation_rules: [
{
quorum: 0.5,
fields: [...privateFields, 'roles', 'uid', 'utype'],
min_sig_member: 1,
},
],
storages: []
},
validator: {
members: [validatorId],
validation_rules: [
{
quorum: 0.5,
fields: ['idCertified', 'roles'],
min_sig_member: 1,
},
{
quorum: 0.0,
fields: [...privateFields],
min_sig_member: 0,
},
],
storages: []
},
apophis: {
members: [ownerId],
validation_rules: [],
storages: []
}
};
return new Promise<any>((resolve: (processCreated: any) => void, reject: (error: string) => void) => {
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
this.getCollaboratorByUid(processCreated.processData.uid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
public static getCollaborators(): Promise<any[]> {
// Check if we have valid cache
const items: any[] = this.getItems('_collaborators_');
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['utype'] &&
publicValues['utype'] === 'collaborator' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false' &&
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
).then((processes: any[]) => {
if (processes.length === 0) {
return items;
} else {
for (const process of processes) {
// Update cache
this.setItem('_collaborators_', process);
items.push(process);
}
return items;
}
});
}
public static getCollaboratorByUid(uid: string): Promise<any> {
// Check if we have valid cache
const item: any = this.getItem('_collaborators_', uid);
if (item) {
return Promise.resolve(item);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['uid'] === uid &&
publicValues['utype'] &&
publicValues['utype'] === 'collaborator' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then((processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
const process: any = processes[0];
// Update cache
this.setItem('_collaborators_', process);
resolve(process);
}
}).catch(reject);
});
}
public static updateCollaborator(process: any, newData: any): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => {
const newStateId: string = processUpdated.diffs[0]?.state_id;
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
const collaboratorUid: string = process.processData.uid;
this.removeItem('_collaborators_', collaboratorUid);
this.getCollaboratorByUid(collaboratorUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
}

View File

@ -0,0 +1,152 @@
import { v4 as uuidv4 } from 'uuid';
import User from 'src/sdk/User';
import AbstractService from './AbstractService';
export default class OfficeService extends AbstractService {
private constructor() {
super();
}
public static createOffice(officeData: any, validatorId: string): Promise<any> {
const ownerId = User.getInstance().getPairingId()!;
const processData: any = {
uid: uuidv4(),
utype: 'office',
isDeleted: 'false',
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
...officeData,
};
const privateFields: string[] = Object.keys(processData);
privateFields.splice(privateFields.indexOf('uid'), 1);
privateFields.splice(privateFields.indexOf('utype'), 1);
privateFields.splice(privateFields.indexOf('isDeleted'), 1);
const roles: any = {
demiurge: {
members: [...[ownerId], validatorId],
validation_rules: [],
storages: []
},
owner: {
members: [ownerId],
validation_rules: [
{
quorum: 0.5,
fields: [...privateFields, 'roles', 'uid', 'utype'],
min_sig_member: 1,
},
],
storages: []
},
validator: {
members: [validatorId],
validation_rules: [
{
quorum: 0.5,
fields: ['idCertified', 'roles'],
min_sig_member: 1,
},
{
quorum: 0.0,
fields: [...privateFields],
min_sig_member: 0,
},
],
storages: []
},
apophis: {
members: [ownerId],
validation_rules: [],
storages: []
}
};
return new Promise<any>((resolve: (processCreated: any) => void, reject: (error: string) => void) => {
this.messageBus.createProcess(processData, privateFields, roles).then((processCreated: any) => {
this.messageBus.notifyUpdate(processCreated.processId, processCreated.process.states[0].state_id).then(() => {
this.messageBus.validateState(processCreated.processId, processCreated.process.states[0].state_id).then((_stateValidated: any) => {
this.getOfficeByUid(processCreated.processData.uid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
public static getOffices(): Promise<any[]> {
// Check if we have valid cache
const items: any[] = this.getItems('_offices_');
return this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['utype'] &&
publicValues['utype'] === 'office' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false' &&
!items.map((item: any) => item.processData.uid).includes(publicValues['uid'])
).then((processes: any[]) => {
if (processes.length === 0) {
return items;
} else {
for (const process of processes) {
// Update cache
this.setItem('_offices_', process);
items.push(process);
}
return items;
}
});
}
public static getOfficeByUid(uid: string): Promise<any> {
// Check if we have valid cache
const item: any = this.getItem('_offices_', uid);
if (item) {
return Promise.resolve(item);
}
return new Promise<any>((resolve: (process: any) => void, reject: (error: string) => void) => {
this.messageBus.getProcessesDecoded((publicValues: any) =>
publicValues['uid'] &&
publicValues['uid'] === uid &&
publicValues['utype'] &&
publicValues['utype'] === 'office' &&
publicValues['isDeleted'] &&
publicValues['isDeleted'] === 'false'
).then((processes: any[]) => {
if (processes.length === 0) {
resolve(null);
} else {
const process: any = processes[0];
// Update cache
this.setItem('_offices_', process);
resolve(process);
}
}).catch(reject);
});
}
public static updateDocument(process: any, newData: any): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (error: string) => void) => {
this.messageBus.updateProcess(process.processId, { updated_at: new Date().toISOString(), ...newData }, [], null).then((processUpdated: any) => {
const newStateId: string = processUpdated.diffs[0]?.state_id;
this.messageBus.notifyUpdate(process.processId, newStateId).then(() => {
this.messageBus.validateState(process.processId, newStateId).then((_stateValidated) => {
const officeUid: string = process.processData.uid;
this.removeItem('_offices_', officeUid);
this.getOfficeByUid(officeUid).then(resolve).catch(reject);
}).catch(reject);
}).catch(reject);
}).catch(reject);
});
}
}

View File

@ -40,7 +40,7 @@ export default class Auth extends BaseApiService {
} }
} }
public async getIdnotJwt(autorizationCode: string | string[]): Promise<{ accessToken: string; refreshToken: string }> { public async getIdNotUser(autorizationCode: string | string[]): Promise<{ idNotUser: any }> {
// const variables = FrontendVariables.getInstance(); // const variables = FrontendVariables.getInstance();
// TODO: review // TODO: review
@ -48,7 +48,7 @@ export default class Auth extends BaseApiService {
const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`); const url = new URL(`${baseBackUrl}/api/v1/idnot/user/${autorizationCode}`);
try { try {
return await this.postRequest<{ accessToken: string; refreshToken: string }>(url); return await this.postRequest<{ idNotUser: any }>(url);
} catch (err) { } catch (err) {
this.onError(err); this.onError(err);
return Promise.reject(err); return Promise.reject(err);

View File

@ -2,11 +2,12 @@ import React, { useEffect } from "react";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
import Module from "@Front/Config/Module"; import Module from "@Front/Config/Module";
import UserStore from "@Front/Stores/UserStore";
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block"; import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList"; import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
import User from "le-coffre-resources/dist/Notary"; import User from "le-coffre-resources/dist/Notary";
// import JwtService from "@Front/Services/JwtService/JwtService";
// import Users, { IGetUsersparams } from "@Front/Api/LeCoffreApi/Admin/Users/Users"; import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
type IProps = IPropsDashboardWithList; type IProps = IPropsDashboardWithList;
@ -33,7 +34,20 @@ export default function DefaultCollaboratorDashboard(props: IProps) {
.get(query) .get(query)
.then((users) => setCollaborators(users)); .then((users) => setCollaborators(users));
*/ */
setCollaborators([]);
const user: any = UserStore.instance.getUser();
const officeUid: string = user.office.uid;
CollaboratorService.getCollaborators().then((processes: any[]) => {
if (processes.length > 0) {
let collaborators: any[] = processes.map((process: any) => process.processData);
// FilterBy office.uid
collaborators = collaborators.filter((collaborator: any) => collaborator.office.uid === officeUid);
setCollaborators(collaborators);
}
});
}, []); }, []);
const onSelectedBlock = (block: IBlock) => { const onSelectedBlock = (block: IBlock) => {
@ -49,10 +63,10 @@ export default function DefaultCollaboratorDashboard(props: IProps) {
blocks={ blocks={
collaborators collaborators
? collaborators.map((collaborator) => ({ ? collaborators.map((collaborator) => ({
id: collaborator.uid!, id: collaborator.uid!,
primaryText: collaborator.contact?.first_name + " " + collaborator.contact?.last_name, primaryText: collaborator.contact?.first_name + " " + collaborator.contact?.last_name,
isActive: collaborator.uid === collaboratorUid, isActive: collaborator.uid === collaboratorUid,
})) }))
: [] : []
} }
/> />

View File

@ -4,8 +4,6 @@ import { useRouter } from "next/router";
import Module from "@Front/Config/Module"; import Module from "@Front/Config/Module";
import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block"; import { IBlock } from "@Front/Components/DesignSystem/SearchBlockList/BlockList/Block";
import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList"; import DefaultDashboardWithList, { IPropsDashboardWithList } from "../DefaultDashboardWithList";
import { OfficeRole } from "le-coffre-resources/dist/Notary";
// import OfficeRoles, { IGetRolesParams } from "@Front/Api/LeCoffreApi/Admin/OfficeRoles/OfficeRoles";
import { v4 as uuidv4 } from 'uuid'; import { v4 as uuidv4 } from 'uuid';
@ -14,7 +12,7 @@ import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
type IProps = IPropsDashboardWithList; type IProps = IPropsDashboardWithList;
export default function DefaultRoleDashboard(props: IProps) { export default function DefaultRoleDashboard(props: IProps) {
const [roles, setRoles] = React.useState<OfficeRole[] | null>(null); const [roles, setRoles] = React.useState<any[] | null>(null);
const router = useRouter(); const router = useRouter();
const { roleUid } = router.query; const { roleUid } = router.query;
useEffect(() => { useEffect(() => {
@ -112,12 +110,14 @@ export default function DefaultRoleDashboard(props: IProps) {
const roles: any[] = processes.map((process: any) => process.processData); const roles: any[] = processes.map((process: any) => process.processData);
setRoles(roles); setRoles(roles);
} else { } else {
/*
for (let role of roles) { for (let role of roles) {
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0'; const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
await RoleService.createRole(role, validatorId); await RoleService.createRole(role, validatorId);
} }
setRoles(roles); setRoles(roles);
*/
} }
}); });
}, []); }, []);
@ -134,7 +134,7 @@ export default function DefaultRoleDashboard(props: IProps) {
roles roles
? roles.map((role) => ({ ? roles.map((role) => ({
id: role.uid!, id: role.uid!,
primaryText: role.name, primaryText: role.label,
isActive: role.uid === roleUid, isActive: role.uid === roleUid,
})) }))
: [] : []

View File

@ -18,6 +18,9 @@ import { IOption } from "@Front/Components/DesignSystem/Dropdown/DropdownMenu/Dr
import { getLabel } from "@Front/Components/DesignSystem/Dropdown"; import { getLabel } from "@Front/Components/DesignSystem/Dropdown";
import SelectField from "@Front/Components/DesignSystem/Form/SelectField"; import SelectField from "@Front/Components/DesignSystem/Form/SelectField";
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
type IProps = {}; type IProps = {};
export default function CollaboratorInformations(props: IProps) { export default function CollaboratorInformations(props: IProps) {
const router = useRouter(); const router = useRouter();
@ -120,6 +123,30 @@ export default function CollaboratorInformations(props: IProps) {
useEffect(() => { useEffect(() => {
async function getUser() { async function getUser() {
if (!collaboratorUid) return; if (!collaboratorUid) return;
CollaboratorService.getCollaboratorByUid(collaboratorUid as string).then(async (process: any) => {
if (process) {
const collaborator: any = process.processData;
const roles: any[] = await new Promise<any[]>((resolve: (roles: any[]) => void) => {
RoleService.getRoles().then((processes: any[]) => {
if (processes.length > 0) {
const roles: any[] = processes.map((process: any) => process.processData);
resolve(roles);
}
});
});
setAvailableRoles(roles.map((role) => ({ id: role.uid ?? "", label: role.label })));
setUserSelected(collaborator);
setSelectedOption({
id: (collaborator?.office_role ? collaborator?.office_role?.uid : collaborator?.role?.uid) ?? "",
label: collaborator?.office_role ? collaborator?.office_role?.label : "Utilisateur restreint",
});
}
});
/*
const user = await Users.getInstance().getByUid(collaboratorUid as string, { const user = await Users.getInstance().getByUid(collaboratorUid as string, {
q: { q: {
contact: true, contact: true,
@ -142,6 +169,7 @@ export default function CollaboratorInformations(props: IProps) {
id: (user?.office_role ? user?.office_role?.uid : user?.role?.uid) ?? "", id: (user?.office_role ? user?.office_role?.uid : user?.role?.uid) ?? "",
label: user?.office_role ? user?.office_role?.name : "Utilisateur restreint", label: user?.office_role ? user?.office_role?.name : "Utilisateur restreint",
}); });
*/
} }
getUser(); getUser();

View File

@ -6,8 +6,6 @@ import Typography, { ETypo, ETypoColor } from "@Front/Components/DesignSystem/Ty
import HelpBox from "@Front/Components/Elements/HelpBox"; import HelpBox from "@Front/Components/Elements/HelpBox";
import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage";
import Module from "@Front/Config/Module"; import Module from "@Front/Config/Module";
import CookieService from "@Front/Services/CookieService/CookieService";
import JwtService from "@Front/Services/JwtService/JwtService";
import UserStore from "@Front/Stores/UserStore"; import UserStore from "@Front/Stores/UserStore";
import Image from "next/image"; import Image from "next/image";
import { useRouter } from "next/router"; import { useRouter } from "next/router";
@ -16,89 +14,213 @@ import classes from "./classes.module.scss";
import AuthModal from "src/sdk/AuthModal"; import AuthModal from "src/sdk/AuthModal";
import MessageBus from "src/sdk/MessageBus";
import Iframe from "src/sdk/Iframe";
import OfficeService from "src/common/Api/LeCoffreApi/sdk/OfficeService";
import RoleService from "src/common/Api/LeCoffreApi/sdk/RoleService";
import CollaboratorService from "src/common/Api/LeCoffreApi/sdk/CollaboratorService";
export default function LoginCallBack() { export default function LoginCallBack() {
const router = useRouter(); const router = useRouter();
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false); const [idNotUser, setIdNotUser] = useState<any>(null);
const [isAuthModalOpen, setIsAuthModalOpen] = useState(false);
const [isConnected, setIsConnected] = useState(false);
useEffect(() => { const getOffice = async (idNotUser: any) => {
async function getUser() { return await new Promise<any>((resolve: (office: any) => void) => {
// TODO: review OfficeService.getOffices().then((processes: any[]) => {
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client const officeFound: any = processes.length > 0 ? processes.map((process: any) => process.processData).find((office: any) => office.idNot === idNotUser.office.idNot) : null;
// Replace with http://localhost:3000/authorized-client if (officeFound) {
if (window.location.href.startsWith('http://local.lecoffreio.4nkweb:3000/authorized-client')) { resolve(officeFound);
window.location.href = window.location.href.replace('http://local.lecoffreio.4nkweb:3000/authorized-client', 'http://localhost:3000/authorized-client'); } else {
return; const officeData: any = {
} idNot: idNotUser.office.idNot,
name: idNotUser.office.name,
crpcen: idNotUser.office.crpcen,
address: {
create: {
address: idNotUser.office.address.address,
zip_code: idNotUser.office.address.zip_code,
city: idNotUser.office.address.city,
},
},
office_status: 'ACTIVATED'
};
const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
const code = router.query["code"]; OfficeService.createOffice(officeData, validatorId).then((process: any) => {
if (code) { if (process) {
try { const office: any = process.processData;
const token = await Auth.getInstance().getIdnotJwt(code as string); resolve(office);
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path); }
await UserStore.instance.connect(token.accessToken, token.refreshToken); });
const jwt = JwtService.getInstance().decodeJwt(); }
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1"); });
if (jwt.rules && !jwt.rules.includes("GET folders")) { });
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path); };
}
setIsAuthModalOpen(true);
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
return;
} catch (e: any) {
if (e.http_status === 401 && e.message === "Email not found") {
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3");
}
if (e.http_status === 409) {
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=4");
}
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
}
}
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken"); const getRole = async (idNotUser: any) => {
if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1"); return await new Promise<any>((resolve: (role: any) => void) => {
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken); RoleService.getRoles().then((processes: any[]) => {
const jwt = JwtService.getInstance().decodeJwt(); const roleFound: any = processes.length > 0 ? processes.map((process: any) => process.processData).find((role: any) => role.name === idNotUser.role.name) : null;
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1"); if (roleFound) {
if (!jwt.rules.includes("GET folders")) { resolve(roleFound);
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path); } else {
} const roleData: any = {
if (isTokenRefreshed) { name: idNotUser.role!.name,
setIsAuthModalOpen(true); label: idNotUser.role!.label
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path); };
return; const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
}
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=2");
}
getUser();
}),
[router];
return ( RoleService.createRole(roleData, validatorId).then((process: any) => {
<DefaultDoubleSidePage title={"Login"} image={backgroundImage}> if (process) {
<div className={classes["root"]}> const role: any = process.processData;
<div className={classes["title-container"]}> resolve(role);
<Image alt="coffre" src={CoffreIcon} width={56} /> }
<Typography typo={ETypo.TITLE_H1} color={ETypoColor.TEXT_ACCENT}> });
Connexion à votre espace professionnel }
</Typography> });
</div> });
};
<Loader color={"var(--secondary-default-base, #FF4617)"} width={29} /> const getCollaborator = async (collaboratorData: any) => {
<div /> return await new Promise<any>((resolve: (role: any) => void) => {
<HelpBox CollaboratorService.getCollaborators().then((processes: any[]) => {
title="Vous n'arrivez pas à vous connecter ?" const collaboratorFound: any = processes.length > 0 ? processes.map((process: any) => process.processData).find((collaborator: any) => collaborator.idNot === idNotUser.idNot) : null;
description="Notre équipe de support est là pour vous aider." if (collaboratorFound) {
button={{ text: "Contacter l'administrateur", link: "mailto:support@lecoffre.io" }} resolve(collaboratorFound);
/> } else {
{isAuthModalOpen && <AuthModal const validatorId: string = '884cb36a346a79af8697559f16940141f068bdf1656f88fa0df0e9ecd7311fb8:0';
isOpen={isAuthModalOpen}
onClose={() => { CollaboratorService.createCollaborator(collaboratorData, validatorId).then((process: any) => {
setIsAuthModalOpen(false); if (process) {
router.push(Module.getInstance().get().modules.pages.Folder.props.path); const collaborator: any = process.processData;
}} resolve(collaborator);
/>} }
</div> });
</DefaultDoubleSidePage> }
); });
});
};
useEffect(() => {
async function getUser() {
UserStore.instance.disconnect();
// TODO: review
// HACK: If start with http://local.lecoffreio.4nkweb:3000/authorized-client
// Replace with http://localhost:3000/authorized-client
if (window.location.href.startsWith('http://local.lecoffreio.4nkweb:3000/authorized-client')) {
window.location.href = window.location.href.replace('http://local.lecoffreio.4nkweb:3000/authorized-client', 'http://localhost:3000/authorized-client');
return;
}
const code = router.query["code"];
if (code) {
try {
const idNotUser: any = await Auth.getInstance().getIdNotUser(code as string);
setIdNotUser(idNotUser);
setIsAuthModalOpen(true);
/*
const token: any = null;
if (!token) return router.push(Module.getInstance().get().modules.pages.Login.props.path);
await UserStore.instance.connect(token.accessToken, token.refreshToken);
const jwt = JwtService.getInstance().decodeJwt();
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
if (jwt.rules && !jwt.rules.includes("GET folders")) {
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
}
setIsAuthModalOpen(true);
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
*/
return;
} catch (e: any) {
if (e.http_status === 401 && e.message === "Email not found") {
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=3");
}
if (e.http_status === 409) {
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=4");
}
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
}
}
/*
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
if (!refreshToken) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
const isTokenRefreshed = await JwtService.getInstance().refreshToken(refreshToken);
const jwt = JwtService.getInstance().decodeJwt();
if (!jwt) return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=1");
if (!jwt.rules.includes("GET folders")) {
return router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
}
if (isTokenRefreshed) {
//setIsAuthModalOpen(true);
//return router.push(Module.getInstance().get().modules.pages.Folder.props.path);
return;
}
*/
return router.push(Module.getInstance().get().modules.pages.Login.props.path + "?error=2");
}
getUser();
}, [router]);
return (
<DefaultDoubleSidePage title={"Login"} image={backgroundImage}>
<div className={classes["root"]}>
<div className={classes["title-container"]}>
<Image alt="coffre" src={CoffreIcon} width={56} />
<Typography typo={ETypo.TITLE_H1} color={ETypoColor.TEXT_ACCENT}>
Connexion à votre espace professionnel
</Typography>
</div>
<Loader color={"var(--secondary-default-base, #FF4617)"} width={29} />
<div />
<HelpBox
title="Vous n'arrivez pas à vous connecter ?"
description="Notre équipe de support est là pour vous aider."
button={{ text: "Contacter l'administrateur", link: "mailto:support@lecoffre.io" }}
/>
{isAuthModalOpen && <AuthModal
isOpen={isAuthModalOpen}
onClose={() => {
setIsAuthModalOpen(false);
setIsConnected(true);
setTimeout(() => {
MessageBus.getInstance().initMessageListener();
MessageBus.getInstance().isReady().then(async () => {
const office: any = await getOffice(idNotUser);
const role: any = await getRole(idNotUser);
const collaboratorData: any = {
idNot: idNotUser.idNot,
contact: idNotUser.contact,
office: {
uid: office.uid
},
role: {
uid: role.uid
}
};
const collaborator: any = await getCollaborator(collaboratorData);
collaborator.office = office;
collaborator.role = role;
UserStore.instance.connect(collaborator);
MessageBus.getInstance().destroyMessageListener();
/*
if (jwt.rules && !jwt.rules.includes("GET folders")) {
router.push(Module.getInstance().get().modules.pages.Subscription.pages.New.props.path);
}
*/
router.push(Module.getInstance().get().modules.pages.Folder.props.path);
});
}, 100);
}}
/>}
{isConnected && <Iframe />}
</div>
</DefaultDoubleSidePage>
);
} }

View File

@ -24,7 +24,7 @@ export default function RolesInformations() {
const router = useRouter(); const router = useRouter();
let { roleUid } = router.query; let { roleUid } = router.query;
const [roleSelected, setRoleSelected] = useState<OfficeRole | null>(null); const [roleSelected, setRoleSelected] = useState<any | null>(null);
const [rulesGroupsCheckboxes, setRulesGroupsCheckboxes] = useState<RuleGroupsCheckbox[]>([]); const [rulesGroupsCheckboxes, setRulesGroupsCheckboxes] = useState<RuleGroupsCheckbox[]>([]);
const [selectAll, setSelectAll] = useState<boolean>(false); const [selectAll, setSelectAll] = useState<boolean>(false);
@ -169,7 +169,7 @@ export default function RolesInformations() {
<Typography typo={ETypo.TITLE_H1}>Gestion des rôles</Typography> <Typography typo={ETypo.TITLE_H1}>Gestion des rôles</Typography>
</div> </div>
<div className={classes["subtitle"]}> <div className={classes["subtitle"]}>
<Typography typo={ETypo.TITLE_H5}>{roleSelected?.name}</Typography> <Typography typo={ETypo.TITLE_H5}>{roleSelected?.label}</Typography>
</div> </div>
<div className={classes["rights-container"]}> <div className={classes["rights-container"]}>
<div className={classes["rights-header"]}> <div className={classes["rights-header"]}>

View File

@ -29,7 +29,7 @@ export interface ICustomerJwtPayload {
export default class JwtService { export default class JwtService {
private static instance: JwtService; private static instance: JwtService;
private constructor() {} private constructor() { }
public static getInstance() { public static getInstance() {
return (this.instance ??= new this()); return (this.instance ??= new this());
@ -38,25 +38,25 @@ export default class JwtService {
public getUserJwtPayload(): IUserJwtPayload | undefined { public getUserJwtPayload(): IUserJwtPayload | undefined {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return; if (!accessToken) return;
return jwt_decode(accessToken); return undefined; //jwt_decode(accessToken);
} }
public getCustomerJwtPayload(): ICustomerJwtPayload | undefined { public getCustomerJwtPayload(): ICustomerJwtPayload | undefined {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return; if (!accessToken) return;
return jwt_decode(accessToken); return undefined; //jwt_decode(accessToken);
} }
public decodeJwt(): IUserJwtPayload | undefined { public decodeJwt(): IUserJwtPayload | undefined {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return; if (!accessToken) return;
return jwt_decode(accessToken); return undefined; //jwt_decode(accessToken);
} }
public decodeCustomerJwt(): ICustomerJwtPayload | undefined { public decodeCustomerJwt(): ICustomerJwtPayload | undefined {
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken"); const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
if (!accessToken) return; if (!accessToken) return;
return jwt_decode(accessToken); return undefined; //jwt_decode(accessToken);
} }
/** /**
@ -74,8 +74,7 @@ export default class JwtService {
const headers = new Headers(); const headers = new Headers();
headers.append("Authorization", `Bearer ${refreshToken}`); headers.append("Authorization", `Bearer ${refreshToken}`);
const response = await fetch( const response = await fetch(
`${ `${variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/idnot/user/auth/refresh-token`, }/idnot/user/auth/refresh-token`,
{ method: "POST", headers: headers }, { method: "POST", headers: headers },
); );
@ -93,8 +92,7 @@ export default class JwtService {
const headers = new Headers(); const headers = new Headers();
headers.append("Authorization", `Bearer ${refreshToken}`); headers.append("Authorization", `Bearer ${refreshToken}`);
const response = await fetch( const response = await fetch(
`${ `${variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/id360/customers/refresh-token`, }/id360/customers/refresh-token`,
{ method: "POST", headers: headers }, { method: "POST", headers: headers },
); );
@ -122,8 +120,7 @@ export default class JwtService {
const headers = new Headers(); const headers = new Headers();
headers.append("Authorization", `Bearer ${refreshToken}`); headers.append("Authorization", `Bearer ${refreshToken}`);
const response = await fetch( const response = await fetch(
`${ `${variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/idnot/user/auth/refresh-token`, }/idnot/user/auth/refresh-token`,
{ method: "POST", headers: headers }, { method: "POST", headers: headers },
); );
@ -141,8 +138,7 @@ export default class JwtService {
const headers = new Headers(); const headers = new Headers();
headers.append("Authorization", `Bearer ${refreshToken}`); headers.append("Authorization", `Bearer ${refreshToken}`);
const response = await fetch( const response = await fetch(
`${ `${variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
variables.BACK_API_PROTOCOL + variables.BACK_API_HOST + variables.BACK_API_ROOT_URL + variables.BACK_API_VERSION
}/id360/customers/refresh-token`, }/id360/customers/refresh-token`,
{ method: "POST", headers: headers }, { method: "POST", headers: headers },
); );

View File

@ -2,7 +2,6 @@
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";
import JwtService from "@Front/Services/JwtService/JwtService";
import User from "src/sdk/User"; import User from "src/sdk/User";
@ -10,23 +9,16 @@ export default class UserStore {
public static readonly instance = new this(); public static readonly instance = new this();
protected readonly event = new EventEmitter(); protected readonly event = new EventEmitter();
private constructor() {} private constructor() { }
public isConnected(): boolean { public isConnected(): boolean {
return !!CookieService.getInstance().getCookie("leCoffreAccessToken"); return !!CookieService.getInstance().getCookie("leCoffreAccessToken");
} }
public getRole(): string | undefined { public async connect(user: any) {
const decodedPayload = JwtService.getInstance().decodeJwt();
return decodedPayload?.role;
}
public async connect(accessToken: string, refreshToken: string) {
try { try {
//Save tokens in cookies //Save tokens in cookies
CookieService.getInstance().setCookie("leCoffreAccessToken", accessToken); CookieService.getInstance().setCookie("leCoffreAccessToken", JSON.stringify(user));
CookieService.getInstance().setCookie("leCoffreRefreshToken", refreshToken);
this.event.emit("connection", CookieService.getInstance().getCookie("leCoffreAccessToken")); this.event.emit("connection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@ -37,12 +29,10 @@ export default class UserStore {
public async disconnect() { public async disconnect() {
try { try {
//Remove tokens from cookies
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
CookieService.getInstance().deleteCookie("leCoffreRefreshToken");
User.getInstance().clear(); User.getInstance().clear();
//Remove tokens from cookies
CookieService.getInstance().deleteCookie("leCoffreAccessToken");
this.event.emit("disconnection", CookieService.getInstance().getCookie("leCoffreAccessToken")); this.event.emit("disconnection", CookieService.getInstance().getCookie("leCoffreAccessToken"));
} catch (error) { } catch (error) {
console.error(error); console.error(error);
@ -59,11 +49,7 @@ export default class UserStore {
return () => this.event.off("connection", callback); return () => this.event.off("connection", callback);
} }
public getAccessToken(): string { public getUser(): any {
return CookieService.getInstance().getCookie("leCoffreAccessToken") || ""; return JSON.parse(CookieService.getInstance().getCookie("leCoffreAccessToken") || "");
}
public getRefreshToken(): string {
return CookieService.getInstance().getCookie("leCoffreRefreshToken") || "";
} }
} }

View File

@ -8,6 +8,7 @@ export async function middleware(request: NextRequest) {
const cookies = request.cookies.get("leCoffreAccessToken"); const cookies = request.cookies.get("leCoffreAccessToken");
if (!cookies) return NextResponse.redirect(new URL("/", request.url)); if (!cookies) return NextResponse.redirect(new URL("/", request.url));
/*
// Decode it // 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;
@ -23,6 +24,7 @@ export async function middleware(request: NextRequest) {
if (customerDecodedToken.customerId && customerDecodedToken.exp < now) { if (customerDecodedToken.customerId && customerDecodedToken.exp < now) {
return NextResponse.redirect(new URL("/id360/customer-callback", request.url)); return NextResponse.redirect(new URL("/id360/customer-callback", request.url));
} }
*/
return NextResponse.next(); return NextResponse.next();
} }

View File

@ -1,3 +1,5 @@
import { v4 as uuidv4 } from 'uuid';
import React, { useState, useEffect, useRef } from 'react'; import React, { useState, useEffect, useRef } from 'react';
import Modal from '@Front/Components/DesignSystem/Modal'; import Modal from '@Front/Components/DesignSystem/Modal';
import Loader from '@Front/Components/DesignSystem/Loader'; import Loader from '@Front/Components/DesignSystem/Loader';
@ -54,19 +56,22 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
console.log('[AuthModal] handleMessage:', message); console.log('[AuthModal] handleMessage:', message);
switch (message.type) { switch (message.type) {
case 'LISTENING': case 'LISTENING': {
iframeRef.current.contentWindow!.postMessage({ type: 'REQUEST_LINK' }, targetOrigin); const messageId = `REQUEST_LINK_${uuidv4()}`;
iframeRef.current.contentWindow!.postMessage({ type: 'REQUEST_LINK', messageId }, targetOrigin);
setIsIframeReady(true); setIsIframeReady(true);
break; break;
}
case 'LINK_ACCEPTED': case 'LINK_ACCEPTED': {
setShowIframe(false); setShowIframe(false);
User.getInstance().setTokens(message.accessToken, message.refreshToken); User.getInstance().setTokens(message.accessToken, message.refreshToken);
iframeRef.current.contentWindow!.postMessage({ type: 'GET_PAIRING_ID', accessToken: message.accessToken }, targetOrigin); const messageId = `GET_PAIRING_ID_${uuidv4()}`;
iframeRef.current.contentWindow!.postMessage({ type: 'GET_PAIRING_ID', accessToken: message.accessToken, messageId }, targetOrigin);
break; break;
}
case 'GET_PAIRING_ID': case 'GET_PAIRING_ID': {
User.getInstance().setPairingId(message.userPairingId); User.getInstance().setPairingId(message.userPairingId);
setAuthSuccess(true); setAuthSuccess(true);
@ -77,6 +82,7 @@ export default function AuthModal({ isOpen, onClose }: AuthModalProps) {
onClose(); onClose();
}, 500); }, 500);
break; break;
}
} }
}; };
window.addEventListener('message', handleMessage); window.addEventListener('message', handleMessage);