2454 Commits

Author SHA1 Message Date
PangBo
b2ce374650
FIX: error when trying to un-favorite badge (#32369)
This PR addresses the issue discussed in
https://meta.discourse.org/t/failed-error-when-trying-to-un-star-the-bug-reporter-badge/330523

1. Fixed an issue in `user_badges_controller.rb` where the
`toggle_favorite` method could incorrectly treat badges already marked
as favorite as not being favorite.
2. Automatically synchronize the `is_favorite` status for new badges
when a user is granted a multiple-grant badge.
2025-04-22 15:36:48 +08:00
Alan Guo Xiang Tan
2ec0bf32da
DEV: Fix broken request/qunit_controller_spec.rb (#32376)
This test file fails locally if `tmp/theme-transpiler.js` does not
exists.
Since the test file stubs the production env, we have to ensure that
`DiscourseJsProcessor::Transpiler.build_production_theme_transpiler` is
run first to mirror the production environment where the theme
transpiler file is built as part of assets precompilation.

### Review notes:

Example failure:
https://github.com/discourse/discourse/actions/runs/14529161497/job/40766003075

To repro locally, run the following steps: 

1. In your Discourse directory, run `rm -rf tmp`
2. `rspec spec/requests/qunit_controller_spec.rb`
2025-04-21 13:46:25 +08:00
Renato Atilio
4c26679b2d
DEV: fix form template flaky (#32360) 2025-04-17 19:54:38 -03:00
Renato Atilio
cd805d0d8f
DEV: Revert "FIX: Flaky test for FormTemplatesController (#32351)" (#32359)
This reverts commit 4cd7ca677f69a18ab680c4b0ecac4a0d583d533b.
2025-04-17 18:39:26 -03:00
Juan David Martínez Cubillos
4cd7ca677f
FIX: Flaky test for FormTemplatesController (#32351) 2025-04-17 10:23:58 -05:00
Juan David Martínez Cubillos
72f9714ddc
FEATURE: Implement tag group selection in dropdown and multi-select for topic creation and preview when using Form Templates (#32108)
Adds support for a tag-chooser in form templates. It supports single tag
and multi tags. The source of the displayed tags has to be a tag_group
name.

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2025-04-17 08:38:03 -05:00
Gary Pendergast
9b351614ea
FIX: Set X-Robots-Tag header to prevent indexing of /safe-mode (#32329)
This change adds the `X-Robots-Tag` header to the `/safe-mode` response, discouraging search engines from including the page in their index.
2025-04-16 16:51:32 +10:00
Chris Alberti
375a36e2ef
Don't require password to create users with previous authentication (#32201)
Don't require password to create users with previous authentication in
the session, regardless of email/email verification during user creation

Before my changes we were calling `user.password_required!` in
`UserAuthenticator.authenticated?` based on whether authentication
session data contained a matching email address and email verified
externally. I believe `authenticated?` is intended for our own email
validation during the activation process, but shouldn't be a gate for
password requirement.

Even when we were setting `user.password_required`, then during user
creation we were creating random passwords to get around the blank
password restriction when creating accounts with external auth.

After my change we can remove the random password creation because we no
longer require a password when the session has previous authentication
info at all.

Looks like this extra password requirement may have been introduced as a
side effect during a previous refactor of `UserController` here:
51eff92170
Before that change, password requirement was simply based on whether
session[:authentication] existed, but after that change it was based on
the email/email_valid fields as well.
2025-04-15 10:35:49 -05:00
Osama Sayegh
351a295846
DEV: Fix failing test after a rename (#32314) 2025-04-15 17:05:06 +03:00
Osama Sayegh
0b8df4b833
UX: Use 'unused' instead of 'active' for components (#32284)
This commits changes the language for components that aren't used on any themes to be "used/unused" instead of "active/inactive" throughout the new components listing page.
2025-04-15 16:12:20 +03:00
Osama Sayegh
71b31604b5
PERF: Implement infinite scrolling for new components page (#32291)
On sites with many components, serializing and rendering all components
in one-go on a page can take quite a bit of time. The new components
listing page that was introduced in
https://github.com/discourse/discourse/pull/32164 currently loads all
components in one-go, so this commit implements infinite-scrolling
pagination for the page to address this performance issue for sites with
many components.
2025-04-15 16:05:10 +03:00
Krzysztof Kotlarek
ee035582e2
FIX: Rename branding to logo and fonts (#32264)
Change branding page into logo and fonts.

In addition, icon for email setting and email appearance were changed.
2025-04-14 10:49:47 +08:00
Gary Pendergast
05e0491902
FIX: Ensure uploaded watched word CSVs are converted to utf-8. (#32263)
When a watched words CSV file is uploaded, we assume it's utf-8 encoded, but that's not always going to be the case. This change loads the CSV and converts it to utf-8 before processing it.
2025-04-11 16:12:45 +10:00
Krzysztof Kotlarek
14a42bdafe
FIX: incorrect flag message when en_GB language (#32191)
Currently, this is the order of i18n translate function:
1. Translation in required language;
2. Optional `defaultValue` provided;
3. Fallback to forum default language.

When admin set language as English GB, translation was not correctly
displayed as it went to step 2 and displayed `defaultValue` instead of
correct translation from default language.
2025-04-10 08:06:52 +08:00
Chris Alberti
3106c30f16
Added button to remove password from account (#32200)
Added button to remove password from account if user has a linked
external account or passkey

The button only displays if the user has at least one associated account
or a passkey set up. Uses the ConfirmSession dialog in addition to a
warning about deleting the password.

Users can still reset their password via the Reset Password button
(which will now display "Set Password" if they've removed it).

Also prevent user from removing their last remaining associated account
or passkey if they have no password set.

Replaces PR #31489 from my personal repo, with some fixes for conflicts
since then.
2025-04-09 09:32:51 -05:00
Alan Guo Xiang Tan
6e969d5cd4
DEV: Skip a flaky test (#32230)
Has been assigned for investigation soon

```
1) Admin::SiteSettingsController#update when logged in as an admin sanitizes integer values
    Failure/Error: expect(SiteSetting.suggested_topics).to eq(1000)

      expected: 1000
          got: 5

      (compared using ==)
    # ./spec/requests/admin/site_settings_controller_spec.rb:318:in `block (4 levels) in <main>'
    # ./spec/rails_helper.rb:588:in `block (3 levels) in <top (required)>'
    # ./vendor/bundle/ruby/3.3.0/gems/timeout-0.4.3/lib/timeout.rb:185:in `block in timeout'
    # ./vendor/bundle/ruby/3.3.0/gems/timeout-0.4.3/lib/timeout.rb:192:in `timeout'
    # ./spec/rails_helper.rb:578:in `block (2 levels) in <top (required)>'
    # ./spec/rails_helper.rb:535:in `block (2 levels) in <top (required)>'
    # ./vendor/bundle/ruby/3.3.0/gems/webmock-3.25.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'
```
2025-04-09 09:49:16 +08:00
Osama Sayegh
ad0966afa9
FEATURE: Introduce new components listing page (#32164)
Follow-up to https://github.com/discourse/discourse/pull/31887

This commit introduces a new design for the components listing page, which
is not linked from anywhere in the UI at the moment, but it can be
accessed by heading to the `/admin/config/customize/components` path
directly. We'll make this new design available from the sidebar and
remove the old page once we've tested and validated the new design
internally.

Internal topic: t/146007.

---------

Co-authored-by: Ella <ella.estigoy@gmail.com>
2025-04-08 17:58:29 +03:00
Ted Johansson
b1e97d9ebd
DEV: Add e-mail site settings to e-mail admin page (#32214)
Follow-up to #32211. This PR adds a Settings tab to the Email settings admin page. The current Settings tab is renamed to Server settings.
2025-04-08 18:59:50 +08:00
Ted Johansson
a021032a35
DEV: Extract e-mail logs into their own admin page (#32211)
This is a lift-and-shift of the admin e-mail logs, moving it out of the "Server setup & logs" page and into its own dedicated admin page.
2025-04-08 17:50:12 +08:00
Roman Rizzi
7b5839ec44
DEV: Optionally include everyone groups when searching (#32199)
`GroupsController#search` now accepts an `include_everyone` parameter to
include the "everyone" group in the results. discourse-ai relies on this
 endpoint for configuring personas' allowed groups and needs this group
 to be present. You still need to be able to see the group.
2025-04-07 11:55:27 -03:00
Krzysztof Kotlarek
928f9175f0
FEATURE: fonts section for branding page (#32031)
New configure fonts section was added. Because now we have two sections
completed (logos and fonts), new /branding page was introduced and old
/logo and /font pages was removed.

When text size is changed, modal is displayed to ask if preferences of
existing users should be retrospectively updated.



https://github.com/user-attachments/assets/f6b0c92a-117f-4064-bd76-30fa05acc6d3

---------

Co-authored-by: Ella <ella.estigoy@gmail.com>
Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2025-04-07 10:28:42 +08:00
Gabriel Grubba
a88d8a0393
FEATURE: prioritize the user who is getting the reply in the autocomplete (#32086)
When replying to a post, the user who is getting the reply should be
prioritized in the autocomplete

- Added in composer a getter for getting `.replyingToUser`
- Added in d-editor the reference to the user that is getting the
reply(`this.composer.replyingToUser`)
- Passed along the reference to the user that is getting the reply to
the user-search service as `replyingToUser`
- Controller `users_controller.rb` was modified to accept the `user_id`
parameter and pass it to the `UserSearch` model
- The `UserSearch` model was modified to accept the `user_id` parameter
and use it to prioritize the user that is getting the reply in the
autocomplete on the first time you call the autocomplete service and
while the username is included in the searched term
- Had to update the serializer to pass the id of the `replyingToUser`
from the post
2025-04-04 10:11:37 -03:00
Ted Johansson
c4502b31e4
FEATURE: Bulk save site settings (#32013)
This feature adds a bulk-save feature to site settings.
2025-04-01 09:39:19 +08:00
Gary Pendergast
b4cdc39e51
FEATURE: Allow rejected user details to be scrubbed (#31987)
When a site has the `must_approve_users` setting enabled, new user data is stored on the Reviewable model, including username, email, and any other data that is entered during signup. If the user is rejected, that data is retained, without a clear path to deleting it.

In order to allow data that could be PII to be removed, without breaking Discourse's audit and logging trails, this change scrubs the PII from the relevant `ReviewableUser` and `UserHistory` objects, replacing that data with who scrubbed it, and why.
2025-03-31 12:40:35 +11:00
Ted Johansson
c8ccd4da31
DEV: Move setting deprecation check to SiteSetting::Update service (#31993)
This PR moves the logic that checks if a site setting we're trying to update has been deprecated from one of the controllers into a policy of the SiteSetting::Update service.

It also gives us the opportunity to shift the error message into a locale file.
2025-03-26 15:56:18 +08:00
David Battersby
d06c60ca7c
FEATURE: add icons and emojis to category (#31795)
This feature allow admins to personalize their communities by
associating emojis or icons with their site categories.

There are now 3 style types for categories:
- Square (the default)
- Emoji
- Icon

### How it looks 🎨 

Adding an icon:

<img width="502" alt="Category with an icon"
src="https://github.com/user-attachments/assets/8f711340-166e-4781-a7b7-7267469dbabd"
/>

Adding an emoji:

<img width="651" alt="Category with an emoji"
src="https://github.com/user-attachments/assets/588c38ce-c719-4ed5-83f9-f1e1cb52c929"
/>

Sidebar:

<img width="248" alt="Sidebar with emojis"
src="https://github.com/user-attachments/assets/cd03d591-6170-4515-998c-0cec20118568"
/>

Category menus:

<img width="621" alt="Screenshot 2025-03-13 at 10 32 30 AM"
src="https://github.com/user-attachments/assets/7d89797a-f69f-45e5-bf64-a92d4cff8753"
/>

Within posts/topics:

<img width="382" alt="Screenshot 2025-03-13 at 10 33 41 AM"
src="https://github.com/user-attachments/assets/b7b1a951-44c6-4a4f-82ad-8ee31ddd6061"
/>

Chat messages:

<img width="392" alt="Screenshot 2025-03-13 at 10 30 20 AM"
src="https://github.com/user-attachments/assets/126f8076-0ea3-4f19-8452-1041fd2af29f"
/>

Autocomplete:

<img width="390" alt="Screenshot 2025-03-13 at 10 29 53 AM"
src="https://github.com/user-attachments/assets/cad75669-225f-4b8e-a7b5-ae5aa8f1bcad"
/>

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2025-03-26 09:46:17 +04:00
Martin Brennan
e99ed81586
DEV: Serialize theme_id and colors for user selectable color palettes (#31972)
We currently have `user_color_schemes` serialized on the preloaded
`Site` object, but it's very lightweight, only having an ID and name.
It would be useful for some themes and also the user Interface
preferences tab to be able to access the colors for the color scheme,
as well as the theme it belongs to.

This commit expands the serializer to include these extra attributes.
This `user_color_schemes` key is already cached as a fragment, so this
shouldn't be too much extra burden to send to the client.
2025-03-25 16:31:28 +10:00
Régis Hanol
558c566ca8
FIX: avatar, profile & card backgrounds url in DiscourseConnect (#31956)
The URLs returned by DiscourseConnect for the user's avatar, profile and
card backgrounds were not always correctly handling CDN.

This make use of the `GlobalPath.full_cdn_url` helper method which has
been battle-tested.

Ref - https://meta.discourse.org/t/-/356599
2025-03-24 16:23:05 +01:00
Gary Pendergast
b77d0f7589
FEATURE: Sync Reviewable Status (#31901)
When multiple admins are working in the review queue, it's quite easy for two people to try and handle the same reviewable at the same time. This change addresses the two major situations where this can occur.

The `ReviewableClaimedTopic` model has been extended to allow the system to mark a reviewable as claimed as soon as the first moderator starts handling the reviewable, even when the `reviewable_claiming` setting is disabled. This ensures that reviewable actions with client-site activity (for example, `agree_and_suspend`) will lock the reviewable before another moderator starts working on it.

When someone handles handles a reviewable, we now use `MessageBus` to inform other moderators that it's changed. If any of the other moderator have that reviewable open (either individually, or on the list screen), it will automatically refresh that data.
2025-03-24 14:27:18 +11:00
Osama Sayegh
f7f7642ae0
UX: Improve naming for anonymous mode settings (#31832)
This PR renames a couple of settings related to anonymous mode:

1. `allow_anonymous_posting` → `allow_anonymous_mode`. This setting is
used as a switch for the entire anonymous mode feature, so it makes
sense to give it a generic name that better reflects what the setting
does.
2. `allow_anonymous_likes` → `allow_likes_in_anonymous_mode`. The new
name is clearer and will match a new setting that we'll add to allow
anonymous users to post in chat.

Internal topic: t/148088.
2025-03-21 04:54:06 +03:00
Alan Guo Xiang Tan
b3881d42d0
DEV: Disallow the use of Rails.logger= in RSpec tests (#31920)
Setting Rails.logger after the application has been initialized does not
seem to be safe anymore and can lead to flaky tests. This commit
disallows the reassignment of `Rails.logger` going forward and updates
the affected test.

### Reviewer notes

Reassigning `Rails.logger` from within RSpec tests is causing tests
which uses `Rails.logger.broadcast_to(FakeLogger.new)` to flake.
Example:
https://github.com/discourse/discourse/actions/runs/13951116847/job/39050616967

```
  1) invalid requests handles NotFound with invalid json body
     Failure/Error: expect(fake_logger.errors).to have_attributes(size: 1)
     
       expected [] to have attributes {:size => 1} but had attributes {:size => 0}
       Diff:
       @@ -1 +1 @@
       -:size => 1,
       +:size => 0,
       
     # ./spec/integration/invalid_request_spec.rb:18:in `block (2 levels) in <main>'
     # ./spec/rails_helper.rb:619:in `block (3 levels) in <top (required)>'
     # /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/benchmark-0.4.0/lib/benchmark.rb:304:in `measure'
     # ./spec/rails_helper.rb:619:in `block (2 levels) in <top (required)>'
     # ./spec/rails_helper.rb:580:in `block (3 levels) in <top (required)>'
     # /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/timeout-0.4.3/lib/timeout.rb:185:in `block in timeout'
     # /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/timeout-0.4.3/lib/timeout.rb:192:in `timeout'
     # ./spec/rails_helper.rb:570:in `block (2 levels) in <top (required)>'
     # ./spec/rails_helper.rb:527:in `block (2 levels) in <top (required)>'
     # /var/www/discourse/vendor/bundle/ruby/3.3.0/gems/webmock-3.25.1/lib/webmock/rspec.rb:39:in `block (2 levels) in <top (required)>'
```
2025-03-21 08:48:38 +08:00
Ted Johansson
1a7303a35e
FIX: Amend broken group automatic member dialog (#31854)
When creating or editing a group, we are meant to show a dialog telling the admin how many members will be automatically added.
2025-03-18 19:37:37 +08:00
Penar Musaraj
ecbd3cc93a
DEV: Fix custom homepage crawler display and override (#31841)
Fixes the custom homepage crawler output to include links to the site's
top menu.

![CleanShot 2025-03-15 at 16 27
16@2x](https://github.com/user-attachments/assets/57f25b65-a218-4811-b7d4-211e3d60e586)

This also provides a way to override that content via a plugin. Example
usage in a `plugin.rb` file:

```
register_html_builder("server:custom-homepage-crawler-view") do |c|
  "<div>override</div>"
end
```
2025-03-17 13:06:09 -04:00
Alan Guo Xiang Tan
577c043487
FIX: Ensure ordering is enforced in PostsController#replies (#31826)
This was picked up by the `PostsController#replies supports pagination`
requests spec as it was flaky from time to time.
2025-03-14 17:56:26 +08:00
Penar Musaraj
ef006ec76b
DEV: Add support for .well-known/apple-app-site-association (#31798)
We already support `/apple-app-site-association` at the root. Apple also
accepts `.well-known/apple-app-site-association` as a valid path so this
adds that as well, just in case.
2025-03-13 10:49:47 -04:00
David Taylor
e8f4433872
DEV: Stop using sprockets to compile service-worker js (#31796)
The service worker isn't served via normal asset paths or the CDN.
Instead, the ERB was being compiled by sprockets, fished out of the
`public/` directory by the static_controller, and then the
sprockets-specific stuff like `sourceMappingUrl` was being removed.

Instead, we can put the ERB under `views/static/`, and have it evaluate
at runtime. There are only a couple of super-cheap interpolations, plus
the route is cached in nginx, so there is no performance concern.

This takes us one step closer to removing sprockets.
2025-03-13 12:49:33 +00:00
Martin Brennan
38920724a0
DEV: Refactor reports index into service (#31667)
This list of all reports is needed in the admin search
controller as well, so this commit refactors it into
a service, adds specs, and also updates the admin
search code to use this new service & avoid a second
AJAX call to the server.
2025-03-11 14:36:06 +10:00
Krzysztof Kotlarek
7da4fe82b6
FIX: redirect to parent tag when synonym page visited (#31688)
When a synonym page is visited, the user should be redirected to the
parent tag.
2025-03-10 09:45:38 +11:00
Gary Pendergast
e77e5bd3cc
FIX: If a tag has a description, use it for the meta description. (#31689)
When a tag has a description defined, we should use that in the `<meta
name="description"...` tag on the tagged topic list page. This matches
the behaviour on the equivalent category pages.
2025-03-07 12:53:54 +11:00
Kelv
305039b1c3
DEV: ensure Rails application default headers are present in responses (#31619)
Follow up from https://github.com/discourse/discourse/pull/31559.

We expect some standard headers to be added from
`Rails.application.config.action_dispatch.default_headers` for
responses, however these were found to be removed in some error paths. 
For more detail on this behaviour, refer to https://github.com/discourse/discourse/pull/31619#issuecomment-2699644232.

This PR adds those headers back if they aren't there, with the caveats
that we don't add headers that are irrelevant for non-HTML responses,
and neither do we add X-Frame-Options which is intentionally removed for
embeddables.
2025-03-05 13:19:09 +08:00
Krzysztof Kotlarek
702a2a9cbc
UX: display html tags in silence reason (#31598)
Allow HTML tags in silence reason. Tags must be stripped for title
attribute.

Before

![image](https://github.com/user-attachments/assets/05d9819a-9dbf-46b2-b9c5-88187ca9af5b)


After
<img width="1079" alt="Screenshot 2025-03-04 at 11 39 05 am"
src="https://github.com/user-attachments/assets/2bb41deb-227c-47a8-b840-b0316a764252"
/>
<img width="1096" alt="Screenshot 2025-03-04 at 11 39 22 am"
src="https://github.com/user-attachments/assets/02e27fc0-317e-43df-bce8-6b68e48ac40e"
/>
2025-03-05 12:43:03 +11:00
Guhyoun Nam
2ab00c5b37
DEV: Add apply_modifier on group's mentionable scope (#31565)
This PR adds DiscoursePluginRegistry.apply_modifier on group's
mentionable scope.
2025-03-04 15:36:55 -06:00
Joffrey JAFFEUX
80625f6c1c
DEV: explicit json for emojis/search-aliases (#31582)
Adds `.json` a suffix everywhere and makes it clear that's it's a json
route.

Also adds a missing spec for this endpoint and updates the underlying
discourse-emojis gem for better symlinking
2025-03-03 15:21:16 +01:00
Joffrey JAFFEUX
d38acc5df1
DEV: discourse-emojis gem (#31408)
This commit moves most of emoji logic into the discourse-emojis gem:
https://github.com/discourse/discourse-emojis/

Most notably:
- images are now symlinked from the gem
- the gem provides path to the json files

Search aliases have also been made asynchronous and memoized. When you
will search for an emoji we will now load the aliases and store the list
for future use.

---------

Co-authored-by: David Taylor <david@taylorhq.com>
2025-03-03 13:09:08 +01:00
Kelv
0d90f6e3c3
FIX: cross origin opener policy should apply to public error responses (#31559)
In some error paths, headers that were set earlier can get overwritten
(e.g. `Cross-Origin-Opener-Policy`) by middleware such as
ActionDispatch::ShowExceptions.

This PR sets the `Cross-Origin-Opener-Policy` header to the value of the
SiteSetting `cross_origin_opener_policy_header` if it's missing and if
the response is for HTML.

In future, this DefaultHeaders middleware can be used to set other
default headers that relate to security or other purposes.

### Testing
<img width="631" alt="test"
src="https://github.com/user-attachments/assets/05106a40-2bc7-435d-91a2-4dd2a098f349"
/>
2025-03-03 17:04:24 +08:00
Alan Guo Xiang Tan
66ecfc8996
DEV: Correct users create API docs (#31578)
The API docs is incorrect as the `active` param is only permitted when
an admin API key
is used. This has always been the case since
429f27ec96c090d9054c498263f0cb635b665d99
2025-03-03 16:42:46 +08:00
Gary Pendergast
8615fc6cbb
DEV: Add a user agent to all HTTP requests that Discourse makes. (#31555)
This change standardises the `User-Agent` header that Discourse will send when talking to other sites.

`Discourse.user_agent` is now the authority on what the user agent value should be. For Onebox requests, this changes the user agent from their existing value to match the new value (unless overridden).

For all other requests, `Net::HTTPHeader` is monkey-patched to add a default `User-Agent` header when one hasn't been provided.
2025-03-03 16:32:25 +11:00
Isaac Janzen
176ee0bf60
DEV: Add posts_controller_create_user modifier (#31562)
Add `posts_controller_create_user` modifier to modify which user is associated with the post creation.
2025-02-28 15:11:12 -06:00
Joffrey JAFFEUX
8c9a2d21ce
Revert "DEV: Prevent crawlers from loading search results. (#31535)" (#31540)
This reverts commit 38de3d7bd1f503743c5d0237bc8a8d9d89effb8e. This
changed seemed to be blocking our own AI helper as well if it has the
“Search” tool.
2025-02-27 10:34:18 +01:00
Gary Pendergast
38de3d7bd1
DEV: Prevent crawlers from loading search results. (#31535)
This change detects if a crawler is trying to load a search results page, and returns a simple response that should indicate to them that there's no content of interest available there.
2025-02-27 14:34:19 +11:00