2e78045a fixed the anonymization job so that it correctly updated self-mentions, which are not logged in the post_actions table. The solution was to scan the entire `posts` table with an `raw ILIKE` query. On sites with many posts, this can take a very long time.
This commit updates the job to take a two-pass approach:
First, we update posts based on the post_actions table. This is much more efficient than a full table scan, and takes care of all 'non-self' mentions.
Then, we make a second pass using the `raw ILIKE` approach. Since we already took care of most posts, we can scope this down to self-mentions only. By filtering the query to a specific posts.user_id, it is significantly more performant than a full table scan.
EmberObject's `reopen` feature allows changes to be made to the prototype of the class, but it does not work with native class fields. Native class field values are set on the instance in the constructor, and therefore override any values from the prototype.
This commit implements a workaround which detects possible field overrides and then sets the values during the `init()` function of the EmberObject. This isn't perfect - old field values will still be present while any constructor function is running. But in the vast majority of cases, it should provide parity with old non-native-class EmberObject properties.
This commit also adds a warning when trying to override fields on non-EmberObject classes. There is no change in behavior here - we're just warning about the fact it doesn't work.
When running `yarn install` in a yarn workspace, the lifecycle hooks in the root package.json are not triggered. https://github.com/yarnpkg/yarn/issues/5790
As a workaround, we can additionally run `patch-package` from the `javascripts/discourse/package.json` `postinstall` hook. `patch-package` is idempotent, so it doesn't matter if it is triggered multiple times.
Longer term we intend to move to pnpm, which has built-in patch support.
Currently, we’re performing a check when a user is suspended in the
`UserEmail` job and we’re assuming a `post` is always available, which
is not the case. The code indeed breaks when the job is called with the
`account_suspended` type option.
This patch fixes this issue by making the check use the safe navigation
operator, thus making it working when `post` is not provided.
Previously, Discourse's password hashing was hard-coded to a specific algorithm and parameters. Any changes to the algorithm or parameters would essentially invalidate all existing user passwords.
This commit introduces a new `password_algorithm` column on the `users` table. This persists the algorithm/parameters which were use to generate the hash for a given user. All existing rows in the users table are assumed to be using Discourse's current algorithm/parameters. With this data stored per-user in the database, we'll be able to keep existing passwords working while adjusting the algorithm/parameters for newly hashed passwords.
Passwords which were hashed with an old algorithm will be automatically re-hashed with the new algorithm when the user next logs in.
Values in the `password_algorithm` column are based on the PHC string format (https://github.com/P-H-C/phc-string-format/blob/master/phc-sf-spec.md). Discourse's existing algorithm is described by the string `$pbkdf2-sha256$i=64000,l=32$`
To introduce a new algorithm and start using it, make sure it's implemented in the `PasswordHasher` library, then update `User::TARGET_PASSWORD_ALGORITHM`.
Fixes the unnecessary message when starting ember server:
```
Invalid watchman found, version: [2023.04.03.00] did not satisfy [>= 3.0.0].
Visit https://ember-cli.com/user-guide/#watchman for more info.
```
Moves a couple things from discourse-boot.js to a different JS file imported from app/app.js.
This is a forwards compatible technique to import and throw data on the window.
One thing to make note of, though, is that if the virtual-dom and discourse-widget-hbs/helpers were previously included in the build elsewhere, they will now become part of the app bundle.
Later, when using embroider, all bundles will be chunks, and webpack will optimize which chunk contains which modules appropriately.
When selecting the "Keep bookmark" in the user preference for what to do after a bookmark reminder is sent, it does not propagate to the drop-down in the "Create bookmark" modal. Instead it defaults to "Keep bookmark and clear reminder". All other options work fine.
We set a default ("Keep bookmark and clear reminder") if no user preference is found, However, this uses the index of the option, and the index of the first option ("Keep bookmark") is 0, which is treated as falsey in JavaScript, thus causing the default to be selected.
This change switches from logical "or" conditional `||` operator to nullish coalescing `??` operator.
Previously, public custom sections were only visible to logged-in users. In this PR, we are making them visible to anonymous as well.
The reason is that Community Section will be moved into custom section model to be easily editable by admins.
Followup to 6ad9e4ad06,
I was not aware that `site.categories` is undefined if
the user is anon and the site is login_required, this
handles that scenario and does not continue trying to
generate CSS.
This commit adds a system to generate CSS variables and classes for categories
and hashtags, which will be used in an effort to remove baked icons for hashtags
and add color to those icons.
This is in two parts. First I added an initializer generate a category color CSS
variable style tag in the head tag that looks like this:
```css
:root {
--category-1-color: #0088CC;
--category-2-color: #808281;
--category-3-color: #E45735;
--category-4-color: #A461EF;
--category-5-color: #ee56c9;
--category-6-color: #da28c2;
--category-7-color: #ab8b0a;
--category-8-color: #45da37;
...
}
```
The number is the category ID. This only generates CSS variables for categories
the user can access based on `site.categories`. If you need the parent color variable
you can just use the `category.parentCategory.id` to get it.
Then, I added an initializer to generate a hashtag CSS style tag using these variables.
Only the category and channel hashtags need this, the category one generates the
background-gradient needed for the swatch, and the channel just generates a color
for the icon. This is done in an extendable way using the new `api.registerHashtagType`
JS plugin API:
```css
hashtag-color--category-1 {
background: linear-gradient(90deg, var(--category-1-color) 50%, var(--category-1-color) 50%);
}
hashtag-color--category-2 {
background: linear-gradient(90deg, var(--category-2-color) 50%, var(--category-2-color) 50%);
}
hashtag-color--category-5 {
background: linear-gradient(90deg, var(--category-5-color) 50%, var(--category-4-color) 50%);
}
...
.hashtag-color--channel-4 {
color: var(--category-12-color);
}
.hashtag-color--channel-92 {
color: var(--category-24-color);
}
```
Note if a category has a parent, its color is used in the gradient correctly. The numbers
here are again IDs (e.g. channel ID, category ID) and the channel’s chatable ID is used
to find the category color variable.