This commit updates the `Jobs::BadgeGrant` scheduled job to enqueue on
`Job::BackfillBadge` regular job for each enabled badge on the site.
The rationale for this change is that we started seeing the
`Jobs::BadgeGrant` job taking hours on sites with lots of enabled badges
as well as users because the job was backfilling all enabled badges
serially within the job. This is bad as it means that a `mini_scheduler`
thread is tied up
by this job thus reducing the overall capacity of `mini_scheduler` for
hours.
The name "Staff Notice" was not quite right since TL4 users
can also add these notices. This commit changes the wording to
"Official Notice".
In addition to this, currently you have to go look into the staff
action logs to see who is responsible for a notice. This commit
stores the ID of the user who created the notice, then shows this
information on each notice to staff users.
Finally, I migrated the ChangePostNoticeModal component to gjs.
Follow-up to 7fc8d74f3eed52116add452b5321b41e02e04499.
This change moves the guardian check for whether an export has been generated too recently to the endpoint handler, since we only want this check to apply when generating an export.
The GDPR requires all users to be able to export their data, or request an export of their data. This is fine for active users as we have a data export button on user profiles, but suspended users have no way of accessing the data export function, and the workaround for admins to export data for suspended users involves temporarily unsuspending them, then impersonating the user to export the data as them.
Since suspended users no longer have access to their account, we can safely assume that the export request will be coming via a medium outside of Discourse (eg, email). This change is built with this workflow in mind.
This change adds a new "User exports" section to the admin user page, allowing admins to start a new export, and to download the latest export file.
Recently we introduced a new `PostList` component (d886c55f63). In this update, we make broader adoption of this component. In particular, these areas include using the new component in the user activity stream pages, user's deleted posts, and pending posts page. This update also takes the existing `posts` route and adds a barebones front-end for it to view posts all in one page.
---------
Co-authored-by: David Taylor <david@taylorhq.com>
adds a hidden site setting, "prioritize_full_names_in_ux", whose effect is to prefer full names in user-menu notifications
Co-authored-by: Mark VanLandingham <markvanlan@gmail.com>
Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
Follow up from https://github.com/discourse/discourse/pull/27712.
Currently, we already add `noindex` to /u routes. However, due to
robots.txt blocking this, search engines are not able to see the header.
This commit removes /u from our robots.txt to allow search engines to
see the header. This commit also includes a migration to remove the /u
from admins who have overridden the file. I had contemplated not
including this migration, but seeing there are existing site admins who
are trying to remove errors from their dashboard, they would probably
welcome this change.
The migration replaces overridden text at this area, and will not modify
if additional routes have been added in-between:
<img width="500" alt="Screenshot 2025-01-15 at 11 28 43 AM copy"
src="https://github.com/user-attachments/assets/60db64c9-ed33-48a5-a917-a10545282a5c"
/>
Side effect note: This might potentially result in more pageviews* from
GoogleBot (for example) for a period of time as Google starts visiting
the user routes they have been denied before.
This change allows controllers that construct TopicQuery parameters, to pass per_page into the TopicQuery constructor as an option. I can't see why this shouldn't be a public param, so long as we properly validate the value!
Internal discussion at t/145686.
It is possible for admins to rename users like `system`
to some other username, but if they try to change it back
they cannot, since `system` is a reserved username.
This commit allows admins to change any user's username
to a reserved username _as long as that username is not
already in use_.
The chat emoji picker is renamed emoji-picker, and the old emoji-picker is removed.
This commit doesn't attempt to fully rework a new emoji-picker but instead tries to migrate everything to one picker (the chat one) and add small changes.
Other notable changes:
- all the favorite emojis code has been mixed into one service which is able to store one state per context, favorites emojis will be stored for all topics, and for each chat channel. Meaning that if you always use a specific emoji in a channel, it will only show as favorite emoji in this channel.
- a lot of static code has been removed which should improve initial load perf of discourse. Initially this code was around to improve the performance of the emoji picker rendering.
- the emojis are now stored, once the full list has been loaded, if you close and reopen the picker it won't have to load them again.
List of components:
- `<EmojiPicker />` will render a button which will open a dropdown
- `<EmojiPickerContent />` represents the content of the dropdown alone, it's useful when you want to render a picker from an action which is not the default picker button
- `<EmojiPickerDetached />` just a simple wrapper over `<EmojiPickerContent />` to make it easier to use it with `this.menu.show(...)`
---------
Co-authored-by: Renato Atilio <renatoat@gmail.com>
This adds the Silence Reason column to silenced user lists.
This feature helps combat large spam attacks cause you can quickly see
why a user was silenced and then bulk act on all the silenced users
The customize routes add CSS classes that make these admin
config pages look different from the ones under /admin/config.
We want all config routes to be under /admin/config as well.
This commit moves the emoji, user fields, and permalinks pages
out of customize and into config, updating all references and
adding more rails routes as needed.
Also renames admin emojis route to emoji, emoji is singular and plural.
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.
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.
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.
In 806e37aaec549069a599fd31edc16c5cdcd0774e, I improved the conflict handling when editing a post to account for title and tags.
This fixes an edge cases when a topic has a hidden tag the current editor can't see. When they submit their edit, we automatically add the hidden tags before checking with the tags stored in the database.
Reported in https://meta.discourse.org/t/341375
PostMover has a new option called freeze_original implemented in this commit. It was previously unexposed in the controller. This PR permits the param in the controller, and passes it into PostMover.
Also, this applies a value transformer for move/merge payload options. In addition a plugin outlet in the move post modal. This allows plugins to add content to the modal, which can modify the payload (and use the freeze_original argument for example)
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.
The hierarchical search for categories is composed of several complex
nested queries. This change ensures that the secured categories are
filtered out as soon as possible to ensure that the default limit of 5
categories is reached.
Without this fix, the search can return less than 5 categories if any
of the first 5 categories cannot be displayed due to permissions.
Sometimes changes to "What's new?" feed items are made or the feed items are
removed altogether, and the polling interval to check for new features is 1 day.
This is quite long, so this commit introduces a "Check for updates"
button for admins to click on the "What's new?" page which will bust
the cache for the feed and check again at the new features endpoint.
This is limited to 5 times per minute to avoid rapid sending of
requests.
Previously, the secure-upload redirection logic would fail for extension-less files. This commit updates it to work, and adds a spec for the behavior.
Extension-less file uploads are not allowed by default, so this is a very niche situation.
This commit introduces a new feature that allows staff to bulk select and delete users directly from the users list at `/admin/users/list`. The main use-case for this feature is make deleting spammers easier when a site is under a large spam attack.
Internal topic: t/140321.
This moves the logic of setting the correct permalink values back into the controller. And it replaces the validation with a simpler one, that always works, even when the model is loaded from the DB.
Follow-up to #29634 which broke import scripts and lots of documentation on Meta.
* FEATURE: Add skip notification option to group invite to topic
* DEV: rename `skip_notification` to `should_notify`
* DEV: update `should_notify` param to be default `true` in controllers
* DEV: update spec to use `greater than` instead of `equal to` to prevent flakiness
* Update app/controllers/topics_controller.rb
Co-authored-by: David Taylor <david@taylorhq.com>
* DEV: merged two `#invite_group` specs into one
* DEV: Added test case for `invite-group` in requests spec
---------
Co-authored-by: David Taylor <david@taylorhq.com>
Redesign the permalinks page to follow the UX guide. In addition, the ability to edit permalinks was added.
This change includes:
- move to RestModel
- added Validations
- update endpoint and clear old values after the update
- system specs and improvements for unit tests
Follow up to 6f8f6a7726
Prior to the linked commit, the `uploads#create` endpoint had a `upload_type` and `type` param that acted as aliases for each other and raised an error if both of them were missing. In the linked commit, we removed the `type` param and always required the `upload_type` param which break API consumers that only included `type` in their requests.
This commit adds back the `type` param temporarily and introduces a deprecation message for it so that API consumers are made aware of the eventual removal of the `type` param.
Prior to Uppy, the `uploads#create` endpoint used to receive a `type` param that indicated the purpose/target of the upload, such as `avatar`, `site_setting` and so on. With the introduction of Uppy, the `type` param became the MIME type of the file being uploaded, and the purpose/target of the upload became a new param called `upload_type`, however the backend could still use the `type` param (which now contains MIME type) as the purpose/target of the upload if `upload_type` is absent.
We technically don't need to send the MIME type over the network, but it seems like it's done by Uppy and we have no control over the `type` param that Uppy includes:
758de8167b/app/assets/javascripts/discourse/app/lib/uppy/uppy-upload.js (L146-L151)
This commit does a couple of things:
1. It amends the `uploads#create` endpoint so it always requires the `upload_type` param and doesn't fallback to `type` if `upload_type` is absent
2. It forces consumers of the `UppyUpload` class (and by extension `UppyImageUploader`) to specify `type` of the upload
Internal topic: t/140945.