|
|
@@ -88,11 +88,32 @@ router.get('/oidc/callback', async (req, res) => {
|
|
|
);
|
|
|
|
|
|
const claims = tokenSet.claims();
|
|
|
- const sub = claims.sub;
|
|
|
- const email = claims.email;
|
|
|
- const name = claims.name || claims.preferred_username || email || `user_${sub}`;
|
|
|
- const firstName = claims.given_name || null;
|
|
|
- const lastName = claims.family_name || null;
|
|
|
+
|
|
|
+ // Log claims pour diagnostic (à retirer en production)
|
|
|
+ console.log('[OIDC] claims reçus:', JSON.stringify(claims, null, 2));
|
|
|
+
|
|
|
+ // Récupérer userinfo si disponible (Authelia y expose email et profil)
|
|
|
+ let userinfo = {};
|
|
|
+ try {
|
|
|
+ userinfo = await oidcClient.userinfo(tokenSet);
|
|
|
+ console.log('[OIDC] userinfo reçu:', JSON.stringify(userinfo, null, 2));
|
|
|
+ } catch (e) {
|
|
|
+ console.warn('[OIDC] userinfo non disponible:', e.message);
|
|
|
+ }
|
|
|
+
|
|
|
+ const all = { ...claims, ...userinfo };
|
|
|
+ const sub = all.sub;
|
|
|
+
|
|
|
+ // Authelia peut exposer l'email dans différents claims
|
|
|
+ const email = all.email || all.mail || all.upn || null;
|
|
|
+
|
|
|
+ // Construire le nom depuis les claims disponibles
|
|
|
+ const firstName = all.given_name || all.givenname || null;
|
|
|
+ const lastName = all.family_name || all.sn || null;
|
|
|
+ const name = all.name || all.preferred_username || all.username
|
|
|
+ || (firstName && lastName ? `${firstName} ${lastName}` : null)
|
|
|
+ || email
|
|
|
+ || `user_${sub}`;
|
|
|
|
|
|
if (!sub) return res.redirect(`${frontendUrl}/login?error=no_sub`);
|
|
|
|
|
|
@@ -100,7 +121,7 @@ router.get('/oidc/callback', async (req, res) => {
|
|
|
let user = (await pool.query('SELECT * FROM users WHERE oidc_sub = $1', [sub])).rows[0];
|
|
|
|
|
|
if (!user && email) {
|
|
|
- // Tenter de lier à un compte local existant avec le même email
|
|
|
+ // Tenter de lier à un compte existant avec le même email
|
|
|
user = (await pool.query('SELECT * FROM users WHERE email = $1', [email])).rows[0];
|
|
|
if (user) {
|
|
|
await pool.query('UPDATE users SET oidc_sub = $1 WHERE id = $2', [sub, user.id]);
|
|
|
@@ -114,6 +135,21 @@ router.get('/oidc/callback', async (req, res) => {
|
|
|
[email || `oidc_${sub}@sso`, name, firstName, lastName, sub]
|
|
|
);
|
|
|
user = result.rows[0];
|
|
|
+ } else {
|
|
|
+ // Mettre à jour les infos du profil si de meilleures données sont disponibles
|
|
|
+ const updates = [];
|
|
|
+ const vals = [];
|
|
|
+ let i = 1;
|
|
|
+ if (email && user.email !== email && (user.email || '').endsWith('@sso')) {
|
|
|
+ updates.push(`email = $${i++}`); vals.push(email);
|
|
|
+ }
|
|
|
+ if (name && user.name !== name) { updates.push(`name = $${i++}`); vals.push(name); }
|
|
|
+ if (firstName && !user.first_name) { updates.push(`first_name = $${i++}`); vals.push(firstName); }
|
|
|
+ if (lastName && !user.last_name) { updates.push(`last_name = $${i++}`); vals.push(lastName); }
|
|
|
+ if (updates.length) {
|
|
|
+ vals.push(user.id);
|
|
|
+ await pool.query(`UPDATE users SET ${updates.join(', ')} WHERE id = $${i}`, vals);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const token = jwt.sign({ userId: user.id }, JWT_SECRET, { expiresIn: '7d' });
|