V1_Sans_Congé_Anticipéfemini collaboratrice

This commit is contained in:
2025-08-29 15:30:31 +02:00
parent 34a369dccd
commit 0eb4dbb99b
41 changed files with 30347 additions and 2733 deletions

View File

@@ -6,9 +6,7 @@ const AuthContext = createContext();
export const useAuth = () => {
const context = useContext(AuthContext);
if (!context) {
throw new Error('useAuth must be used within an AuthProvider');
}
if (!context) throw new Error('useAuth must be used within an AuthProvider');
return context;
};
@@ -16,25 +14,17 @@ const msalInstance = new msal.PublicClientApplication(msalConfig);
export const AuthProvider = ({ children }) => {
const [user, setUser] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [userGroups, setUserGroups] = useState([]);
const [isAuthorized, setIsAuthorized] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [isMsalInitialized, setIsMsalInitialized] = useState(false);
// Fonction pour obtenir l'URL de l'API backend
const getApiUrl = (endpoint) => {
const possibleUrls = [
'http://localhost/GTA/project/public/php/',
'http://localhost:80/GTA/project/public/php/',
'http://localhost/GTA/public/php/',
'http://localhost/public/php/'
];
return possibleUrls[0] + endpoint; // Utilisez votre URL préférée
};
const getApiUrl = (endpoint) => `http://localhost:3000/${endpoint}`;
// Vérifier les groupes utilisateur via l'API backend
// --- Vérifie l'autorisation de l'utilisateur via groupes
const checkUserAuthorization = async (userPrincipalName, accessToken) => {
try {
const response = await fetch(getApiUrl('check-user-groups.php'), {
const response = await fetch(getApiUrl('check-user-groups'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
@@ -56,30 +46,22 @@ export const AuthProvider = ({ children }) => {
}
};
// Synchroniser l'utilisateur avec la base locale
// --- Synchronisation utilisateur connecté
const syncUserToDatabase = async (entraUser, accessToken) => {
try {
const response = await fetch(getApiUrl('check-user-groups.php'), {
const response = await fetch(getApiUrl('initial-sync'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${accessToken}`
},
body: JSON.stringify({
entraUserId: entraUser.id,
userPrincipalName: entraUser.userPrincipalName,
email: entraUser.mail || entraUser.userPrincipalName,
displayName: entraUser.displayName,
givenName: entraUser.givenName,
surname: entraUser.surname,
jobTitle: entraUser.jobTitle,
department: entraUser.department,
officeLocation: entraUser.officeLocation
})
body: JSON.stringify(entraUser)
});
if (response.ok) {
return await response.json();
const data = await response.json();
console.log('Utilisateur synchronisé:', entraUser.userPrincipalName);
return data;
}
} catch (error) {
console.error('Erreur synchronisation utilisateur:', error);
@@ -87,22 +69,52 @@ export const AuthProvider = ({ children }) => {
return null;
};
// Initialisation MSAL
// --- Full sync admin
const fullSyncDatabase = async (accessToken) => {
try {
const response = await fetch(getApiUrl('initial-sync'), {
method: 'POST',
headers: { 'Authorization': `Bearer ${accessToken}` }
});
if (response.ok) {
const data = await response.json();
console.log('Full sync terminée:', data);
return data;
}
} catch (error) {
console.error('Erreur full sync:', error);
}
return null;
};
// --- S'assurer que MSAL est initialisé avant tout appel
const ensureMsalInitialized = async () => {
if (!isMsalInitialized) {
try {
await msalInstance.initialize();
setIsMsalInitialized(true);
console.log('MSAL initialisé');
} catch (error) {
console.error('Erreur initialisation MSAL:', error);
throw error;
}
}
};
// --- Initialisation au chargement
useEffect(() => {
const initializeMsal = async () => {
try {
await msalInstance.initialize();
await ensureMsalInitialized();
// Vérifier si il y a un utilisateur connecté
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
// Essayer de récupérer un token silencieusement
try {
const response = await msalInstance.acquireTokenSilent({
...loginRequest,
account: accounts[0]
});
await handleSuccessfulAuth(response);
} catch (error) {
console.log('Token silent acquisition failed:', error);
@@ -118,18 +130,12 @@ export const AuthProvider = ({ children }) => {
initializeMsal();
}, []);
// Gérer l'authentification réussie
// Gérer l'authentification réussie
// --- Gestion login réussi
const handleSuccessfulAuth = async (authResponse) => {
try {
const account = authResponse.account;
const accessToken = authResponse.accessToken;
// 🔹 Récupérer profil Microsoft Graph
const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
let entraUser = {
id: account.homeAccountId,
displayName: account.name,
@@ -137,35 +143,31 @@ export const AuthProvider = ({ children }) => {
mail: account.username
};
const graphResponse = await fetch('https://graph.microsoft.com/v1.0/me', {
headers: { 'Authorization': `Bearer ${accessToken}` }
});
if (graphResponse.ok) {
const graphData = await graphResponse.json();
entraUser = { ...entraUser, ...graphData };
}
// 🔹 Synchroniser lutilisateur dans la DB
// 1 Synchroniser lutilisateur connecté
const syncResult = await syncUserToDatabase(entraUser, accessToken);
console.log("Résultat syncUserToDatabase:", syncResult);
// 🚀 Si admin → lancer full-sync.php
if (syncResult?.role === "Admin") {
try {
const syncResp = await fetch(getApiUrl('full-sync.php'), {
method: "POST",
headers: { "Authorization": `Bearer ${accessToken}` }
});
const syncData = await syncResp.json();
console.log("Résultat Full Sync:", syncData);
} catch (err) {
console.error("Erreur synchronisation groupes:", err);
}
// 2⃣ Full sync si admin
if (syncResult?.role === 'Admin') {
console.log('Admin détecté → lancement full sync...');
await fullSyncDatabase(accessToken);
}
// 🔹 Vérifier autorisation via groupes DB
// 3 Vérifier groupes
const authResult = await checkUserAuthorization(entraUser.userPrincipalName, accessToken);
if (authResult.authorized) {
const userData = {
setUser({
id: syncResult?.localUserId || entraUser.id,
CollaborateurADId: syncResult?.localUserId, // ⭐ AJOUT
entraUserId: entraUser.id,
name: entraUser.displayName,
prenom: entraUser.givenName || entraUser.displayName?.split(' ')[0] || '',
@@ -173,22 +175,15 @@ export const AuthProvider = ({ children }) => {
email: entraUser.mail || entraUser.userPrincipalName,
userPrincipalName: entraUser.userPrincipalName,
role: syncResult?.role || 'Employe',
// ✅ Correction ici
service: syncResult?.service
|| syncResult?.user?.service
|| entraUser.department
|| 'Non défini',
service: syncResult?.service || entraUser.department || 'Non défini',
jobTitle: entraUser.jobTitle,
department: entraUser.department,
officeLocation: entraUser.officeLocation,
typeContrat: syncResult?.typeContrat || '37h', // ⭐ AJOUT
dateEntree: syncResult?.dateEntree || null, // ⭐ AJOUT
groups: authResult.groups
};
setUser(userData);
});
setIsAuthorized(true);
return true;
} else {
throw new Error('Utilisateur non autorisé - pas membre des groupes requis');
}
@@ -198,32 +193,20 @@ export const AuthProvider = ({ children }) => {
}
};
// Connexion classique (email/mot de passe)
// --- Connexion classique
const login = async (email, password) => {
try {
const response = await fetch(getApiUrl('login.php'), {
const response = await fetch(getApiUrl('login'), {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, mot_de_passe: password }),
body: JSON.stringify({ email, mot_de_passe: password })
});
if (!response.ok) {
throw new Error('Erreur de connexion');
}
const text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch {
console.error("Réponse non-JSON:", text.substring(0, 200));
throw new Error("Le serveur PHP ne répond pas correctement.");
}
if (!response.ok) throw new Error('Erreur de connexion');
const data = await response.json();
if (data.success) {
const userData = {
setUser({
id: data.user.id,
name: `${data.user.prenom} ${data.user.nom}`,
prenom: data.user.prenom,
@@ -231,9 +214,7 @@ export const AuthProvider = ({ children }) => {
email: data.user.email,
role: data.user.role || 'Employe',
service: data.user.service || 'Non défini'
};
setUser(userData);
});
setIsAuthorized(true);
return true;
}
@@ -244,9 +225,10 @@ export const AuthProvider = ({ children }) => {
}
};
// Connexion Office 365
// --- Connexion Office 365
const loginWithO365 = async () => {
try {
await ensureMsalInitialized();
const authResponse = await msalInstance.loginPopup(loginRequest);
await handleSuccessfulAuth(authResponse);
return true;
@@ -259,14 +241,12 @@ export const AuthProvider = ({ children }) => {
}
};
// Déconnexion
// --- Déconnexion
const logout = async () => {
try {
const accounts = msalInstance.getAllAccounts();
if (accounts.length > 0) {
await msalInstance.logoutPopup({
account: accounts[0]
});
await msalInstance.logoutPopup({ account: accounts[0] });
}
} catch (error) {
console.error('Erreur lors de la déconnexion:', error);
@@ -277,13 +257,12 @@ export const AuthProvider = ({ children }) => {
}
};
// Obtenir un token pour l'API
// --- Obtenir token API
const getAccessToken = async () => {
try {
await ensureMsalInitialized();
const accounts = msalInstance.getAllAccounts();
if (accounts.length === 0) {
throw new Error('Aucun compte connecté');
}
if (accounts.length === 0) throw new Error('Aucun compte connecté');
const response = await msalInstance.acquireTokenSilent({
...loginRequest,
@@ -308,11 +287,7 @@ export const AuthProvider = ({ children }) => {
getAccessToken
};
return (
<AuthContext.Provider value={value}>
{children}
</AuthContext.Provider>
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};
export default AuthContext;
export default AuthContext;