Commit Graph

1184 Commits

Author SHA1 Message Date
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)
Followup 30fdd7738e

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
Krzysztof Kotlarek c5a024f8df
FIX: custom flag name should be unique (#28869)
Validation to ensure that the custom flag name is unique.
2024-09-30 09:17:19 +10:00
Linca a1e5796ba1
FEAT: Allow admin delete user's associated accounts (#29018)
This commit introduces a feature that allows an admin to delete a user's
associated account. After deletion, a log will be recorded in staff
actions.

ref=t/136675
2024-09-27 20:08:05 +08:00
Bianca Nenciu e2f3474bc3
FIX: permanent delete of posts by deleted users (#28992)
Permanently deleting posts that no longer have a user associated was not
working as expected because of UserAction.log which expected user_id to
be present.
2024-09-24 12:26:31 +03:00
Loïc Guitaut 05b8ff436c DEV: Introduce a `Service::ActionBase` class for service actions
This will help to enforce a consistent pattern for creating service
actions.

This patch also namespaces actions and policies, making everything
related to a service available directly in
`app/services/<concept-name>`, making things more consistent at that
level too.
2024-09-18 17:02:46 +02:00
Ted Johansson be33363f13
FEATURE: Add ability to dismiss admin notices (#28916)
his is a new feature that lets admins dismiss notices from the dashboard. This helps with self-service in cases where a notice is "stuck", while we work on provisions to prevent "sticking" in the first place.
2024-09-17 14:43:34 +08:00
Loïc Guitaut b806dce13d DEV: Refactor suspend/silence user services
- fetch models inside services
- validate `user_id` in contracts
- use policy objects
- extract more logic to actions
- write specs for services and action
2024-09-12 10:28:48 +02:00
Linca aab2987438
FEATURE: Log tag group changes in staff action log (#28787)
* FEATURE: Log tag group changes in staff action log

This commit records every change (add, change, delete) to a tag group in
the staff action log.

It uses a modal that was originally called ThemeChangeModal to display
changes, allowing staffs to see the specific changes clearly. The modal
is renamed to StaffActionLogChangeModal in this PR.

ref: https://meta.discourse.org/t/-/325011/14

Co-authored-by: Keegan George <kgeorge13@gmail.com>
2024-09-09 10:50:48 +08:00
Loïc Guitaut e94707acdf DEV: Drop `WithServiceHelper`
This patch removes the `with_service` helper from the code base.
Instead, we can pass a block with actions directly to the `.call` method
of a service.

This simplifies how to use services:
- use `.call` without a block to run the service and get its result
  object.
- use `.call` with a block of actions to run the service and execute
  arbitrary code depending on the service outcome.

It also means a service is now “self-contained” and can be used anywhere
without having to include a helper or whatever.
2024-09-05 09:58:20 +02:00
David Taylor 80b9c280ba
DEV: Switch to pnpm for JS dependencies (#28671)
This will bring significant improvements to install speed & storage requirements. For information on how it may affect you, see https://meta.discourse.org/t/324521

This commit:
- removes the `yarn.lock` and replaces with `pnpm-lock.yaml`
- updates workspaces to pnpm format
- adjusts package dependencies to work with pnpm's stricter resolution strategy
- updates Rails app to load modules from more specific node_modules directories
- adds a `.pnpmfile` which automatically cleans up old yarn-managed `node_modules` directories
- updates various scripts to call `pnpm` instead of `yarn`
- updates patches to use pnpm's native patch system instead of patch-package
- adds a patch for licensee to support pnpm
2024-09-03 10:51:07 +01:00
Kelv a455567f9e
DEV: make UserPassword 1:1 to User (#28528)
* add data migration to keep only unexpired or most recently expired user password
* refactor to 1:1 relationship between User and UserPassword
* add migration to remove redundant indexes on user passwords
2024-09-03 11:09:33 +08:00
Krzysztof Kotlarek b90b56f953
FIX: do not enforce 2fa when an account is created with OAuth (#28625)
In this PR we introduced a new setting `enforce_second_factor_on_external_auth` which disables enforce 2FA when the user is authenticated with an external provider.

https://github.com/discourse/discourse/pull/27506

However, with the first registration with an external provider, we authenticate the user right after activation. In that case, we need to also keep information that the user was authenticated with an external OAuth provider.
2024-08-29 11:19:04 +10:00
Loïc Guitaut d26d45540e DEV: Use `run_successfully` matcher in service specs 2024-08-28 16:30:09 +02:00
Osama Sayegh 67cde14a61
DEV: Use `Service::Base` for suspend and silence actions (#28459)
This commit moves the business logic in the `Admin::UsersController#suspend` and `Admin::UsersController#silence` actions to dedicated service classes. There's no functional changes in this commit.

Internal topic: t/130014.
2024-08-22 14:38:56 +03:00
Loïc Guitaut 0636855706 DEV: Allow using an AR relation as a model in services
This patch allows using an AR relation as a model in services without
fetching associated records. It will just check if the relation is empty
or not. In the former case, the execution will stop at that point, as
expected.
2024-08-20 16:32:46 +02:00
David Battersby 0954ae70a6
FEATURE: add delay to native push notifications (#28314)
This change ensures native push notifications respect the site setting for push_notification_time_window_mins. Previously only web push notifications would account for the delay, now we can bring more consistency between Discourse in browser vs Hub, by applying the same delay strategy to both forms of push notifications.
2024-08-13 12:12:05 +04:00
Ted Johansson 6d1c2a3d5a
FIX: Don't clear inline problems when loading admin dashboard (#28220)
We support a low-level construct called "inline checks", which you can use to register a problem ad-hoc from within application code.

Problems registered by inline checks never show up in the admin dashboard, this is because when loading the dashboard, we run all realtime checks and look for problems. Because of an oversight, we considered inline checks to be "realtime", causing them to be run and clear their problem status.

To fix this, we don't consider inline checks to be realtime, to prevent them from running when loading the admin dashboard.
2024-08-05 11:45:55 +08:00
David Battersby 6ec8728ebf
DEV: refactor live notifications setting in user preferences (#28145)
This change is mainly a refactor of the desktop notifications service to improve readability and have standardised values for tracking state for current user in regards to the Notification API and Push API.

Also improves readability when handling push notification jobs, especially in scenarios where the push_notification_time_window_mins site setting is set to 0, which will allow sending push notifications instantly.
2024-08-02 17:25:15 +04:00
锦心 a749387c80
FEATURE: Clean up previously logged information after permanently deleting posts (#28033)
* FEATURE: Clean up previously logged information after permanently deleting posts

When soft deleteing a topic or post, we will log some details in the
staff log, including the raw content of the post. Before this commit, we
will not clear the information in these records. Therefore, after
permanently deleting the post, `UserHistory` still retains copy of the
permanently deleted post. This is an unexpected behaviour and may raise
some potential legal issues.

This commit adds a behavior that when a post is permanently deleted, the
details column of the `UserHistory` associated with the post will be
overwritten to "(permanently deleted)". At the same time, for permanent
deletion, a new `action_id` is introduced to distinguish it from soft
deletion.

Related meta topic: https://meta.discourse.org/t/introduce-a-way-to-also-permanently-delete-the-sensitive-info-from-the-staff-logs/292546
2024-07-23 15:27:11 +08:00
Krzysztof Kotlarek e020888b0a
FIX: flag valid type inclusion should be lambda (#28030)
There is a bug with chat type flags - "An error occurred: Applies to is not included in the list"

Flag.valid_applies_to_types is a set of core types and types registered by plugins `Set.new(DEFAULT_VALID_APPLIES_TO | DiscoursePluginRegistry.flag_applies_to_types)`

Using lamba should ensure that valid values are calculated dynamically.
2024-07-23 11:47:50 +10:00
锦心 199f980e6a
FEATURE: Add creator and logging for CustomEmoji (#28004)
* FEATURE: Add logging for CustomEmoji

We didn't provide any logs for CustomEmoji before, nor did we record the
person who added any emoji in the database. As a result, the staff had
no way to trace back who added a certain emoji.

This commit adds a new column `user_id` to `custom_emojis` to record the
creator of an emoji. At the same time, a log is added for staff logs to
record who added or deleted a custom emoji.
2024-07-22 14:44:49 +08:00
Martin Brennan 48d13cb231
UX: Use a dropdown for SSL mode for group SMTP (#27932)
Our old group SMTP SSL option was a checkbox,
but this was not ideal because there are actually
3 different ways SSL can be used when sending
SMTP:

* None
* SSL/TLS
* STARTTLS

We got around this before with specific overrides
for Gmail, but it's not flexible enough and now people
want to use other providers. It's best to be clear,
though it is a technical detail. We provide a way
to test the SMTP settings before saving them so there
should be little chance of messing this up.

This commit also converts GroupEmailSettings to a glimmer
component.
2024-07-18 10:33:14 +10:00
Krzysztof Kotlarek c975c7fe1b
FEATURE: custom flag can require additional message (#27908)
Allow admin to create custom flag which requires an additional message.

I decided to rename the old `custom_flag` into `require_message` as it is more descriptive.
2024-07-18 10:10:22 +10:00
锦心 600f2854c7
FEATURE: Log topic slow mode changes (#27934)
Previously, we did not log any topic slow mode changes. This allowed
some malicious (or just careless) TL4 users to delete slow modes created
by moderators at will. Administrators could not see who changed the slow
mode unless they had SQL knowledge and used Data Explorer.

This commit enables logging who turns slow mode on, off, or changes it.

Related meta topic: https://meta.discourse.org/t/why-is-there-no-record-of-who-added-or-removed-slow-mode/316354
2024-07-16 17:08:09 +08:00
Martin Brennan 0783bfbbfe
FIX: Use login SMTP auth for office365 in group mailer (#27931)
Followup 7b627dc14b

In this other commit, I changed the email settings validator
to always use the `login` authentication method for
office365 and outlook, but I didn't change the actual
group SMTP mailer to do this.

This commit fixes that issue and does some minor refactoring.
2024-07-16 16:21:14 +10:00
Martin Brennan 00608a19c6
FIX: Show the SMTP authentication error for group UI (#27914)
Originally in 964da21817
we hid the SMTPAuthenticationError message except in
very specific cases. However this message often contains
helpful information from the mail provider, for example
here is a response from Office365:

> 535 5.7.139 Authentication unsuccessful, user is locked by your
organization's security defaults policy. Contact your administrator.

So, we will show the error message in the modal UI instead
of supressing it with a generic message to be more helpful.
2024-07-16 09:14:17 +10:00
Ted Johansson cf5174da69
FIX: Fix broken out of date themes admin notice (#27916)
The OutOfDateThemes problem check is using an old method of setting the message, by overriding #message. It should instead use #translation_keys. (By chance I noticed the same thing applies to UnreachableThemes.
2024-07-15 16:12:44 +08:00
Krzysztof Kotlarek 9e4e591d60
Revert "FEATURE: custom flag can require additional message (#27706)" (#27906)
This reverts commit c0bcd979e3.
2024-07-15 09:45:57 +10:00
Krzysztof Kotlarek c0bcd979e3
FEATURE: custom flag can require additional message (#27706)
Allow admin to create custom flag which requires an additional message.

I decided to rename the old `custom_flag` into `require_message` as it is more descriptive.
2024-07-15 08:48:01 +10:00