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`
Includes support for flags, reviewable users and queued posts, with REST API
backwards compatibility.
Co-Authored-By: romanrizzi <romanalejandro@gmail.com>
Co-Authored-By: jjaffeux <j.jaffeux@gmail.com>
Migrates email user options to a new data structure, where `email_always`, `email_direct` and `email_private_messages` are replace by
* `email_messages_level`, with options: `always`, `only_when_away` and `never` (defaults to `always`)
* `email_level`, with options: `always`, `only_when_away` and `never` (defaults to `only_when_away`)
It is not a setting, and only relevant in specs. The new API is:
```
Jobs.run_later! # jobs will be thrown on the queue
Jobs.run_immediately! # jobs will run right away, avoid the queue
```
Previously if you wanted to have jobs execute in test mode, you'd have
to do `SiteSetting.queue_jobs = false`, because the opposite of queue
is to execute.
I found this very confusing, so I created a test helper called
`run_jobs_synchronously!` which is much more clear about what it does.
Uses github.com/discourse/moment-timezone-names-translations to translate timezone names.
Plugins can also provide their own timezone name translations.
* Add missing icons to set
* Revert FA5 revert
This reverts commit 42572ff
* use new SVG syntax in locales
* Noscript page changes (remove login button, center "powered by" footer text)
* Cast wider net for SVG icons in settings
- include any _icon setting for SVG registry (offers better support for plugin settings)
- let themes store multiple pipe-delimited icons in a setting
- also replaces broken onebox image icon with SVG reference in cooked post processor
* interpolate icons in locales
* Fix composer whisper icon alignment
* Add support for stacked icons
* SECURITY: enforce hostname to match discourse hostname
This ensures that the hostname rails uses for various helpers always matches
the Discourse hostname
* load SVG sprite with pre-initializers
* FIX: enable caching on SVG sprites
* PERF: use JSONP for SVG sprites so they are served from CDN
This avoids needing to deal with CORS for loading of the SVG
Note, added the svg- prefix to the filename so we can quickly tell in
dev tools what the file is
* Add missing SVG sprite JSONP script to CSP
* Upgrade to FA 5.5.0
* Add support for all FA4.7 icons
- adds complete frontend and backend for renamed FA4.7 icons
- improves performance of SvgSprite.bundle and SvgSprite.all_icons
* Fix group avatar flair preview
- adds an endpoint at /svg-sprites/search/:keyword
- adds frontend ajax call that pulls icon in avatar flair preview even when it is not in subset
* Remove FA 4.7 font files
* First take on subsetting svg icons
* FontAwesome 5 svg subset WIP
* Include icons from plugins/badges into svg sprite subset
* add svg icon support to themes
* Add spec for SvgSprite
* Misc. SVG icon fixes
* Use FA5 svgs in local-dates plugin
* CSS adjustments, fix SVG icons in group flair
* Use SVG icons in poll plugin
* Add SVG icons to /wizard
Previously we would render "Today at 2:42 PM"
Now we render "Today 2:42 PM"
This also introduces new strings so it can be properly translated
Finally it introduces tests so we can make sure this keeps working