thoka
(Thomas Kalka)
Abril 22, 2026, 7:47pm
1
Ao investigar Private Topics Plugin - #109 by thoka , descobri que uma menção a um usuário em uma categoria restrita não é relatada quando o nome de usuário contém letras maiúsculas.
Se eu mencionar @SomeUser, o editor solicita
/composer/mentions.json?names[]=SomeUser&topic_id=10728
e, no resultado, o nome de usuário é retornado em minúsculas, sem user_reasons definido.
Uma consulta ao nome de usuário em letras minúsculas retorna "user_reasons": {"someuser":"category"}.
Se eu usar letras minúsculas para os nomes de usuário no compositor, avisos para usuários sem direitos suficientes serão exibidos.
Se alguém usar a autocompletar fornecida pelo editor, os nomes de usuário digitados em minúsculas serão substituídos por nomes em maiúsculas e, portanto, não serão relatados.
3 curtidas
RGJ
(Richard - Communiteq)
Abril 22, 2026, 9:26pm
2
Ótima descoberta, @thoka !
O problema está aqui
users retorna {"username_lower" => objeto User }
No entanto, se name não estiver em minúsculas, users[name] não existe.
Correção:
if user = users[name.downcase]
...
elsif group = groups[name.downcase]
...
Ou melhor: converta todos os nomes para minúsculas no início do método, pois há muitos problemas ali. groups faz corretamente .where("lower(name) IN (?)", @names.map(&:downcase)), mas funções como visible_group_ids_for_allowed_check, topic_allowed_group_ids, mentionable_group_ids e members_visible_group_ids todas usam where(name: @names), o que também introduz problemas de sensibilidade a maiúsculas e minúsculas.
3 curtidas
A correção correta é
main ← fix/unicode-username-lookups
closed 02:15AM - 14 Apr 26 UTC
Leverages Rails' built-in `normalizes` feature to handle username
normalization … consistently throughout the codebase. When you call
`User.where(username_lower: value)` or `find_by(username_lower: value)`,
ActiveRecord now automatically normalizes the input value.
Key changes:
- Adds `normalizes :username` (unicode normalize) and
`normalizes :username_lower` (unicode normalize + downcase) to User
- Adds `normalizes :email` (strip + downcase) to UserEmail
- Removes manual `.downcase` and `.map(&:downcase)` calls before AR queries
- Adds `User#matches_username?` method for comparing usernames
- Simplifies `filter_by_username` and `filter_by_username_or_email` scopes
to use `ILIKE ANY(ARRAY[?])` instead of branching on array vs single value
- Updates `filter_by_username` to normalize input for ILIKE patterns
- Updates `find_by_username` to rely on AR normalization
- Fixes a SQL injection vulnerability in search user ordering
- Uses before_save callback for username_lower assignment to ensure it
runs even when validation is skipped (e.g., finish installation flow)
- Adds shoulda matcher tests for username normalizations
The `normalize_username` class method is kept for cases where AR can't help:
raw SQL queries, ILIKE patterns, and direct comparisons.
Ref - https://meta.discourse.org/t/393646
mas é uma mudança grande demais para eu me sentir confortável em mesclar neste momento
Em vez disso, vou corrigir cada “endpoint” um por um para tornar a revisão mais simples e menos arriscada.
Aqui está o primeiro passo
main ← fix-composer-mention-case-sensitivity
opened 08:30AM - 23 Apr 26 UTC
Mentioning `@SomeUser` in a topic the mentioned user can't see (restricted categ… ory, PM they aren't invited to, topic they've muted) silently skipped the "cannot see this mention" warning popup whenever the typed name contained any uppercase letter. Same for mixed-case group names. Mention validation itself worked because of an existing client-side `.toLowerCase()` workaround, so the bug was easy to miss — mentions stayed `<a class="mention">` but the user got no signal that the mentioned account wouldn't actually be notified.
Server side, `ComposerController#mentions` builds its `users` lookup keyed by `username_lower` and `groups` keyed by the case-preserved DB `name`, then iterated `@names.each { |n| users[n] || groups[n] }` without normalizing — so any uppercase character missed both hashes and `user_reasons`/`group_reasons` came back empty. Four downstream group helpers (`mentionable_group_ids`, `members_visible_group_ids`, `topic_allowed_group_ids`, `visible_group_ids_for_allowed_check`) used `where(name: @names)` which is case-sensitive in PostgreSQL, and the `SiteSetting.here_mention` membership test compared raw strings.
Client side, `link-mentions.js` cached `foundUsers` / `userReasons` / `foundGroups` / `groupReasons` by the case as typed, and the prosemirror `mention.js` warning lookup did `response.users.includes(name)` plus `response.user_reasons[name]` with the original case — both of which the server only ever returned in the casing it had on hand.
Normalize the controller's `@names` and `@allowed_names` once at the top of the action, switch all four group helpers to `LOWER(name) IN (?)`, lower-case the response keys, and lower-case client caches and lookups end to end. Also extract the inline notified-member query into `already_notified_member_count` and tighten the request specs to cover users, mentionable groups, group reasons in PMs, and `allowed_names` (both user and group branches) with mixed-case input.
https://meta.discourse.org/t/401292
7 curtidas
Ethsim2
(Ethan )
Maio 13, 2026, 3:03pm
5
Desde que reconstruí o Discourse para os 188 commits de 645cb014c0 a 102c93e2ea , notei uma nova regressão no editor de Markdown.
Esse popup não significa nada, mas aparece toda vez que tento acionar meu agente personalizado @Forum_Research_Assis.
Conseguir reproduzir isso consistentemente, conforme mostrado no vídeo:
Acredito que este mesmo commit está sem a lógica necessária para ignorar quando o usuário menciona um Agente de IA.
Estou pronto para iniciar outro pull request quando vocês estiverem, embora eu já tenha um aberto na minha única conta do GitHub.
1 curtida
Parece que minha “correção” revelou esse problema para Agentes de IA
main ← fix-composer-mention-warning-ai-bots
opened 04:24PM - 13 May 26 UTC
Mentioning an AI bot (e.g. `@Forum_Research_Assis`) in a topic the bot's User re… cord can't see — like a category restricted to a group the bot isn't part of — surfaced the "this user cannot see this mention" warning popup in the composer. The warning is misleading: AI bots reply via `PostCreator.create!(... skip_guardian: true)` (`playground.rb`), so they respond regardless of whether their User can `Guardian#can_see?` the topic.
The previous case-insensitive fix (9a4cca29) exposed this latent behavior. Pre-fix, mixed-case names hit a case-sensitive hash miss in `ComposerController#mentions` and silently returned an empty `user_reasons`. Post-fix, the lookup hits correctly and the reachability check — which was always there — now fires for AI bot users that genuinely can't see the topic.
Adds a `:composer_mention_user_reason` plugin modifier, applied after the standard reason is computed in `user_reason`, so plugins can clear or transform it. The AI plugin registers against the modifier and returns `nil` for any user in `DiscourseAi::AiBot::EntryPoint.all_bot_ids` (covering both AI agent users and chat-bot-enabled LLM model users).
discobot and the system user are intentionally unaffected: discobot's `PostCreator.create!` does not skip the guardian, so the reachability warning remains accurate for it.
https://meta.discourse.org/t/401292
3 curtidas