Commit Graph

805 Commits

Author SHA1 Message Date
37609897e8 FEATURE: log manual bounce reset (#20758)
DEV: rename the route "/admin/users/:id/reset_bounce_score" to use dashes instead of underscores
2023-03-21 15:26:26 +01:00
db74e9484b FEATURE: ability to reorder links in custom sidebar sections (#20626)
Drag and drop to reorder custom sidebar sections
2023-03-21 12:23:28 +11:00
66c50547b4 DEV: Experimental /filter route to filter through topics (#20494)
This commit introduces an experimental `/filter` route which allows a
user to input a query string to filter through topics.

Internal Ref: /t/92833
2023-03-03 09:46:21 +08:00
666b4a7e6b DEV: Define form template field inputs (#20430) 2023-03-01 11:07:13 -08:00
b9d037770c DEV: configurable public sidebar sections (#20303)
Extension of https://github.com/discourse/discourse/pull/20057

Admin can create a public session visible to everyone. An additional checkbox is displayed for staff members.
2023-02-22 08:55:44 +11:00
871607a420 DEV: Create form templates (#20189) 2023-02-08 11:21:39 -08:00
84a87a703c DEV: configurable custom sidebar sections (#20057)
Allows users to configure their own custom sidebar sections with links withing Discourse instance. Links can be passed as relative path, for example "/tags" or full URL.

Only path is saved in DB, so when Discourse domain is changed, links will be still valid.

Feature is hidden behind SiteSetting.enable_custom_sidebar_sections. This hidden setting determines the group which members have access to this new feature.
2023-02-03 14:44:40 +11:00
c8f8d9dbb6 DEV: Change slugs/generate endpoint from GET to POST (#19984)
Followup on feedback on PR #19928
https://github.com/discourse/discourse/pull/19928#discussion_r1083687839,
it makes more sense to have this endpoint as a POST rather than
a GET.
2023-01-27 10:58:33 +10:00
641e94fc3c FEATURE: Allow changing slug on create channel (#19928)
This commit allows us to set the channel slug when creating new chat
channels. As well as this, it introduces a new `SlugsController` which can
generate a slug using `Slug.for` and a name string for input. We call this
after the user finishes typing the channel name (debounced) and fill in
the autogenerated slug in the background, and update the slug input
placeholder.

This autogenerated slug is used by default, but if the user writes anything
else in the input it will be used instead.
2023-01-23 14:48:33 +10:00
292d3677e9 FEATURE: Allow admins to permanently delete revisions (#19913)
# Context
This PR introduces the ability to permanently delete revisions from a post while maintaining the changes implemented by the revisions.
Additional Context: /t/90301

# Functionality
In the case a staff member wants to _remove the visual cue_ that a post has been edited eg.

<img width="86" alt="Screenshot 2023-01-18 at 2 59 12 PM" src="https://user-images.githubusercontent.com/50783505/213293333-9c881229-ab18-4591-b39b-e3419a67907d.png">

while maintaining the changes made in the edits, they can enable the (hidden) site setting of `can_permanently_delete`.
When this is enabled, after _hiding_ the revisions

<img width="149" alt="Screenshot 2023-01-19 at 1 53 35 PM" src="https://user-images.githubusercontent.com/50783505/213546080-2a9e9c55-b3ef-428e-a93d-1b6ba287dfae.png">

there will be an additional button in the history modal to <kbd>Delete revisions</kbd> on a post.

<img width="997" alt="Screenshot 2023-01-19 at 1 49 51 PM" src="https://user-images.githubusercontent.com/50783505/213546333-49042558-50ab-4724-9da7-08bacc68d38d.png">

Since this action is permanent, we display a confirmation dialog prior to triggering the destroy call

<img width="722" alt="Screenshot 2023-01-19 at 1 55 59 PM" src="https://user-images.githubusercontent.com/50783505/213546487-96ea6e89-ac49-4892-b4b0-28996e3c867f.png">

Once confirmed the history modal will close and the post will `rebake` to display an _unedited_ post.

<img width="868" alt="Screenshot 2023-01-19 at 1 56 35 PM" src="https://user-images.githubusercontent.com/50783505/213546608-d6436717-8484-4132-a1a8-b7a348d92728.png">
 
see that there is not a visual que for _revision have been made on this post_ for a post that **HAS** been edited. In addition to this, a user history log for `purge_post_revisions` will be added for each action completed.

# Limits
- Admins are rate limited to 20 posts per minute
2023-01-19 15:09:01 -06:00
d2e9ea6193 FEATURE: Allow group owners promote more owners (#19768)
This change allows group owners (in addition to admins) to promote other members to owners.
2023-01-11 16:43:18 +08:00
7c77cc6a58 DEV: Apply syntax_tree formatting to config/* 2023-01-09 11:13:29 +00:00
cf862e7365 SECURITY: Convert send_digest to a post request (#19746)
Co-authored-by: Isaac Janzen <isaac.janzen@discourse.org>
2023-01-05 06:57:12 +08:00
f9bdda84ca DEV: Admin webhooks interface issues (#19360)
1. The events table had broken styling, making each row overflow
2. It had confusing routes: `/:id` for "edit" and `/:id/events` for "show" (now it's `/:id/edit` and `/:id` respectively)
3. There previously was an unused backend action (`#edit`) - now it is used (and `web_hooks/:id/events` route has been removed)
4. There was outdated/misplaced/duplicated CSS
5. And more
2022-12-13 01:53:08 +01:00
1db3a578e4 PERF: Improve Accept header handling for stylesheets and theme-js (#19357)
The default behavior for Rails is to vary the response of an endpoint based on the `Accept:` header, and therefore it returns a `Vary:` header on responses. This instructs browsers and intermediate proxies to key their caches based on the value of the request's `Accept` header. In some cases (e.g. Akamai), the presence of a `Vary` header is enough to prevent caching entirely.

This commit restructures the Rails route definitions so that:
1. The "format" segment of the route is 'required'
2. The "format" segment of the route is constrained to a single value (e.g. `js` or `css`)

Now that the routes are guaranteed to have a `:format` segment, Rails will always prioritize that over the `Accept` header, and will therefore omit the `Vary` header.

Request specs are also added to test this behaviour for both stylesheets and theme-javascripts.
2022-12-07 15:46:35 +00:00
93859037ef FEATURE: Improve composer warnings for mentions (#18796)
* FEATURE: Show warning if group cannot be mentioned

A similar warning is displayed when the user cannot be mentioned because
they have not been invited to the topic.

* FEATURE: Resolve mentions for new topic

This commit improves several improvements and refactors
/u/is_local_username route to a better /composer/mentions route that
can handle new topics too.

* FEATURE: Show warning if only some are notified

Sometimes users are still notified even if the group that was mentioned
was not invited to the message. This happens because its members were
invited directly or are members of other groups that were invited.

* DEV: Refactor _warnCannotSeeMention
2022-12-05 20:22:05 +02:00
6357a3ce33 FEATURE: User Status API (#19149)
This adds API scope for the user status. This also adds a get method to the user status controller. We didn't need a dedicated method that returns status before because the server returns status with user objects, but I think we need to provide this method for API clients.
2022-11-24 19:16:28 +04:00
d3f02a1270 FEATURE: Generic hashtag autocomplete lookup and markdown cooking (#18937)
This commit fleshes out and adds functionality for the new `#hashtag` search and
lookup system, still hidden behind the `enable_experimental_hashtag_autocomplete`
feature flag.

**Serverside**

We have two plugin API registration methods that are used to define data sources
(`register_hashtag_data_source`) and hashtag result type priorities depending on
the context (`register_hashtag_type_in_context`). Reading the comments in plugin.rb
should make it clear what these are doing. Reading the `HashtagAutocompleteService`
in full will likely help a lot as well.

Each data source is responsible for providing its own **lookup** and **search**
method that returns hashtag results based on the arguments provided. For example,
the category hashtag data source has to take into account parent categories and
how they relate, and each data source has to define their own icon to use for the
hashtag, and so on.

The `Site` serializer has two new attributes that source data from `HashtagAutocompleteService`.
There is `hashtag_icons` that is just a simple array of all the different icons that
can be used for allowlisting in our markdown pipeline, and there is `hashtag_context_configurations`
that is used to store the type priority orders for each registered context.

When sending emails, we cannot render the SVG icons for hashtags, so
we need to change the HTML hashtags to the normal `#hashtag` text.

**Markdown**

The `hashtag-autocomplete.js` file is where I have added the new `hashtag-autocomplete`
markdown rule, and like all of our rules this is used to cook the raw text on both the clientside
and on the serverside using MiniRacer. Only on the server side do we actually reach out to
the database with the `hashtagLookup` function, on the clientside we just render a plainer
version of the hashtag HTML. Only in the composer preview do we do further lookups based
on this.

This rule is the first one (that I can find) that uses the `currentUser` based on a passed
in `user_id` for guardian checks in markdown rendering code. This is the `last_editor_id`
for both the post and chat message. In some cases we need to cook without a user present,
so the `Discourse.system_user` is used in this case.

**Chat Channels**

This also contains the changes required for chat so that chat channels can be used
as a data source for hashtag searches and lookups. This data source will only be
used when `enable_experimental_hashtag_autocomplete` is `true`, so we don't have
to worry about channel results suddenly turning up.

------

**Known Rough Edges**

- Onebox excerpts will not render the icon svg/use tags, I plan to address that in a follow up PR
- Selecting a hashtag + pressing the Quote button will result in weird behaviour, I plan to address that in a follow up PR
- Mixed hashtag contexts for hashtags without a type suffix will not work correctly, e.g. #ux which is both a category and a channel slug will resolve to a category when used inside a post or within a [chat] transcript in that post. Users can get around this manually by adding the correct suffix, for example ::channel. We may get to this at some point in future
- Icons will not show for the hashtags in emails since SVG support is so terrible in email (this is not likely to be resolved, but still noting for posterity)
- Additional refinements and review fixes wil
2022-11-21 08:37:06 +10:00
a6c787345c UX: reorganize user prefs for experimental user nav (#18764)
Trying out changes to reduce the number of nav items in the experimental horizontal user nav. These changes should only appear with the redesigned_user_page_nav_enabled feature flag.

1. Created a new "Tracking" route. This combines some tracking-related settings from Notifications and Category and Tag tracking (which were separate tabs previously). Don't love the layout yet, but it's something that we can work on.

2. Moved some user-related settings out of Notifications and to the
Users tab. These seem more user-related to me, and it's nice that we can
associate enabling messages with the setting to limit who can send
messages.

3. Moved the App tab (lists app permissions) to be within the Security tab. It's very similar to Recently Used Devices.
2022-11-18 09:09:04 +08:00
8b8c1291e7 FIX: do not preload topic list for new topic/message routes (#18959)
This commit fixes the issue where the sub-category topic list was not
loading for new-topic routes. Since we do not need to preload topic
lists for new topic/message routes this commit adds a no-op controller
that prevents topic lists pre loading and at the same time fixes the sub
category topics not loading issue.
2022-11-09 20:57:42 +05:30
0be0bcfc7d FIX: Do not show a 404 page when visiting messages (#18652)
* DEV: Use list controller and action

It used an empty action handler which just returned the app and it
required another request to get the topic list. By using the correct
controller and action we can preload the topic list.
2022-10-20 16:24:56 +03:00
9a4072fe31 DEV: Load plugin CSS in tests (#18668) 2022-10-19 18:10:06 +01:00
7c25597da2 FEATURE: Generic hashtag autocomplete part 1 (#18592)
This commit adds a new `/hashtag/search` endpoint and both
relevant JS and ruby plugin APIs to handle plugins adding their
own data sources and priority orders for types of things to search
when `#` is pressed.

A `context` param is added to `setupHashtagAutocomplete` which
a corresponding chat PR https://github.com/discourse/discourse-chat/pull/1302
will now use.

The UI calls `registerHashtagSearchParam` for each context that will
require a `#` search (e.g. the topic composer), for each type of record that
the context needs to search for, as well as a priority order for that type. Core
uses this call to add the `category` and `tag` data sources to the topic composer.

The `register_hashtag_data_source` ruby plugin API call is for plugins to
add a new data source for the hashtag searching endpoint, e.g. discourse-chat
may add a `channel` data source.

This functionality is hidden behind the `enable_experimental_hashtag_autocomplete`
flag, except for the change to `setupHashtagAutocomplete` since only core and
discourse-chat are using that function. Note this PR does **not** include required
changes for hashtag lookup or new styling.
2022-10-19 14:03:57 +10:00
be3d6a56ce DEV: Introduce minification and source maps for Theme JS (#18646)
Theme javascript is now minified using Terser, just like our core/plugin JS bundles. This reduces the amount of data sent over the network.

This commit also introduces sourcemaps for theme JS. Browser developer tools will now be able show each source file separately when browsing, and also in backtraces.

For theme test JS, the sourcemap is inlined for simplicity. Network load is not a concern for tests.
2022-10-18 18:20:10 +01:00
ae1e536e83 SECURITY: moderator shouldn't be able to import a theme via API (#18418)
* SECURITY: moderator shouldn't be able to import a theme via API.
* DEV: apply `AdminConstraint` for all the "themes" routes.

Co-authored-by: Vinoth Kannan <svkn.87@gmail.com>
2022-09-29 20:00:20 +02:00
8ebd5edd1e DEV: Rename secure_media to secure_uploads (#18376)
This commit renames all secure_media related settings to secure_uploads_* along with the associated functionality.

This is being done because "media" does not really cover it, we aren't just doing this for images and videos etc. but for all uploads in the site.

Additionally, in future we want to secure more types of uploads, and enable a kind of "mixed mode" where some uploads are secure and some are not, so keeping media in the name is just confusing.

This also keeps compatibility with the `secure-media-uploads` path, and changes new
secure URLs to be `secure-uploads`.

Deprecated settings:

* secure_media -> secure_uploads
* secure_media_allow_embed_images_in_emails -> secure_uploads_allow_embed_images_in_emails
* secure_media_max_email_embed_image_size_kb -> secure_uploads_max_email_embed_image_size_kb
2022-09-29 09:24:33 +10:00
2ee721f8aa FEATURE: add composer warning when user haven't been seen in a long time (#18340)
* FEATURE: add composer warning when user haven't been seen in a long time

When a user creates a PM and adds a recipient that hasn't been seen in a
long time then we'll now show a warning in composer indicating that the
user hasn't been seen in a long time.
2022-09-27 22:06:40 +05:30
6771673a1b Fix constraints typo in routes config (#17994) 2022-08-24 10:27:05 +08:00
473695ee4d DEV: Add messages tab to the new user menu (#17850)
Some of the changes in this PR are extracted from https://github.com/discourse/discourse/pull/17379.

Similar to the bookmarks tab in the new user menu, the messages tab also displays a mix of notifications and messages. When there are unread message notifications, the tab displays all of these notifications at the top and fills the remaining space in the menu with a list of the user's messages. The bubble/badge count on the messages tab indicates how many unread message notifications there are.
2022-08-10 08:25:39 +03:00
4fdb275683 DEV: Add bookmarks tab to the new user menu (#17814)
Some of the changes in this commit are extracted from https://github.com/discourse/discourse/pull/17379.

The bookmarks tab in the new user menu is different from the other tabs in that it can display a mixture of notifications and bookmarks. When there are unread bookmark reminder notifications, the tab displays all of these notifications at the top and fills the remaining space in the menu with the rest of the bookmarks. The bubble/badge count on the bookmarks tab indicates how many unread bookmark reminder notifications there are.

On the technical aspect, since this commit introduces a new `bookmark-item` component, we've done some refactoring so that all 3 "item" components (`notification-item`, `reviewable-item` and the new `bookmark-item`) inherit from a base component and get identical HTML structure so they all look consistent.

Internal tickets: t70584 and t65045.
2022-08-08 17:24:04 +03:00
f590b62a31 FIX: Accept HEAD requests for mandrill webhook (#17180)
Madrill uses a HEAD request for validation, accept it.
2022-07-29 16:26:31 +10:00
988a175e94 DEV: Add reviewables tab to the new user menu (#17630)
This commit is a subset of the changes proposed in https://github.com/discourse/discourse/pull/17379.
2022-07-28 11:16:33 +03:00
3266350e80 FEATURE: Decouple category/tag presence in sidebar from notifi level (#17273) 2022-06-30 14:54:20 +08:00
2c1fc28d00 DEV: Remove ember-cli flags from the backend (#17147)
…and other auxiliary code

* Restore `QUNIT_EMBER_CLI` flag warning
* Add `ALLOW_EMBER_CLI_PROXY_BYPASS`
2022-06-20 16:33:05 +02:00
5c596273a0 FEATURE: user status (#16875) 2022-05-27 13:15:14 +04:00
9fc3d46003 Update wordpress scopes and add `session/scopes` endpoint (#15366)
* Update wordpress scopes && add ``session/scopes`` endpointt

* Fix failing spec

* Add users#show scope to discourse_connect

* Update app/controllers/session_controller.rb

Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com>

Co-authored-by: Roman Rizzi <rizziromanalejandro@gmail.com>
2022-05-02 12:15:32 -03:00
2a96bca7a1 FIX: Correctly handle the print param on topics#show. (#16555)
The controller incorrectly sets print to true when passing `print=false`, which causes the rate limit to perform.
2022-04-25 16:04:13 -03:00
48417b59d6 FIX: Return a 404 when a sitemap request doesn't have a format (#16506) 2022-04-19 11:07:25 -03:00
6f76a12e0a FEATURE: Let sites add a sitemap.xml file. (#16357)
* FEATURE: Let sites add a sitemap.xml file.

This PR adds the same features discourse-sitemap provides to core. Sitemaps are only added to the robots.txt file if the `enable_sitemap` setting is enabled and `login_required` disabled.

After merging discourse/discourse-sitemap#34, this change will take priority over the sitemap plugin because it will disable itself. We're also using the same sitemaps table, so our migration won't try to create it
again using `if_not_exists: true`.
2022-04-12 10:33:59 -03:00
0f7b9878ff SECURITY: Category group permissions leaked to normal users.
After this commit, category group permissions can only be seen by users
that are allowed to manage a category. In the past, we inadvertently
included a category's group permissions settings in `CategoriesController#show`
and `CategoriesController#find_by_slug` endpoints for normal users when
those settings are only a concern to users that can manage a category.
2022-04-08 13:46:20 +08:00
daacb3b038 FIX: Ensure all/none subcategory filters work correctly with tags
This is done by defining a `/all` route for use when a category's default filter is 'none'. This was defined for regular category routes in 3e7f7fdd, but not for tag routes.

This commit also corrects the route name TagsShowNoneCategory*Route -> TagsShowCategoryNone*Route, which fixes an error when setting subcategories=none while filtering by tags.
2022-03-22 15:26:00 +00:00
02fa04e333 FIX: Update topic route id param (#16166)
This update topic route has never worked. Better late than never. I am
in favor of using non-slug urls when using the api so I do think we
should fix this route.

Just thought I would update the `:id` param to `:topic_id` here in the
routes file instead of updating the controller to handle both params.

Added a spec to test this route.

Also added the same constraint we have on other topic routes to ensure
we only pass in an ID that is a digit.
2022-03-11 11:01:08 -07:00
e3b4998efc DEV: Remove notify user topic from share modal (#16085)
This feature was rarely used, could be used for spamming users and was
impossible to add a context to why the user was notified of a topic. A
simple private messages that includes the link and personalized message
can be used instead.
2022-03-03 09:27:45 +11:00
dd6ec65061 FEATURE: Centralized 2FA page (#15377)
2FA support in Discourse was added and grown gradually over the years: we first
added support for TOTP for logins, then we implemented backup codes, and last
but not least, security keys. 2FA usage was initially limited to logging in,
but it has been expanded and we now require 2FA for risky actions such as
adding a new admin to the site.

As a result of this gradual growth of the 2FA system, technical debt has
accumulated to the point where it has become difficult to require 2FA for more
actions. We now have 5 different 2FA UI implementations and each one has to
support all 3 2FA methods (TOTP, backup codes, and security keys) which makes
it difficult to maintain a consistent UX for these different implementations.
Moreover, there is a lot of repeated logic in the server-side code behind these
5 UI implementations which hinders maintainability even more.

This commit is the first step towards repaying the technical debt: it builds a
system that centralizes as much as possible of the 2FA server-side logic and
UI. The 2 main components of this system are:

1. A dedicated page for 2FA with support for all 3 methods.
2. A reusable server-side class that centralizes the 2FA logic (the
`SecondFactor::AuthManager` class).

From a top-level view, the 2FA flow in this new system looks like this:

1. User initiates an action that requires 2FA;

2. Server is aware that 2FA is required for this action, so it redirects the
user to the 2FA page if the user has a 2FA method, otherwise the action is
performed.

3. User submits the 2FA form on the page;

4. Server validates the 2FA and if it's successful, the action is performed and
the user is redirected to the previous page.

A more technically-detailed explanation/documentation of the new system is
available as a comment at the top of the `lib/second_factor/auth_manager.rb`
file. Please note that the details are not set in stone and will likely change
in the future, so please don't use the system in your plugins yet.

Since this is a new system that needs to be tested, we've decided to migrate
only the 2FA for adding a new admin to the new system at this time (in this
commit). Our plan is to gradually migrate the remaining 2FA implementations to
the new system.

For screenshots of the 2FA page, see PR #15377 on GitHub.
2022-02-17 12:12:59 +03:00
07893779df DEV: Correct service-worker sourceMappingURL (#15916)
We serve `service-worker.js` in an unusual way, which means that the sourcemap is not available on an adjacent path. This means that the browser fails to fetch the map, and shows an error in the console.

This commit re-writes the source map reference in the static_controller to be an absolute link to the asset (including the appropriate CDN, if enabled), and adds a spec for the behavior.

It's important to do this at runtime, rather than JS precompile time, so that changes to CDN configuration do not require re-compilation to take effect.
2022-02-14 12:47:56 +00:00
71f7f7ed49 FEATURE: Add external_id to topics (#15825)
* FEATURE: Add external_id to topics

This commit allows for topics to be created and fetched by an
external_id. These changes are API only for now as there aren't any
front changes.

* add annotations

* add external_id to this spec

* Several PR feedback changes

- Add guardian to find topic
- 403 is returned for not found as well now
- add `include_external_id?`
- external_id is now case insensitive
- added test for posts_controller
- added test for topic creator
- created constant for max length
- check that it redirects to the correct path
- restrain external id in routes file

* remove puts

* fix tests

* only check for external_id in webhook if exists

* Update index to exclude external_id if null

* annotate

* Update app/controllers/topics_controller.rb

We need to check whether the topic is present first before passing it to the guardian.

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

* Apply suggestions from code review

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2022-02-08 20:55:32 -07:00
9bfe5e58d3 Revert "DEV: Add context in AdminConstraint (#15838)" (#15845)
This reverts commit 492226a9737fc6c8d672383316569b7d2c523a55.
2022-02-07 21:05:19 +03:00
492226a973 DEV: Add context in AdminConstraint (#15838)
This allows plugins to override the permissions required to access
specific things like the Logster and Sidekiq web UI without the changes
leaking to the rest of Discourse routes.
2022-02-07 16:25:31 +03:00
5d35c38db2 FEATURE: Search screened IP address in blocks (#15461)
An admin could search for all screened ip addresses in a block by
using wildcards. 192.168.* returned all IPs in range 192.168.0.0/16.
This feature allows admins to search for a single IP address in all
screened IP blocks. 192.168.0.1 returns all IP blocks that match it,
for example 192.168.0.0/16.

* FEATURE: Remove roll up button for screened IPs

* FIX: Match more specific screened IP address first
2022-01-11 09:16:51 +02:00
df3886d6e5 FEATURE: Experimental support for group membership via google auth (#14835)
This commit introduces a new site setting "google_oauth2_hd_groups". If enabled, group information will be fetched from Google during authentication, and stored in the Discourse database. These 'associated groups' can be connected to a Discourse group via the "Membership" tab of the group preferences UI. 

The majority of the implementation is generic, so we will be able to add support to more authentication methods in the near future.

https://meta.discourse.org/t/managing-group-membership-via-authentication/175950
2021-12-09 12:30:27 +00:00