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? },
)
```
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
Followup 203f93bcaf
This commit makes sure the background for all the admin
site settings filters (including the filter input and
override checkbox) is consistent no matter what the theme,
as it currently changes based on theme.
The security fix in 15b43a2 also introduced some unrelated refactoring to the file, which seems to be causing issues in some environments. This commit reverts the refactoring, and applies the security fix to each block individually.
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"
/>
```
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.
extra-locales bundles have unique digests in their URLs, and include an indefinite cache-control header. Therefore we should include them in the heavily-cached group of URLs in NGINX.
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.
When adding new fonts to our discourse-fonts gem,
you may want to test these changes locally using the
`path` option of the gem line in bundler.
However we set a symlink for the fonts dir for public/fonts,
which does not get updated if the gem path changes. This
fix checks if the current symlink resolved path is equal to
the DiscourseFont gem path, and if not deletes + recreates it.
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.
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.
This will help us keep consistency with things that we've decided to rename. Initial rules are for "color scheme" -> "color palette", and "private message" -> "personal message".
Also updates some remaining occurences of "color scheme" in our translation files.
Co-authored-by: Gerhard Schlager <gerhard.schlager@discourse.org>
`<DSelect />` is a wrapper similar to our existing `<DButton />` over the html element `<select>`. The code is ported from form kit which is now directly using `<DSelect />`. Note this component has also been used in edit topic timer modal.
This component is recommended for a small list of text items (no icons, no rich formatting...).
Usage:
```gjs
<DSelect class="my-select" @onChange={{this.handleChange}} as |select|>
<select.Option @value="foo" class="my-favorite-option">Foo</select.Option>
<select.Option @value="bar">Bar</select.Option>
</DSelect>
```
This commit comes with a set of assertions:
```gjs
import dselect from "discourse/tests/helpers/d-select-helper";
import { select } from "@ember/test-helpers";
assert
.dselect(".my-select")
.hasOption({ value: "bar", label: "Bar" })
.hasOption({ value: "foo", label: "Foo" })
.hasNoOption("baz");
await select(".my-select", "foo");
assert.dselect(".my-select").hasSelectedOption({value: "foo", label: "Foo"});
```
This commit starts the rollout of the Glimmer post menu:
- default to `auto`: after the upgrade, it will be enabled on all discourse instances that do not have incompatible customizations
- unsilence the deprecation messages in the console
- removes the setting `glimmer_post_menu_groups` as it's no longer in the test phase
In 6cafe59c76, we added a monkey patch to
`Unicorn::HtppServer#murder_lazy_workers` to log a message and send a
`USR2` signal to the Unicorn worker process when they Unicorn worker
process is 2 seconds away from being timed out by the Unicorn master
process. However, we ended up loggging multiple messages and sending
multiple USR2 signal during the 2 seconds before the Unicorn worker
process hit the time out.
To overcome this problem, we will now set an instance variable on the
`Unicorn::Worker` instance and use it to ensure that the log message is
only logged once and USR2 signal to the Unicorn worker process is only
sent one as well.
This is a follow-up to e6fdfcdcd2 which
did not remove the site setting from `config/site_settings.yml` and drop
the site setting value from the database.
This commit will now show a "Select..." option when no value selected and a "None" option when a value is selected, as the first row. It ensures that people don't think a value is selected when it's actually just the html select showing the first available option.
* DEV: add table heading for status
* UX: Move revoked status to its own column with a badge; remove revoked icon
* UX: Increase text contrast for revoked rows
Previously when attempting to edit a globally shadowed setting, the
error message was not very helpful, it said "You are not allowed to
change hidden settings". This commit changes the error message to
reflect the actual problem, which is that the setting is shadowed by
a global setting via ENV var.
In our CI env, sometimes, we see problems regarding getting a connection
from the pool. As it’s currently set to 1, increasing it a bit should
fix that kind of issues.