113 lines
3.1 KiB
JavaScript
113 lines
3.1 KiB
JavaScript
// filepath: c:\Users\amaizy\Desktop\cvgen\controllers\linkedin.js
|
|
|
|
const axios = require("axios");
|
|
const querystring = require("querystring");
|
|
|
|
const clientId = "780w7gsy8eysmj";
|
|
const clientSecret = "WPL_AP1.w6OTTkAndAdT3PYF.UZEcwQ==";
|
|
const redirectUri = "http://localhost:4200/api/auth/linkedin/callback";
|
|
const scope = "openid profile email";
|
|
|
|
let accessToken = "";
|
|
|
|
const authenticateUser = (req, res) => {
|
|
const authUrl = `https://www.linkedin.com/oauth/v2/authorization?${querystring.stringify(
|
|
{
|
|
response_type: "code",
|
|
client_id: clientId,
|
|
redirect_uri: redirectUri,
|
|
scope: scope,
|
|
}
|
|
)}`;
|
|
res.redirect(authUrl);
|
|
};
|
|
|
|
const handleCallback = async (req, res) => {
|
|
const { code } = req.query;
|
|
|
|
try {
|
|
const tokenResponse = await axios.post(
|
|
"https://www.linkedin.com/oauth/v2/accessToken",
|
|
querystring.stringify({
|
|
grant_type: "authorization_code",
|
|
code: code,
|
|
redirect_uri: redirectUri,
|
|
client_id: clientId,
|
|
client_secret: clientSecret,
|
|
})
|
|
);
|
|
|
|
const accessToken = tokenResponse.data.access_token;
|
|
|
|
// Stocke dans la session
|
|
req.session.user = {
|
|
accessToken,
|
|
};
|
|
|
|
res.send("Authentication successful! User session created.");
|
|
} catch (error) {
|
|
console.error(
|
|
"LinkedIn token error:",
|
|
error.response ? error.response.data : error.message
|
|
);
|
|
res.status(500).send("Error retrieving access token.");
|
|
}
|
|
};
|
|
|
|
const getUserProfile = async (req, res) => {
|
|
try {
|
|
const token = req.session?.user?.accessToken;
|
|
if (!token) {
|
|
return res.status(401).json({ error: "Aucun accessToken en session." });
|
|
}
|
|
|
|
const url =
|
|
"https://api.linkedin.com/v2/me" +
|
|
"?projection=(id,localizedFirstName,localizedLastName,profilePicture(displayImage~:playableStreams))";
|
|
|
|
const { data } = await axios.get(url, {
|
|
headers: {
|
|
Authorization: `Bearer ${token}`,
|
|
"X-Restli-Protocol-Version": "2.0.0", // souvent requis par les endpoints v2
|
|
Accept: "application/json",
|
|
},
|
|
});
|
|
|
|
return res.json(data);
|
|
} catch (error) {
|
|
const status = error.response?.status ?? 500;
|
|
const payload = error.response?.data ?? { message: error.message };
|
|
|
|
// Log côté serveur pour diagnostiquer vite
|
|
console.error("LinkedIn API error:", status, payload);
|
|
|
|
if (status === 401) {
|
|
return res.status(401).json({
|
|
error: "Token invalide ou expiré.",
|
|
hint: "Renouvelle le token OAuth (nouvelle auth) et réessaie.",
|
|
});
|
|
}
|
|
if (status === 403) {
|
|
return res.status(403).json({
|
|
error: "Permissions insuffisantes.",
|
|
hint: "Ajoute le scope 'r_liteprofile' (et 'r_emailaddress' si besoin) et assure que ton app y est autorisée.",
|
|
});
|
|
}
|
|
if (status === 429) {
|
|
return res.status(429).json({
|
|
error: "Trop de requêtes (rate limit).",
|
|
hint: "Ajoute du retry/backoff.",
|
|
});
|
|
}
|
|
return res.status(500).json({
|
|
error: "Erreur lors de la récupération du profil.",
|
|
details: payload,
|
|
});
|
|
}
|
|
};
|
|
|
|
module.exports = {
|
|
authenticateUser,
|
|
handleCallback,
|
|
getUserProfile,
|
|
};
|