When converting a PM to a public topic (and vice versa), if there was a validation error (like a topic already used, or a tag required or not allowed) the error message wasn't bubbled up nor shown to the user.
This fix ensures we properly stop the conversion whenever a validation error happens and bubble up the errors back to the user so they can be informed.
Internal ref - t/128795
Using the CategoryDrop on the categories page redirected the user to the
"latest topics" page with topics only from that category. With these
changes, selecting a category will take the user to a "subcategories
page" where only the subcategories of the selected property will be
displayed.
The watched word group's create, update and delete action logs were missing the translations. This PR will add those strings and will use the group key instead of watched word key where needed.
... wasn't working because it wasn't storing the proper "action" value.
Issue was that we were using the "action" parameter which is being used by Rails to determine which controller action to call.
We need to use the "action_key" parameter instead.
At the moment, there is no way to create a group of related watched words together. If a user needed a set of words to be created together, they'll have to create them individually one at a time.
This change attempts to allow related watched words to be created as a group. The idea here is to have a list of words be tied together via a common `WatchedWordGroup` record. Given a list of words, a `WatchedWordGroup` record is created and assigned to each `WatchedWord` record. The existing WatchedWord creation behaviour remains largely unchanged.
Co-authored-by: Selase Krakani <skrakani@gmail.com>
Co-authored-by: Martin Brennan <martin@discourse.org>
This commit introduces a few changes as a result of
customer issues with finding why a topic was relisted.
In one case, if a user edited the OP of a topic that was
unlisted and hidden because of too many flags, the topic
would get relisted by directly changing topic.visible,
instead of going via TopicStatusUpdater.
To improve tracking we:
* Introduce a visibility_reason_id to topic which functions
in a similar way to hidden_reason_id on post, this column is
set from the various places we change topic visibility
* Fix Post#unhide! which was directly modifying topic.visible,
instead we use TopicStatusUpdater which sets visibility_reason_id
and also makes a small action post
* Show the reason topic visibility changed when hovering the
unlisted icon in topic status on topic titles
Selecting the +subcategories option does not work sometimes when "lazy
load categories" is enabled because the subcategories may not be
fetched. This ensures that subcategories are loaded by requesting them
before being used.
Our 'page_view_crawler' / 'page_view_anon' metrics are based purely on the User Agent sent by clients. This means that 'badly behaved' bots which are imitating real user agents are counted towards 'anon' page views.
This commit introduces a new method of tracking visitors. When an initial HTML request is made, we assume it is a 'non-browser' request (i.e. a bot). Then, once the JS application has booted, we notify the server to count it as a 'browser' request. This reliance on a JavaScript-capable browser matches up more closely to dedicated analytics systems like Google Analytics.
Existing data collection and graphs are unchanged. Data collected via the new technique is available in a new 'experimental' report.
Fixes two issues:
- frontend was reloading the page when clicking-to-remove avatar
- backend wasn't allowing resetting the setting by deleting all avatars
For better performances when listing all the API keys.
Loading all the "api key scopes" is slow and not required when showing the list of all the api keys.
- Run the CSP-nonce-related middlewares on the generated response
- Fix the readonly mode checking to avoid empty strings being passed (the `check_readonly_mode` before_action will not execute in the case of these re-dispatched exceptions)
- Move the BlockRequestsMiddleware cookie-setting to the middleware, so that it is included even for unusual HTML responses like these exceptions
Full text search does not return ideal results for category dropdown.
Usually, in category dropdowns we want to search for categories as we
type. For example, while typing "theme", the dropdown should show
intermediary results for "t", "th", "the", "them" and finally "theme".
For some of these substrings (like "the"), full text search does not
return any results, which leads to an unpleasant user experience.
The breadcrumbs were updated everytime there were changes to the
categories which was not efficient and caused unnecessary rerendering
of the CategoryDrop elements when "lazy load categories" is enabled.
This commit also ensures that all category fields are serialized for
ancestors too for the categories#search endpoint.
Include categories when fetching admin/web_hooks and make
'extras' more useful. 'extras' is the mechanism we use to provide
context for rest objects.
However, previously:
* When you fetched many objects, extras was only set on the ResultSet,
not on each object,
* If you need derived data from extras, there wasn't a sensible place to
put this code. Now, you can create an 'ExtrasClass' static field on
your rest model and this class will be used for your extras data,
When lazy load categories is enabled, categories should be loaded with
user activity items and drafts because the categories may not be
preloaded on the client side.
Using around_action means `add_early_hint_header` is in the stack for every request, and gets included in the backtrace of any errors.
We can manage with an after_action instead, which avoids adding to the stack depth (and avoids people blaming me for unrelated application errors 😉)
We will be collecting the logo URL and the site's default locale values along with existing basic details to display the site on the Discourse Discover listing page. It will be included only if the site is opted-in by enabling the "`include_in_discourse_discover`" site setting.
Also, we no longer going to use `about.json` and `site/statistics.json` endpoints retrieve these data. We will be using only the `site/basic-info.json` endpoint.
Plugins that are hidden or disabled aren't shown in the plugins list at `/admin/plugins` because they cannot be changed. However, the `#show` route doesn't check for the plugin's state and responds with 200 and the plugin's info even if the plugin is hidden or disabled. This commit makes the `#show` route respond with 404 if the plugin is hidden or disabled.
Why this change?
Before this change, the validation error message shown to the user when
saving a theme objects setting is very cryptic. This commit changes the
validation error messages to be displayed on top of the editor instead.
Note that I don't think this way of displaying is the ideal state we
want to get to but given the time we have this will do for now.
This commit removes the 'experimental_preconnect_link_header' site setting, and the 'preload_link_header' site setting, and introduces two new global settings: early_hint_header_mode and early_hint_header_name.
We don't actually send 103 Early Hint responses from Discourse. However, upstream proxies can be configured to cache a response header from the app and use that to send an Early Hint response to future clients.
- `early_hint_header_mode` specifies the mode for the early hint header. Can be nil (disabled), "preconnect" (lists just CDN domains) or "preload" (lists all assets).
- `early_hint_header_name` specifies which header name to use for the early hint. Defaults to "Link", but can be changed to support different proxy mechanisms.
Why this change?
Previously, we were preloading the necessary metadata for
`adminCustomizeThemes.show.schema` route in the
`adminCustomizeThemes.show` route. This is wasteful because we're
loading data upfront when the objects setting editor may not be used.
This change also lays the ground work for a future commit where we need
to be shipping down additional metadata which may further add to the
payload.
Previously, when crawlers triggered a Discourse::InvalidAccess exception, they would be served the full Ember SPA. The SPA is not optimized for crawling, and so this is likely to cause problems for sites. This issue is particularly problematic when user profiles are hidden from the public via the `hide_user_profiles_from_public` setting, because the crawler would end up being 'soft-redirected' to the homepage in the SPA.
Why this change?
In https://web.dev/articles/preconnect-and-dns-prefetch, it describes
how hinting to the browser to preconnect to domains which we will
eventually use the connection for can help improve the time it takes to
load a page.
We are putting this behind an experimental flag so that we can test and
profile this in a production environment.
What does this change introduce?
Introduce a hidden experimental `experimental_preconnect_link_header`
site setting which when enabled will add the `preconnect` and
`dns-prefetch` resource hints to the response headers for full page load
requests.
This commit makes it so the site settings filter controls and
the list of settings input editors themselves can be used elsewhere
in the admin UI outside of /admin/site_settings
This allows us to provide more targeted groups of settings in different
UI areas where it makes sense to provide them, such as on plugin pages.
You could open a single page for a plugin where you can see information
about that plugin, change settings, and configure it with custom UIs
in the one place.
In future we will do this in "config areas" for other parts of the
admin UI.
This commit operates at three levels of abstraction:
1. We want to prevent user history rows from being unbounded in size.
This commit adds rails validations to limit the sizes of columns on
user_histories,
2. However, we don't want to prevent certain actions from being
completed if these columns are too long. In those cases, we truncate
the values that are given and store the truncated versions,
3. For endpoints that perform staff actions, we can further control
what is permitted by explicitly validating the params that are given
before attempting the action,
With the new admin sidebar restructure, we have a link to "Installed plugins". We would like to ensure that when the admin is searching for a plugin name like "akismet" or "automation" this link will be visible. Also when entering the plugins page, related plugins should be highlighted.
This commit adds new plugin show routes (`/admin/plugins/:plugin_id`) as we move
towards every plugin having a consistent UI/landing page.
As part of this, we are introducing a consistent way for plugins
to show an inner sidebar in their config page, via a new plugin
API `register_admin_config_nav_routes`
This accepts an array of links with a label/text, and an
ember route. Once this commit is merged we can start the process
of conforming other plugins to follow this pattern, as well
as supporting a single-page version of this for simpler plugins
that don't require an inner sidebar.
Part of /t/122841 internally
Previously, if the sso= payload was invalid Base64, but signed correctly, there would be no useful log or error. This commit improves things by:
- moving the base64 check before the signature checking so that it's properly surfaced
- split the ParseError exception into PayloadParseError and SignatureError
- add user-facing errors for both of those
- add/improve spec for both
When "lazy load categories" is enabled, the CategoryDrop component will
render at most 15 categories. If there are more categories, a "Show
more" link pointing to the categories page will be displayed.
CategoryChooser component usually displays just categories, but
sometimes it can show two none values: a "no category" or Uncategorized.
This commit makes sure that these are rendered correctly.
The problem was that the "none" item was automatically inserted in the
list of options, but that should not always happen. Toggling option
`autoInsertNoneItem` requires setting `none` too.
Users can hide their public profile and presence information by checking
“Hide my public profile and presence features” on the
`u/{username}/preferences/interface` page. In that case, we also don't
want to return user status from the server.
This work has been started in https://github.com/discourse/discourse/pull/23946.
The current PR fixes all the remaining places in Core.
Note that the actual fix is quite simple – a5802f484d.
But we had a fair amount of duplication in the code responsible for
the user status serialization, so I had to dry that up first. The refactoring
as well as adding some additional tests is the main part of this PR.