I also took the opportunity with this commit to move some test specific
stuff out of `discourse-loader` which is loaded on the front end of the
application. The test module building now happens in the `test_helper`
bundle.
DEV: Replace instances of Discourse.base_uri with Discourse.base_path
This is clearer because the base_uri is actually just a path prefix. This continues the work started in 555f467.
This is long overdue. We had a lot of (not linted) code to initialize
our test suite as part of the Ruby `test_helper.js` bundle.
This refactor moves that out to a `setup-tests` module, which imports
all the modules properly, rather than using `require`.
It also removes the global `server` variable which some tests were using
for pretender. Those tests are fixed, and in the case of widget tests,
support for a `pretend()` was added, which mimics our acceptance tests.
One problematic test was removed, which overwrites `/posts` - this could
break tons of other tests depending on order.
We used many global functions to handle tests when they should be
imported like other libraries in our application. This also gets us
closer to the way Ember CLI prefers our tests to be laid out.
This plugin is only useful for developers, however, making it core allows us to centralize any component modification in one commit.
This integration also adds a new site_setting: `styleguide_admin_only` which allows to enable a styleguide on a live site while restricting visibility to admins only.
By default, styleguide is disabled.
Poll markdown processing failed when there were any heading elements preceding a poll.
(Issue originally reported in babbebfb35 (commitcomment-42983768))
This is where they should be as far as ember is concerned. Note this is
a huge commit and we should be really careful everything continues to
work properly.
Adds an optional title attribute to polls. The rationale for this addition is that polls themselves didn't contain context/question and relied on post body to explain them. That context wasn't always obvious (e.g. when there are multiple polls in a single post) or available (e.g. when you display the poll breakdown - you see the answers, but not the question)
As a side note, here's a word on how the poll plugin works:
> We have a markdown poll renderer, which we use in the builder UI and the composer preview, but… when you submit a post, raw markdown is cooked into html (twice), then we extract data from the generated html and save it to the database. When it's render time, we first display the cooked html poll, and then extract some data from that html, get the data from the post's JSON (and identify that poll using the extracted html stuff) to then render the poll using widgets and the JSON data.
eslint --fix is capable of fix it automatically for you, ensure prettier is run after eslint as eslint --fix could leave the code in an invalid prettier state.
This is a little bit of refactoring. Core Discourse should have default promotion message for TL2.
In addition, when the Discobot plugin is enabled, the user is invited to advanced training
This PR removes the user reminder topic timers, because that system has been supplanted and improved by bookmark reminders. The option is removed from the UI and all existing user reminder topic timers are migrated to bookmark reminders.
Migration does this:
* Get all topic_timers with status_type 5 (reminders)
* Gets all bookmarks where the user ID and topic ID match
* Loops through the found topic timers
* If there is no bookmark for the OP of the topic, then we just create a bookmark with a reminder
* If there is a bookmark for the OP of the topic and it does **not** have a reminder set, then just
update it with the topic timer reminder
* If there is a bookmark for the OP of the topic with a reminder then just discard the topic timer
* Cancels all outstanding user reminder topic timers
* **Trashes (not deletes) all user reminder topic timers**
Notes:
* For now I have left the user reminder topic timer job class in place; this is so the jobs can be cancelled in the migration. It and the specs will be deleted in the next PR.
* At a later date I will write a migration to delete all trashed user topic timers. They are not deleted here in case there are data issues and they need to be recovered.
* A future PR will change the UI of the topic timer modal to make it look more like the bookmark modal.
Previously we were manually comparing the composer 'action' to the REPLY and EDIT constants. This meant that other forms of editing (e.g. shared drafts) were not included. This commit changes the presence logic to use the existing composer computed variables.
* FIX - make Discobot new user tutorial a little more robust
Plugin allows reply, regardless of other SiteSettings
Skip image upload step if user can’t upload images, calls new ‘likes’ step instead
* Test that the images step is skipped
* Slight optimization
eg:
timezone="America/Detroit"
timezones="US/Eastern"
Before this commit we would show America/Detroit in previews and not US/Eastern, given US/Eastern and America/Detroit are equivalent.
After this commit, we will display the date with America/Detroit but show US/Eastern in the previews.
The poll breakdown modal replaces the grouped pie charts feature.
Includes:
* MODAL: Untangle `onSelectPanel`
Previously modal-tab component would call on click the onSelectPanel callback with itself (modal-tab) as `this` which severely limited its usefulness. Now showModal binds the callback to its controller.
"The PR includes a fix/change to d-modal (b7f6ec6) that hasn't been extracted to a separate PR because it's not currently possible to test a change like this in abstract, i.e. with dynamically created controllers/components in tests. The percentage/count toggle test for the poll breakdown feature is essentially a test for that d-modal modification."
Ensure that the inappropriate flag is used and not some other flag
type. If some other flag is used a message will be posted letting the
user know they used the wrong flag and the original flag will be removed
so that they can try again.
Bug reported on meta: https://meta.discourse.org/t/-/157075
Per the linked site (http://mths.be/details) and https://caniuse.com/#feat=details the <details> element is supported since Chrome 12/Safari 6/Firefox 49/Edge 79. IE 11 doesn't handle them, but we dropped the support for that browser.
Previously it would sleep for either 2 or 3 seconds instead of sleeping
between a range of 2 to 3 seconds. Also, 2 to 3 seconds seems to be
excessivly long when I tried out discobot again.
* Remove unused Discourse.SiteSettings
* Remove `Discourse.SiteSettings` from many tests
* REFACTOR: `lib:formatter` was using a lot of leaky state
* Remove more `Discourse.SiteSettings` from tests
* More SiteSettings removed from tests
When doing a migration, there might be some cases where the discobot user
doesn't have a user_option / user_profile record(s).
This ensures we always create one during the seed phase.
In French, the help trigger has a raw content of "afficher l'aider" which is then cooked into "afficher l’aide" (note the different quote character).
Since we were checking the raw content of the trigger against the cooked version of the post, this trigger never worked in French.
This changes so that we cook the trigger before checking in against the cooked version of the post.
DEV: new 'discobot_username' method that is used everywhere instead of 'discobot_user.username' / 'discobot_user.username_lower'
This reverts commit 20780a1eee.
* SECURITY: re-adds accidentally reverted commit:
03d26cd6: ensure embed_url contains valid http(s) uri
* when the merge commit e62a85cf was reverted, git chose the 2660c2e2 parent to land on
instead of the 03d26cd6 parent (which contains security fixes)
We have been using YouTube's 'hqdefault.jpg' image which works consistently to provide a 480x360 thumbnail. YouTube does provide larger thumbnails, but not consistently for every video. By using og:image, we will fetch the best resolution YouTube can provide for each video.
This commit also refactors lazy-yt to re-use the thumbnail already existing in the cooked content. This means we get lazy-loading for free, and avoid hotlinking images to YouTube (when download remote images is enabled on the site).
The thumbnails were being correctly downloaded, but the URLs were not being substituted correctly in post_process_cooked because the lazy-yt output did not include the `onebox` class.
Previously the image was imported from a Discourse hosted CDN but the
URL has since become invalid. However, it was not caught since all
errors are rescued. This commit fixes the issue by shipping the user
avatar with the plugin.
This will make a few minor improvements to the second factor user interface. Highlights include:
- Using the site's title to prefix the backup code filename. If non-ascii characters are detected, then prefix "discourse" instead.
- Add icons and change the text on some of the buttons for better clarity and consistency
- Add an education link to the security key modal
This change amends it so we use a static service to keep track of
the typing presence.
It correct various edge cases the initial implementation had
- Faster close messages
- When composing on topic 1 and viewing topic 2 we had incorrect
presence
- Changing a running composer to reply as new topic or reply to a
differet topic would not correctly shift presence
Authored by tgxworld, with contributions by sam
* Rename all instances of bookmarkWithReminder and bookmark_with_reminder to just bookmark
* Delete old bookmark code at the same time
* Add migration to remove the bookmarkWithReminder post menu item if people have it set in site settings
On some installations, there may be a leftover symlink which uses the
old plugin name:
public/plugins/discourse-internet-explorer ->
-> plugins/discourse-internet-explorer/public
Before this commit, the presence state of users were stored on the
server side and any updates to the state meant we had to publish the
entire state to the clients. Also, the way the state of users were
stored on the server side meant we didn't have a way to differentiate
between replying users and whispering users.
In this redesign, we decided to move the tracking of users state to the client
side and have the server publish client events instead. As a result of
this change, we're able to remove the number of opened connections
needed to track presence and also reduce the payload that is sent for
each event.
At the same time, we've also improved on the restrictions when publishing message_bus messages. Users that
do not have permission to see certain events will not receive messages
for those events.
* Bookmarks with reminders is a core feature now, no need to have a separate URL
* Keep around the old /u/:username/activity/bookmarks-with-reminders route for backwards compat in Ember but just redirect to user activity bookmarks.
The main thrust of this PR is to take all the conditional checks based on the `enable_bookmarks_with_reminders` away and only keep the code from the `true` path, making bookmarks with reminders the core bookmarks feature. There is also a migration to create `Bookmark` records out of `PostAction` bookmarks for a site.
### Summary
* Remove logic based on whether enable_bookmarks_with_reminders is true. This site setting is now obsolete, the old bookmark functionality is being removed. Retain the setting and set the value to `true` in a migration.
* Use the code from the rake task to create a database migration that creates bookmarks from post actions.
* Change the bookmark report to read from the new table.
* Get rid of old endpoints for bookmarks
* Link to the new bookmarks list from the user summary page
This is to streamline the new user narrative. only works when creating the bookmark, if editing/deleting the modal is shown. This is done via the plugin initializer.
This change refactors the code a bit so that a plugin could easily
replace which badge is awarded when completing the discobot new user
tutorial and advanced tutorial.
By adding a static method and putting the BADGE_NAME constant inside of
that method we can simply call that method now instead of the constant.
A plugin could then `class_eval` that method and replace it with
whatever badge name they choose. This is way cleaner than having the
plugin change the frozen constant! eeek.
This required properly plumbing the guardian into the serializer.
Notably, the default state in the client was not changed - if you haven't voted in
the poll, you need to click the button to view the results instead of the results
being immediately visible on page load.
Implements https://meta.discourse.org/t/-/138108
For convenience the i18n helper has been made returning a SafeString, but when used with other helpers, a String is expected and will cause unexpected behaviors.
This is the root cause of the initial bug fixed in d2bb127e2c
This commit is kept as it's a better security in case of unexpected behavior.
* Remove some `.es6` from comments where it does not matter
* Use a post processor for transpilation
This will allow us to eventually use the directory structure to
transpile rather than the extension.
* FIX: Some errors and clean up in confirm-new-email
It would throw an error if the webauthn element wasn't present.
Also I changed things so that no-module is not explicitly
referenced.
* Remove `no-module`
Instead we allow a magic comment: `// discourse-skip-module` to prevent
the asset pipeline from creating a module.
* DEV: Enable babel transpilation based on directory
If it's in `app/assets/javascripts/dicourse` it will be transpiled
even without the `.es6` extension.
* REFACTOR: Remove Tilt/ES6ModuleTranspiler
* Do not grant badges for posts with no user
* Ensure instructions are correct in Change Owner modal
* Hide user-dependent actions from posts with no user
* Make PostRevisor work with posts with no user
* Ensure posts with no user can be deleted
* discourse-narrative-bot should ignore posts with no user
* Skip TopicLink creation for posts with no user
This pr replaces `{{{ }}}` usage by a {{html-safe}} helper. While it doesn't solve the underlying issue, it gives us a path forward without risking breaking too much existing behavior.
Also introduces an htmlSafe computed macro:
```
import { htmlSafe } from "discourse/lib/computed";
htmlDescription: htmlSafe("description")
```
Overtime {{html-safe}} usage should be removed and moved to components properties or specialized components/helpers.
This pr replaces `{{{ }}}` usage by a {{html-safe}} helper. While it doesn't solve the underlying issue, it gives us a path forward without risking breaking too much existing behavior.
Also introduces an htmlSafe computed macro:
```
import { htmlSafe } from "discourse/lib/computed";
htmlDescription: htmlSafe("description")
```
Overtime {{html-safe}} usage should be removed and moved to components properties or specialized components/helpers.
From ember-template-lint documentation (https://github.com/ember-template-lint/ember-template-lint/blob/master/docs/rule/no-unbound.md):
```
{{unbound}} is a legacy hold over from the days in which Ember's template engine was less performant. Its use today is vestigial, and it no longer offers performance benefits.
It is also a poor practice to use it for rendering only the initial value of a property that may later change.
```
Co-Authored-By: Jarek Radosz <jradosz@gmail.com>
This new iteration of select-kit focuses on following best principales and disallowing mutations inside select-kit components. A best effort has been made to avoid breaking changes, however if you content was a flat array, eg: ["foo", "bar"] You will need to set valueProperty=null and nameProperty=null on the component.
Also almost every component should have an `onChange` handler now to decide what to do with the updated data. **select-kit will not mutate your data by itself anymore**
* DEV: Fix the function prototype observers deprecation
DEPRECATION: Function prototype extensions have been deprecated, please migrate from function(){}.observes('foo') to observer('foo', function() {}). [deprecation id: function-prototype-extensions.observes] See https://deprecations.emberjs.com/v3.x/#toc_function-prototype-extensions-observes for more details.
* DEV: Fix the function prototype event listeners deprecation
DEPRECATION: Function prototype extensions have been deprecated, please migrate from function(){}.on('foo') to on('foo', function() {}). [deprecation id: function-prototype-extensions.on] See https://deprecations.emberjs.com/v3.x/#toc_function-prototype-extensions-on for more details.
* DEV: Simplify `default as` imports
Co-authored-by: Joffrey JAFFEUX <j.jaffeux@gmail.com>
The bug was mentioned here: https://meta.discourse.org/t/poll-name/136436
I added specs to cover existing behaviour and refactored can_see_results method.
Guard condition should apply only if the poll result setting is set to `staff_only`.
In other cases, user can see results when the poll result setting is set to `always` or user voted or poll is closed.
A proper fix would involve it being precompiled like other assets, but
due to the conditional nature of the resource this is more complicated.
For now this is better than IE being broken.
When a user accepts an invite with an email address that matches a group
which automatically awards its members Trust Level 2, a race condition might happen
when the 'send_advanced_tutorial_message' job runs.
That job is enqueued inside the 'user_promoted' event which is triggered inside a
transaction on the user record. If the job runs before the transaction is done,
the user record is invisible and this generates an exception.
This commit mostly get rid of the later() call and encapsulate all pie chart display logic inside discourse-poll-pie-canvas widget instead of sharing it between discourse-poll-pie-chart and discourse-poll-pie-canvas
For various reasons, users may want to change their response to a poll.
Currently they have permission to do so, however it is hidden behind the 'Hide
results' button. Since what this button does is take the user back to the vote
panel, it seems more appropriate to name it 'Show vote', where it becomes
obvious that it can be modified and re-submitted.
As discussed here [1], there are mulitple users, myself included, who assumed
that editing a misclick response was impossible. This improves the label to make
it more descriptive of the action actually being taken.
[1] https://meta.discourse.org/t/ability-to-remove-my-choice-in-a-poll/53642/6
This PR aims to make poll results easily exportable to staff in a CSV format, so they can be analyzed in external software.
It also makes the export data easily customizable by allowing users to leverage any data explorer query to generate the report. By default, we use a query that ships with data explorer, but user can change the ID in settings or use 0 to disable this feature.
One potential upgrade is using the recent work that allows arbitrary group to run data explorer and allow all the groups with access to the configured query to also export polls, but that can be added later.
Co-Authored-By: Joffrey JAFFEUX <j.jaffeux@gmail.com>
FileHelper.download requires a string not a URI. I also found another
instance of using open-uri directly and swapped it out to use
FileHelper.
I also updated it to not `read` a file if it comes back nil.
Follow up to: fe01099a38
By requiring open-uri this will fix the following error:
```
NoMethodError (private method `open' called for #<URI::Generic...
```
also switched to the shorter syntax and removed default options. Since
ruby 2.4 redirect is on by default.
* DEV: Provide radix 10 argument to parseInt
* DEV: Provide radix 16 argument to parseInt
* DEV: Remove unnecessary parseInt calls
* Fix year formatting
parseInt was used here to convert decimals to ints
To eliminate a DDOS attack vector, we're taking the following measures:
The endpoint will be rate-limited to 3 requests every 60 seconds (per user).
A 24 hours max-age cache header is sent with the response.
The route will be hijacked to generate the certificate in the background.
AppEvents was always a service object in disguise, so we should move it
to the correct place in the application. Doing this allows other service
objects to inject it easily without container access.
In the future we should also deprecate `this.appEvents` without an
explicit injection too.
Zeitwerk simplifies working with dependencies in dev and makes it easier reloading class chains.
We no longer need to use Rails "require_dependency" anywhere and instead can just use standard
Ruby patterns to require files.
This is a far reaching change and we expect some followups here.
Advanced trigger is currently broken on:
ca
es
et
fr
he
it
pt_BR
And that is because the translation levels for the plugin are kinda low, so I would guess it's broken for half the languages.
Since we have only two tracks for a while now, a quick fix to me is inverting the selectors.
This patch works because the advanced key is "larger" than the new user one.
* FEATURE: Staff only poll results
These changes allow only staff to see the results of a poll.
Non-staff users will be shown a screen like this:
1b8bd76013.png
The "Votes are public" message has been removed from the info section,
and the button to show the votes has been replaced with a message
stating the results will only be shown to staff.
* Update PR based on feedback
* Update plugins/poll/app/models/poll.rb
make sure we return a boolean
Co-Authored-By: Régis Hanol <regis@hanol.fr>
The migration script is not idempotent due to database constrains on the
poll related objects, namely:
polls: index_polls_on_post_id_and_name (post_id,name) UNIQUE
poll_options: index_poll_options_on_poll_id_and_digest (poll_id,digest) UNIQUE
poll_votes: index_poll_votes_on_poll_id_and_poll_option_id_and_user_id (poll_id,poll_option_id,user_id) UNIQUE
This change skips a particular poll migration if it's already found on
the db.
If a locale has triggers that start with the same word, our regexp will
always end up matching the first trigger. For example,
`start tutorial` and `start tutorial advanced`
To support the change, we have to make the match on triggers more
restrictive. `@discobot quote here` will no longer work like `@discobot
quote`.
* Calling `Discourse.reset()` creates a new container
We should run our de-initializers only after acceptance tests,
since initializers are not run outside of acceptance tests anyway,
and the container at this point can be passed properly to the
`teardown()` method.
* Remove `Discourse.reset` from tests
This would cause a new container to be created which leaks many objects.
* `updateCurrentUser` is more accurate than `replaceCurrentUser`
* Remove long-deprecated method
* FIX: Memory Leaks when decorating posts
Previously we'd keep creating mixins dynamically when decorating the
same class.
This code changes the API to recommend an `id` parameter for each
decorator which will avoid leaks. All plugins should be updated to
include this parameter, although if they don't in the meantime it'll
just mean a warning in the console (and a continued leak.)
Previously we relied on fabrication on anonymous, we can not get the
transaction commit pipeline to work as it does in production, cleanly
This amends it so our anonymous user is created using the core APIs
Signed-off-by: Sam Saffron <sam.saffron@gmail.com>
They were relying on a pristine message bus, however current implementation
still uses redis, stuff can get held up and we can end up publishing
distributed cache messages in the middle invalidating the tests
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.
Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
We found the previous triggers less straight forward than just calling
it tutorial.
`start new user` -> `start tutorial`
`start new advanced user` -> `start advanced tutorial`