1212 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
Krzysztof Kotlarek
a69a304f11
FEATURE: allow edit custom flags (#32344)
Allow admins to edit user custom flags. Because changing
name/description will update name/description for old reviewables,
warning has to be displayed.

Still, system flags can never be edited or deleted (only disabled).
2025-04-17 12:31:52 +08: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
Renato Atilio
bc070dcbe3
FIX: avoid double base path on push notification (#32228)
Our service worker concatenates `baseUrl` with `url` coming from the
payload:


e8f4433872/app/views/static/service-worker.js.erb (L96)

This PRs strips the base path before sending `url` to the push
notification to avoid having a URL with the base path duplicated,
causing a 404.
2025-04-12 08:16:53 +10:00
Loïc Guitaut
c90544ab44 DEV: Add missing specs to User::BulkDestroy 2025-04-08 11:42:51 +02:00
Ted Johansson
b40cbfcb76
DEV: Move backfill into SiteSetting::Update service (#32037)
Some site settings support backfilling if the user specified it. This works fine for singular site settings sent to the SiteSettingsController#update endpoint, but with bulk save we need to support this for a list of settings as well.

This change alters the params format for SiteSetting::Update.

It also moves the backfill logic into the service.
2025-03-28 12:01:56 +08: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
Penar Musaraj
6aaddcf381
FEATURE: enable full page login by default (#31771)
This switches the signup/login UI to the full page experience by
default. This has been in use by many sites for multiple months and we
have ironed out many fixes in the meantime.

The `full_page_login` setting is also marked for removal in about
1.5mths, by the end of April 2025.
2025-03-25 13:43:51 -04:00
Ted Johansson
b4085c7b50
DEV: Support target in problem check problem constructor (#31922)
We didn't have support in the #problem constructor for multiple targets, forcing developers to manually construct a Problem instance. This involves a lot of details and is error prone.

This PR supports passing an optional target argument to the constructor. This will be passed on to the translation_data method to generate the correct message as well.
2025-03-24 10:10:41 +08: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
Ted Johansson
3165992a90
DEV: Destroy posts rake task enhancements (#31739)
This improves the new rake task to bulk delete posts based on feedback:

- Honour the `can_permanently_delete` site setting.
- Fix a warning about a scope order no being applied due to batching.
- Fix an issue where double delete would result in duplicate user
histories.
2025-03-14 13:20:43 +08:00
Osama Sayegh
25e8b5af9f
FEATURE: Introduce new color palettes config area (#31742)
As part of the theme/color palette overhaul project, we're introducing a
new admin page for editing color palettes. The new page is located at
`/admin/config/colors/:id`. It's linked from anywhere, but it will be
linked in the sidebar as we progress more in the overhaul project.

Related PRs: https://github.com/discourse/discourse/pull/30893
https://github.com/discourse/discourse/pull/30915
https://github.com/discourse/discourse/pull/31328.

Internal topic: t/148628.
2025-03-12 16:57:31 +03:00
dsims
89a297fde3
FIX: Use filename as alt for hotlinked image uploads (#31651)
Currently, when converting raw hotlinked image urls to image upload
markdown, the `alt` attribute is left blank.
This change sets the `alt` to the original filename (which means it will
also appear in the lightbox).
This adds more context and accessibility to the image and is consistent
with how regular uploaded images default to use the filename.

For example:
`http://foo.bar/screenshot.jpg` becomes
`![screenshot](upload://bEs9WFJErcB8y7m1Ye5JopTWeX3.jpeg)`
2025-03-11 14:45:06 +11:00
Krzysztof Kotlarek
54771b5949
FIX: remove admin_sidebar_enabled_groups setting (#31693)
Old no sidebar admin panel is deprecated and admin sidebar is not
experimental anymore. Therefore, old setting should be deleted.
2025-03-11 11:41:38 +11:00
Gary Pendergast
e4401e587e
FIX: Ensure queued posts with watched words are processed correctly. (#31641)
This change ensures that queued posts that have ended up in the review queue due to matched a watched word display correctly.

It also improves the data checking to ensure that any other reviewables with watched words don't break the review queue, either.
2025-03-05 13:59:42 +11:00
Ted Johansson
828fcb1ad3
DEV: Add rake task to bulk delete posts (#31642)
Same as #31576, but in that one I added some support files that turned out to be unnecessary and broke the build. So this is the re-do. 🙏
2025-03-05 09:31:23 +08:00
Ted Johansson
7d4e4e9422
Revert "DEV: Add rake task to bulk delete posts" (#31607)
Breaks the build. Need to update the spec.
2025-03-04 20:54:03 +08:00
Ted Johansson
42c4427cb1
DEV: Add rake task to bulk delete posts (#31576)
This PR adds a destroy:posts rake task that can be used to hard-delete a list of posts. Useful for dealing with large amounts of spam that has been soft deleted and needs to go.

Notes:

Works on both non-deleted and soft-deleted posts. (We might want to change this to work on only soft-deleted posts?)
Works exclusively on post IDs. We can't mix topic and post IDs as they might clash, and we have no way of resolving that ambiguity.
Accepts either a rake-style array of IDs or, more conveniently, you can pipe the argument in through STDIN.
Added a confirmation step since it's a fairly destructive operation.
2025-03-04 17:29:38 +08:00
Krzysztof Kotlarek
d50bba3bdc
DEV: Allow SiteSetting::Update service to bulk update (#31438)
Previously, the SiteSetting::Update service allowed to update of a
single site setting. In the About controller, we were using the loop
through all settings -
https://github.com/discourse/discourse/blob/main/app/controllers/admin/config/about_controller.rb#L39

It is suboptimal because if the 3 first settings are saved and the
fourth is invalid, we will end with partially updated data.

Changing SiteSetting::Update to accept hash means that we will check
upfront if none of the settings are hidden or invalid and update all or
none.

Custom policies are used to report which settings are failing.
2025-02-24 11:09:44 +11:00
Bianca Nenciu
41c80959c7
FIX: Ensure revoke_ungranted_titles! works with user_ids (#31371)
When `revoke_ungranted_titles!` was invoked, the optional list of
`user_ids` was not passed from the argument list to the query. This
resulted in an exception because the placeholder `:user_ids` existed in
the query.
2025-02-18 15:55:48 +02:00
benj
43ececd22d
FIX: Adds further support for 'prioritize_full_name_in_ux' setting (#31346)
This sets the stage for being able to consolidate Like notifications
using full names. It also is crucial to this [Reactions plugin
PR](https://github.com/discourse/discourse/pull/31292).

The Like consolidation PR will come after these.
2025-02-17 12:09:18 -06:00
Martin Brennan
a2dbcedbd9
UX: Show parent category name for category hashtags (#31188)
This commit changes the display of category hashtag
autocomplete to show the parent category name in this
format:

* Parent Name > Child Name

This helps further distinguish categories in the autocomplete
where there may be multiple different parent categories with
the same name child category, e.g. if every category has an
Announcements subcategory.
2025-02-05 12:31:50 +10:00
Alan Guo Xiang Tan
3e4eac0fed
PERF: Enqueue Job::BackfillBadge in Jobs::BadgeGrant (#30945)
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.
2025-01-24 09:35:01 +08:00
Martin Brennan
32c6d3be06
FIX: Admin sidebar problem check missing -1 check (#30916)
When we initially turned on admin sidebar for new sites,
existing sites had the value set to -1. We need to show
the problem check to these sites too, but currently it only
checks if `admin_sidebar_enabled_groups` is empty.
2025-01-22 10:21:30 +10:00
Ted Johansson
6b4aa1221c
DEV: Add problem check informing about admin layout deprecation (#30685)
We want to avoid surprises when we make the new admin sidebar baseline, so in addition to announcements, we're also adding a problem check that informs you if you don't have it enabled for any group yet.
2025-01-14 13:22:59 +08:00
Jarek Radosz
affe26f0dd
DEV: Update nokogiri to 1.18.1 (#30554)
Nokogiri/libxml is now more strict in terms of params it receives.

It uses kwargs vs options object (I fixed an issue there in #30545) doesn't accept nil/blank html (fixed here) and most importantly handles encoding in a different way. It seems to require explicitly specifying UTF8.

* Build(deps): Bump nokogiri from 1.16.8 to 1.18.1

Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.16.8 to 1.18.1.
- [Release notes](https://github.com/sparklemotion/nokogiri/releases)
- [Changelog](https://github.com/sparklemotion/nokogiri/blob/main/CHANGELOG.md)
- [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.16.8...v1.18.1)

---
updated-dependencies:
- dependency-name: nokogiri
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-01-07 12:05:39 +01:00
Osama Sayegh
3187606d34
FEATURE: Add option to hide full name input at signup (#30471)
This commit replaces the `full_name_required` setting with a new `full_name_requirement` setting to allow more flexibility with the name field in the signup form. The new setting has 2 options, "Required at signup" and "Optional at signup", which are equivalent to the true/false possibilities of the old setting, and a third option "Hidden at signup" that hides the name field from the signup form, making it effectively optional too.

New sites will have the "Hidden at signup" option as the default option, and existing site will continue to use the option that maps to their current configuration.

Internal topic: t/136746.
2024-12-30 22:26:20 +03:00
Osama Sayegh
acc180611f
FEATURE: Add an option to block IPs and emails to bulk user delete (#29993)
This commit adds an option for blocking the IP and email addresses when bulk-deleting users.

Internal topic: t/140321/11.
2024-12-09 14:25:31 +03:00
Martin Brennan
9c5eb7952e
UX: Improve error when trying to edit globally shadowed setting (#30092)
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.
2024-12-04 13:41:32 +10:00
Loïc Guitaut
cf2b4d9934 DEV: Apply new Rubocop linting on services 2024-12-02 17:31:36 +01:00
Osama Sayegh
118f7869bb
FEATURE: Add bulk destroy to admin users list (#29744)
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.
2024-11-25 11:13:35 +03:00
Jan Cernik
234133bd3b
UX: Split hide_profile_and_presence user option (#29632)
It splits the hide_profile_and_presence user option and the default_hide_profile_and_presence site setting for more granular control. It keeps the option to hide the profile under /u/username/preferences/interface and adds the presence toggle in the quick user menu.

Co-authored-by: Régis Hanol <regis@hanol.fr>
2024-11-12 22:22:58 -03:00
Roman Rizzi
d97d48ead1
FIX: Ensure normalized_email gets anonymized (#29719) 2024-11-12 14:36:17 -03:00
Angus McLeod
cb4b8146a3
Add dedicated user_api_key_clients table to allow for 1:many use cases (#28119) 2024-11-08 12:05:03 -05:00
Alan Guo Xiang Tan
57f4176b57
DEV: Bump rubocop_discourse (#29608) 2024-11-06 06:27:49 +08:00
Loïc Guitaut
2f334964f2 DEV: Remove hash-like access from service contracts
We decided to keep only one way to access values from a contract. This
patch thus removes the hash-like access from contracts.
2024-10-29 16:02:51 +01:00
Martin Brennan
27bdfb6437
FEATURE: Add user preference to disable smart lists (#29434)
Some checks are pending
Licenses / run (push) Waiting to run
Linting / run (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (annotations, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (backend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (frontend, themes) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, chat) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, core) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, plugins) (push) Waiting to run
Tests / ${{ matrix.target }} ${{ matrix.build_type }} (system, themes) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Chrome) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox ESR) (push) Waiting to run
Tests / core frontend (${{ matrix.browser }}) (Firefox Evergreen) (push) Waiting to run
Followup 30fdd7738ec942126bb055c9a6a8d69ddffba2da

Adds a new site setting and corresponding user preference
to disable smart lists. By default they are enabled, because
this is a better experience for most users. A small number of
users would prefer to not have this enabled.

Smart lists automatically append new items to each
list started in the composer when enter is pressed. If
enter is pressed on an empty list item, it is cleared.

This setting will be removed when the new composer is complete.
2024-10-28 14:18:15 +10:00
Loïc Guitaut
584424594e DEV: Replace params by the contract object in services
This patch replaces the parameters provided to a service through
`params` by the contract object.

That way, it allows better consistency when accessing input params. For
example, if you have a service without a contract, to access a
parameter, you need to use `params[:my_parameter]`. But with a contract,
you do this through `contract.my_parameter`. Now, with this patch,
you’ll be able to access it through `params.my_parameter` or
`params[:my_parameter]`.

Some methods have been added to the contract object to better mimic a
Hash. That way, when accessing/using `params`, you don’t have to think
too much about it:
- `params.my_key` is also accessible through `params[:my_key]`.
- `params.my_key = value` can also be done through `params[:my_key] =
  value`.
- `#slice` and `#merge` are available.
- `#to_hash` has been implemented, so the contract object will be
  automatically cast as a hash by Ruby depending on the context. For
  example, with an AR model, you can do this: `user.update(**params)`.
2024-10-25 14:48:34 +02:00
Loïc Guitaut
41584ab40c DEV: Provide user input to services using params key
Currently in services, we don’t make a distinction between input
parameters, options and dependencies.

This can lead to user input modifying the service behavior, whereas it
was not the developer intention.

This patch addresses the issue by changing how data is provided to
services:
- `params` is now used to hold all data coming from outside (typically
  user input from a controller) and a contract will take its values from
  `params`.
- `options` is a new key to provide options to a service. This typically
  allows changing a service behavior at runtime. It is, of course,
  totally optional.
- `dependencies` is actually anything else provided to the service (like
  `guardian`) and available directly from the context object.

The `service_params` helper in controllers has been updated to reflect
those changes, so most of the existing services didn’t need specific
changes.

The options block has the same DSL as contracts, as it’s also based on
`ActiveModel`. There aren’t any validations, though. Here’s an example:
```ruby
options do
  attribute :allow_changing_hidden, :boolean, default: false
end
```
And here’s an example of how to call a service with the new keys:
```ruby
MyService.call(params: { key1: value1, … }, options: { my_option: true }, guardian:, …)
```
2024-10-25 09:57:59 +02:00
Loïc Guitaut
f79dd5c8b5 DEV: Stop injecting a service result object in the caller object
Currently, when calling a service with its block form, a `#result`
method is automatically created on the caller object. Even if it never
clashed so far, this could happen.

This patch removes that method, and instead use a more classical way of
doing things: the result object is now provided as an argument to the
main block. This means if we need to access the result object in an
outcome block, it will be done like this from now on:
```ruby
MyService.call(params) do |result|
  on_success do
    # do something with the result object
    do_something(result)
  end
end
```

In the same vein, this patch introduces the ability to match keys from
the result object in the outcome blocks, like we already do with step
definitions in a service. For example:
```ruby
on_success do |model:, contract:|
  do_something(model, contract)
end
```
Instead of
```ruby
on_success do
  do_something(result.model, result.contract)
end
```
2024-10-22 16:58:54 +02:00
Krzysztof Kotlarek
433fadbd52
FEATURE: allow admins to enable announced experimental features (#29244)
Toggle the button to enable the experimental site setting from "What's new" announcement.

The toggle button is displayed when:
- site setting exists and is boolean;
- potentially required plugin is enabled.
2024-10-22 10:56:58 +11:00
Krzysztof Kotlarek
644e6c7f46
FEATURE: auto_action_type field for flags (#29306)
Allow admins to specify if the flag should be `auto_action_type`. If yes, then when an admin flags a post,  it is automatically actioned.

Meta: https://meta.discourse.org/t/allow-creation-of-custom-flags-which-auto-hide-content-similar-to-spam-and-inapproriate/329894
2024-10-22 10:56:31 +11:00
Loïc Guitaut
e95edd079b DEV: Refactor some core services
Extracted from https://github.com/discourse/discourse/pull/29129.

This patch makes the code more compliant with the upcoming service docs
best practices.
2024-10-18 16:06:58 +02:00
Loïc Guitaut
7f607699b8 DEV: Refactor flag related services a bit
Extracted from https://github.com/discourse/discourse/pull/29129.

This patch makes the code more compliant with the upcoming service docs
best practices.
2024-10-18 10:10:28 +02:00
Alan Guo Xiang Tan
322a3be2db
DEV: Remove logical OR assignment of constants (#29201)
Constants should always be only assigned once. The logical OR assignment
of a constant is a relic of the past before we used zeitwerk for
autoloading and had bugs where a file could be loaded twice resulting in
constant redefinition warnings.
2024-10-16 10:09:07 +08:00
Kelv
32e261ef73
DEV: Migrate user passwords data to UserPassword table (#28746)
* Add migrations to ensure password hash is synced across users & user_passwords

* Persist password-related data in user_passwords instead of users

* Merge User#expire_old_email_tokens with User#expire_tokens_if_password_changed

* Add post deploy migration to mark password-related columns from users table as read-only

* Refactored UserPassword#confirm_password? and changes required to accommodate hashing the password after validations
2024-10-10 09:23:06 +08:00
Loïc Guitaut
229773e7a8 DEV: Drop OpenStruct for the context object in services
While using `OpenStruct` is nice, it’s generally not a very good idea as
it usually leads to performance problems.

The `OpenStruct` source code even says basically to avoid it.

Since the context object is crucial in our services, this patch replaces
`OpenStruct` with a custom implementation instead.
2024-10-08 10:34:55 +02:00
Ted Johansson
7ecb258b83
FIX: Support idempotent admin notice dismissal (#29099)
If you have the admin dashboard open, and one of the admin notices listed has already been dismissed (e.g. in another tab, or by another admin) we would show an ugly "FAILED" modal.

This change makes the admin dismiss endpoint idempotent. If the admin notice is already destroyed, then respond with 200. This will also correctly remove it from the list in the front-end.
2024-10-07 12:29:33 +08:00
Loïc Guitaut
fc1c5f6a8d DEV: Have contract take a block in services
Currently in services, the `contract` step is only used to define where
the contract will be called in the execution flow. Then, a `Contract`
class has to be defined with validations in it.

This patch allows the `contract` step to take a block containing
validations, attributes, etc. directly. No need to then open a
`Contract` class later in the service.

It also has a nice side effect, as it’s now easy to define multiples
contracts inside the same service. Before, we had the `class_name:`
option, but it wasn’t really useful as you had to redefine a complete
new contract class.
Now, when using a name for the contract other than `default`, a new
contract will be created automatically using the provided name.

Example:
```ruby
contract(:user) do
  attribute :user_id, :integer

  validates :user_id, presence: true
end
```
This will create a `UserContract` class and use it, also putting the
resulting contract in `context[:user_contract]`.
2024-10-02 17:00:01 +09:00