Riepilogo
Quando un post passa attraverso la coda di approvazione, ReviewableQueuedPost.payload["raw"] contiene una copia completa del corpo inviato. Dopo che il post viene approvato e successivamente cancellato dall’autore, il post pubblico viene sostituito dallo stub “(post cancellato dall’autore)”, ma l’elemento in revisione (reviewable) conserva il corpo originale per tutto il tempo in cui esiste la riga del post — che, dopo una cancellazione da parte dell’autore, è indefinito — e continua a fornirlo al personale in /review.
Non esiste un percorso di pulizia (scrub) per questo: Reviewable.scrubbable_types è [ReviewableUser], quindi l’azione di amministrazione per la pulizia aggiunta in #36556 (“i moderatori possono ora utilizzare un’azione ‘Scrub’ per rimuovere i dati personali dell’utente”) non copre i post in coda. Il payload viene rimosso solo se qualcuno distrugge permanentemente il record del post, cosa che la cancellazione dell’autore non fa e che l’interfaccia utente non consente per il primo post di un topic.
Riprodotto su v2026.7.1. Il codice pertinente è invariato su main al 25-09-2026.
Versione
Discourse v2026.7.1 (self-hosted, istanza di test locale autorizzata). Solo Core — nessun plugin coinvolto.
Passi per riprodurre
-
Come amministratore, imposta che i post di un utente normale richiedano approvazione, ad esempio impostando
approve post countsu 5 e rimuovendotrust_level_0daapprove unless allowed groups. -
Come quell’utente normale, crea un topic con un marker univoco nel corpo. La risposta torna come
{"action": "enqueued"}. -
Come personale, approvalo:
PUT /review/<reviewable_id>/perform/approve_post?version=0. Il post viene creato. -
Come autore, cancellalo tramite l’azione normale rivolta all’utente —
DELETE /t/<topic_id>.jsonper il topic di cui questo è il primo post. -
Come personale, richiedi
GET /review.json?status=all.
Atteso
Una volta che l’autore cancella il contenuto, la copia di moderazione dello stesso testo dovrebbe seguire il ciclo di vita del contenuto: dovrebbe essere eliminata, pulita o almeno essere pulibile da un amministratore allo stesso modo di un ReviewableUser rifiutato.
Reale
Il passo 5 restituisce ancora l’intero corpo originale. Misurato nell’esecuzione riprodotta:
| Osservazione | Risultato |
|---|---|
riga posts dopo la cancellazione dell’autore |
user_deleted = t, raw = '(topic cancellato dall'autore)' |
reviewables.payload dopo la cancellazione dell’autore |
{"raw":"Corpo in coda DRLGQUEUEDfb08ab5b648f. padding …"} — invariato |
Personale GET /review.json?status=all |
contiene il corpo originale |
Reviewable.scrubbable_types |
["ReviewableUser"] |
Amministratore PUT /review/<id>/scrub.json |
HTTP 404 (non è un tipo pulibile) |
| Dopo che il record del post viene distrutto permanentemente | la riga reviewable è scomparsa (dependent: :destroy) |
L’ultima riga è l’unico percorso che la elimina, e non è raggiungibile dalla cancellazione dell’autore: la cancellazione dell’autore marca il post come user_deleted e, dopo delete_removed_posts_after ore, lo sposta nel cestino. Una riga di post nel cestino continua a esistere, quindi il payload continua a esistere.
Da dove deriva
-
app/models/reviewable_queued_post.rbcostruisce e leggepayload['raw']; nulla specifica uno scopo o una durata di conservazione per questo. -
lib/post_destroyer.rb:562resolve_reviewables_for_author_deletiontocca soloReviewable.where(target: @post, status: pending). Un reviewable di post in coda approvato non viene mai fatto passare a uno stato successivo o pulito. -
app/models/post.rb:71has_many :reviewables, as: :target, dependent: :destroy— si attiva alla distruzione del record, non alla cancellazione soft prodotta dalla cancellazione dell’autore. -
app/models/reviewable.rb:81scrubbable_typesrestituisce[ReviewableUser];app/controllers/reviewables_controller.rb:191richiede inoltrestatus: rejected. -
Non esiste una pulizia programmata per i reviewables.
app/jobs/scheduled/contiene jobclean_up_*/purge_*per bozze, token email, esportazioni, upload, chiavi API e altro, ma nulla per i reviewables.
Impatto
Questo non è una divulgazione pubblica — la coda di revisione è riservata al personale, e non affermo il contrario. È un gap di conservazione dei dati: il testo che un utente ha rimosso dal forum rimane indefinitamente nello store di moderazione, viene mostrato nell’interfaccia della coda di revisione e nessuna azione amministrativa può rimuoverlo se non distruggendo permanentemente il record del post.
Questo è importante per lo stesso motivo per cui #36556 ha aggiunto la pulizia per gli utenti rifiutati: i payload dei reviewables possono contenere dati personali, e un sito che riceve una richiesta di cancellazione non ha un modo supportato per eliminare un payload di post in coda.
Correzione suggerita
Uno di questi la risolve; farne entrambi è meglio:
-
Estendere
resolve_reviewables_for_author_deletion(e il percorso del cestino) per pulirepayload['raw']sui reviewables il cui post di destinazione è stato cancellato dall’autore o spostato nel cestino. -
Aggiungere
ReviewableQueuedPostaReviewable.scrubbable_typese consentire che l’azione di pulizia amministrativa esistente si applichi quando il post di destinazione non contiene più il contenuto, in modo che gli operatori abbiano un rimedio supportato per i payload creati prima della correzione.
Una specifica di regressione dovrebbe asserire che dopo che un autore cancella un post in coda approvato, il payload del reviewable non contiene più il corpo inviato.