Commit Graph

12470 Commits

Author SHA1 Message Date
Mark VanLandingham df1fc5bca8
FIX: Consistently notify lowest post number if post_moved notification generation (#30448)
We currently query the posts table without an order when notifying users of moved posts. Generally the query will return the lowest post number post (b/c ID correlates with post_number in most cases) but not always. This adds an order to the post query in notify_moved_posts job.

Also I removed some if statement nesting with early returns / guard clauses.
2024-12-23 09:53:43 -06:00
Osama Sayegh e2cd1da26d
FIX: All admins should be allowed to see deleted PM posts regardless of their mod status (#30206)
Admins and moderators can see a user's deleted posts via the `/u/:username/deleted-posts` route. Admins can always see any post on the site, but that's not always the case for moderators, e.g., they can't see all PMs. So, this route accounts for that and excludes posts that a moderator wouldn't be allowed to see if they were not deleted.

However, there's currently a problem with that logic where admins who also have moderation privileges, are treated the same way as moderators and prevented from seeing posts that pure moderators can't see. This commit fixes that problem and only applies the permission checks to moderators who don't have admin privileges.

Internal topic: t/143107.
2024-12-23 12:48:03 +03:00
Alan Guo Xiang Tan 859d61003e
DEV: API to register custom request rate limiting conditions (#30239)
This commit adds the `add_request_rate_limiter` plugin API which allows plugins to add custom rate limiters on top of the default rate limiters which requests by a user's id or the request's IP address.

Example to add a rate limiter that rate limits all requests from Googlebot under the same rate limit bucket:

```
add_request_rate_limiter(
  identifier: :country,
  key: ->(request) { "country/#{DiscourseIpInfo.get(request.ip)[:country]}" },
  activate_when: ->(request) { DiscourseIpInfo.get(request.ip)[:country].present? },
)
```
2024-12-23 09:57:18 +08:00
Sam 3fd3a76422
FIX: we introduced a Jobs::UserEmail which broke consistency checks (#30409)
Fix ensures all classes are rooted and there is a spec that will catch
failures next time
2024-12-22 21:33:47 +11:00
Régis Hanol 268d4d4fb9
FIX: more... should not show when there are no visible links (#30405)
When lurking on a Discourse as anonymous, if the sidebar is enabled, and a section contains only secondary links that are not visible to anonymous users, we should not display the "more..." button.

Otherwise it feels broken because clicking on it does nothing, since there are no "visible" links to be shown.

Internal ref t/144716
2024-12-21 01:06:46 +01:00
marstall 3e8e861103
DEV: return full name in /notifications.json (#30335)
* wip: return full name in /notifications.json

* DEV: test for full name

* DEV: add test for enable_names=true

* DEV: add notification6, cleanup

* DEV: fix tests
2024-12-20 11:43:13 -05:00
Keegan George 380910aedd
DEV: Cleanup todos from codebase (#30394)
This PR involves cleaning up the codebase from my (@keegangeorge's) todos. 

In particular:
- Remove Form Template related todos (these are no longer in the roadmap)
- Remove old left-over AI summarization related code after moving to AI (https://github.com/discourse/discourse-ai/pull/658)
- Update one form template related spec
2024-12-19 18:22:33 -08:00
Sam c315e26485
FIX: handle more thread pool edge cases (#30392)
* Split `shutdown` into two separate methods for better control:
  - `shutdown` - signals threads to stop accepting new work
  - `wait_for_termination` - waits for threads to finish (with optional timeout)

* Add tracking of busy threads via `@busy_threads` Set
* Make idle_time parameter optional with 30-second default
* Improve thread spawning logic:
  - Spawn initial thread immediately when work is posted
  - Spawn additional threads when all threads are busy and work is queued
* Fix race condition in work distribution
* Add busy thread count to stats output
* Add test coverage for zero min_threads configuration

This commit makes the ThreadPool more reliable, easier to use, and adds 
better visibility into its internal state.

---------

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2024-12-20 11:50:00 +11:00
Martin Brennan b3fa335c7d
UX: Admin sidebar link changes (#30365)
Make all links in the admin sidebar follow https://meta.discourse.org/t/formatting-text-in-discourse-documentation-and-uis/324637

Remove the following links, and add keywords to their root links.
Email logs section is removed entirely.

* Email Settings > Preview Summary
* Email Logs > Sent
* Email Logs > Skipped
* Email Logs > Bounced
* Email Logs > Received
* Email Logs > Rejected
* Security > Error Logs
* Security > Screened Emails
* Security > Screened IPs
* Security > Screened URLs
* Security > Search Logs
* Advanced > Webhooks
2024-12-20 09:58:42 +10:00
Sam efa50a4da2
FEATURE: ThreadPool implementation (#30364)
This commit introduces a new ThreadPool class that provides efficient worker
thread management for background tasks. Key features include:

- Dynamic scaling from min to max threads based on workload
- Proper database connection management in multisite setup
- Graceful shutdown with task completion
- Robust error handling and logging
- FIFO task processing with a managed queue
- Configurable idle timeout for worker threads

The implementation is thoroughly tested, including stress tests, error
scenarios, and multisite compatibility.
2024-12-20 07:37:12 +11:00
Penar Musaraj 6873962572
DEV: Fix flakey spec (#30382) 2024-12-19 14:19:34 -05:00
David Taylor d2979997e9
DEV: Introduce new 'glimmer topic list mode' site setting (#30375)
This replaces the previous group-based site setting
2024-12-19 17:38:35 +00:00
Keegan George d886c55f63
DEV: Reusable post-list component (#30312)
This update adds a  _new_ `<PostList />` component, along with it's child components (`<PostListItem/>` and `<PostListItemDetails />`). This new generic component can be used to show a list of posts.

It can be used like so:
```js
/**
 * A component that renders a list of posts
 *
 * @component PostList
 *
 * @args {Array<Object>} posts - The array of post objects to display
 * @args {Function} fetchMorePosts - A function that fetches more posts. Must return a Promise that resolves to an array of new posts.
 * @args {String} emptyText (optional) - Custom text to display when there are no posts
 * @args {String|Array} additionalItemClasses (optional) - Additional classes to add to each post list item
 * @args {String} titleAriaLabel (optional) - Custom Aria label for the post title
 * 
*/
```
```hbs
<PostList
    @posts={{this.posts}}
    @fetchMorePosts={{this.loadMorePosts}}
    @emptyText={{i18n "custom_identifier.empty"}}
    @additionalItemClasses="custom-class"
 />
```
2024-12-19 09:20:25 -08:00
Blake Erickson 17bdffc900 SECURITY: When enabled only allow Discourse Connect logins
If Discourse Connect is enabled no other methods for account creation or
authentication should be allowed.
2024-12-19 13:13:23 -03:00
Krzysztof Kotlarek 95564a3df2 SECURITY: Moderators cannot see user emails.
Unless `moderators_view_emails` SiteSetting is enabled, moderators should not be able to discover users’ emails.
2024-12-19 13:13:18 -03:00
Martin Brennan 553784f919
DEV: Delete AdminPageHeader and AdminPageSubheader components (#30337)
No longer needed because of https://github.com/discourse/discourse/pull/30146
and there are plugin PRs to remove other traces of it
2024-12-19 12:47:14 +10:00
Alan Guo Xiang Tan e4e5db57f0
DEV: Fix undefined method `check_email_sync_heartbeat` in unicorn conf (#30360)
This is a follow-up to 9812407f76
2024-12-19 10:10:11 +08:00
Krzysztof Kotlarek fdb6634fa9
FEATURE: settings tab for permalinks (#30192)
Setting tab should be added to permalinks so admins do not need to have left `/permalinks`.

A new component called `AreaSetting` was added to avoid duplications and
simplify adding settings to other sections.
2024-12-19 10:40:34 +11:00
Mark VanLandingham 5721c29429
DEV: Plugin modifier to skip enqueue PostCreator jobs on PostMove (#30344)
This allows plugins to skip the "posted" notifications for watching users, when posts get moved. The specs are kind of wild looking, as this unit tests a private method. This is difficult to isolate otherwise, with lots of trickery needed to make sure that this actually works.

I opted to unit test just this method instead.
2024-12-18 12:37:52 -06:00
Jarek Radosz 5747b910e6
FIX: Unpinning topics in glimmer topic list (#30342)
it's already handled by TopicStatus component (so one was undoing the other's toggle)
2024-12-18 15:55:02 +01:00
Loïc Guitaut 133a648d9b DEV: Fix policy classes delegating their `#call` method in services
There’s currently a bug when using a dedicated class as a policy in
services: if that class delegates its `#call` method (to an underlying
strategy object for example), then an error will be raised saying steps
aren’t allowed to provide default parameters.

This should not happen, and this patch fixes that issue.
2024-12-18 09:59:40 +01:00
Alan Guo Xiang Tan 9812407f76
FIX: Redo Sidekiq monitoring to restart stuck sidekiq processes (#30198)
This commit reimplements how we monitor Sidekiq processes that are
forked from the Unicorn master process. Prior to this change, we rely on
`Jobs::Heartbeat` to enqueue a `Jobs::RunHeartbeat` job every 3 minutes.
The `Jobs::RunHeartbeat` job then sets a Redis key with a timestamp. In
the Unicorn master process, we then fetch the timestamp that has been set
by the job from Redis every 30 minutes. If the timestamp has not been
updated for more than 30 minutes, we restart the Sidekiq process. The
fundamental flaw with this approach is that it fails to consider
deployments with multiple hosts and multiple Sidekiq processes. A
sidekiq process on a host may be in a bad state but the heartbeat check
will not restart the process because the `Jobs::RunHeartbeat` job is
still being executed by the working Sidekiq processes on other hosts.

In order to properly ensure that stuck Sidekiq processs are restarted,
we now rely on the [Sidekiq::ProcessSet](https://github.com/sidekiq/sidekiq/wiki/API#processes)
API that is supported by Sidekiq. The API provides us with "near real-time (updated every 5 sec)
info about the current set of Sidekiq processes running". The API
provides useful information like the hostname, pid and also when Sidekiq
last did its own heartbeat check. With that information, we can easily
determine if a Sidekiq process needs to be restarted from the Unicorn
master process.
2024-12-18 12:48:50 +08:00
Martin Brennan a879bcdc35
DEV: Introduce <DPageHeader /> and <DPageSubheader /> components (#30146)
This converts the `<AdminPageHeader />` component and the
`<AdminPageSubheader />` components into new components
that can be used outside of admin, and updates the CSS classes.
Also introduces a `<DPageActionButton />` component and child
components for the header action buttons.

I have to keep the old admin-only components around for
now until plugins are updated, then we can remove it,
and remove the re-exports that are done within
admin-page-action-button.gjs
2024-12-18 08:13:39 +10:00
Mark VanLandingham 415abe6491
FIX: Correctly place moderator post for full topic move with freeze_original (#30324)
When freeze_original option is passed to PostMover, and we are moving all posts there is an issue. We attempt to put the small_action right after the last moved post. The issue is when there is an existing small action after the last moved "real" post. We then try to put the moderator post at the same location of the existing small action, which causes an index conflict and the move fails.

This makes sure that we place the moderator post at the verrrrrry end of the topic :)
2024-12-17 10:31:34 -06:00
Ted Johansson f9e07ff9d2
DEV: Fix flaky users_email_controller_spec test case (#30318)
This should be the last fallout from changing hide_email_address_taken default. 🤞
2024-12-17 18:20:01 +08:00
Ted Johansson d56346982f
DEV: Fix controller tests failing in parallel suite only (#30314)
These controller tests are passing locally and in CI, but are failing the build when run in parallel.

I managed to recreate the failures by running the entire suite with turbo_spec and the right seed locally. After these changes, the parallel suite passes locally as well. 🤞
2024-12-17 14:08:40 +08:00
Sam 4437aced91
FIX: use relations for new_in_category (#30313)
`new_in_category` was using `first` instead of `limit`

This meant it gets an array and that means that you can not operate on it easily in a modifier.

This ensures we always give the modifier a relation, with the notable exception of suggested topics.
2024-12-17 16:39:07 +11:00
Ted Johansson c1c7ea8959
DEV: Change hide_email_address_taken default to true (#30293)
We're changing the default of hide_email_address_taken to true. This is a trade-off we want to make, as it prevents account enumeration with minimal impact on legitimate users. If you forget you have an account and try to sign up again with the same e-mail you'll receive an e-mail letting you know.
2024-12-17 10:46:04 +08:00
Sam 55a8184231
FEATURE: Reason and deleted content support in the review queue (#30295)
Add flag reason filter and improve handling of deleted content in review queue

This commit enhances the review queue with several key improvements:

1. Adds a new "Reason" filter to allow filtering flags by their score type
2. Improves UI for deleted content by:
   - Adding visual indication for deleted posts (red background)
   - Properly handling deleted content visibility for staff (category mods can not see deleted content)
3. Refactors reviewable score type handling for better code organization
4. Adds  tests for trashed topics/posts visibility

This change will help moderators more efficiently manage the review queue by
being able to focus on specific types of flags and better identify deleted
content.
2024-12-17 11:44:46 +11:00
Natalie Tay d43d8e0023
FIX: Searchable user fields do not always have an integer name (#30223) 2024-12-17 11:06:19 +11:00
Krzysztof Kotlarek a8bdc5f7c5
UX: display link to groups in admin sidebar (#30291)
Add groups link to admin and moderator sidebar for easy access.
Currently, the admin needs to go to `users` first.
2024-12-17 10:07:24 +11:00
Joffrey JAFFEUX 41df705188
DEV: replaces topic-notifications-options by DMenu (#30298)
This commit introduces <NotificationsTracking /> which is a wrapper component around <DMenu /> which replaces the select-kit component <TopicNotificationsButton />.

Each tracking case has its dedicated component:

- topic -> `<TopicNotificationsTracking />`
- group -> `<GroupNotificationsTracking />`
- tag -> `<TagNotificationsTracking />`
- category -> `<CategoryNotificationsTracking />`
- chat thread -> `<ThreadNotificationsTracking />`
2024-12-16 19:59:18 +01:00
David Taylor ea9cdf7d47
DEV: Compile theme raw-hbr to modules (#30299)
Previously, theme hbr files were compiled to an IIFE, which would be executed before the app is booted. That is causing silenced deprecations to be printed, because the deprecation-workflow isn't set up when the IIFE is run.

This commit updates the theme compiler so that it matches the ember-cli-based raw-hbs compiler. Templates are output to normal modules, which will then be loaded by the existing `eager-load-raw-templates` initializer. This runs after the app has started booting.
2024-12-16 17:31:49 +00:00
Kelv 04ba5baec0
DEV: ensure rebaking works even when some users have inconsistent data (#30261)
* DEV: add db consistency check for UserEmail

* DEV: add db consistency check for UserAvatar

* DEV: ignore inconsistent data related to user avatars when deciding whether to rebake old posts


Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

---------

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2024-12-16 19:48:25 +08:00
Mark VanLandingham 85773eee21
DEV: Pass in old post to post_moved DiscourseEvent (#30274) 2024-12-13 12:30:00 -06:00
Renato Atilio a21f064fad
UX: add color-scheme meta tag to _head (#30245)
Adds the `color-scheme` meta tag to the `_head` partial and removes it from the finish installation template to prevent it from being added twice.
2024-12-13 08:10:08 -03:00
Loïc Guitaut 9e9abe0a82 DEV: Unify params access in services
Currently, there are two ways (kind of) for accessing `params` inside a
service:
- when there is no contract or it hasn’t been reached yet, `params` is
  just the hash that was provided to the service. To access a key, you
  have to use the bracket notation `params[:my_key]`.
- when there is a contract and it has been executed successfully,
  `params` now references the contract and the attributes are accessible
  using methods (`params.my_key`).

This patch unifies how `params` exposes its attributes. Now, even if
there is no contract at all in a service, `params` will expose its
attributes through methods, that way things are more consistent.

This patch also makes sure there is always a `params` object available
even when no `params` key is provided to the service (this allows a
contract to fail because its attributes are blank instead of having the
service raising an error because it doesn’t find `params` in its context).
2024-12-13 11:13:18 +01:00
Mark VanLandingham bbb31b05ca
DEV: add full_move to MovedPost record small_action modifier (#30236)
This commit adds a new column full_move to the moved_posts table. This is useful to look back at history and determine if a whole topic was moved or partial.

This commit also adds an apply_modifier to skip the creation of the moved posts small action.
2024-12-12 11:47:14 -06:00
Loïc Guitaut a589b48f9a DEV: Display better output when inspecting service steps
This patch aims to improve the steps inspector output:
- The service class name is displayed at the top.
- Next to each step is displayed the time it took to run said step.
- Steps that didn’t run are hidden.
- `#inspect` automatically outputs the error when it is present.
2024-12-12 15:21:10 +01:00
Régis Hanol 44cabc3569
FIX: proper details / summary excerpt (#30229)
It doesn't make much sense to have the content of a `<details>` in an excerpt so I replaced them with "▶ summary" instead.

That way, they can't be (ab)used in user cards for example.

Reference - https://meta.discourse.org/t/335094
2024-12-12 09:09:49 +01:00
Bianca Nenciu a835fd99bd FIX: Truncate bookmarks.name when remapping
The new name may be too long for the bookmarks.name column and raise an
exception. This changes allows the remapper to truncate the new value to
fit (truncates to 100 characters).
2024-12-11 18:53:17 -05:00
Sérgio Saquetim 1505978586
DEV: Upgrade dependencies to Ember 5.12 (#30131) 2024-12-11 11:09:25 -03:00
Régis Hanol 6ef0b5d508
Cleanup mobile topic footer area (#30132) 2024-12-11 14:59:37 +01:00
Gary Pendergast 28a1463baf
FIX: When moving first posts between topics, ensure only relevant timings are moved (#30217) 2024-12-11 17:03:47 +11:00
Alan Guo Xiang Tan 864b7b6bc8
DEV: Fix flaky test (#30215)
The test was flaky and failing with the following errors:

```
Failure/Error:
  klass
    .connection
    .select_raw(relation.arel) do |result, _|
      result.type_map = DB.type_map
      result.nfields == 1 ? result.column_values(0) : result.values
    end

NoMethodError:
  undefined method `select_raw' for nil

./lib/freedom_patches/fast_pluck.rb:60:in `pluck'
./vendor/bundle/ruby/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/relation/calculations.rb:354:in `pick'
./app/models/web_crawler_request.rb:27:in `request_id'
./app/models/web_crawler_request.rb:31:in `rescue in request_id'
./app/models/web_crawler_request.rb:26:in `request_id'
./app/models/web_crawler_request.rb:19:in `write_cache!'
./app/models/concerns/cached_counting.rb:135:in `block (3 levels) in flush_to_db'
./vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
./vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
./app/models/concerns/cached_counting.rb:134:in `block (2 levels) in flush_to_db'
./app/models/concerns/cached_counting.rb:124:in `each'
./app/models/concerns/cached_counting.rb:124:in `block in flush_to_db'
./lib/distributed_mutex.rb:53:in `block in synchronize'
./lib/distributed_mutex.rb:49:in `synchronize'
./lib/distributed_mutex.rb:49:in `synchronize'
./lib/distributed_mutex.rb:34:in `synchronize'
./app/models/concerns/cached_counting.rb:120:in `flush_to_db'
./app/models/concerns/cached_counting.rb:187:in `perform_increment!'
./app/models/web_crawler_request.rb:15:in `increment!'
./lib/middleware/request_tracker.rb:74:in `log_request'
./lib/middleware/request_tracker.rb:409:in `block in log_later'
./lib/scheduler/defer.rb:125:in `block in do_work'
./vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management/null_instance.rb:49:in `with_connection'
./vendor/bundle/ruby/3.3.0/gems/rails_multisite-6.1.0/lib/rails_multisite/connection_management.rb:21:in `with_connection'
./lib/scheduler/defer.rb:119:in `do_work'
./lib/scheduler/defer.rb:105:in `block (2 levels) in start_thread'
```

This was due to running the defer thread in an async manner which is
actually no representative of the production environment. It also
revealed a spot in our code base where writes are happening in a GET
request which can cause requests to fail if ActiveRecord is in readonly
mode.
2024-12-11 10:12:58 +08:00
Isaac Janzen 00f8d7bb5d
DEV: Remove unused `binding.pry` (#30207) 2024-12-10 11:25:37 -06:00
Blake Erickson ed13ae7787
DEV: Fix specs for directory items controller (#30160)
The directory items controller specs that have a search param were not
matching how things worked in production. In a non-test environment the
UserSearch class depends on the `user_search_data` table being
populated, so the tests I corrected now use this table as well to match
reality.

Also added a new test to match the 20 user limit for search results that
currently exists. This 20 user limit is on the line between a bug and a
feature but it is how it is currently working so we should document
that. We have plans to increase this limit and it has been documented
here: https://meta.discourse.org/t/296485

This PR is a no-op and only changes the tests.

Co-authored-by: brrusselburg <25828824+brrusselburg@users.noreply.github.com>
2024-12-10 08:55:29 -07:00
zogstrip aaec80413d FIX: fast edit with a typographic character
When a post containing an apostrophe (') is being cooked, the apostrophe is being converted to the "typographic" version (’) (because we enable markdown-it's **typographer** mode by default in Discourse)

When you select text that contains such apostrophe and then try to save your fast edit, it fails miserably without any error.

That's because when you select text from the DOM, it uses the cooked version which has the typographic apostrophe.

When you save your fast edit, we fetch the raw version of the post, which has the "regular" apostrophe. Thus doing `raw.replace(selectedText, editedText)` doesn't work because `raw` has the regular apostrophe but `selectedText` has the typographic apostrophe.

Since it's somewhat complicated to handle all typographic characters, we would basically have to reverse the process done in `custom-typographer-replacements.js`, we instead bail out and show the composer when we detect such character in the selection.

Internal ref - t/143836
2024-12-10 12:13:10 +01:00
Alan Guo Xiang Tan f35128c6ed
DEV: Fix broken sidekiq logging due to eeb01ea0de (#30199) 2024-12-10 17:01:25 +08:00
Sam 58e3e0cc4f
FEATURE: add support for "Flagged By" filter in reviewable (#30197)
Previous to this change there was no way to find all the flags
a user raised.

New filter allows you to find all the flags raised by a user.
2024-12-10 18:26:38 +11:00