Commit Graph

1764 Commits

Author SHA1 Message Date
Alan Guo Xiang Tan fc40a572bb
DEV: Register question_answer_user_commented notification type. (#16297)
The notification type is used by https://github.com/discourse/discourse-question-answer
2022-03-28 16:03:19 +08:00
Mark VanLandingham a3563336db
FIX: Bug setting notification level to muted/ignored on user page (#16268) 2022-03-25 10:51:45 -05:00
Daniel Waterworth 9ce6280f51
DEV: Make tests more resilient (#16279)
Since we give a 200 response for login errors, we should be checking
whether the error key exists in each case or not.

Some tests were broken, because they weren't checking.
2022-03-25 10:44:12 -05:00
Dan Ungureanu 03ad88f2c2
FIX: Add `errors` field if group update confirmation (#16260)
* FIX: Redirect if Discourse-Xhr-Redirect is present

`handleRedirect` was passed an wrong argument type (a string) instead of
a jqXHR object and missed the fields checked in condition, thus always
evaluating to `false`.

* FIX: Add `errors` field if group update confirmation

An explicit confirmation about the effect of the group update is
required if the default notification level changes. Previously, if the
confirmation was missing the API endpoint failed silently returning
a 200 response code and a `user_count` field. This change ensures that
a proper error code is returned (422), a descriptive error message and
the additional information in the `user_count` field.

This commit also refactors the API endpoint to use the
`Discourse-Xhr-Redirect` header to redirect the user if the group is
no longer visible.
2022-03-24 14:50:44 +02:00
David Taylor 80dd769530 FIX: Issue 404 for invalid `/tags/c/...` routes
Previously we would issue a 403 for all invalid routes under `/tags/c/...`, which is not semantically correct. In some cases, these 403'd routes would then be handled successfully in the Ember app, leading to some very confusing behavior.
2022-03-22 15:26:00 +00:00
Blake Erickson 61248652cd
DEV: Allow params to be passed on topic redirects (#16218)
* DEV: Allow params to be passed on topic redirects

There are several places where we redirect a url to a standard topic url
like `/t/:slug/:topic_id` but we weren't always passing query parameters
to the new url.

This change allows a few more query params to be included on the
redirect. The new params that are permitted are page, print, and
filter_top_level_replies. Any new params will need to be specified.

This also prevents the odd trailing empty page param that would
sometimes appear on a redirect. `/t/:slug/:id.json?page=`

* rubocop: fix missing space after comma

* fix another page= reference
2022-03-17 19:27:51 -06:00
Rafael dos Santos Silva 100a84d345
DEV: Reserve assigned notification type (#16207)
* DEV: Reserve assigned notification type

* update constants
2022-03-16 17:08:10 -03:00
Sam de9a031073
FEATURE: use canonical links in posts.rss feed (#16190)
* FEATURE: use canonical links in posts.rss feed

Previously we used non canonical links in posts.rss

These links get crawled frequently by crawlers when discovering new
content forcing crawlers to hop to non canonical pages just to end up
visiting canonical pages

This uses up expensive crawl time and adds load on Discourse sites

Old links were of the form:

`https://DOMAIN/t/SLUG/43/21`

New links are of the form

`https://DOMAIN/t/SLUG/43?page=2#post_21`

This also adds a post_id identified element to crawler view that was
missing.

Note, to avoid very expensive N+1 queries required to figure out the
page a post is on during rss generation, we cache that information.

There is a smart "cache breaker" which ensures worst case scenario is
a "page drift" - meaning we would publicize a post is on page 11 when
it is actually on page 10 due to post deletions. Cache holds for up to
12 hours.

Change only impacts public post RSS feeds (`/posts.rss`)
2022-03-15 20:17:06 +11:00
David Taylor 8664712c1a
PERF: Fix n+1 for categories + featured topics (#16188)
`topic.featured_topic` and `topic.category` are used by `TopicGuardian#can_see_topic?`
2022-03-14 22:23:39 +00:00
Blake Erickson 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
Sam 43da88db6c
PERF: avoid following links in topic RSS feeds (#16145)
Topic RSS feeds contain many non canonical links such as:

- https://site.com/t/a-b-c/111/1
- https://site.com/t/a-b-c/111/2
- https://site.com/t/a-b-c/111/3
- https://site.com/t/a-b-c/111/4
- https://site.com/t/a-b-c/111/5
- https://site.com/t/a-b-c/111/6

Previously we were not indexing RSS feeds yet still following these
links.


This change means we totally ignore links in the RSS feeds which
avoids expensive work scanning them just to find we should not
include them.
2022-03-09 18:25:20 +11:00
Martin Brennan ca93e5e68b
FIX: Allow admins to change user ignore list (#16129)
Previously, if an admin user tried to add/remove
users to another user's ignored list, it would
be added to their own ignore list because the
controller used current_user. Now for admins only
a source_user_id parameter can be passed through,
which will be used to ignore the target user for
that source user.
2022-03-09 14:51:30 +10:00
Jarek Radosz bf252752e7
FIX: Make reply-ids public by fixing a typo (#16137)
…and spec the endpoint
2022-03-08 21:08:15 +01:00
Jarek Radosz 14109ea92c
FIX: Show 404 html on /posts/:id/raw and /p/:id (#16131)
It returned a blank page before.
2022-03-08 17:42:07 +01:00
Jarek Radosz 768c80c2a4
DEV: Make `find_post_using` raise only `Discourse::NotFound` (#16133) 2022-03-08 17:39:52 +01:00
Martin Brennan 7af01d88d2
FIX: Better 0 file size detection and logging (#16116)
When creating files with create-multipart, if the file
size was somehow zero we were showing a very unhelpful
error message to the user. Now we show a nicer message,
and proactively don't call the API if we know the file
size is 0 bytes in JS, along with extra console logging
to help with debugging.
2022-03-07 12:39:33 +10:00
Blake Erickson d760fd4074
DEV: Add API scope for categories endpoint (#16105)
This change adds support for the categories endpoint to have an api
scope. Only adds GET scope for listing categories and for fetching a
single category.

See: https://meta.discourse.org/t/218080/4
2022-03-04 14:29:47 -07:00
David Taylor eb2e3b510d
FEATURE: Introduce 'Subcategories with featured topics' view (#16083)
This categories view is designed for sites which make heavy use of subcategories, and use top-level categories mainly for grouping
2022-03-04 21:11:59 +00:00
Osama Sayegh 8c71878ff5
UX: Add description to the 2FA page when adding new admins (#16098)
This PR adds an extra description to the 2FA page when granting a user admin access. It also introduces a general system for adding customized descriptions that can be used by future actions.

(Follow-up to dd6ec65061)
2022-03-04 06:43:06 +03:00
Dan Ungureanu 39ab14531a
FEATURE: API to create user's associated account (#15737)
Discourse users and associated accounts are created or updated when a
user logins or connects the account using their account preferences.
This new API can be used to create associated accounts and users too,
if necessary.
2022-03-03 18:17:02 +02:00
Sam 3bf5692c72
FEATURE: prioritize group search order based on prefix match (#16093)
Our @mention user search prioritized users based on prefix matches.

So if searching for `sa` we will display `sam`, `asam` in that order

Previously, we did not prioritize group matches based on prefix. This change ensures better parity.

Implementation notes:

1. User search only prioritizes based on username prefix, not name prefix. TBD if we want to change that.
2. @mention on client side will show 0 group matches if we fill up all the spots with user matches. TBD if we want to unconditionally show the first / second group match.

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2022-03-03 16:57:52 +11:00
Dan Ungureanu 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
Bianca Nenciu b21bf840cb
FEATURE: Return geoname IDs from MaxMindDb (#16082)
The geoname IDs can be used by plugins to locate the user more precisely.
2022-03-02 23:51:42 +02:00
Blake Erickson df2441ee37
Top level replies (#16087)
* DEV: Show only top level replies

Adds a new query param to the topic view so that we can filter out posts
that aren't top level replies. If a post is a reply to another post
instead of the original topic post we should not include it in the
response if the `filter_top_level_replies` query param is present.

* add rspec test
2022-03-02 13:25:36 -07:00
David Taylor c9dab6fd08
DEV: Automatically require 'rails_helper' in all specs (#16077)
It's very easy to forget to add `require 'rails_helper'` at the top of every core/plugin spec file, and omissions can cause some very confusing/sporadic errors.

By setting this flag in `.rspec`, we can remove the need for `require 'rails_helper'` entirely.
2022-03-01 17:50:50 +00:00
Jarek Radosz 2fc70c5572
DEV: Correctly tag heredocs (#16061)
This allows text editors to use correct syntax coloring for the heredoc sections.

Heredoc tag names we use:

languages: SQL, JS, RUBY, LUA, HTML, CSS, SCSS, SH, HBS, XML, YAML/YML, MF, ICS
other: MD, TEXT/TXT, RAW, EMAIL
2022-02-28 20:50:55 +01:00
Jarek Radosz c97b4d530a
DEV: Freeze time in time-sensitive specs (#16062)
Hopefully fixes a flake 🙂
2022-02-28 14:15:13 +08:00
Jarek Radosz 6f6406ea03
DEV: Fix random typos (#16066) 2022-02-28 10:20:58 +08:00
Jeff Wong d1bdb6c65d
FEATURE: upload an avatar option for uploading avatars with selectable avatars (#15878)
* FEATURE: upload an avatar option for uploading avatars with selectable avatars

Allow staff or users at or above a trust level to upload avatars even when the site
has selectable avatars enabled.

Everyone can still pick from the list of avatars. The option to upload is shown
below the selectable avatar list.

refactored boolean site setting into an enum with the following values:

disabled: No selectable avatars enabled (default)
everyone: Show selectable avatars, and allow everyone to upload custom avatars
tl1: Show selectable avatars, but require tl1+ and staff to upload custom avatars
tl2: Show selectable avatars, but require tl2+ and staff to upload custom avatars
tl3: Show selectable avatars, but require tl3+ and staff to upload custom avatars
tl4: Show selectable avatars, but require tl4 and staff to upload custom avatars
staff: Show selectable avatars, but only allow staff to upload custom avatars
no_one: Show selectable avatars. No users can upload custom avatars

Co-authored-by: Régis Hanol <regis@hanol.fr>
2022-02-24 12:57:39 -08:00
Loïc Guitaut e871865a61 FIX: Sanitize parameters provided to user actions
Currently, providing things like `filter[%24acunetix]=1` to
`UserActionsController#index` will throw an exception because instead of
getting a string as expected, we get a hash instead.

This patch simply uses `#permit` from strong parameters properly: first
we apply it on the whole parameters, this way it filters the keys we’re
interested in. By doing this, if the value is a hash for example, the
whole key/value pair will be ignored completely.
2022-02-23 15:46:40 +01:00
Bianca Nenciu ae1d2d957f
FEATURE: Replace share post popup with share modal (#15875)
This uniformizes the topic share modal and the post link popup. It also
introduces a new feature which can notify the user of a post.
2022-02-21 22:14:28 +02:00
David Taylor 5d6d3fb244
DEV: Remove child theme settings/variables from parent compilation (#16001)
aa1442fdc3 split theme stylesheets so that every component gets its own stylesheet. Therefore, there is now no need for parent themes to collate the settings/variables of its children during scss compilation.

Technically this is a breaking change for any themes which depend on the settings/variables of their child components. That was never a supported/recommended arrangement, so we don't expect this to cause issues.
2022-02-21 11:15:35 +00:00
Osama Sayegh 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
Dan Ungureanu effbd6d3e4
FEATURE: Show error if invite to topic is invalid (#15959)
This can happen if the topic to which a user is invited is in a private
category and the user was not invited to one of the groups that can see
that specific category.

This used to be a warning and this commit makes it an error.
2022-02-16 18:35:02 +02:00
Martin Brennan 2d30dd439f
DEV: Add chat_quoted notification type (#15968)
This is needed for the notification sent when quoting
chat messages inside a post.
2022-02-16 15:22:08 +10:00
Vinoth Kannan 1ea19a4d51
FIX: unable to filter user directory when sorted by user field. (#15951)
Since the "users" table is already added in the "includes" method it gives unexpected results while using it again in the "joins" method.
2022-02-16 07:57:35 +05:30
Dan Ungureanu dd5373cc4c
FIX: Do not increase invite count for current user (#15952)
The current user could redeem an invite created by themselves.
2022-02-15 17:35:58 +02:00
Martin Brennan 4086ee551e
DEV: Add bounce_error_code to EmailLog (#15948)
Whenever we got a bounced email in the Email::Receiver we
previously would just set bounced: true on the EmailLog and
discard the status/diagnostic code. This commit changes this
flow to store the bounce error code (defined in the RFC at
https://www.iana.org/assignments/smtp-enhanced-status-codes/smtp-enhanced-status-codes.xhtml)
not just in the Email::Receiver, but also via webhook events
from other mail services and from SNS.

This commit does not surface the bounce error in the UI,
we can do that later if necessary.
2022-02-15 14:17:26 +10:00
David Taylor 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
Blake Erickson febc2361bd
DEV: Document external topic id endpoints (#15897)
* DEV: Document external topic id endpoints

This commit documents the existing Create Topic endpoint with the
`external_id` param and documents the new get topic by external id
endpoint.

It also refactors the existing topic show endpoint to use the new format
where we load the expected json schema response from a file.

See: 71f7f7ed49

* clean up unused test variables
2022-02-10 19:01:19 -07:00
Alan Guo Xiang Tan b876ff6281
FIX: Update user stat counts when post/topic visibility changes. (#15883)
Breakdown of fixes in this commit:

* `UserStat#topic_count` was not updated when visibility of
the topic changed.

* `UserStat#post_count` was not updated when post was hidden or
unhidden.

* `TopicConverter` was only incrementing or decrementing the counts by 1
even if a user has multiple posts in the topic.

* The commit turns off the verbose logging by default as it is just
noise to normal users who are not debugging this problem.
2022-02-11 09:00:58 +08:00
Blake Erickson e66241af7f
DEV: Update api docs to update username and to get post replies (#15881)
Added api docs for:

 - update username
 - get post replies
2022-02-09 15:04:36 -07:00
Dan Ungureanu 2d8ebe989a
FEATURE: Redeem invites for existent users (#15866)
This adds logic to increase an `InvitedUser` record, increase
`redemption_count` and create a `:invitee_accepted` to let the inviter
know that the invitee used the invite.

Initial support for this was implemented in commit 9969631.
2022-02-09 17:22:30 +02:00
Bianca Nenciu c38114f0c6
FIX: Sort group owners and members together (#15708)
Sorting group members worked always kept the group owners at the top of
the list. This commit keeps the group owners at the top of the list only
when no order exists.
2022-02-09 11:43:58 +02:00
Bianca Nenciu f704deca17
FIX: Clear drafts only when post is created by real user (#15720)
This commits adds a new advance_draft to PostCreator that controls if
the draft sequence will be advanced or not. If the draft sequence is
advanced then the old drafts will be cleared. This used to happen for
posts created by plugins or through the API and cleared user drafts
by mistake.
2022-02-09 10:37:38 +02:00
Blake Erickson 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
Andrei Prigorshnev 404f882e5c
FEATURE: in result.rb don't use email for username suggestions until enabled in settings (#15586) 2022-02-07 16:02:26 +04:00
Martin Brennan 0a738bd5bc
FEATURE: Allow sending group SMTP emails with from alias (#15687)
This commit allows group SMTP emails to be sent with a
different from email address that has been set up as an
alias in the email provider. Emails from the alias will
be grouped correctly using Message-IDs in the mail client,
and replies to the alias go into the correct group inbox.
2022-02-07 13:52:01 +10:00
Alan Guo Xiang Tan 454d3740b4
DEV: Remove deprecated site settings. (#15725) 2022-02-07 11:26:06 +08:00
Alan Guo Xiang Tan 5bd55acf83
FIX: Add DB constraints for post & topic counter cache for `UserStat` (#15626)
Ensures that `UserStat#post_count` and `UserStat#topic_count` does not
go below 0. When it does like it did now, we tend to have bugs in our
code since we're usually coding with the assumption that the count isn't
negative.

In order to support the constraints, our post and topic fabricators in
tests will now automatically increment the count for the respective
user's `UserStat` as well. We have to do this because our fabricators
bypasss `PostCreator` which holds the responsibility of updating `UserStat#post_count` and
`UserStat#topic_count`.
2022-02-07 11:23:34 +08:00
Alan Guo Xiang Tan 65f46ad4ed FIX: Better param guards for `wiki` and `post_type` posts controller. 2022-02-07 09:21:24 +08:00
janzenisaac cffc2836cb
DEV: Don't allow users to immediately reinvite (#15722)
- Limit bulk re-invite to 1 time per day
- Move bulk invite by csv behind a site setting (hidden by default)
- Bump invite expiry from 30 -> 90 days

## Updates to rate_limiter
When limiting reinvites I found that **staff** are never limited in any way. So I updated the **rate_limiter** model to allow for a few things:
- add an optional param of `staff_limit`, which (when included and passed values, and the user passes `.staff?`) will override the default `max` & `secs` values and apply them to the user.
- in the case you **do** pass values to `staff_limit` but the user **does not** pass `staff?` the standard `max` & `secs` values will be applied to the user.

This should give us enough flexibility to 
1. continue to apply a strict rate limit to a standard user
2. but also apply a secondary (less strict) limit to staff
2022-02-03 13:07:40 -06:00
Krzysztof Kotlarek bb01563682
FIX: post mover validation color and message (#15688)
When the record is not saved, we should display a proper message.
One potential reason can be plugins for example discourse-calendar is specifying that only first post can contain event
2022-02-02 16:22:52 +11:00
Rafael dos Santos Silva 2e2fee9da3
FIX: Remove svg icons from webmanifest shortcuts (#15765)
* FIX: Remove svg icons from webmanifest shortcuts

While SVGs are valid in the webmanifest, Chromium has not implemented
support for it in this specific manifest member.

Revert when https://bugs.chromium.org/p/chromium/issues/detail?id=1091612
lands.

* fix test
2022-02-01 15:26:58 -03:00
Martin Brennan 0b8d0a14d7
DEV: Add markdown_additional_options to Site (#15738)
Sometimes plugins need to have additional data or options available
when rendering custom markdown features/rules that are not available
on the default opts.discourse object. These additional options should
be namespaced to the plugin adding them.

```
Site.markdown_additional_options["chat"] = { limited_pretty_text_markdown_rules: [] }
```

These are passed down to markdown rules on opts.discourse.additionalOptions.

The main motivation for adding this is the chat plugin, which currently stores
chat_pretty_text_features and chat_pretty_text_markdown_rules on
the Site object via additions to the serializer, and the Site object is
not accessible to import via markdown rules (either through
Site.current() or through container.lookup). So, to have this working
for both front + backend code, we need to attach these additional options
from the Site object onto the markdown options object.
2022-01-28 13:02:02 +10:00
Dan Ungureanu f5b94f152f
FIX: Allow staff to reset passwords by username (#15709)
When staff visits the user profile of another user, the `email` field
in the model is empty. In this case, staff cannot send the reset email
password because nothing is passed in the `login` field.

This commit changes the behavior for staff users to allow resetting
password by username instead.
2022-01-26 10:39:58 +02:00
David Taylor 820564826e
FIX: Ensure that login does not fail for users with invite records (#15647)
In the unlikely, but possible, scenario where a user has no email_tokens, and has an invite record for their email address, login would fail. This commit fixes the `Invite` `user_doesnt_already_exist` validation so that it only applies to new invites, or when changing the email address.

This regressed in d8fe0f4199 (based on `git bisect`)
2022-01-20 10:54:38 +00:00
Dan Ungureanu 5b7bddf966
FIX: Prefer email when resetting password (#15650)
The UI used to request a password reset by username when the user was
logged in. This did not work when hide_email_already_taken site setting
was enabled, which disables the lookup-by-username functionality.

This commit also introduces a check to ensure that the parameter is an
email when hide_email_already_taken is enabled as the single allowed
type is email (no usernames are allowed).
2022-01-20 10:04:45 +02:00
Blake Erickson 12f041de5d
FIX: Tag watching for everyone tag groups (#15622)
* FIX: Tag watching for everyone tag groups

Tags in tag groups that have permissions set to everyone were not able
to be saved correctly. A user on their preferences page would mark the
tags that they wanted to save, but the watched_tags in the response
would be empty. This did not apply to admins, just regular users. Even
though the watched tags were being saved in the db, the user serializer
response was filtering them out. When a user refreshed their preferences
pages it would show zero watched tags.

This appears to be a regression introduced by:

0f598ca51e

The issue that needed to be fixed is that we don't track the "everyone"
group (which has an id of 0) in the group_users table. This is because
everyone has access to it, so why fill a row for every single user, that
would be a lot. The fix was to update the query to include tag groups
that had permissions set to the "everyone" group (group_id 0).

I also added another check to the existing spec for updating
watched tags for tags that aren't in a tag group so that it checks the
response body. I then added a new spec which updates watched tags for
tags in a tag group which has permissions set to everyone.

* Resolve failing tests

Improve SQL query syntax for including the "everyone" group with the id
of 0.

This commit also fixes a few failing tests that were introduced. It
turns out that the Fabrication of the Tag Group Permissions was faulty.
What happens when creating the tag groups without any permissions is
that it sets the permission to "everyone". If we then follow up with
fabricating a tag group permission on the tag group instead of having a
single permission it will have 2 (everyone + the group specified)! We
don't want this. To fix it I removed the fabrication of tag group
permissions and just set the permissions directly when creating the tag
group.

* Use response.parsed_body instead of JSON.parse
2022-01-18 15:02:29 -07:00
Mark VanLandingham fcc80137ce
DEV: Add chat_group_mention notification type (#15616) 2022-01-18 08:26:27 -06:00
Rafael dos Santos Silva 3f91c8835b
FEATURE: Export topics to markdown (#15615)
* FEATURE: Export topics to markdown

The route `/raw/TOPIC_ID` will now export whole topics (paginated to 100
posts) in a markdown format.

See https://meta.discourse.org/t/-/152185/12
2022-01-17 18:05:14 -03:00
Martin Brennan 5d0c2cba07
DEV: Fix typo for email encoded (#15577) 2022-01-14 09:33:15 +10:00
Robin Ward 6272edd121 DEV: Support for running theme test with Ember CLI (third attempt)
The second attempt fixed issues with smoke test.

This one makes sure minification only happens in production mode.
2022-01-13 16:02:07 -05:00
Martin Brennan 107239a442
Revert "DEV: Support for running theme test with Ember CLI (second attempt)" (#15559)
This reverts commit 2c7906999a.

The changes break some things in local development (putting JS files
into minified files, not allowing debugger, and others)
2022-01-13 10:05:35 +10:00
Robin Ward 2c7906999a DEV: Support for running theme test with Ember CLI (second attempt)
This PR includes support for running theme tests in legacy ember
production envrionments.
2022-01-12 15:43:29 -05:00
Dan Ungureanu 584c6a2e8b
SECURITY: Do not sign in unapproved users (#15552) 2022-01-12 22:24:54 +02:00
David Taylor 252bb87ab3
Revert "DEV: Support for running theme test with Ember CLI" (#15547)
This reverts commit ea84a82f77.

This is causing problems with `/theme-qunit` on legacy, non-ember-cli production sites. Reverting while we work on a fix
2022-01-11 23:38:59 +00:00
Robin Ward ea84a82f77 DEV: Support for running theme test with Ember CLI
This is quite complex as it means that in production we have to build
Ember CLI test files and allow them to be used by our Rails application.

There is a fair bit of glue we can remove in the future once we move to
Ember CLI completely.
2022-01-11 15:42:13 -05:00
Bianca Nenciu 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
Bianca Nenciu 5a8b8f6f1e
FEATURE: Show warning if user won't be mentioned (#15339)
The new warnings cover more cases and more accurate. Most of the
warnings will be visible only to staff members because otherwise they
would leak information about user's preferences.
2022-01-11 09:16:20 +02:00
Jarek Radosz 0d9ab0beb3
DEV: Fix a flaky spec (#15529)
It's very much possible for there to be a topic with id 999.
2022-01-11 01:51:57 +01:00
Jarek Radosz 5a50f18c0c
DEV: Avoid `$` globals (#15453)
Also:
* Remove an unused method (#fill_email)
* Replace a method that was used just once (#generate_username) with `SecureRandom.alphanumeric`
* Remove an obsolete dev puma `tmp/restart` file logic
2022-01-08 23:39:46 +01:00
Blake Erickson a850568a52
DEV: Document delete post API endpoint (#15495)
Adding a spec for documenting the delete post API endpoint for our api
docs. As part of this added detailed info for the `force_destroy`
parameter for permanently deleting a post.
2022-01-07 16:09:32 -07:00
Andrei Prigorshnev 16d9b2755c
DEV: rename single_sign_on classes to discourse_connect (#15332) 2022-01-06 16:28:46 +04:00
Peter Zhu ab33d44bf6 DEV: Fix tests broken in 3.0 due to separation of keyword arguments
Tests fail in Ruby 3.0 and later due to separation of positional and
keyword arguments. RSpec treats the hash at the end of include_examples
as keyword arguments when it should be passed as a positional argument.
2022-01-05 13:37:52 -05:00
Peter Zhu c5fd8c42db
DEV: Fix methods removed in Ruby 3.2 (#15459)
* File.exists? is deprecated and removed in Ruby 3.2 in favor of
File.exist?
* Dir.exists? is deprecated and removed in Ruby 3.2 in favor of
Dir.exist?
2022-01-05 18:45:08 +01:00
Bianca Nenciu 5e2e178fcf FIX: Hide user's bio if profile is restricted
The bio was sometimes visible in the meta tags even though it it should
not have been.
2022-01-05 10:23:36 +08:00
Daniel Waterworth 4a0f73a337
PERF: Turn common test prefixes into contexts in topics_controller_spec (#15439) 2022-01-03 11:00:03 -06:00
Daniel Waterworth 9e18868c31
DEV: Re-organize TopicsController#reset_new tests (#15399) 2021-12-23 12:29:51 -06:00
David Taylor cdf4d7156e
DEV: Introduce Auth::Result API for overrides_* (#15378)
This allows authenticators to instruct the Auth::Result to override attributes without using the general site settings. This provides an easy migration path for auth plugins which offer their own "overrides email", "overrides username" or "overrides name" settings. With this new api, they can set `overrides_*` on the result object, and the attribute will be overriden regardless of the general site setting.

ManagedAuthenticator is updated to use this new API. Plugins which consume ManagedAuthenticator will instantly take advantage of this change.
2021-12-23 10:53:17 +00:00
Martin Brennan 19089f21d2
DEV: Add API docs for uploads and API doc watcher (#15387)
This commit adds API documentation for the new upload
endpoints related to direct + multipart external uploads.

Also included is a rake task which watches the files in
the spec/requests/api directory and calls a script file
(spec/regenerate_swagger_docs) whenever one changes. This
script runs rake rswag:specs:swaggerize and then copies
the openapi.yml file over to the discourse_api_docs repo
directory, and hits a script there to convert the YML to
JSON so the API docs are refreshed while the server is
still running. This makes the loop of making a doc change
and seeing it in the local server much faster.

The rake task is rake autospec:swagger
2021-12-23 08:40:15 +10:00
Daniel Waterworth 5ff0b86b57
PERF: Make tests faster by prefabricating more things (#15392) 2021-12-22 11:09:43 -06:00
Jarek Radosz 72ad5bf8bd
FIX: SiteSetting.title was being polluted in StaticController (#15385)
Regressed in #15324
2021-12-21 20:51:18 +01:00
Daniel Waterworth 80591724cf
DEV: Avoid shadowing variables in topics_controller_spec (#15383) 2021-12-21 12:28:12 -06:00
Jarek Radosz c209be09f1
DEV: Fix a flaky test (#15374)
See: https://github.com/discourse/discourse/runs/4589134998?check_suite_focus=true
2021-12-21 02:21:47 +01:00
Daniel Waterworth 7e0c1fb039
PERF: Make tests faster by prefabricating more things (#15370) 2021-12-20 12:59:10 -06:00
Sam b6c3e9aa03
FEATURE: hide_email_address_taken forces use of email in forgot password form (#15362)
* FEATURE: hide_email_address_taken forces use of email in forgot password form

This strengthens this site setting which is meant to be used to harden sites
that are experiencing abuse on forgot password routes.

Previously we would only deny letting people know if forgot password worked on not
New change also bans usage of username for forgot password when enabled
2021-12-20 12:54:10 +11:00
Gerhard Schlager 769388b8ba FIX: Translation overrides from fallback locale didn't work on client
Discourse sent only translation overrides for the current language to the client instead of sending overrides from fallback locales as well. This especially impacted en_GB -> en since most overrides would be done in English instead of English (UK).

This also adds lots of tests for previously untested code.

There's a small caveat: The client currently doesn't handle fallback locales for MessageFormat strings. That is why overrides for those strings always have a higher priority than regular translations. So, as an example, the lookup order for MessageFormat strings in German is:
1. override for de
2. override for en
3. value from de
4. value from en
2021-12-17 14:03:35 +01:00
Gerhard Schlager 4cd5158974 FIX: "Customize Text" showed compiled MessageFormat string for overridden `_MF` translations 2021-12-17 14:03:35 +01:00
Daniel Waterworth ca0eb8041d
PERF: Prefabricate more parts of users_controller_spec (#15335) 2021-12-16 13:36:49 -06:00
Andrei Prigorshnev 9365c4b364
DEV: make sure we handle staged users correctly in DiscourseConnect (#15320)
Some time ago, we made this fix to external authentication –  https://github.com/discourse/discourse/pull/13706. We didn't address Discourse Connect (https://meta.discourse.org/t/discourseconnect-official-single-sign-on-for-discourse-sso/13045) at that moment, so I wanted to fix it for Discourse Connect as well.

Turned out though that Discourse Connect doesn't contain this problem and already handles staged users correctly. This PR adds tests that confirm it. Also, I've extracted two functions in Discourse Connect implementation along the way and decided to merge this refactoring too (the refactoring is supported with tests).
2021-12-16 19:44:07 +04:00
Jarek Radosz c46b351888
DEV: Make i18n spec ignore these test-only settings (#15329)
Fixes flakyness introduced in #15324
2021-12-16 15:49:20 +01:00
Jarek Radosz 2a4df93b8e
FEATURE: Allow to modify topic-backed static pages (#15324)
A plugin API that allows customizing existing topic-backed static pages, like:
faq, tos, privacy (see: StaticController) The block passed to this
method has to return a SiteSetting name that contains a topic id.

```
add_topic_static_page("faq") do |controller|
  current_user&.locale == "pl" ? "polish_faq_topic_id" : "faq_topic_id"
end
```

You can also add new pages in a plugin, but remember to add a route,
for example:

```
get "contact" => "static#show", id: "contact"
```
2021-12-16 04:24:11 +01:00
Daniel Waterworth 102fa71ef3
PERF: Speed up the tests by pre-fabricating more things (#15318) 2021-12-15 11:41:14 -06:00
Daniel Waterworth 61e449379c
PERF: Prefabricate posters in topics_controller_spec (#15297)
It would be clearer to prefabricate posts, but that changes redis and
enabling snapshotting for all the tests in topics_controller_spec is
expensive.
2021-12-14 12:09:07 -06:00
Mark VanLandingham 175ced5096
DEV: Add chat invitation notification type (#15288) 2021-12-14 09:01:53 -06:00
Daniel Waterworth 9334abe249
PERF: Prefabricate more of topics_controller_spec.rb (#15281) 2021-12-13 13:44:55 -06:00
Dan Ungureanu 3d4aee1487
DEV: Drop unused column email_tokens.token (#15203) 2021-12-13 16:29:47 +11:00
Daniel Waterworth 02245ce41f
PERF: Redis snapshotting during tests (#15260)
We can fake redis transactions so that `fab!` works for redis and PG
data, but it's too slow to be used indiscriminately. Instead, you can
opt into it with the `use_redis_snapshotting` helper.

Insofar as snapshotting allows us to `fab!` more things, it provides a
speedup.
2021-12-10 14:25:26 -06:00
Angus McLeod 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
Andrei Prigorshnev 4e8983036a
DEV: do not return no_result_help from the server (#15220)
We don't need it anymore. Actually, I removed using of it on the client side a long time ago, when I was working on improving blank page syndrome on user activity pages (see https://github.com/discourse/discourse/pull/14311).

This PR also removes some old resource strings that we don't use anymore. We have new strings for blank pages.
2021-12-08 21:46:54 +04:00
Dan Ungureanu d8fe0f4199
FEATURE: Restrict link invites to email domain (#15211)
Allow multiple emails to redeem a link invite only if the email domain
name matches the one specified in the link invite.
2021-12-08 17:06:57 +02:00
Andrei Prigorshnev 77cca39c2d
DEV: dry up omni_auth_callback_controller_spec (#15213) 2021-12-07 23:06:44 +04:00
Daniel Waterworth 8371c96b7e
PERF: Speed up tests (#15214) 2021-12-07 12:45:58 -06:00
Alan Guo Xiang Tan 44588255fc FEATURE: Introduce API scopes for badges. 2021-12-07 10:17:17 +08:00
Andrei Prigorshnev f3508065a3
FIX: auth incorrectly handles duplicate usernames (#15197) 2021-12-06 20:49:04 +04:00
Andrei Prigorshnev 10cc082560
FIX: when using external auth disallowed characters weren't removed from username (#15185) 2021-12-06 15:06:35 +04:00
Jarek Radosz 28bf9599f5
FEATURE: Pre-setting user locale via bulk invite (#15195) 2021-12-06 02:08:21 +01:00
Daniel Waterworth 63112f89a3
PERF: Shave off some test-suite time (#15183) 2021-12-03 14:54:07 -06:00
Blake Erickson 643f82d8d6
DEV: Update email responses in api docs (#15178)
Documenting the `/u/:username:/emails.json` endpoint.

Also removing some email fields from user api responses because they
aren't actually included in the response unless you are querying
yourself.
2021-12-03 08:03:58 -07:00
David Taylor cfb6199a95
FIX: Don't redirect XHR/JSON requests when login is required (#15093)
When redirecting to login, we store a destination_url cookie, which the user is then redirected to after login. We never want the user to be redirected to a JSON URL. Instead, we should return a 403 in these situations.

This should also be much less confusing for API consumers - a 403 is a better representation than a 302.
2021-12-02 15:12:25 +00:00
Osama Sayegh 1d69261bc0
FIX: Set `auto_update` to false for non-git themes/components (#15157)
Related to: 20f736aa11.

`auto_update` is true by default at the database level, but it doesn't make sense for `auto_update` to be true on themes that are not imported from a Git repository.
2021-12-01 19:58:13 +03:00
David Taylor 1fa7a87f86
SECURITY: Remove ember-cli specific response from application routes (#15155)
Under some conditions, these varied responses could lead to cache poisoning, hence the 'security' label.

Previously the Rails application would serve JSON data in place of HTML whenever Ember CLI requested an `application.html.erb`-rendered page. This commit removes that logic, and instead parses the HTML out of the standard response. This means that Rails doesn't need to customize its response for Ember CLI.
2021-12-01 16:10:40 +00:00
Andrei Prigorshnev 88f9bb3dc9
FIX: do not suggest "user1" as a username to invited users (#15031)
Recently, the wrong new behavior appeared – we started to suggest to invited users usernames like "user1".

To reproduce:
1. Create an invitation with default settings, do not restrict it to email
2. Copy an invitation link and follow it in incognito mode
See username already filled, with eg “user1”. See screenshot. Should be empty.

This bug was very likely introduced by my recent changes to UserNameSuggester.
2021-11-30 16:59:37 +04:00
Osama Sayegh 7bd3986b21
FEATURE: Replace `Crawl-delay` directive with proper rate limiting (#15131)
We have a couple of site setting, `slow_down_crawler_user_agents` and `slow_down_crawler_rate`, that are meant to allow site owners to signal to specific crawlers that they're crawling the site too aggressively and that they should slow down.

When a crawler is added to the `slow_down_crawler_user_agents` setting, Discourse currently adds a `Crawl-delay` directive for that crawler in `/robots.txt`. Unfortunately, many crawlers don't support the `Crawl-delay` directive in `/robots.txt` which leaves the site owners no options if a crawler is crawling the site too aggressively.

This PR replaces the `Crawl-delay` directive with proper rate limiting for crawlers added to the `slow_down_crawler_user_agents` list. On every request made by a non-logged in user, Discourse will check the User Agent string and if it contains one of the values of the `slow_down_crawler_user_agents` list, Discourse will only allow 1 request every N seconds for that User Agent (N is the value of the `slow_down_crawler_rate` setting) and the rest of requests made within the same interval will get a 429 response. 

The `slow_down_crawler_user_agents` setting becomes quite dangerous with this PR since it could rate limit lots if not all of anonymous traffic if the setting is not used appropriately. So to protect against this scenario, we've added a couple of new validations to the setting when it's changed:

1) each value added to setting must 3 characters or longer
2) each value cannot be a substring of tokens found in popular browser User Agent. The current list of prohibited values is: apple, windows, linux, ubuntu, gecko, firefox, chrome, safari, applewebkit, webkit, mozilla, macintosh, khtml, intel, osx, os x, iphone, ipad and mac.
2021-11-30 12:55:25 +03:00
Loïc Guitaut a5fbb90df4 FEATURE: Display pending posts on user’s page
Currently when a user creates posts that are moderated (for whatever
reason), a popup is displayed saying the post needs approval and the
total number of the user’s pending posts. But then this piece of
information is kind of lost and there is nowhere for the user to know
what are their pending posts or how many there are.

This patch solves this issue by adding a new “Pending” section to the
user’s activity page when there are some pending posts to display. When
there are none, then the “Pending” section isn’t displayed at all.
2021-11-29 10:26:33 +01:00
Penar Musaraj d99deaf1ab
FEATURE: show recent searches in quick search panel (#15024) 2021-11-25 15:44:15 -05:00
Rafael dos Santos Silva 5647819de4
FEATURE: Send a 'noindex' header in non-canonical responses (#15026)
* FEATURE: Optionally send a 'noindex' header in non-canonical responses

This will be used in a SEO experiment.

Co-authored-by: David Taylor <david@taylorhq.com>
2021-11-25 16:58:39 -03:00
Dan Ungureanu fa8cd629f1
DEV: Hash tokens stored from email_tokens (#14493)
This commit adds token_hash and scopes columns to email_tokens table.
token_hash is a replacement for the token column to avoid storing email
tokens in plaintext as it can pose a security risk. The new scope column
ensures that email tokens cannot be used to perform a different action
than the one intended.

To sum up, this commit:

* Adds token_hash and scope to email_tokens

* Reuses code that schedules critical_user_email

* Refactors EmailToken.confirm and EmailToken.atomic_confirm methods

* Periodically cleans old, unconfirmed or expired email tokens
2021-11-25 09:34:39 +02:00
RogerBW fd66df5997
FEATURE: adds uploads scope for API keys (#14941)
* FEATURE: adds uploads scope for API keys

* Add basic test, change "image" to "file"
2021-11-22 10:49:08 -07:00
Penar Musaraj 20f5474be9
FEATURE: Log only topic/post search queries in search log (#14994) 2021-11-18 09:21:12 +08:00
Martin Brennan b96c10a903
DEV: Extract shared external upload routes into controller helper (#14984)
This commit refactors the direct external upload routes (get presigned
put, complete external, create/abort/complete multipart) into a
helper which is then included in both BackupController and the
UploadController. This is done so UploadController doesn't need
strange backup logic added to it, and so each controller implementing
this helper can do their own validation/error handling nicely.

This is a follow up to e4350bb966
2021-11-18 09:17:23 +10:00
Osama Sayegh b86127ad12
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706)
Currently, Discourse rate limits all incoming requests by the IP address they
originate from regardless of the user making the request. This can be
frustrating if there are multiple users using Discourse simultaneously while
sharing the same IP address (e.g. employees in an office).

This commit implements a new feature to make Discourse apply rate limits by
user id rather than IP address for users at or higher than the configured trust
level (1 is the default).

For example, let's say a Discourse instance is configured to allow 200 requests
per minute per IP address, and we have 10 users at trust level 4 using
Discourse simultaneously from the same IP address. Before this feature, the 10
users could only make a total of 200 requests per minute before they got rate
limited. But with the new feature, each user is allowed to make 200 requests
per minute because the rate limits are applied on user id rather than the IP
address.

The minimum trust level for applying user-id-based rate limits can be
configured by the `skip_per_ip_rate_limit_trust_level` global setting. The
default is 1, but it can be changed by either adding the
`DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the
desired value to your `app.yml`, or changing the setting's value in the
`discourse.conf` file.

Requests made with API keys are still rate limited by IP address and the
relevant global settings that control API keys rate limits.

Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters
string that Discourse used to lookup the current user from the database and the
cookie contained no additional information about the user. However, we had to
change the cookie content in this commit so we could identify the user from the
cookie without making a database query before the rate limits logic and avoid
introducing a bottleneck on busy sites.

Besides the 32 characters auth token, the cookie now includes the user id,
trust level and the cookie's generation date, and we encrypt/sign the cookie to
prevent tampering.

Internal ticket number: t54739.
2021-11-17 23:27:30 +03:00
Martin Brennan e7a4742490
FIX: Clean up emoji name which is file name (#14980)
Uppy adds the file name as the "name" parameter in the
payload by default, which means that for things like the
emoji uploader which have a name param used by the controller,
that param will be passed as the file name. We already use
the existing file name if the name param is null, so this
commit just does further cleanup of the name param, removing
the extension if it is a filename so we don't end up with
emoji names like blah_png.
2021-11-17 09:20:44 +10:00
Akshay Birajdar 6b5e8be25a Support parsing array in #param_to_integer_list
Co-authored-by: Akshay Birajdar <akshay.birajdar@coupa.com>
2021-11-16 10:27:00 -05:00
Martin Brennan 08e625c446
FIX: Use previous chunk to check if local backup chunk upload complete (#14896)
Uppy and Resumable slice up their chunks differently, which causes a difference
in this algorithm. Let's take a 131.6MB file (137951695 bytes) with a 5MB (5242880 bytes)
chunk size. For resumable, there are 26 chunks, and uppy there are 27. This is
controlled by forceChunkSize in resumable which is false by default. The final
chunk size is 6879695 (chunk size + remainder) whereas in uppy it is 1636815 (just remainder).

This means that the current condition of uploaded_file_size + current_chunk_size >= total_size
is hit twice by uppy, because it uses a more correct number of chunks. This
can be solved for both uppy and resumable by checking the _previous_ chunk
number * chunk_size as the uploaded_file_size.

An example of what is happening before that change, using the current
chunk number to calculate uploaded_file_size.

chunk 26: resumable: uploaded_file_size (26 * 5242880) + current_chunk_size (6879695) = 143194575 >= total_size (137951695) ? YES
chunk 26: uppy: uploaded_file_size (26 * 5242880) + current_chunk_size (5242880) = 141557760 >= total_size (137951695) ? YES
chunk 27: uppy: uploaded_file_size (27 * 5242880) + current_chunk_size (1636815) = 143194575 >= total_size (137951695) ? YES

An example of what this looks like after the change, using the previous
chunk number to calculate uploaded_file_size:

chunk 26: resumable: uploaded_file_size (25 * 5242880) + current_chunk_size (6879695) = 137951695 >= total_size (137951695) ? YES
chunk 26: uppy: uploaded_file_size (25 * 5242880) + current_chunk_size (5242880) = 136314880 >= total_size (137951695) ? NO
chunk 27: uppy: uploaded_file_size (26 * 5242880) + current_chunk_size (1636815) = 137951695 >= total_size (137951695) ? YES
2021-11-15 15:08:21 +10:00
Jarek Radosz 043e0dcad7
DEV: Don't try to load admin locales in tests (#14917)
It always fails with:

```
Failed to load resource: the server responded with a status of 403 (Forbidden), url: http://localhost:60099/extra-locales/admin?v=[…]
```
2021-11-13 15:31:55 +01:00
Roman Rizzi a3814b1e56
FIX: Display top posts from private categories if the user has access. (#14878)
Users viewing the top topics from the categories page should see those belonging to a private category if they have access to it.
2021-11-11 13:35:03 -03:00
Martin Brennan e4350bb966
FEATURE: Direct S3 multipart uploads for backups (#14736)
This PR introduces a new `enable_experimental_backup_uploads` site setting (default false and hidden), which when enabled alongside `enable_direct_s3_uploads` will allow for direct S3 multipart uploads of backup .tar.gz files.

To make multipart external uploads work with both the S3BackupStore and the S3Store, I've had to move several methods out of S3Store and into S3Helper, including:

* presigned_url
* create_multipart
* abort_multipart
* complete_multipart
* presign_multipart_part
* list_multipart_parts

Then, S3Store and S3BackupStore either delegate directly to S3Helper or have their own special methods to call S3Helper for these methods. FileStore.temporary_upload_path has also removed its dependence on upload_path, and can now be used interchangeably between the stores. A similar change was made in the frontend as well, moving the multipart related JS code out of ComposerUppyUpload and into a mixin of its own, so it can also be used by UppyUploadMixin.

Some changes to ExternalUploadManager had to be made here as well. The backup direct uploads do not need an Upload record made for them in the database, so they can be moved to their final S3 resting place when completing the multipart upload.

This changeset is not perfect; it introduces some special cases in UploadController to handle backups that was previously in BackupController, because UploadController is where the multipart routes are located. A subsequent pull request will pull these routes into a module or some other sharing pattern, along with hooks, so the backup controller and the upload controller (and any future controllers that may need them) can include these routes in a nicer way.
2021-11-11 08:25:31 +10:00
Bianca Nenciu 3791fbd919
FEATURE: Add read-only scope to API keys (#14856)
This commit adds a global read-only scope that can be used to create
new API keys.
2021-11-10 17:48:00 +02:00
Martin Brennan 6a68bd4825
DEV: Limit list multipart parts to 1 (#14853)
We are only using list_multipart_parts right now in the
uploads controller for multipart uploads to check if the
upload exists; thus we don't need up to 1000 parts.

Also adding a note for future explorers that list_multipart_parts
only gets 1000 parts max, and adding params for max parts
and starting parts.
2021-11-10 08:01:28 +10:00
David Taylor 65a389c3ac
FIX: Allow bulk invites to be used with DiscourseConnect (#14862)
Support for invites alongside DiscourseConnect was added in 355d51af. This commit fixes the guardian method so that the bulk invite button functionality also works.
2021-11-09 17:43:23 +00:00
Bianca Nenciu b203e316ac
FEATURE: Add pagination to API keys page (#14777) 2021-11-09 12:18:23 +02:00
Blake Erickson 892e33fd93
Add `embed_url` to the api docs (#14813)
When creating a topic via the api you can pass in the `embed_url` param,
so adding this to the api docs.

See: https://github.com/discourse/discourse_api_docs/pull/26
2021-11-03 19:22:55 -06:00
Jean 8d73730c44
FEATURE: Add setting to disable notifications for topic tags edits (#14794) 2021-11-02 13:53:21 -04:00
jbrw cfc62dbace
FIX: allowed_theme_ids should not be persisted in GlobalSettings (#14756)
* FIX: allowed_theme_ids should not be persisted in GlobalSettings

It was observed that the memoized value of `GlobalSetting.allowed_theme_ids` would be persisted across requests, which could lead to unpredictable/undesired behaviours in a multisite environment.

This change moves that logic out of GlobalSettings so that the returned theme IDs are correct for the current site.

Uses get_set_cache, which ultimately uses DistributedCache, which will take care of multisite issues for us.
2021-10-29 11:46:52 -04:00
Jean 92f4cdd330
FEATURE: bypass topic bump when disable_category_edit_notifications is enabled (#14754) 2021-10-27 17:05:10 -04:00
David Taylor 9ac6f1d3bb
FIX: Include the Vary:Accept header on all Accept-based responses (#14647)
By default, Rails only includes the Vary:Accept header in responses when the Accept: header is included in the request. This means that proxies/browsers may cache a response to a request with a missing Accept header, and then later serve that cached version for a request which **does** supply the Accept header. This can lead to some very unexpected behavior in browsers.

This commit adds the Vary:Accept header for all requests, even if the Accept header is not present in the request. If a format parameter (e.g. `.json` suffix) is included in the path, then the Accept header is still omitted. (The format parameter takes precedence over any Accept: header, so the response is no longer varies based on the Accept header)
2021-10-25 12:53:50 +01:00
David Taylor aac3547cc2
DEV: Update AWS API stub following gem version bump (#14673)
The latest version of the gem doesn't send whitespace in this request body, so we need to update the test stub accordingly
2021-10-20 23:04:08 +01:00
David Taylor 567c470361
FIX: Allow staff to view pending/expired invites of other users (#14602)
`/u/username/invited.json?filter=expired` and `/u/username/invited.json?filter=pending` APIs are already returning data to admins. However, the `can_see_invite_details?` boolean was false, which prevented the Ember frontend from showing the tabs correctly. This commit updates the guardian method to match reality.
2021-10-14 15:57:01 +01:00
Krzysztof Kotlarek 9062fd9b7a
FIX: improvements for download local dates (#14588)
* FIX: do not display add to calendar for past dates

There is no value in saving past dates into calendar

* FIX: remove postId and move ICS to frontend

PostId is not necessary and will make the solution more generic for dates which doesn't belong to a specific post.

Also, ICS file can be generated in JavaScript to avoid calling backend.
2021-10-14 09:22:44 +11:00
Bianca Nenciu c4843fc1c1
FEATURE: Allow admins to permanently delete posts and topics (#14406)
Sometimes administrators want to permanently delete posts and topics
from the database. To make sure that this is done for a good reasons,
administrators can do this only after one minute has passed since the
post was deleted or immediately if another administrator does it.
2021-10-13 12:53:23 +03:00
Alan Guo Xiang Tan d0595127cc
FIX: Missing excerpt for post small actions in topic timeline. (#14547) 2021-10-12 09:20:35 +08:00
David Taylor a55642a30a
DEV: Various behind-the-scenes improvements to PresenceChannel (#14518)
- Allow the `/presence/get` endpoint to return multiple channels in a single request (limited to 50)
- When multiple presence channels are initialized in a single Ember runloop, batch them into a single GET request
- Introduce the `presence-pretender` to allow easy testing of PresenceChannel-related features
- Introduce a `use_cache` boolean (default true) on the the server-side PresenceChannel initializer. Useful during testing.
2021-10-07 15:50:14 +01:00
David Taylor ba380c5f52
DEV: Update invite API docs expires_at default (#14550) 2021-10-07 12:41:04 +01:00
Blake Erickson 2fb9834821
DEV: Fix api docs for default calendar (#14539)
Change the type for default_calendar to a string.

The type specified for the default calendar in the api docs wasn't a
valid type. The linting in the api docs repo reports:

```
`type` can be one of the following only: "object", "array", "string", "number", "integer", "boolean", "null".
```

This linting currently is only in the `discourse_api_docs` repo.
2021-10-06 13:36:11 -06:00
Blake Erickson aaf7ac8936
DEV: Add include_subcategories param to api docs (#14534)
* DEV: Add include_subcategories param to api docs

Adding the `include_subcategories=true` query param to the
`/categories.json` api docs.

Follow up to: fe676f334a

* fix spec
2021-10-06 12:34:03 -06:00
Krzysztof Kotlarek cb5b0cb9d8
FEATURE: save local date to calendar (#14486)
It allows saving local date to calendar.
Modal is giving option to pick between ics and google. User choice can be remembered as a default for the next actions.
2021-10-06 14:11:52 +11:00
Blake Erickson fe676f334a
FEATURE: Return subcategories on categories endpoint (#14492)
* FEATURE: Return subcategories on categories endpoint

When using the API subcategories will now be returned nested inside of
each category response under the `subcategory_list` param. We already
return all the subcategory ids under the `subcategory_ids` param, but
you then would have to make multiple separate API calls to fetch each of
those subcategories. This way you can get **ALL** of the categories
along with their subcategories in a single API response.

The UI will not be affected by this change because you need to pass in
the `include_subcategories=true` param in order for subcategories to be
returned.

In a follow up PR I'll add the API scoping for fetching categories so
that a readonly API key can be used for the `/categories.json` endpoint. This
endpoint should be used instead of the `/site.json` endpoint for
fetching a sites categories and subcategories.

* Update PR based on feedback

- Have spec check for specific subcategory
- Move comparison check out of loop
- Only populate subcategory list if option present
- Remove empty array initialization
- Update api spec to allow null response

* More PR updates based on feedback

- Use a category serializer for the subcategory_list
- Don't include the subcategory_list param if empty
- For the spec check for the subcategory by id
- Fix spec to account for param not present when empty
2021-10-05 12:12:31 -06:00
Yasuo Honda dbbfad7ed0 FIX: Support Ruby 3 keyword arguments 2021-10-05 11:25:00 -04:00
Dan Ungureanu 76a7b75d8a
DEV: Reuse can_invite_to_forum? in can_invite_to? (#14392)
This commit resolves refactors can_invite_to? to use
can_invite_to_forum? for checking the site-wide permissions and then
perform topic specific checkups.

Similarly, can_invite_to? is always used with a topic object and this is
now enforced.

There was another problem before when `must_approve_users` site setting
was not checked when inviting users to forum, but was checked when
inviting to a topic.

Another minor security issue was that group owners could invite to
group topics even if they did not have the minimum trust level to do
it.
2021-09-29 17:40:16 +03:00
Andrei Prigorshnev b609f6c11c
FIX: restrict other user's notification routes (#14442)
It was possible to see notifications of other users using routes:
- notifications/responses
- notifications/likes-received
- notifications/mentions
- notifications/edits

We weren't showing anything private (like notifications about private messages), only things that're publicly available in other places. But anyway, it feels strange that it's possible to look at notifications of someone else. Additionally, there is a risk that we can unintentionally leak something on these pages in the future.

This commit restricts these routes.
2021-09-29 16:24:28 +04:00
Dan Ungureanu 2e085915cc
FIX: `include_` serializer methods must end with ? (#14407)
Otherwise, they are simply dead code and the attribute is visible by
default. These bugs did not expose any sensitive information.
2021-09-22 16:01:25 +03:00
Martin Brennan dba6a5eabf
FEATURE: Humanize file size error messages (#14398)
The file size error messages for max_image_size_kb and
max_attachment_size_kb are shown to the user in the KB
format, regardless of how large the limit is. Since we
are going to support uploading much larger files soon,
this KB-based limit soon becomes unfriendly to the end
user.

For example, if the max attachment size is set to 512000
KB, this is what the user sees:

> Sorry, the file you are trying to upload is too big (maximum
size is 512000KB)

This makes the user do math. In almost all file explorers that
a regular user would be familiar width, the file size is shown
in a format based on the maximum increment (e.g. KB, MB, GB).

This commit changes the behaviour to output a humanized file size
instead of the raw KB. For the above example, it would now say:

> Sorry, the file you are trying to upload is too big (maximum
size is 512 MB)

This humanization also handles decimals, e.g. 1536KB = 1.5 MB
2021-09-22 07:59:45 +10:00
Martin Brennan 0c42a1e5f3
FEATURE: Topic-level bookmarks (#14353)
Allows creating a bookmark with the `for_topic` flag introduced in d1d2298a4c set to true. This happens when clicking on the Bookmark button in the topic footer when no other posts are bookmarked. In a later PR, when clicking on these topic-level bookmarks the user will be taken to the last unread post in the topic, not the OP. Only the OP can have a topic level bookmark, and users can also make a post-level bookmark on the OP of the topic.

I had to do some pretty heavy refactors because most of the bookmark code in the JS topics controller was centred around instances of Post JS models, but the topic level bookmark is not centred around a post. Some refactors were just for readability as well.

Also removes some missed reminderType code from the purge in 41e19adb0d
2021-09-21 08:45:47 +10:00
Blake Erickson 4a4881613b
DEV: Refactor the api docs for the user endpoint (#14377)
Due to the way that rswag expands shared components we were getting this
warning when linting our api docs:

```
Component: "user_response" is never used.
```

This change refactors the `api/users_spec.rb` file so that it uses the
new way of doing things with a separate `user_get_response.json` schema
file rather then the old way of loading a shared response inside of the
swagger_helper.rb file.
2021-09-20 10:04:57 -06:00
Bianca Nenciu c9ad9bff8a
FIX: Update only passed custom fields (#14357)
It used to replace custom fields instead of updating only the custom
fields that were passed. The changes to custom fields will also be
logged.
2021-09-17 13:37:56 +03:00
Blake Erickson 91453dd3fc
DEV: Fix flaky site.json api test (#14351)
The color_scheme_id needs to be an integer not a string.

This is one of the failing tests that showed this error:

 https://github.com/discourse/discourse/runs/3598414971

It showed this error

`POSSIBLE ISSUE W/: /user_themes/0/color_scheme_id`

And this is part of the site.json response:

```
...
"user_themes"=>[{"theme_id"=>149, "name"=>"Cool theme 111", "default"=>false, "color_scheme_id"=>37}]
...
```
2021-09-15 18:03:08 -06:00
Martin Brennan 41e19adb0d
DEV: Ignore reminder_type for bookmarks (#14349)
We don't actually use the reminder_type for bookmarks anywhere;
we are just storing it. It has no bearing on the UI. It used
to be relevant with the at_desktop bookmark reminders (see
fa572d3a7a)

This commit marks the column as readonly, ignores it, and removes
the index, and it will be dropped in a later PR. Some plugins
are relying on reminder_type partially so some stubs have been
left in place to avoid errors.
2021-09-16 09:56:54 +10:00
Martin Brennan 22208836c5
DEV: Ignore bookmarks.topic_id column and remove references to it in code (#14289)
We don't need no stinkin' denormalization! This commit ignores
the topic_id column on bookmarks, to be deleted at a later date.
We don't really need this column and it's better to rely on the
post.topic_id as the canonical topic_id for bookmarks, then we
don't need to remember to update both columns if the bookmarked
post moves to another topic.
2021-09-15 10:16:54 +10:00
Mark VanLandingham 68bb7c5a66
DEV: Support translated title in desktop/notifications (#14325) 2021-09-14 09:57:38 -05:00
Bianca Nenciu 6a7ea66670
FEATURE: Use second factor for admin confirmation (#14293)
Administrators can use second factor to confirm granting admin access
without using email. The old method of confirmation via email is still
used as a fallback when second factor is unavailable.
2021-09-14 15:19:28 +03:00
Dan Ungureanu f517b6997c
FEATURE: Cook drafts excerpt in user activity (#14315)
The previous excerpt was a simple truncated raw message. Starting with
this commit, the raw content of the draft is cooked and an excerpt is
extracted from it. The logic for extracting the excerpt mimics the the
`ExcerptParser` class, but does not implement all functionality, being
a much simpler implementation.

The two draft controllers have been merged into one and the /draft.json
route has been changed to /drafts.json to be consistent with the other
route names.
2021-09-14 15:18:01 +03:00
Bianca Nenciu dde66b9e16
FIX: Update only present fields in request (#14310)
Some category fields were always updated, even if they were not present
in the request. When this happened, these field were erased.
2021-09-14 15:04:54 +03:00
Alan Guo Xiang Tan bc23dcd30b
FIX: Don't publish PM archive events to acting user. (#14291)
When a user archives a personal message, they are redirected back to the
inbox and will refresh the list of the topics for the given filter.
Publishing an event to the user results in an incorrect incoming message
because the list of topics has already been refreshed.

This does mean that if a user has two tabs opened, the non-active tab
will not receive the incoming message but at this point we do not think
the technical trade-offs are worth it to support this feature. We
basically have to somehow exclude a client from an incoming message
which is not easy to do.

Follow-up to fc1fd1b416
2021-09-10 09:20:50 +08:00
Alan Guo Xiang Tan 7b77dd5c05
FIX: Display unread/new PM links only when viewing own user. (#14290)
At this point in time, we do not think supporting unread and new when an
admin is looking at another user's messages is worth supporting.

Follow-up to fc1fd1b416
2021-09-09 14:02:17 +08:00
Alan Guo Xiang Tan ee8c943326
FIX: Remove dismissed new topics from PM topic tracking state. (#14288)
Follow-up to fc1fd1b416
2021-09-09 12:39:27 +08:00
Krzysztof Kotlarek e3793e6d7c
FIX: better filter for groups search (#14262)
Follow up of https://github.com/discourse/discourse/pull/14216

Allow plugins to register custom filter with block
2021-09-08 09:38:45 +10:00
Blake Erickson c6bcf1f06c
DEV: Add site.json to api docs (#14249)
Documenting the site.json api endpoint. This endpoint is often used as a
way to get all of the categories and subcategories in a single api call.
2021-09-07 10:36:05 -06:00
Vinoth Kannan 0c777825b3
FIX: perform `agree_and_keep` action only if possible. (#13967)
While deleting spammers from flag modal it's trying to perform `agree_and_keep` action where it's not possible (or already performed).
2021-09-06 11:41:44 +05:30
Krzysztof Kotlarek f859fd6bde
FEATURE: allow plugins to extend Groups (#14216)
* add_permitted_group_param API for plugins
* add groups-interaction-custom-options outlet
* custom search can use custom group scope
2021-09-06 10:18:51 +10:00
Blake Erickson ee7809e8a8
DEV: Add missing operationIds to the api docs (#14235)
From the openapi spec:

 https://spec.openapis.org/oas/latest.html#fixed-fields-7

each endpoint needs to have an `operationId`:

> Unique string used to identify the operation. The id MUST be unique
> among all operations described in the API. The operationId value is
> case-sensitive. Tools and libraries MAY use the operationId to uniquely
> identify an operation, therefore, it is RECOMMENDED to follow common
> programming naming conventions.

Running the linter on our openapi.json file with this command:

`npx @redocly/openapi-cli lint openapi.json`

produced the following warning on all of our endpoints:

> Operation object should contain `operationId` field

This commit resolves these warnings by adding an operationId field to
each endpoint.
2021-09-03 07:39:29 -06:00
Jean 85c31c73ba
FIX: allow single string values on custom multiple select fields and not just arrays (#14236) 2021-09-03 09:26:57 -04:00
Vinoth Kannan 49b2bb294e
FEATURE: option to update default notification level of existing users. (#14084)
Previously, a group's `default_notification_level` change will only affect the users added after it.

Co-authored-by: Alan Guo Xiang Tan <gxtan1990@gmail.com>
2021-08-31 16:11:26 +05:30
Blake Erickson 70eca1dc4e
DEV: Update api docs for search endpoint (#14181) 2021-08-30 11:25:34 -06:00
Vinoth Kannan 08dce4f477
UX: use existing guardian method to check messageable group. (#14174)
We should display "Message" button only if personal messages are enabled. Currently, it's not respecting that site setting.
2021-08-30 10:38:33 +05:30
Vinoth Kannan 465774cf2c
UX: display correct replies count in embedded comments view. (#14175)
Previosuly, the reply count included the "small_action" posts too. It also caused the broken embed HTML issue.
2021-08-30 10:37:53 +05:30
David Taylor 31db83527b DEV: Introduce PresenceChannel API for core and plugin use
PresenceChannel aims to be a generic system for allow the server, and end-users, to track the number and identity of users performing a specific task on the site. For example, it might be used to track who is currently 'replying' to a specific topic, editing a specific wiki post, etc.

A few key pieces of information about the system:
- PresenceChannels are identified by a name of the format `/prefix/blah`, where `prefix` has been configured by some core/plugin implementation, and `blah` can be any string the implementation wants to use.
- Presence is a boolean thing - each user is either present, or not present. If a user has multiple clients 'present' in a channel, they will be deduplicated so that the user is only counted once
- Developers can configure the existence and configuration of channels 'just in time' using a callback. The result of this is cached for 2 minutes.
- Configuration of a channel can specify permissions in a similar way to MessageBus (public boolean, a list of allowed_user_ids, and a list of allowed_group_ids). A channel can also be placed in 'count_only' mode, where the identity of present users is not revealed to end-users.
- The backend implementation uses redis lua scripts, and is designed to scale well. In the future, hard limits may be introduced on the maximum number of users that can be present in a channel.
- Clients can enter/leave at will. If a client has not marked itself 'present' in the last 60 seconds, they will automatically 'leave' the channel. The JS implementation takes care of this regular check-in.
- On the client-side, PresenceChannel instances can be fetched from the `presence` ember service. Each PresenceChannel can be used entered/left/subscribed/unsubscribed, and the service will automatically deduplicate information before interacting with the server.
- When a client joins a PresenceChannel, the JS implementation will automatically make a GET request for the current channel state. To avoid this, the channel state can be serialized into one of your existing endpoints, and then passed to the `subscribe` method on the channel.
- The PresenceChannel JS object is an ember object. The `users` and `count` property can be used directly in ember templates, and in computed properties.
- It is important to make sure that you `unsubscribe()` and `leave()` any PresenceChannel objects after use

An example implementation may look something like this. On the server:

```ruby
register_presence_channel_prefix("site") do |channel|
  next nil unless channel == "/site/online"
  PresenceChannel::Config.new(public: true)
end
```

And on the client, a component could be implemented like this:

```javascript
import Component from "@ember/component";
import { inject as service } from "@ember/service";

export default Component.extend({
  presence: service(),
  init() {
    this._super(...arguments);
    this.set("presenceChannel", this.presence.getChannel("/site/online"));
  },
  didInsertElement() {
    this.presenceChannel.enter();
    this.presenceChannel.subscribe();
  },
  willDestroyElement() {
    this.presenceChannel.leave();
    this.presenceChannel.unsubscribe();
  },
});
```

With this template:

```handlebars
Online: {{presenceChannel.count}}
<ul>
  {{#each presenceChannel.users as |user|}} 
    <li>{{avatar user imageSize="tiny"}} {{user.username}}</li>
  {{/each}}
</ul>
```
2021-08-27 16:26:06 +01:00
Martin Brennan 99ec8eb6df
FIX: Capture S3 metadata when calling create_multipart (#14161)
The generate_presigned_put endpoint for direct external uploads
(such as the one for the uppy-image-uploader) records allowed
S3 metadata values on the uploaded object. We use this to store
the sha1-checksum generated by the UppyChecksum plugin, for later
comparison in ExternalUploadManager.

However, we were not doing this for the create_multipart endpoint,
so the checksum was never captured and compared correctly.

Also includes a fix to make sure UppyChecksum is the last preprocessor to run.
It is important that the UppyChecksum preprocessor is the last one to
be added; the preprocessors are run in order and since other preprocessors
may modify the file (e.g. the UppyMediaOptimization one), we need to
checksum once we are sure the file data has "settled".
2021-08-27 09:50:23 +10:00
Dan Ungureanu 3406a49e21
FEATURE: Create notification for redeemed invite (#14146)
Users can invite people to topic and they will be automatically
redirected to the topic when logging in after signing up. This commit
ensures a "invited_to_topic" notification is created when the invite is
redeemed.

The same notification is used for the "Notify" sharing method that is
found in share topic modal.
2021-08-26 10:43:56 +03:00
Martin Brennan 1646856974
FIX: Topic reset_new unscoped causing huge queries (#14158)
Since ad3ec5809f when a user chooses
the Dismiss New... option in the New topic list, we send a request
to topics/reset-new.json with ?tracked=false as the only parameter.

This then uses Topic as the scope for topics to dismiss, with no
other limitations. When we do topic_scope.pluck(:id), it gets the
ID of every single topic in the database (that is not deleted) to
pass to TopicsBulkAction, causing a huge query with severe performance
issues.

This commit changes the default scope to use
`TopicQuery.new(current_user).new_results(limit: false)`
which should only use the topics in the user's New list, which
will be a much smaller list, depending on the user's "new_topic_duration_minutes"
setting.
2021-08-26 11:25:20 +10:00
Penar Musaraj 85b8fea262
UX: Add Styling step to wizard (#14132)
Refactors three wizard steps (colors, fonts, homepage style) into one new step called Styling.
2021-08-25 17:10:12 -04:00
Alan Guo Xiang Tan f66007ec83
FEATURE: Display unread and new counts for messages. (#14059)
There are certain design decisions that were made in this commit.

Private messages implements its own version of topic tracking state because there are significant differences between regular and private_message topics. Regular topics have to track categories and tags while private messages do not. It is much easier to design the new topic tracking state if we maintain two different classes, instead of trying to mash this two worlds together.

One MessageBus channel per user and one MessageBus channel per group. This allows each user and each group to have their own channel backlog instead of having one global channel which requires the client to filter away unrelated messages.
2021-08-25 11:17:56 +08:00
Martin Brennan d295a16dab
FEATURE: Uppy direct S3 multipart uploads in composer (#14051)
This pull request introduces the endpoints required, and the JavaScript functionality in the `ComposerUppyUpload` mixin, for direct S3 multipart uploads. There are four new endpoints in the uploads controller:

* `create-multipart.json` - Creates the multipart upload in S3 along with an `ExternalUploadStub` record, storing information about the file in the same way as `generate-presigned-put.json` does for regular direct S3 uploads
* `batch-presign-multipart-parts.json` - Takes a list of part numbers and the unique identifier for an `ExternalUploadStub` record, and generates the presigned URLs for those parts if the multipart upload still exists and if the user has permission to access that upload
* `complete-multipart.json` - Completes the multipart upload in S3. Needs the full list of part numbers and their associated ETags which are returned when the part is uploaded to the presigned URL above. Only works if the user has permission to access the associated `ExternalUploadStub` record and the multipart upload still exists.

  After we confirm the upload is complete in S3, we go through the regular `UploadCreator` flow, the same as `complete-external-upload.json`, and promote the temporary upload S3 into a full `Upload` record, moving it to its final destination.
* `abort-multipart.json` - Aborts the multipart upload on S3 and destroys the `ExternalUploadStub` record if the user has permission to access that upload.

Also added are a few new columns to `ExternalUploadStub`:

* multipart - Whether or not this is a multipart upload
* external_upload_identifier - The "upload ID" for an S3 multipart upload
* filesize - The size of the file when the `create-multipart.json` or `generate-presigned-put.json` is called. This is used for validation.

When the user completes a direct S3 upload, either regular or multipart, we take the `filesize` that was captured when the `ExternalUploadStub` was first created and compare it with the final `Content-Length` size of the file where it is stored in S3. Then, if the two do not match, we throw an error, delete the file on S3, and ban the user from uploading files for N (default 5) minutes. This would only happen if the user uploads a different file than what they first specified, or in the case of multipart uploads uploaded larger chunks than needed. This is done to prevent abuse of S3 storage by bad actors.

Also included in this PR is an update to vendor/uppy.js. This has been built locally from the latest uppy source at d613b849a6. This must be done so that I can get my multipart upload changes into Discourse. When the Uppy team cuts a proper release, we can bump the package.json versions instead.
2021-08-25 08:46:54 +10:00
Bianca Nenciu ff367e22fb
FEATURE: Make allow_uploaded_avatars accept TL (#14091)
This gives admins more control over who can upload custom profile
pictures.
2021-08-24 10:46:28 +03:00
Bianca Nenciu eb6d66fe6f
FIX: Do not allow negative values for LIMIT (#14122)
Negative values generated invalid SQL queries.
2021-08-24 10:45:26 +03:00
Roman Rizzi a50cb61dd5
FIX: Deprecated method should still behave the same. (#14067) 2021-08-19 09:58:26 +08:00
Grayden 64ead3c3a1
FIX: Revoking admin or moderator status doesn't require refresh to delete/anonymize/merge user (#14073)
* FIX: Revoking admin or moderator status doesn't require refresh to delete/anonymize/merge user

On the /admin/users/<id>/<username> page, there are action buttons that are either visible or hidden depending on a few fields from the AdminDetailsSerializer: `can_be_deleted`, `can_be_anonymized`, `can_be_merged`, `can_delete_all_posts`.

These fields are updated when granting/revoking admin or moderator status. However, those updates were not being reflected on the page. E.g. if a user is granted moderation privileges, the 'anonymize user' and 'merge' buttons still appear on the page, which is inconsistent with the backend state of the user. It requires refreshing the page to update the state.

This commit fixes that issue, by syncing the client model state with the server state when handling a successful response from the server. Now, when revoking privileges, the buttons automatically appear without refreshing the page. Similarly, when granting moderator privileges, the buttons automatically disappear without refreshing the page.

* Add detailed user response to spec for changed routes.

Add tests to verify that the revoke_moderation, grant_moderation, and revoke_admin routes return a response formatted according to the AdminDetailedUserSerializer.
2021-08-19 09:57:16 +08:00
Penar Musaraj 08a3aa546b
DEV: Include `login_required` attribute in basic info endpoint (#14064)
This is useful in the DiscourseHub mobile app, currently the app queries
the `about.json` endpoint, which can raise a CORS issue in some cases,
for example when the site only accepts logins from an external provider.
2021-08-17 14:05:51 -04:00
Blake Erickson b35695e411
DEV: Fix some openapi spec issues (#14037)
- Remove duplicate paths
- Remove query param listed in the path
2021-08-13 04:22:15 -06:00
Blake Erickson 65f6d46045
DEV: Fix several type issues with the api docs (#14016)
`nullable` is no longer a valid type, and types also can't be an empty
string, so just bringing a number of issues with types in compliance
with the openapi spec.
2021-08-12 12:25:17 -06:00
Roman Rizzi 630d485f0f
DEV: Remove unused server-side route. (#14011)
We no longer use this route. When a staff member wants to see a user flagged posts, we redirect them to the review queue.
2021-08-11 17:29:19 -03:00
Blake Erickson ce015f5b75
DEV: Fix api docs tagging format (#14010)
When specifying multiple tags they should be separate strings, not a
single string.
2021-08-11 11:00:48 -06:00
David Taylor 7dc8f8b794 FEATURE: Allow linking an existing account during external-auth signup
When a user signs up via an external auth method, a new link is added to the signup modal which allows them to connect an existing Discourse account. This will only happen if:

- There is at least 1 other auth method available

and

- The current auth method permits users to disconnect/reconnect their accounts themselves
2021-08-10 15:07:40 +01:00
David Taylor 46dc189850 DEV: Improve robustness of associate_accounts_controller
This handles a few edge cases which are extremely rare (due to the UI layout), but still technically possible:

- Ensure users are authenticated before attempting association.

- Add a message and logic for when a user already has an association for a given auth provider.
2021-08-10 15:07:40 +01:00
David Taylor 2cae29f644 DEV: Update associate_accounts_controller to use secure_session
This is much cleaner than using redis directly. It also opens the door to more complex association change flows which may happen during login.
2021-08-10 15:07:40 +01:00
Arpit Jalan 3006de39d1
REVERT "FIX: do not show private group flair on user avatars" (#13991)
This reverts commit fe3e18f981 and 0d8fd9ace6
2021-08-10 17:25:11 +05:30
Martin Brennan 6774c600a4
DEV: Fix uploads controller flaky presigned put spec (#13985)
Was missing RateLimiter.clear_all!, leading to 403 errors
2021-08-10 14:30:22 +10:00
Andrei Prigorshnev 09ad3ed41d
FEATURE: revert disallowing putting URLs in titles for TL0 users (#13970)
This reverts a part of changes introduced by https://github.com/discourse/discourse/pull/13947

In that PR I:
1. Disallowed topic feature links for TL-0 users
2. Additionally, disallowed just putting any URL in topic titles for TL-0 users

Actually, we don't need the second part. It introduced unnecessary complexity for no good reason. In fact, it tries to do the job that anti-spam plugins (like Akismet plugin) should be doing.

This PR reverts this second change.
2021-08-06 20:07:42 +04:00
Arpit Jalan 0d8fd9ace6
FIX: do not show flair bg color if flair is not visible (#13969)
follow up to fe3e18f981
2021-08-06 20:53:23 +05:30
Andrei Prigorshnev 0c0a11b66a
FEATURE: Disallow putting urls in the title for TL-0 users (#13947)
This disallows putting URLs in topic titles for TL0 users, which means that:

If a TL-0 user puts a link into the title, a topic featured link won't be generated (as if it was disabled in the site settings)
Server methods for creating and updating topics will be refusing featured links when they are called by TL-0 users
TL-0 users won't be able to put any link into the topic title. For example, the title "Hey, take a look at https://my-site.com" will be rejected.

Also, it improves a bit server behavior when creating or updating feature links on topics in the categories with disabled featured links. Before the server just silently ignored a featured link field that was passed to him, now it will be returning 422 response.
2021-08-05 13:38:39 +04:00
Alan Guo Xiang Tan 3f59ccefd7 FIX: Remove limit on dismissing unread and new messages.
Follow-up to 2c046cc670
2021-08-05 14:55:38 +08:00
Alan Guo Xiang Tan 2c046cc670 FEATURE: Dismiss new and unread for PM inboxes. 2021-08-05 12:56:15 +08:00
jbrw fb14e50741
SECURITY: Destroy `EmailToken` when `EmailChangeRequest` is destroyed (#13950) 2021-08-04 19:14:56 -04:00
Jarek Radosz 07c6b720bc
DEV: Remove `PostProcessed` trigger option (#13916)
It was deprecated 5 years ago in e55e2aff94

I've seen it still being used in the wild, even though it doesn't do anything anymore as I understand it.
2021-08-04 22:24:47 +02:00
Blake Erickson 5c6e7e3401
DEV: Document some of the badge api endpoints (#13919)
Adding some api documentation for the badge routes.
2021-08-03 06:25:12 -06:00
Jean e7b8e75583
FEATURE: Add post edits count to user activity (#13495) 2021-08-02 10:15:53 -04:00
Alan Guo Xiang Tan 016efeadf6
FEATURE: New and Unread messages for user personal messages. (#13603)
* FEATURE: New and Unread messages for user personal messages.

Co-authored-by: awesomerobot <kris.aubuchon@discourse.org>
2021-08-02 12:41:41 +08:00
Arpit Jalan fe3e18f981
FIX: do not show private group flair on user avatars (#13872)
Meta ref: https://meta.discourse.org/t/visible-flair-for-invisible-groups-is-that-on-purpose/167674
2021-08-02 06:21:00 +05:30
Jean ac777440fd
FIX: Validate value of custom dropdown user fields - dropdowns and multiple selects (#13890) 2021-07-30 13:50:47 -04:00
Blake Erickson 1c60be7658
DEV: Document anonymize user api endpoint (#13893)
Adding the anonymize user endpoint to the api docs.

See: https://meta.discourse.org/t/158704/7
2021-07-29 17:40:41 -06:00
Joffrey JAFFEUX 74f0631acd
FIX: allows authentication data to be present in bootstrap (#13885) 2021-07-29 15:01:11 +02:00
Alan Guo Xiang Tan 2b5625bbf0
FIX: Avoid creating a post revision when topic tags have not changed. (#13881)
Co-authored-by: jmperez127 <jmperez127@gmail.com>
2021-07-29 08:14:25 -04:00
Alan Guo Xiang Tan 543a2d70b2 FIX: PM tags route should work for usernames with a period. 2021-07-29 13:54:29 +08:00
Alan Guo Xiang Tan 32951ca2f4 FIX: User can change name when auth_overrides_name is enabled. 2021-07-28 14:40:57 +08:00
Martin Brennan b500949ef6
FEATURE: Initial implementation of direct S3 uploads with uppy and stubs (#13787)
This adds a few different things to allow for direct S3 uploads using uppy. **These changes are still not the default.** There are hidden `enable_experimental_image_uploader` and `enable_direct_s3_uploads`  settings that must be turned on for any of this code to be used, and even if they are turned on only the User Card Background for the user profile actually uses uppy-image-uploader.

A new `ExternalUploadStub` model and database table is introduced in this pull request. This is used to keep track of uploads that are uploaded to a temporary location in S3 with the direct to S3 code, and they are eventually deleted a) when the direct upload is completed and b) after a certain time period of not being used. 

### Starting a direct S3 upload

When an S3 direct upload is initiated with uppy, we first request a presigned PUT URL from the new `generate-presigned-put` endpoint in `UploadsController`. This generates an S3 key in the `temp` folder inside the correct bucket path, along with any metadata from the clientside (e.g. the SHA1 checksum described below). This will also create an `ExternalUploadStub` and store the details of the temp object key and the file being uploaded.

Once the clientside has this URL, uppy will upload the file direct to S3 using the presigned URL. Once the upload is complete we go to the next stage.

### Completing a direct S3 upload

Once the upload to S3 is done we call the new `complete-external-upload` route with the unique identifier of the `ExternalUploadStub` created earlier. Only the user who made the stub can complete the external upload. One of two paths is followed via the `ExternalUploadManager`.

1. If the object in S3 is too large (currently 100mb defined by `ExternalUploadManager::DOWNLOAD_LIMIT`) we do not download and generate the SHA1 for that file. Instead we create the `Upload` record via `UploadCreator` and simply copy it to its final destination on S3 then delete the initial temp file. Several modifications to `UploadCreator` have been made to accommodate this.

2. If the object in S3 is small enough, we download it. When the temporary S3 file is downloaded, we compare the SHA1 checksum generated by the browser with the actual SHA1 checksum of the file generated by ruby. The browser SHA1 checksum is stored on the object in S3 with metadata, and is generated via the `UppyChecksum` plugin. Keep in mind that some browsers will not generate this due to compatibility or other issues.

    We then follow the normal `UploadCreator` path with one exception. To cut down on having to re-upload the file again, if there are no changes (such as resizing etc) to the file in `UploadCreator` we follow the same copy + delete temp path that we do for files that are too large.

3. Finally we return the serialized upload record back to the client

There are several errors that could happen that are handled by `UploadsController` as well.

Also in this PR is some refactoring of `displayErrorForUpload` to handle both uppy and jquery file uploader errors.
2021-07-28 08:42:25 +10:00
Alan Guo Xiang Tan 1780961e70 DEV: Fix flaky topics invite spec due to id collision.
The hardcoded group id eventually became a valid group id leading to 2
groups being attached to the invite.
2021-07-27 13:59:07 +08:00
Vinoth Kannan 5a93893b08
FIX: use correct URL in schema markup for post images. (#13847)
Currently, it wrongly adds Discourse base URL in prefix even for CDN URLs.
2021-07-26 21:39:51 +05:30
Bianca Nenciu 6db93e86d4
FIX: Show Uncategorized when unsubscribing (#13832)
If user tried to unsubscribe from a post from category Uncategorized,
the category name was not displayed. It said only "Stop watching all
topics in".
2021-07-26 12:19:30 +10:00
Blake Erickson 6ac3f1f7b5
DEV: Return 400 instead of 500 for invalid top period (#13828)
* DEV: Return 400 instead of 500 for invalid top period

This change will prevent a fatal 500 error when passing in an invalid
period param value to the `/top` route.

* Check if the method exists first

I couldn't get `ListController.respond_to?` to work, but was still able
to check if the method exists with
`ListController.action_methods.include?`. This way we can avoid relying
on the `NoMethodError` exception which may be raised during the course
of executing the method.

* Just check if the period param value is valid

* Use the new TopTopic.validate_period method
2021-07-23 14:58:10 -06:00
Robin Ward 7b45a5ce55 FIX: Better and more secure validation of periods for TopicQuery
Co-authored-by: Martin Brennan <mjrbrennan@gmail.com>
2021-07-23 14:24:44 -04:00
Andrei Prigorshnev 8bc01c1bb5
DEV: extract leave_group method from the group#remove_member method (#13823)
* Copy remove_member to new `leave` method

* Remove unneeded code from the leave method

* Rearrange the leave method

* Remove unneeded code from the remove_member method

* Add tests

* Implement on the client side
2021-07-22 20:14:18 +04:00
Andrei Prigorshnev 3cf7a3766a
DEV: extract join_group method from groups#add_members method (#13807)
* Copy the add_members method to the new join method

* Remove unneeded code from the join method

* Rearrange the join method

* Remove unneeded stuff from the add_members method

* Extract add_user_to_group method

* Implement of the client side

* Tests

* Doesn't inline users.uniq

* Return promise from join.then()

* Remove unnecessary begin and end

* Revert "Return promise from join.then()"

This reverts commit bda84d8d

* Remove variable already_in_group
2021-07-22 11:11:23 +04:00
Martin Brennan f41908ad5b
SECURITY: Validate period param for top topic routes (#13818)
Fixes a possible SQL injection vector
2021-07-22 16:31:53 +10:00
Penar Musaraj 2ce2c83bc9
FIX: Show user filter hints when typing `@` in search (#13799)
Will show the last 6 seen users as filtering suggestions when typing @ in quick search. (Previously the user suggestion required a character after the @.)

This also adds a default limit of 6 to the user search query, previously the backend was returning 20 results but a maximum of 6 results was being shown anyway.
2021-07-21 09:14:53 -04:00
mintsaxon 7162ecfb04 FEATURE: Per-category default slow mode duration for topics.
When configured, all topics in the category inherits the slow mode
duration from the category's default.

Note that currently there is no way to remove the slow mode from the
topics once it has been set.
2021-07-21 12:32:07 +08:00
Andrei Prigorshnev 1a8c949900
UX: suspend forever time period messages (#13776)
When the Forever option is selected for suspending a user, the user is suspended for 1000 years. Without customizing the site’s text, this time period is displayed to the user in the suspension email that is sent to the user, and if the user attempts to log back into the site. Telling someone that they have been suspended for 1000 years seems likely to come across as a bad attempt at humour.

This PR special case messages when a user suspended or silenced forever.
2021-07-20 14:42:08 +04:00
Rafael dos Santos Silva e12b00eab7
FEATURE: Stop checking referer for embeds (#13756)
Flips content_security_policy_frame_ancestors default to enabled, and
removes HTTP_REFERER checks on embed requests, as the new referer
privacy options made the check fragile.
2021-07-16 15:25:49 -03:00
Andrei Prigorshnev 1cadae3879
FIX: simplify and improve choosing favorite badges (#13743)
* No need to return anything except a status code from the server

* Switch a badge state before sending a request and then switch it back in case of an error
2021-07-16 11:13:00 +08:00
Vinoth Kannan d6fc39c886
FEATURE: update existing users when group default notifications changed. (#13434)
Currently, the changes will only affect the users added after.
2021-07-15 19:53:57 +05:30
Andrei Prigorshnev 5cd447695e
FIX: problems with choosing favorite badges (#13731) 2021-07-15 14:51:44 +04:00
Osama Sayegh 31aa701518
FEATURE: Add option to grant badge multiple times to users using Bulk Award (#13571)
Currently when bulk-awarding a badge that can be granted multiple times, users in the CSV file are granted the badge once no matter how many times they're listed in the file and only if they don't have the badge already.

This PR adds a new option to the Badge Bulk Award feature so that it's possible to grant users a badge even if they already have the badge and as many times as they appear in the CSV file.
2021-07-15 05:53:26 +03:00
Guhyoun Nam 0dc96ce817
FEATURE: Setting to allow moderators to change post ownership (#13708) 2021-07-13 09:40:11 -05:00
Martin Brennan 7911124d3d
FEATURE: Uppy image uploader with UppyUploadMixin (#13656)
This PR adds the first use of Uppy in our codebase, hidden behind a enable_experimental_image_uploader site setting. When the setting is enabled only the user card background uploader will use the new uppy-image-uploader component added in this PR.

I've introduced an UppyUpload mixin that has feature parity with the existing Upload mixin, and improves it slightly to deal with multiple/single file distinctions and validations better. For now, this just supports the XHRUpload plugin for uppy, which keeps our existing POST to /uploads.json.
2021-07-13 12:22:00 +10:00
Dan Ungureanu 49090c3524
FIX: Suggest current username for staged users (#13706)
If user had a staged account and logged in using a third party service
a different username was suggested. This change will try to use the
username given by the authentication provider first, then the current
staged username and last suggest a new one.
2021-07-13 09:15:06 +10:00
Jeff Wong ee539632ad
FIX: admin_user_response schema (#13711) 2021-07-12 15:00:57 -07:00
Arpit Jalan 953fd2cb50
FEATURE: add title tag for group detail page (#13702) 2021-07-12 20:05:57 +05:30
Dan Ungureanu 2d904ade6d
FIX: Let staged users choose their username (#13678)
When a staged user tried to redeem an invite, a different username was
suggested and manually typing the staged username failed because the
username was not available.
2021-07-12 07:57:38 +10:00
Bianca Nenciu 87c1e98571
FEATURE: Let users select flair (#13587)
User flair was given by user's primary group. This PR separates the
two, adds a new field to the user model for flair group ID and users
can select their flair from user preferences now.
2021-07-08 10:46:21 +03:00
Jarek Radosz 48b92d8897
DEV: Isolate multisite specs (#13634)
Mixing multisite and standard specs can lead to issues (e.g. when using `fab!`)
Disabled the (upcoming https://github.com/discourse/rubocop-discourse/pull/11) rubocop rule for two files that have thoroughly tangled both types of specs.
2021-07-07 18:57:42 +02:00
Dan Ungureanu 9969631cef
FEATURE: Make invites work with existing users (#13532)
* FEATURE: Redirect logged in user to invite topic

Users who were already logged in and were given an invite link to a
topic used to see an error message saying that they already have an
account and cannot redeem the invite. This commit amends that behavior
and redirects the user directly to the topic, if they can see it.

* FEATURE: Add logged in user to invite groups

Users who were already logged in and were given an invite link to a
group used to see an error message saying that they already have an
account and cannot redeem the invite. This commit amends that behavior
and adds the user to the group.
2021-07-07 19:42:42 +03:00
David Taylor a1e5a6bbe0
DEV: Remove `fsl` cookie from specs (#13657)
This cookie has not been used for a number of years, and has no effect. This commit removes it from the specs. (diff is almost entirely whitespace)
2021-07-07 10:54:18 +01:00
Vinoth Kannan 33eae4cbd8
FEATURE: add period filter in top topics route for tags. (#13415)
And also move all the "top topics by period" routes to query string param.

/top/monthly => /top?period=monthly
/c/:slug/:id/l/top/monthly => /c/:slug/:id/l/top?period=monthly
/tag/:slug/l/top/daily => /tag/:slug/l/top?period=daily (new)
2021-07-06 15:25:11 +05:30
Alan Guo Xiang Tan 37b8ce79c9
FEATURE: Add last visit indication to topic view page. (#13471)
This PR also removes grey old unread bubble from the topic badges by
dropping `TopicUser#highest_seen_post_number`.
2021-07-05 14:17:31 +08:00
Dan Ungureanu 16227e38ac
FIX: Do not redirect to a topic user cannot see (#13550)
Inviting a user to a private topic used to redirect them to a 404 page
immediately after sign up.
2021-06-30 12:00:47 +03:00
Arpit Jalan 1ea2880276
FEATURE: add staff action logs for watched words (#13574) 2021-06-30 11:22:46 +05:30
Alan Guo Xiang Tan 9a7adcd178 FIX: Use absolute URL when redirecting SVG sprite path.
This ensures that CDN URLs with relative paths do not end up losing the
relative paths.
2021-06-30 11:25:05 +08:00
Mark VanLandingham 4b27de8c4b
FIX: Include user_field_ids in pagination URL for directory items (#13569) 2021-06-29 14:43:38 -05:00
Mark VanLandingham 18de11f3a6
FIX: Load more users URL respect group param (#13485) 2021-06-23 10:21:53 -05:00
Bianca Nenciu a22aa7562a
FIX: Make favorite work with multiple grant badges (#13492)
Badges that are awarded multiple times can be favorite and not favorite
at the same time. This caused few problems when users tried to favorite
them as they were counted multiple times or their state was incorrectly
displayed.
2021-06-23 14:41:23 +03:00