Versione di Discourse: 2026.5.0-latest.1
Contesto
Quando un utente esterno invia un’e-mail al gestore della posta in arrivo utilizzando una variante con “punto” di Gmail (ad esempio, user.name@gmail.com), ma il suo account forum registrato è la versione primaria senza punti (username@gmail.com), il gestore della posta in arrivo si arresta con un’eccezione non gestita: ActiveRecord::RecordInvalid (Validation failed: Primary email has already been taken).
Inoltre, tentare di risolvere il problema aggiungendo la variante con punti come e-mail secondaria al profilo utente — sia tramite l’interfaccia utente che a livello del modello Rails Console utilizzando UserEmail.create! — fallisce con lo stesso errore di loop di convalida. L’unica soluzione è un’iniezione SQL diretta nel database, aggirando ActiveRecord.
Passaggi per la Riproduzione
-
Crea un account utente su Discourse con l’e-mail primaria
username@gmail.com. -
Fai sì che quell’utente invii un’e-mail in arrivo a un indirizzo di categoria/risposta da
user.name@gmail.com. -
Osserva il rifiuto nei registri della posta in arrivo a causa di
ActiveRecord::RecordInvalid. -
Prova ad aggiungere
user.name@gmail.comcome e-mail secondaria all’accountusername@gmail.comtramite la console Rails:UserEmail.create!(user_id: target_id, email: 'user.name@gmail.com', primary: false) -
Osserva il crash della convalida del modello.
Comportamento Atteso
Discourse gestisce la normalizzazione di Gmail in modo pulito. Dovrebbe:
-
Riconoscere la variante di Gmail con punti in arrivo come appartenente all’account principale in modo trasparente durante la fase di gestione della posta in arrivo.
-
Almeno, permettere a un amministratore di aggiungere la variante con punti come e-mail secondaria all’account principale senza attivare un blocco dell’applicazione per «E-mail primaria già presa», dato che appartiene allo stesso utente ed è esplicitamente impostata su
primary: false.
Comportamento Effettivo
Il livello dell’applicazione rimane bloccato in un loop logico:
-
Rileva
user.name@gmail.comcome una stringa «nuova», quindi tenta di agire su di essa (creare un utente in fase di stesura o aggiungere un’e-mail secondaria). -
Durante la fase di convalida, il modello
UserEmailesegue la sua logica di normalizzazione di Gmail, rimuove i punti, rileva cheusername@gmail.comè già l’indice dell’e-mail primaria per queluser_ide blocca la propria esecuzione sotto la falsa ipotesi che si stia verificando un conflitto di record duplicati.
Soluzione Utilizzata per Sbloccare la Situazione
L’unico modo per risolvere il problema è stato accedere via SSH al contenitore ed eseguire SQL diretto per aggirare completamente le convalide di ActiveRecord:
sql = "INSERT INTO user_emails (user_id, email, \"primary\", created_at, updated_at) VALUES (X, 'user.name@gmail.com', false, NOW(), NOW())"
ActiveRecord::Base.connection.execute(sql)
Una volta forzato tramite SQL diretto, il tracciamento della posta in arrivo funziona perfettamente. Il codice di convalida dovrebbe essere aggiornato per tenere conto di questo caso limite.
Grazie!