Commit Graph
10849 Commits
Author SHA1 Message Date
David Taylor 585ba17f56 DEV: Rename theme-transpiler to asset-processor (#35498)
This is already used for more than just themes, and we plan to extend
its usage even further
2025-10-20 14:16:46 +01:00
Loïc Guitaut 695533b99c DEV: Add a compact_blank option to the ActiveModel array type (#35476)
Instead of having to clean an array in a contract using a
`before_validation` block, for example, we can now pass `compact_blank:
true` to the attribute, like this:

```ruby
attribute :ids, :array, compact_blank: true
```
2025-10-20 11:33:36 +02:00
Jarek Radosz e2e9b3b679 DEV: Don't serialize error objects back into js (#35468)
This will prevent errors like:

```
MiniRacer: InternalError (unsupported type Logster: Message) lib/discourse_js_processor.rb:86
```
2025-10-17 15:00:56 +02:00
David Taylor d9e0a44007 DEV: Fix Zeitwerk reloading in post-voting (#35470)
1. Update `register_preloaded_category_custom_fields` API to be
reload-safe

2. Update post-voting to use this in all cases, and remove the
`respond_to?` checks since this plugin is now bundled with core
2025-10-17 13:58:12 +01:00
Régis Hanol 03629cd561 PERF: N+1 when checking for category moderators when loading channels (#35466)
Avoids an N+1 when loading /chat/api/me/channels and checking for
category moderators.

Internal ref - t/165130
2025-10-17 14:29:28 +02:00
Régis Hanol 1fe35c74e1 FIX: unsuspend a moderator (#35452)
If, for some reasons, you were to try to "unsuspend" a moderator, you
wouldn't be able to because the "can_suspend" was checking for
"user.regular?".

Added a "can_unsuspend?" to support this use-case.

Ref - https://meta.discourse.org/t/-/385786
2025-10-16 21:05:47 +02:00
Régis Hanol b042dbcf67 DEV: correctly detect chromium on macos (#35441)
When Chrome isn't installed, running "bin/rails qunit:test" would fail
because it wouldn't be able to detect that Chromium was installed.

This fixed that and also pass the detected browser to testem
2025-10-16 14:54:58 +02:00
David BattersbyandMartin Brennan b671166ab1 FEATURE: Experimental Photoswipe Lightbox (#35109)
Our current implementation of lightbox uses Magnific Popup, which is now
deprecated and will only receive critical/security bug fixes. Magnific
also relies on jQuery, which we would like to remove where possible
throughout our codebase.

After looking at various options, the general consensus was that
PhotoSwipe was a close match to what we need.

Regular image types that are supported with our current lightbox (jpg,
png etc) will work with their existing cooked markup (no need to rebake
posts). This PR also adds support for SVG images and markup from various
theme components (ie. Discourse Mermaid).

---------

Co-authored-by: Martin Brennan <martin@discourse.org>
2025-10-16 12:24:11 +04:00
Kelv 5d92499edd FIX: only load the api-docs rake task definition when required gems are available (#35432)
This task was failing to load rspec-core because `lib/tasks` are loaded
in full in prod environments and this was meant to be run only in
dev/test environments (the task it is overwriting is defined in a gem
that's only loaded in those environments).

If we add more tasks like this, we can create a new subfolder in `tasks`
to segregate such tasks in a clearer manner.
2025-10-16 12:36:53 +08:00
Kelv daac912405 DEV: add api docs for discourse-calendar events index endpoint (#35400)
This creates an overriding `rswag:specs:swaggerize` rake task that also
adds plugin paths, and updates spec helpers to handle plugin paths.

Also adds the spec files for the discourse-calendar events index
endpoint.

### Testing

Running `rake rswag:specs:swaggerize` now generates the same
`openapi/openapi.yaml` file, with `/discourse-post-event/events.ics` and
`/discourse-post-event/events.json` GET documentation.
2025-10-16 07:39:08 +08:00
Blake Erickson 6467fba73f DEV: Have media convert service set s3 output permissions (#35392)
When converting a video we need to set the appropriate s3 permissions
for the output file.
2025-10-15 12:38:25 -06:00
Ted Johansson 69dfdf5084 FIX: Moderator notifications when new post auto-silences a user (#35403)
When a user is auto-silenced because they receive enough spam flag, we notify moderators (given the notify_mods_when_user_silenced is enabled).

However, when a user is auto-silenced for other reasons, e.g. typing too fast, we don't send this notification.

This commit:

- Lifts the notification logic into a new UserSilencer#auto_silence method, which delegates 99% of its work to UserSilencer#silence.
- Uses this new method in places where users are auto-silenced.
2025-10-15 16:07:56 +08:00
Ted Johansson ce1c48b1a9 FIX: Twitter health check broken on Faraday update (#35407)
Faraday [updated their authentication/authorization middleware in version 2](https://github.com/lostisland/faraday/pull/1306), which was a breaking change for the Twitter auth health check.

The relevant test was manually mocking and stubbing the individual Faraday objects, so the relevant code path wasn't exercised by our tests.

This commit:

- Updates the test to use `stub_request` instead. (This correctly catches
the deprecated method error.)
- Updates the health check to use the new middleware.
2025-10-15 15:27:36 +08:00
Rafael dos Santos Silva 78ae5dbc46 FIX: Handle nil @post in CookedProcessorMixin for chat messages (#35386)
Chat::MessageProcessor includes CookedProcessorMixin but only sets
@model, leaving @post as nil. The process_hotlinked_image method was
attempting to access @post.post_hotlinked_media, causing undefined
method errors when processing chat messages with images.
2025-10-14 16:04:25 -03:00
Régis Hanol 4d4de3e63d FIX: watching_first_post topic filter & query (#35353)
The "watching first post" notification level is not a topic notification
level but a category/tag notification level.

This fixes both the "topics_filter.rb" and "topic_query.rb" to account
for this and allow the filter to work.

Ref - meta/t/385316
2025-10-14 11:12:24 +02:00
Krzysztof Kotlarek c16d1e717a FIX: Use default locale for temporarily_closed_due_to_flags (#34718)
When a topic is automatically closed due to flags, the system message
should always use the site's default locale rather than the current
user's locale to ensure consistency for all users viewing the topic.


https://meta.discourse.org/t/temporarily-closed-due-to-flags-notice-not-in-servers-locale/381000/1
2025-10-13 15:34:43 +08:00
Krzysztof Kotlarek cddebd94e1 FIX: Use system user for email-in when staged users disabled (#34655)
When `enable_staged_users` is disabled and a category has
`email_in_allow_strangers` enabled, fallback to using the system user
instead of raising UserNotFoundError. This allows email-in functionality
to work in categories that explicitly allow anonymous email submissions
even when staged users are globally disabled.
2025-10-13 12:22:07 +08:00
Krzysztof Kotlarek 4cf4f9fa61 FIX: URL encode usernames in grant admin redirect (#34664)
The grant admin action was not properly URL encoding usernames
containing unicode characters, causing broken redirect URLs when
usernames include special characters allowed by the
allowed_unicode_username_characters site setting.


https://meta.discourse.org/t/granting-admin-rights-fails-for-usernames-with-special-characters-when-admin-account-has-2fa-enabled/378063
2025-10-13 09:49:23 +08:00
Penar Musaraj 8cbc3bcdfc UX: Better separate login and authentication settings (#33711)
This splits the Login and Authentication admin page into multiple
sections: Settings, social logins, DiscourseConnect, OAuth2.0, OIDC.
Internal ticket `t/161648`

This PR also adds a new extension point for plugins that want to extend
this area of the app.

```
register_site_setting_area("oauth2")
register_admin_config_login_route("oauth2")
```

Adding this to a plugin allows it to extend both the setting areas
(existing functionality) and add a tab to this admin settings screen via
`register_admin_config_login_route`.
2025-10-09 15:29:21 -04:00
Natalie Tay c17eb25b6c FEATURE: Add locale as a filter on topic /filter (#35299)
Adds `locale` as a new filter on /filter for topics.

- locale:en -- single locale filtering
- locale:ja,es -- comma-separated OR logic
- locale:ja locale:es -- space-separated OR logic
- -locale:en -- exclusion of single locale
- -locale:en,ja -- exclusion of multiple locales
- locale:en status:closed -- combination with other filters
2025-10-09 20:29:06 +08:00
Juan David Martínez Cubillos c9e0ee9649 FIX: PG::UniqueViolation for PostTimings in posts:reorder_posts rake task when PostTiming records have no corresponding Post (#35212)
Description
When trying to fix migration issues for wrongly ordered posts by running
rake posts:reorder_posts, you may encounter errors like:
```
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "post_timings_unique"
```
This happens if there are PostTiming records without a corresponding
Post. Currently, the code does not handle these records, and when
updating records to the new order, some values may collide, causing the
error.
2025-10-08 18:48:21 +02:00
Natalie Tay 38e6420016 FEATURE: Also process manually updated translations (#35276)
This is a follow up to
https://github.com/discourse/discourse/pull/34900.

When a user manually updates translation via the translation composer,
also send the new translated cooked for post processing. I moved the
Processor to core, given PostLocalizations are core feature.

<img width="551" height="385" alt="Screenshot 2025-10-08 at 6 12 26 PM"
src="https://github.com/user-attachments/assets/1cce7ce3-5487-4e75-90fd-440792b9a899"
/>
2025-10-09 00:33:36 +08:00
Loïc Guitaut a39785f3dd DEV: Add only_if step to DRSF (#35247)
This patch introduces a new step to the Ruby Service Framework.

`only_if` will execute its block (other steps) only if the provided
condition evaluates to `true`. As for the other steps, the name provided
is the name of the method that will be executed.

```ruby
only_if(:can_update) do
  model :user
  step :update_user
  step :notify
end

private

def can_update(guardian:)
  …
end
```

This step cannot fail and the whole block will be skipped if the method
evaluates to a falsy value.

This is rendered by the steps inspector:

```
[ 1/13] [options] default 
[ 2/13] [model] model 
[ 3/13] [policy] policy 
[ 4/13] [params] default 
[ 5/13] [lock] parameter:other_param 
[ 6/13]   [transaction]
[ 7/13]     [step] in_transaction_step_1 
[ 8/13]     [step] in_transaction_step_2 
[ 9/13] [try]
[10/13]   [step] might_raise 
[11/13] [only_if] condition ⏭️ (condition was not met)
[12/13]   [step] optional_step
[13/13] [step] final_step 
```

The inspector also renders text with colors now.

<img width="419" height="336" alt="Copie d'écran_20251008_162920"
src="https://github.com/user-attachments/assets/add4fd16-076e-4f30-ae1a-3e933494967e"
/>
2025-10-08 17:20:22 +02:00
David Taylor 94539b9d36 DEV: Remove system for vendored JS (#35251) 2025-10-08 08:48:51 +01:00
David Taylor b21d317c64 DEV: Load magnific-popup via npm/webpack (#35250)
This removes our final vendored JS dependency 🎉
2025-10-08 08:28:06 +01:00
Rafael dos Santos SilvaandNat d4e939d053 FEATURE: Add oneboxes and lightboxes to localized posts (#34900)
This change ensures that oneboxes, lightboxes are correctly generated
for localized posts.

The `PostLocalizer` was using `PrettyText.cook` directly, which does not
perform all the necessary post-processing steps, such as onebox
generation.

This commit introduces a new `LocalizedCookedPostProcessor` class that
is responsible for post-processing the cooked HTML of translated posts.
This new class reuses the `CookedProcessorMixin` to gain access to the
`post_process_oneboxes` method. The `PostLocalizer` is updated to use
this new processor, ensuring that oneboxes are correctly generated in
the translated content.

---------

Co-authored-by: Nat <natalie.tay@discourse.org>
2025-10-08 15:14:56 +08:00
David Taylor 843f74e427 DEV: Load chartjs via npm/webpack (#35249) 2025-10-07 21:20:10 +01:00
David Taylor 782e0ea394 DEV: Replace 'squoosh' with jSquash for local media optimization (#35248)
A new webpack entrypoint is created for media-optimization, so that
webpack can take care of bundling up the dependencies. The main Worker
is still hosted in `public/javascripts`, since Workers must be
same-origin.
2025-10-07 19:31:21 +01:00
David Taylor 6c7baf3135 DEV: Stop vendoring pikaday (#35237)
Replace with Webpack-handled async import
2025-10-07 15:52:02 +01:00
David Taylor 8304bb575d DEV: Fix and run javascript:update (#35235)
- Remove broken uglifier require. It wasn't used anyway
- Remove entries for JS bundles which are now loaded via
webpack/node_modules
2025-10-07 14:50:32 +01:00
ducks 6971fffa32 FIX: crash in Admin::PluginsController when plugin has nil commit URL path (#35186)
The `discourse_owned?` method in `lib/plugin/instance.rb` was calling
`.split` on `parsed_commit_url.path` without checking if the path could
be nil. This caused a 500 error on `/admin/plugins` when any plugin had
a commit URL that parsed successfully but returned a nil path (e.g.,
plugins without a git remote configured).

Added a nil check for `parsed_commit_url.path` to gracefully handle this
edge case and prevent the crash. Also added a test case to verify the
method returns false when the parsed URL has a nil path.
2025-10-06 14:39:23 +00:00
Jarek RadoszandLoïc Guitaut 71834c898f DEV: Update rubocop-discourse to 3.13 and autofix issues (#35073)
Co-authored-by: Loïc Guitaut <loic@discourse.org>
2025-10-06 16:11:01 +02:00
Natalie Tay 273c21997a DEV: Move locale check to unified concern (#35207)
Moves the `in_user_locale?` check to the localizable which can be used
by any localized model.

/t/163217, related https://github.com/discourse/discourse/pull/35152
2025-10-06 20:11:52 +08:00
Osama Sayegh 7d2256c455 FEATURE: Split setting for allowing mods to manage categories and groups (#35174)
This commit splits the `moderators_manage_categories_and_groups` setting
into 2 separate settings to allow for more precise control over
categories and groups management by moderators.

Internal topic: t/141392.
2025-10-06 10:43:42 +03:00
Martin Brennan 5faaa6f869 FEATURE: Bump wiki topics when OP is edited (#35137)
c.f. https://github.com/discourse/discourse/pull/34945

This commit updates `PostRevisor` to bump a topic if the
edited post is a wiki post and it is also the first post in
the topic (OP).

In this case, people want to know about a
change to the OP, because it may need to be reviewed (in the case of a
wiki) or it should be “promoted” so that others can see what’s changed
(in the case of general documentation).

A related change in this commit is to add a `should_bump_topic`
plugin modifier, so plugins like Discourse Doc Categories
(see https://meta.discourse.org/t/discourse-doc-categories/322376)
can enforce bumping in certain cases.
2025-10-06 12:46:28 +10:00
Jarek RadoszandLoïc Guitaut a54e3208cb DEV: Hand-pick Rails/WhereNot autofixes (#35117)
We can't enable `Rails/WhereNot` lint/autofix, because it would break
code that uses mini_sql instead of AR (which rubocop, and tbh also we,
can't easily differentiate)

Those are safe because they either:
* are executed in AR model scope definitions
* are clearly chained starting from a AR model
* are less-clearly chained, but still can be traced to a AR model/scope

---------

Co-authored-by: Loïc Guitaut <loic@discourse.org>
2025-10-03 13:29:22 +02:00
Osama SayeghandAlan Guo Xiang Tan 0bc18fdf78 FEATURE: Add site setting to prevent mods from changing trust levels (#35160)
This commit adds a new setting `moderators_change_trust_levels` to
control whether moderators are allowed to change trust level of users.
Moderators are currently allowed to change trust levels, so this new
setting is enabled by default to avoid sudden changes in behavior for
existing sites.

When the setting is disabled and moderators are not allowed to change
trust levels, they see the trust levels dropdown disabled.

Internal topic: t/141392.

---------

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2025-10-03 13:19:24 +03:00
Juan David Martínez Cubillos b880921acf DEV: Ignore Posts with out topics when reordering posts based on their creation date (#35122)
**Description**
Add an option to ignore orphaned posts since these can cause errors when
running the task like:

```
ERROR:
duplicate key value violates unique
PG:: UniqueViolation:
DETAIL: Key (topic_i, post_number, user_id)=(212064, 1, 33887) already exists.

```
2025-10-03 11:58:24 +02:00
Loïc Guitaut a9c988a606 DEV: Serialize cookies using MessagePack (#35082)
This PR uses MessagePack instead of JSON for serializing our cookies.

MessagePack is almost as fast as Marshal but without the security
issues. It’s also able to serialize more objects than JSON (like Time,
Symbol, etc.). As it’s a binary format, it takes less space than JSON,
sometimes half less. Finally, MessagePack isn’t Ruby-specific and
implementations exist in every existing language.

Regarding the cookies Discourse is using, we can see a small improvement
on the `_forum_session` one when it’s almost empty (around 2%), but the
more things are put into it, the more we’ll see savings. For the `_t`
cookie, we’re saving around 20% for free.
2025-10-03 11:40:49 +02:00
Martin Brennan f0e0b02494 FIX: Streamline topic bump functionality and notification settings behaviour (#34945)
Followup 2a65bf4522

With the above change, we inadvertently made it so that
when you edited the topic title or category, we bumped
the topic.

This fix makes it so we do not bump topics when only title, category,
or tags are changed, to restore the previous behaviour.

In addition, we are making it so the following settings no longer
influence topic bump behaviour, keeping only their intended notification
behaviour around. The site setting description never mentioned anything
about topic bumps:

* disable_category_edit_notifications
* disable_tag_edit_notifications
2025-10-03 10:16:54 +10:00
Loïc Guitaut 5146a8e399 Revert "DEV: Debug cookie overflows" (#35120)
Reverts discourse/discourse#34639

We understood the main culprit for cookie overflows was storing
`destination_url` in the session, so we don’t really need that debug
code anymore.
2025-10-02 09:55:47 +02:00
Ted Johansson 064aba3010 FIX: Don't update last_seen_at when impersonating a user (#34872)
Before this change, impersonating a user would result in that user's
`last_seen_at` being updated. This PR fixes that for the new
impersonation feature gated behind the `experimental_impersonation` site
setting.

The old impersonation feature that logs in as the impersonated user has
a completely separate code path. If we decide to backport this change it
will be in a separate PR.
2025-10-02 11:17:15 +08:00
Penar Musaraj 891106d5f4 UX: Add "works with" explanation for Discourse ID logins (#35088)
https://github.com/user-attachments/assets/e8a90b2a-100d-4b8e-87c3-a617a3b9be7c
2025-10-01 09:21:36 -04:00
Blake Erickson d501952f25 DEV: Move convert video job to upload after create (#35013)
This moves the logic for creating the convert_video job to the upload
after_create hook so that we ensure there is an upload_id. When this
logic
was in the s3 store and direct to s3 uploads was enabled the convert
video job
would never fire because we didn't have an upload_id.
2025-09-30 10:58:07 -06:00
David Taylor e797bb5d5f DEV: Improve turbo_rspec and flaky-test output (#35059)
1. Use relative paths instead of absolute. This will make the commands
portable to other machines, and matches the out-the-box behavior of the
regular rspec command

2. Strip out some 'infrastructure' ENV and params from the
rerun_command, so that it's easier to copy/paste and run locally
2025-09-30 10:01:58 +01:00
Alan Guo Xiang Tan a3018bafa9 Bump version to v3.6.0.beta2-latest 2025-09-30 10:39:08 +08:00
Alan Guo Xiang Tan d63a24313a Bump version to v3.6.0.beta1 2025-09-30 10:39:07 +08:00
Gerhard Schlager 2b6675f064 SECURITY: Use nonce-based restrictions during restore 2025-09-30 10:09:46 +08:00
David Taylor 3280852be3 DEV: Change pre-release suffix from -dev to -latest (#35007)
https://meta.discourse.org/t/383536

Also removes the `3.1`-release-specific logic from `version_bump.rake`
2025-09-29 13:10:03 +01:00
Natalie Tay 69ce962a8a DEV: Add discourse-doc-categories to metadata (#34920)
Part of supporting it on our hosting.

/t/162807
2025-09-26 17:12:21 +08:00