Commit Graph

43539 Commits

Author SHA1 Message Date
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
dependabot[bot] d85cba9394
Build(deps): Bump bootsnap from 1.7.7 to 1.8.0 (#14171)
Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.7.7 to 1.8.0.
- [Release notes](https://github.com/Shopify/bootsnap/releases)
- [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/Shopify/bootsnap/compare/v1.7.7...v1.8.0)

---
updated-dependencies:
- dependency-name: bootsnap
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-27 14:22:51 +02:00
dependabot[bot] 64a464888b
Build(deps): Bump rqrcode_core from 1.1.0 to 1.2.0 (#14170)
Bumps [rqrcode_core](https://github.com/whomwah/rqrcode_core) from 1.1.0 to 1.2.0.
- [Release notes](https://github.com/whomwah/rqrcode_core/releases)
- [Changelog](https://github.com/whomwah/rqrcode_core/blob/master/CHANGELOG.md)
- [Commits](https://github.com/whomwah/rqrcode_core/compare/v1.1.0...v1.2.0)

---
updated-dependencies:
- dependency-name: rqrcode_core
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-27 14:21:35 +02:00
dependabot[bot] c3998bdd7c
Build(deps): Bump rqrcode from 2.0.0 to 2.1.0 (#14169)
Bumps [rqrcode](https://github.com/whomwah/rqrcode) from 2.0.0 to 2.1.0.
- [Release notes](https://github.com/whomwah/rqrcode/releases)
- [Changelog](https://github.com/whomwah/rqrcode/blob/master/CHANGELOG.md)
- [Commits](https://github.com/whomwah/rqrcode/compare/v2.0.0...v2.1.0)

---
updated-dependencies:
- dependency-name: rqrcode
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-27 14:21:06 +02:00
dependabot[bot] fdd9921381
Build(deps): Bump rubocop from 1.19.1 to 1.20.0 (#14168)
Bumps [rubocop](https://github.com/rubocop/rubocop) from 1.19.1 to 1.20.0.
- [Release notes](https://github.com/rubocop/rubocop/releases)
- [Changelog](https://github.com/rubocop/rubocop/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop/rubocop/compare/v1.19.1...v1.20.0)

---
updated-dependencies:
- dependency-name: rubocop
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-27 14:20:39 +02:00
Joffrey JAFFEUX 480e512e37
DEV: reapply height hack for iOS (#14176) 2021-08-27 12:02:05 +02:00
Martin Brennan 90232af778
DEV: Bump Uppy to v2.X and rebuild bundle (#14173)
Uppy V2 includes the S3 multipart batch presigning change
we contributed in d613b849a6
so we need to upgrade it. This also brings both package.json
files into line and accounts for the renaming of Plugin
to BasePlugin in Uppy.

This has been tested and is working locally for both
regular Ember and Ember CLI, for uploads.json
XHR uploads and for direct S3 uploads (single and multipart).
2021-08-27 11:02:57 +10:00
Martin Brennan cfeb6347c3
DEV: Make composer-uppy-upload mixin more extensible (#14138)
This mixin needs to be shared between the composer and composer-like
user interfaces. This commit makes it so the events and the underlying
data model is configurable by the component extending the ComposerUploadUppy
mixin.

Also removes two MessageBus unsubscribe calls which were unnecessary.
2021-08-27 10:04:27 +10:00
Joffrey JAFFEUX 14e92bb0ea
FIX: correctly apply unusual padding to profile dropdowns (#14172) 2021-08-27 10:03:59 +10: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
David Taylor 189b4c4992
DEV: Promote all `javascripts/discourse` devDependencies to dependencies (#14167) 2021-08-26 22:19:44 +01:00
David Taylor 0aa8798046
DEV: Remove `yarn install` during `assets:precompile` (#14166)
Instead, we'll do it alongside `bundle install` in `web.template.yml`: https://github.com/discourse/discourse_docker/pull/565
2021-08-26 19:14:50 +01:00
Andrei Prigorshnev 9415fecfd0
UX: improve blank page syndrome on the user messages page (#14165)
The user-topic-list template is also in use in other places when we want to improve blank page syndrome, so this PR is a preparation for that changes as well.
2021-08-26 21:38:34 +04:00
Daniel Waterworth d11f19f099
PERF: Remove redundant post_timings_summary index (#14164)
It's redundant since post_timings_unique exists which has a superset of
the columns with the same prefix.
2021-08-26 10:50:34 -05:00
Joffrey JAFFEUX f66217c0b3
DEV: updates popperjs 2.0.6 -> 2.9.3 (#14163) 2021-08-26 16:37:04 +02:00
Joffrey JAFFEUX a4684c151b
REFACTOR: badge-title component (#14162)
- uses tagName=""
- removes user property which is not being used
- extract utility functions
- better wording for boolean properties
- initializes all properties
- uses @action
- uses optional chaining
- other minor changes
2021-08-26 15:19:09 +02:00
Martin Brennan 2eddf210d3 DEV: Revert uppy upgrade
This rolls uppy back to the previous bundle that was used,
which will break multipart functionality (which is not yet
enabled anywhere).

No other upload functionality should be affected by this change,
it will be as if d295a16dab had
not been merged.
2021-08-26 09:18:16 -04:00
Bianca Nenciu f0005025c4
FIX: Correctly display GitHub code oneboxes (#14149)
Code fragments without the code lines were not displayed correctly.

Follow-up-to 721a946d77.
2021-08-26 12:55:46 +03: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 e43a8af3bd
FIX: Do not send emails to mailing_list_mode subscribers for PMs (#14159)
This bug was introduced by f66007ec83.

In PostJobsEnqueuer we previously did not fire the after_post_create
event and after_topic_create event for private message topics. This was
changed in the above commit in order to publish message bus messages
for topic tracking state updates. Unfortunately this caused the
NotifyMailingListSubscribers job to be enqueued for all posts including
private messages, and admins and the users involved in the PMs got
emailed the contents of the PMs if they had mailing list mode enabled.

Luckily the impact of this was mitigated by a Guardian#can_see? check
for each mailing list mode user in the NotifyMailingListSubscribers job.
We never want to notify mailing list mode subscribers for private messages
so an early return has been added there, plus the logic in PostJobsEnqueuer
has been fixed, and tests have been added to that class where there were
none before.
2021-08-26 15:16:35 +10: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
Blake Erickson 75b0d6df93
SECURITY: escape cat name (#14154) 2021-08-25 17:11:58 -06:00
Martin Brennan 841e054907
FIX: Do not prefix temp/ S3 keys with s3_bucket_folder_path in S3Helper (#14145)
This is unnecessary, as when the temporary key is created
in S3Store we already include the s3_bucket_folder_path, and
the key will always start with temp/ to assist with lifecycle
rules for multipart uploads.

This was affecting Discourse.store.object_from_path,
Discourse.store.signed_url_for_path, and possibly others.

See also: e0102a5
2021-08-26 08:50:49 +10:00
Robin Ward 167fcb5eef Revert "DEV: fixes broken tests on ember-cli due to uppy"
This reverts commit d4a418e295.
2021-08-25 17:17:53 -04: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
Robin Ward cfbf69848a Revert "FIX: The `LogsNotice` service was never unsubscribing from the mbus"
This reverts commit 14b76dece6.
2021-08-25 17:04:59 -04:00
Robin Ward 14b76dece6 FIX: The `LogsNotice` service was never unsubscribing from the mbus
Whenever we `subscribe` to something there should be an equivalent
`unsubscribe` and this implements it for `LogsNotice`.

In the future we should make this closer to what Ember expects a Service
to be, but at least it's properly cleaning up after itself now.
2021-08-25 16:31:48 -04:00
jjaffeux d4a418e295 DEV: fixes broken tests on ember-cli due to uppy
The import was not found and causing the following error:

```
Uncaught TypeError: Class extends value undefined is not a constructor or null
```
2021-08-25 16:01:14 -04:00
Andrei Prigorshnev 506a5dc607
FEATURE: improve "blank page syndrome" on the user notifications page (#14103) 2021-08-25 20:57:27 +04:00
Bianca Nenciu 721a946d77
FIX: Remove spacing from GitHub oneboxes (#14147)
Each code line was surrounded by a lot of white space. The new styles
are similar to what the web interface is using.
2021-08-25 16:34:01 +03:00
Bianca Nenciu 197532dc31
FIX: Add plugin event to topic list user lookup (#14116)
This can be used to change the list of topic posters. For example,
discourse-solved can use this to move the user who posted the solution
after the original poster.
2021-08-25 13:16:08 +03:00
Bianca Nenciu 5ae700e731
FIX: Make user-card-metadata plugin outlet tagless (#14131) 2021-08-25 13:03:53 +03:00
Martin Brennan a7ec1a86b5
DEV: Do not delete failed uploads from S3 in debug mode (#14143)
See also 58e9fffe4c
2021-08-25 15:35:55 +10:00
Alan Guo Xiang Tan d2fe46d476
DEV: Remove the use of stubs. (#14142)
Follow-up to 419d71abcb
2021-08-25 13:25:01 +08:00
Martin Brennan 58e9fffe4c
DEV: Do not abort direct S3 uploads if upload_debug_mode enabled (#14141)
See the previous commit d66b258b0e as
well.

If enable_upload_debug_mode is true, we do not want to abort the
direct S3 upload, because that will delete the file on S3 and prevent
further inspection of any errors that have come up.
2021-08-25 14:48:06 +10:00
Arpit Jalan 419d71abcb
FEATURE: allow admin to delete all posts by a user irrespectively (#14128)
This commit allows admin to delete all posts by a user irrespective of
site settings `delete_user_max_post_age` and `delete_all_posts_max`.
2021-08-25 10:14:22 +05:30
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
Alan Guo Xiang Tan 4387bc1261
Revert "Build(deps-dev): Bump parallel_tests from 3.7.1 to 3.7.2 (#14136)" (#14140)
Gem got yanked or something. Doesn't exists anymore.

This reverts commit 21beeb4e15.
2021-08-25 10:02:52 +08:00
Penar Musaraj 1167b16913
FIX: Order outputted theme stylesheets (#14133) 2021-08-25 09:37:07 +08:00
dependabot[bot] d88c9d8cd1
Build(deps): Bump rubocop-ast from 1.10.0 to 1.11.0 (#14134)
Bumps [rubocop-ast](https://github.com/rubocop-hq/rubocop-ast) from 1.10.0 to 1.11.0.
- [Release notes](https://github.com/rubocop-hq/rubocop-ast/releases)
- [Changelog](https://github.com/rubocop/rubocop-ast/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rubocop-hq/rubocop-ast/compare/v1.10.0...v1.11.0)

---
updated-dependencies:
- dependency-name: rubocop-ast
  dependency-type: indirect
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-25 09:35:56 +08:00
dependabot[bot] 21beeb4e15
Build(deps-dev): Bump parallel_tests from 3.7.1 to 3.7.2 (#14136)
Bumps [parallel_tests](https://github.com/grosser/parallel_tests) from 3.7.1 to 3.7.2.
- [Release notes](https://github.com/grosser/parallel_tests/releases)
- [Changelog](https://github.com/grosser/parallel_tests/blob/master/CHANGELOG.md)
- [Commits](https://github.com/grosser/parallel_tests/compare/v3.7.1...v3.7.2)

---
updated-dependencies:
- dependency-name: parallel_tests
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-25 09:35:43 +08:00
dependabot[bot] 0ff6bc93dd
Build(deps): Bump rails-html-sanitizer from 1.4.1 to 1.4.2 (#14135)
Bumps [rails-html-sanitizer](https://github.com/rails/rails-html-sanitizer) from 1.4.1 to 1.4.2.
- [Release notes](https://github.com/rails/rails-html-sanitizer/releases)
- [Changelog](https://github.com/rails/rails-html-sanitizer/blob/master/CHANGELOG.md)
- [Commits](https://github.com/rails/rails-html-sanitizer/compare/v1.4.1...v1.4.2)

---
updated-dependencies:
- dependency-name: rails-html-sanitizer
  dependency-type: indirect
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2021-08-25 09:35:31 +08:00
Martin Brennan d66b258b0e
DEV: Do not destroy external upload stub on error in debug mode (#14139)
We do not want to destroy the external upload stub records
in debug mode because they allow for investigation of problems
occuring.
2021-08-25 11:11:19 +10:00
Martin Brennan e0102a533a
FIX: Restructure temp/ folders for direct S3 uploads (#14137)
Previously we had temp/ in the middle of the S3 key path like so

* /uploads/default/temp/randomstring/test.png (normal site)
* /sitename/uploads/default/temp/randomstring/test.png (s3 folder path site)
* /standard10/uploads/sitename/temp/randomstring/test.png (multisite site)

However this necessitates making a lifecycle rule to clean up incomplete
S3 multipart uploads for every site, something which we cannot do. It makes
much more sense to have a structure with /temp at the start of the key,
which is what this commit does:

* /temp/uploads/default/randomstring/test.png (normal site)
* /temp/sitename/uploads/default/randomstring/test.png (s3 folder path site)
* /temp/standard10/uploads/sitename/randomstring/test.png (multisite site)
2021-08-25 09:22:36 +10: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
Kris fdc9de3443
minor wording fix for get a room message (#14130) 2021-08-24 15:53:35 -04:00
Andrei Prigorshnev 4d5f5a67c1
FIX: the empty state message was appearing in wrong moments on the user bookmarks stage (#14127)
Steps to reproduce:

1. Go to activity/bookmarks
2. Search for something that isn’t in your bookmarks, so you get no results
3. Navigate away and then click "Bookmarked" on the sidebar or open the user menu and click the View All Bookmarks button on the bottom of the bookmarks tab, and you get the message "You haven't bookmarked anything yet". 

This commit fixes the problem. We have a controller with a query parameter q that contains a search query. And we also have a property searchTerm that is bound to the search box on the page and mirrors the value in q. We were using a value from searchTerm when querying the server, but ember controllers are singletons so the searchTerm value persisted between page visits and leaded to this bug.

To make things work properly, we should be using the value from q everywhere except two places when we copy a value from q to searchTerm and vice versa.
2021-08-24 23:40:08 +04:00
Discourse Translator Bot c995b20ca4
Update translations (#14063) 2021-08-24 15:25:44 +02:00
Joffrey JAFFEUX eb52abf076
DEV: adds server:after-body-open (#14106)
This change is to allow to add a node at the top of body. This is currently done through DOM in a plugin which is causing a full Recalculate Style.
2021-08-24 14:35:44 +02: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