Changeset 11ba289 in Klonkt


Ignore:
Timestamp:
06/20/2026 01:20:57 AM (3 months ago)
Author:
roboburr <roboburr@…>
Branches:
main
Children:
6d882b1
Parents:
36afccd
Message:

fix(auth): Google login matches on linked google_sub first (not email)

An admin who linked their Google account to an account with a different
email address (e.g. demo-admin demo@… + roboburr@…) was
not recognized on Google login (lookup by email) → a new member account
was created instead. Now looks up google_sub first → logs in with the
proper (admin) role, regardless of email address. Falls back to email for
unlinked listeners.

Co-Authored-By: Claude <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/routes/auth.js

    r36afccd r11ba289  
    335335    if (!email || info.email_verified === false) return failLogin('email');
    336336
    337     let user = db.prepare('SELECT * FROM users WHERE LOWER(email) = ?').get(email);
    338 
    339     if (user && (user.role === 'god' || user.role === 'admin')) {
    340       // Beheerder mag ALLEEN met Google in als 'ie z'n Google expliciet gekoppeld
    341       // heeft (matchende google_sub). Anders blijft gelden: Google = nooit beheer.
    342       if (!(user.google_sub && info.sub && user.google_sub === info.sub)) {
     337    // Zoek EERST op de gekoppelde Google-account (google_sub). Een sub-match is het
     338    // expliciete koppel-bewijs → log in met de eigen rol, OOK als het Google-
     339    // mailadres afwijkt van het account-mailadres (bv. een beheerder die een ander
     340    // Gmail koppelt). Daarna pas op e-mail.
     341    let user = info.sub ? db.prepare('SELECT * FROM users WHERE google_sub = ?').get(info.sub) : null;
     342
     343    if (user) {
     344      // Gekoppeld account gevonden → eigen rol behouden. Avatar bijwerken indien leeg.
     345      db.prepare(`
     346        UPDATE users SET avatar_url = COALESCE(avatar_url, ?), updated_at = CURRENT_TIMESTAMP WHERE id = ?
     347      `).run(info.picture || null, user.id);
     348    } else {
     349      user = db.prepare('SELECT * FROM users WHERE LOWER(email) = ?').get(email);
     350      if (user && (user.role === 'god' || user.role === 'admin')) {
     351        // Beheerder gevonden op e-mail maar ZONDER gekoppelde sub → Google geeft
     352        // nooit beheer. Eerst koppelen via Account → Inloggen met Google.
    343353        return failLogin('admin');
     354      } else if (user) {
     355        // Bestaande luisteraar: koppel google_sub/avatar als die ontbreken.
     356        db.prepare(`
     357          UPDATE users SET google_sub = COALESCE(google_sub, ?), avatar_url = COALESCE(avatar_url, ?),
     358            updated_at = CURRENT_TIMESTAMP WHERE id = ?
     359        `).run(info.sub || null, info.picture || null, user.id);
     360      } else {
     361        // Nieuwe luisteraar — altijd member.
     362        const userId = uuid();
     363        const username = uniqueUsername(info.name || email.split('@')[0]);
     364        db.prepare(`
     365          INSERT INTO users (id, username, email, password_hash, role, avatar_url, theme, palette, google_sub)
     366          VALUES (?, ?, ?, '!google-oauth', 'member', ?, 'dark', 'sage', ?)
     367        `).run(userId, username, info.email || email, info.picture || null, info.sub || null);
     368        user = db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
    344369      }
    345       // gekoppeld + match → doorgaan met de eigen (beheer)rol.
    346     } else if (user) {
    347       // Bestaande luisteraar: koppel google_sub/avatar als die ontbreken; weiger
    348       // als al aan een ander Google-account gekoppeld.
    349       if (user.google_sub && info.sub && user.google_sub !== info.sub) return failLogin('linked');
    350       db.prepare(`
    351         UPDATE users SET google_sub = COALESCE(google_sub, ?), avatar_url = COALESCE(avatar_url, ?),
    352           updated_at = CURRENT_TIMESTAMP WHERE id = ?
    353       `).run(info.sub || null, info.picture || null, user.id);
    354     } else {
    355       // Nieuwe luisteraar — altijd member.
    356       const userId = uuid();
    357       const username = uniqueUsername(info.name || email.split('@')[0]);
    358       db.prepare(`
    359         INSERT INTO users (id, username, email, password_hash, role, avatar_url, theme, palette, google_sub)
    360         VALUES (?, ?, ?, '!google-oauth', 'member', ?, 'dark', 'sage', ?)
    361       `).run(userId, username, info.email || email, info.picture || null, info.sub || null);
    362       user = db.prepare('SELECT * FROM users WHERE id = ?').get(userId);
    363370    }
    364371
Note: See TracChangeset for help on using the changeset viewer.