Commit Graph

834 Commits

Author SHA1 Message Date
OsamaSayegh a28ab171ec DEV: Add index to users.ip_address 2024-11-15 11:17:07 -05:00
Kelv 8f9b827d15
DEV: drop password-related columns from users table (#29187) 2024-10-23 13:42:35 +08:00
Régis Hanol 88449541a5
FIX: participating users statistics... (#29293)
* FIX: participating users statistics...

... was (mis-)counting

- bots
- anonymous users
- suspended users

There's now a "valid_users" function that holds the AR query for valid users and which is used in all "users", "active_users", and "participating_users" queries.

Internal ref - t/138435
2024-10-21 18:18:42 +02:00
Ted Johansson 56df077931
FIX: Don't error out on empty reserved_usernames setting (#29305)
We're seeing errors in logs due to some sites setting the reserved_usernames setting to nil. This is causing multiple use cases upstream of User#reserved_username? to error out.

This commit changes from using the raw #reserved_usernames to using the #reserved_usernames_map helper which exists on list-type site settings. It returns an empty array if the raw value is nil or empty string.
2024-10-21 14:38:37 +08: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
Bianca Nenciu 8016fcab33
DEV: Drop old notification id columns (#28550)
The `id` column of `notifications` table and `notification_id` columns
of the other tables have been migrated to bigint in previous commits
(for example, 799a45a).

In order to run the migrations with zero downtime, the data had to be
copied to new columns and swapped, but the old columns have been kept
to allow for rollback. They are no longer needed now.
2024-10-15 11:58:57 +03: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
Alan Guo Xiang Tan 97143efc52
PERF: Drop `user_search_similar_results` site setting (#28874)
In 14cf8eacf1, we added the
`user_search_similar_results` site setting which when enabled will use
trigram matching for similarity search in `UserSearch`. However, we
noted that adding the `index_users_on_username_lower_trgm` index is
causing the PG planner to not use the `index_users_on_username_lower`
index when the `=` operator is used against the `username_lower` column.

Based on the PG mailing list discussion where support for the `=`
operator in gist_trgm_ops was being considered, it stated that "I also have checked that btree_gist is preferred over pg_trgm gist
index for equality search." This is however quite different from reality
on our own PG clusters where the btree index is not preferred leading to
significantly slower queries when the `=` operator is used.

Since the pg_trgm gist index is only used for queries when the `user_search_similar_results` site setting
is enabled, we decided to drop the feature instead as it is hidden and
disabled by default. As such, we can consider it experiemental and drop
it without deprecation.

PG mailing list discussiong: https://www.postgresql.org/message-id/CAPpHfducQ0U8noyb2L3VChsyBMsc5V2Ej2whmEuxmAgHa2jVXg%40mail.gmail.com
2024-09-13 09:04:02 +08: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
Alan Guo Xiang Tan 4a6fc45429
DEV: Migrate `User#seen_notification_id` to `bigint` (#28572)
`Notification#id` was migrated to `bigint` in 799a45a291
2024-08-27 14:32:55 +03:00
Osama Sayegh 5eea7244c7
FIX: Add users to user directory on account activation (#28505)
Follow-up to e3ae57ea7a

The previous commit added an `after_create` callback that triggers a refresh for the user directory whenever a `User` record is created. Theoretically, this approach should work, however, there's a gotcha in practice, because during a real user registration, when the `User` record is created in the database, it's not marked as active until the user verifies their email address and the user directory excludes inactive users, so the initial directory refresh triggered by the `after_create` callback becomes pointless.

To make a new user appear in the user directory immediately after sign up, we need to trigger a refresh via an `after_save` callback when they verify their email address and become active.
2024-08-26 18:01:24 +03:00
Ted Johansson 981110d96e
FIX: Fix incorrect check for required custom fields (#28541)
This check was checking the wrong scope, causing problems in certain edge conditions, for example:

1. Admin adds an "on signup" field that isn't editable after signup.
2. Admin adds a "for all users" field.
3. User goes and fills up the "for all users" field from 2.
4. User is now stuck on the required fields page without any fields showing.

With this change, we only consider "for all users" fields when asking if required custom fields are filled in.
2024-08-26 15:33:19 +08: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
Osama Sayegh 35b748e7f4
FIX: Don't show silence button on staff users and display similar users (#28423)
This commit fixes a bug where the silence button is incorrectly displayed on the admin page of a staff user. It's not actually possible to silence a staff user because the backend correctly prevents it, but the frontend isn't checking if the button should be displayed.

Another small bug that this commit fixes is the similar users list not showing up inside the silence/suspend modals due to also a bug in the frontend.

I've also changed the way similar users are loaded so that they're not returned by the `admin/users#show` endpoint anymore and moved them into a new endpoint that the penalize modals (suspend and silence) can call directly to retrieve the list of users. This is done because the similar users list is never shown on the admin user page (`/admin/users/:user_id/:username`); they're only needed when the suspend or silence modals are opened.

Internal topic: t/130014.
2024-08-20 15:27:29 +03:00
Krzysztof Kotlarek e82e255531
FIX: serialize Flags instead of PostActionType (#28362)
### Why?
Before, all flags were static. Therefore, they were stored in class variables and serialized by SiteSerializer. Recently, we added an option for admins to add their own flags or disable existing flags. Therefore, the class variable had to be dropped because it was unsafe for a multisite environment. However, it started causing performance problems. 

### Solution
When a new Flag system is used, instead of using PostActionType, we can serialize Flags and use fragment cache for performance reasons. 

At the same time, we are still supporting deprecated `replace_flags` API call. When it is used, we fall back to the old solution and the admin cannot add custom flags. In a couple of months, we will be able to drop that API function and clean that code properly. However, because it may still be used, redis cache was introduced to improve performance.

To test backward compatibility you can add this code to any plugin
```ruby
  replace_flags do |flag_settings|
    flag_settings.add(
      4,
      :inappropriate,
      topic_type: true,
      notify_type: true,
      auto_action_type: true,
    )
    flag_settings.add(1001, :trolling, topic_type: true, notify_type: true, auto_action_type: true)
  end
```
2024-08-14 12:13:46 +10:00
Krzysztof Kotlarek 559c9dfe0a
REVERT: FIX: serialize Flags instead of PostActionType (#28334) 2024-08-13 18:32:11 +10:00
Krzysztof Kotlarek 094052c1ff
FIX: serialize Flags instead of PostActionType (#28259)
### Why?
Before, all flags were static. Therefore, they were stored in class variables and serialized by SiteSerializer. Recently, we added an option for admins to add their own flags or disable existing flags. Therefore, the class variable had to be dropped because it was unsafe for a multisite environment. However, it started causing performance problems. 

### Solution
When a new Flag system is used, instead of using PostActionType, we can serialize Flags and use fragment cache for performance reasons. 

At the same time, we are still supporting deprecated `replace_flags` API call. When it is used, we fall back to the old solution and the admin cannot add custom flags. In a couple of months, we will be able to drop that API function and clean that code properly. However, because it may still be used, redis cache was introduced to improve performance.

To test backward compatibility you can add this code to any plugin
```ruby
  replace_flags do |flag_settings|
    flag_settings.add(
      4,
      :inappropriate,
      topic_type: true,
      notify_type: true,
      auto_action_type: true,
    )
    flag_settings.add(1001, :trolling, topic_type: true, notify_type: true, auto_action_type: true)
  end
```
2024-08-13 11:22:37 +10:00
Isaac Janzen aeaae9babc
DEV: Add `user` modifier to prevent updating ip_address (#28280) 2024-08-08 13:06:08 -05:00
Krzysztof Kotlarek b64d01bc10
FIX: store information about the login method in the database. (#28054)
Previously in these 2 PRs, we introduced a new site setting `SiteSetting.enforce_second_factor_on_external_auth`.

https://github.com/discourse/discourse/pull/27547
https://github.com/discourse/discourse/pull/27674

When disabled, it should enforce 2FA for local login with username and password and skip the requirement when authenticating with oauth2.

We stored information about the login method in a secure session but it is not reliable. Therefore, information about the login method is moved to the database.
2024-07-24 17:19:58 +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
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
Loïc Guitaut 8d249457e8 DEV: Upgrade Rails to version 7.1
---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2024-07-04 10:58:21 +02:00
Vinoth Kannan d1ea598fa2
FIX: should not raise error when both group & site tag preferences are same. (#27704)
When tag preference in group and site settings are both used with same default notification level it will break new users signups because it tries to create duplicate records in the tag_users table which can’t happen because we have a unique index set.
2024-07-04 11:53:28 +05:30
Natalie Tay 55bf0e21fb
FIX: Don't show that an existing user is invited_by another user (#27665)
If an existing user (John) accepts an invite created by Kenny to a group, John may be seen as invited by Kenny, despite already having an account on the site.

This fix removes the bug by excluding invites that determine the invited_by after the user's creation date. The delay buffer in the query accounts for invites that also create the user at the same time.
2024-07-04 10:27:37 +08:00
Loïc Guitaut f58b844f45
Revert "DEV: Upgrade Rails to version 7.1" (#27625)
This reverts commit ce00f83173.
2024-06-26 18:55:05 +02:00
Ted Johansson d63f1826fe
FEATURE: User fields required for existing users - Part 2 (#27172)
We want to allow admins to make new required fields apply to existing users. In order for this to work we need to have a way to make those users fill up the fields on their next page load. This is very similar to how adding a 2FA requirement post-fact works. Users will be redirected to a page where they can fill up the remaining required fields, and until they do that they won't be able to do anything else.
2024-06-25 19:32:18 +08:00
Loïc Guitaut ce00f83173 DEV: Upgrade Rails to version 7.1
---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2024-06-24 11:16:14 +02:00
Loïc Guitaut 160011793a Revert "DEV: Upgrade Rails to version 7.1 (#27539)"
This reverts commit ca4af53be8.
2024-06-21 11:20:40 +02:00
Loïc Guitaut ca4af53be8 DEV: Upgrade Rails to version 7.1 (#27539)
* DEV: Upgrade Rails to 7.1

* FIX: Remove references to `Rails.logger.chained`

`Rails.logger.chained` was provided by Logster before Rails 7.1
introduced their broadcast logger. Now all the loggers are added to
`Rails.logger.broadcasts`.

Some code in our initializers was still using `chained` instead of
`broadcasts`.

* DEV: Make parameters optional to all FakeLogger methods

* FIX: Set `override_level` on Logster loggers (#27519)

A followup to f595d599dd

* FIX: Don’t duplicate Rack response

---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2024-06-21 09:44:06 +02:00
Loïc Guitaut 982c005979 Revert "DEV: Upgrade Rails to version 7.1 (#27539)"
This reverts commit 2301dddcff.
2024-06-20 11:43:35 +02:00
Loïc Guitaut 2301dddcff
DEV: Upgrade Rails to version 7.1 (#27539)
* DEV: Upgrade Rails to 7.1

* FIX: Remove references to `Rails.logger.chained`

`Rails.logger.chained` was provided by Logster before Rails 7.1
introduced their broadcast logger. Now all the loggers are added to
`Rails.logger.broadcasts`.

Some code in our initializers was still using `chained` instead of
`broadcasts`.

* DEV: Make parameters optional to all FakeLogger methods

* FIX: Set `override_level` on Logster loggers (#27519)

A followup to f595d599dd

* FIX: Don’t duplicate Rack response

---------

Co-authored-by: Jarek Radosz <jradosz@gmail.com>
2024-06-20 10:33:01 +02:00
Jarek Radosz 5cb84f8dcf
DEV: Revert rails 7.1 upgrade (#27522)
* Revert "FIX: Set `override_level` on Logster loggers (#27519)"

This reverts commit c1b0488c54.

* Revert "DEV: Make parameters optional to all FakeLogger methods"

This reverts commit 3318dad7b4.

* Revert "FIX: Remove references to `Rails.logger.chained`"

This reverts commit f595d599dd.

* Revert "DEV: Upgrade Rails to 7.1"

This reverts commit 081b00391e.
2024-06-18 23:48:30 +02:00
Loïc Guitaut 081b00391e DEV: Upgrade Rails to 7.1 2024-06-18 15:58:05 +02:00
Alan Guo Xiang Tan e97ef7e9af
FEATURE: Allow site admin to mark a user's password as expired (#27314)
This commit adds the ability for site administrators to mark users'
passwords as expired. Note that this commit does not add any client side
interface to mark a user's password as expired.

The following changes are introduced in this commit:

1. Adds a `user_passwords` table and `UserPassword` model. While the
   `user_passwords` table is currently used to only store expired
   passwords, it will be used in the future to store a user's current
   password as well.

2. Adds a `UserPasswordExpirer.expire_user_password` method which can
   be used from the Rails console to mark a user's password as expired.

3. Updates `SessionsController#create` to check that the user's current
   password has not been marked as expired after confirming the
   password. If the password is determined to be expired based on the
   existence of a `UserPassword` record with the `password_expired_at`
   column set, we will not log the user in and will display a password
   expired notice. A forgot password email is automatically send out to
   the user as well.
2024-06-04 15:42:53 +08:00
Gerhard Schlager 387e906610 REFACTOR: All kinds of permalinks should return relative URLs
Mixing relative and absolute URLs is unnecessary and confusing.
2024-06-03 13:20:24 +02:00
Loïc Guitaut 2a28cda15c DEV: Update to lastest rubocop-discourse 2024-05-27 18:06:14 +02:00
Gerhard Schlager 5e61d55940
FIX: Updating avatar didn't trigger a rebake of posts with quotes of the user (#27184) 2024-05-27 09:57:48 +02:00
Ted Johansson cb592ae4ac
DEV: Remove deprecated User#saw_notification_id method (#27175) 2024-05-27 11:10:46 +08:00
Jean 63b7a36fac
FEATURE: Extend embeddable hosts with Individual tags and author assignments (#26868)
* FEATURE: Extend embeddable hosts with tags and author assignments
2024-05-16 15:47:01 -04:00
Osama Sayegh e3ae57ea7a
FIX: Create directory items for new users when in bootstrap mode (#27020)
The users directory is updated on a daily cadence. However, when a site is new and doesn't have many users, it can be confusing that a user who has just joined doesn't show up in the users until a day after they join. To eliminate this confusion, this commit triggers a refresh for the users directory as soon as as a user joins, if the site is in bootstrap mode. The reason for the conditional trigger is that refreshing the users directory is an expensive operation and doing it often on a large site with many users could lead to performance problems.

Internal topic: t/126076.
2024-05-15 03:06:58 +03:00
Daniel Waterworth a6b8051645
DEV: Use has_many and ArraySerializer for SidebarSectionsSerializer (#26716) 2024-05-06 11:32:18 -05:00
Vinoth Kannan 859b55366f
DEV: don't send moderator welcome message to first admin. (#26719)
We already skipping the admin welcome message for the first admin user. We should also skip the moderator message.
2024-04-24 00:20:14 +05:30
Krzysztof Kotlarek e1d9fd479f
FEATURE: after wizard admin is redirected to the guide page (#26696)
After the wizard is completed, the admin should be redirected to the admin guide topic.

Also tooltip from "Getting started" button was removed.
2024-04-23 10:04:15 +10:00
Krzysztof Kotlarek c5dd50aa02
FIX: don't purge users who were deactivated by the system (#26656)
In a previous PR, we skipped users deactivated by admins from being automatically purged - https://github.com/discourse/discourse/pull/26478.

However, users deactivated by `discourse-auto-deactivate` plugin are deactivated by the system user. Those users should not be purged as well.

https://github.com/discourse/discourse-auto-deactivate/blob/main/plugin.rb#L62
2024-04-18 09:53:43 +10:00
David Taylor 3733db866c
DEV: Introduce default 'auto' mode for glimmer header (#26467)
This will automatically enable the glimmer header when all installed themes/plugins are ready. This replaces the old group-based site setting.

In 'auto' mode, we check for calls to deprecated APIs (e.g. decorateWidget) which affect the old header. If any are present, we stick to the old header implementation and print a message to the console alongside the normal deprecation messages.

To override this automatic behavior, a new `glimmer_header_mode` site setting can be set to 'disabled' or 'enabled'.

This change also means that our test suite is running with the glimmer header. This unveiled a couple of small issues (e.g. some incorrect `aria-*` and `alt` text) which are now fixed. A number of selectors had to be updated to ensure the tests were clicking the actual `<button>` elements rather than the surrounding `<li>` elements.
2024-04-10 14:35:54 +01:00
Krzysztof Kotlarek ba04fc6a01
FEATURE: ignore manually deactivated users when purging (#26478)
When a user is manually deactivated, they should not be deleted by our background job that purges inactive users.

In addition, site settings keywords should accept an array of keywords.
2024-04-03 14:06:31 +11:00
Sam e3a0faefc5
FEATURE: allow re-scoping chat user search via a plugin (#26361)
This enables the following in Discourse AI

```
 plugin.register_modifier(:chat_allowed_bot_user_ids) do |user_ids, guardian|
  if guardian.user
    mentionables = AiPersona.mentionables(user: guardian.user)
    allowed_bot_ids = mentionables.map { |mentionable| mentionable[:user_id] }
    user_ids.concat(allowed_bot_ids)
  end
  user_ids
end
```

some bots that are id < 0 need to be discoverable in search otherwise people can not talk to them.

---------

Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
2024-03-27 08:55:53 +11:00
Isaac Janzen 21f23cc032
DEV: Convert header to glimmer (#25214)
Here is a breakdown of the changes that will be implemented in this PR.

# Widgets -> Glimmer

Obviously, the intention of the todo here is to convert the header from widgets to glimmer. This PR splits the respective widgets as so:

### widgets/site-header.js
```mermaid height=200
flowchart TB
    A[widgets/site-header.js] 
    A-->B[components/glimmer-site-header.gjs]
```

### widgets/header.js and children
```mermaid height=200
flowchart TB
    A[widgets/header.js] 
    A-->B[components/glimmer-header.gjs]
    B-->C[glimmer-header/contents.gjs]
    C-->D[./auth-buttons.gjs]
    C-->E[./icons.gjs]
    C-->F[./user-menu-wrapper.gjs]
    C-->G[./hamburger-dropdown-wrapper.gjs]
    C-->H[./user-menu-wrapper.gjs]
    C-->I[./sidebar-toggle.gjs]
    C-->J[./topic/info.gjs]
```

There are additional components rendered within the `glimmer-header/*` components, but I will leave those out for now. From this view you can see that we split apart the logic of `widgets/header.js` into 10+ components. Breaking apart these mega files has many benefits (readability, etc).

# Services

I have introduced a [header](cdb42caa04/app/assets/javascripts/discourse/app/services/header.js) service. This simplifies how we pass around data in the header, as well as fixes a bug we have with "swiping" menu panels.


# Modifiers
Added a [close-on-click-outside](cdb42caa04/app/assets/javascripts/discourse/app/modifiers/close-on-click-outside.js) modifier that is built upon the [close-on-click-outside modifier](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/float-kit/addon/modifiers/close-on-click-outside.js) that @jjaffeux built for float-kit. I think we could replace float-kit's implementation with mine and have it in a centralized location as they are extremely similar.

# Tests
Rewrote the existing header tests ([1](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/tests/integration/components/widgets/header-test.js), [2](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/tests/integration/components/site-header-test.js)) as system tests. 

# Other
- Converted `widgets/user-status-bubble.js` to a gjs component
- Converted `widgets/sidebar-toggle.js` to a gjs component
- Converted `topicFeaturedLinkNode()` to a gjs component
- Deprecated the [docking mixin](https://github.com/discourse/discourse/blob/main/app/assets/javascripts/discourse/app/mixins/docking.js)
2024-02-23 11:08:15 -07:00
marstall 5a00d1964f
DEV: add site setting to disable watched word checking in user fields (#25411)
adding a hidden sitesetting, `disable_watched_word_checking_in_user_fields` - false by default. if set to true, you can use any word at all in user profile fields.

meta: https://meta.discourse.org/t/watched-words-scope/282699/20
2024-01-29 12:44:32 -05:00