This is another refactoring in the multi-step process to remove all uses
of our custom Render Buffer.
Previous commit: 80f4b9e227 in this
series.
This commit affects the display of translated counts that is used in
multiple places like showing how many posts are selected using the
select posts feature on a topic. It is just a refactor and does not
change any functionality.
This feature adds the ability to define synonyms for tags, and the ability to merge one tag into another while keeping it as a synonym. For example, tags named "js" and "java-script" can be synonyms of "javascript". When searching and creating topics using synonyms, they will be mapped to the base tag.
Along with this change is a new UI found on each tag's page (for example, `/tags/javascript`) where more information about the tag can be shown. It will list the synonyms, which categories it's restricted to (if any), and which tag groups it belongs to (if tag group names are public on the `/tags` page by enabling the "tags listed by group" setting). Staff users will be able to manage tags in this UI, merge tags, and add/remove synonyms.
* FEATURE: ability to add all active components to theme
* FIX: add a component to all themes takes only active ones
* FIX: move select components/themes to top
* FIX: improve defaultIsAvailable
* FIX: Add filter(Boolean) and remove btn class
This is another refactoring in the multi-step process to remove all uses
of our custom Render Buffer.
Previous commit: bb31e7f5b6 in the series.
This commit affects the display of the Webhooks Deliver Status column. It
is just a refactor and does not change any functionality.
If a badge grouping happens to have been deleted a 500 error will be
thrown when looking a user's badges.
This fix allows the badge page to still be shown without any errors. The
badge with the missing badge grouping is still displayed.
I'll follow up with a separate pr/commit that will ensure if a badge
grouping is deleted, all badges with that badge_grouping_id will also be
updated.
* the code to get current user already got their
user_option record as well, so adding the timezone
column to the attributes returned should not create
any additional overhead. this timezone will be very
useful for getting momentjs dates relative to the
user's timezone
The tag-drop component uses the passed in categories to calculate paths,
but only the last category is relevant, since, from a category we can
calculate its ancestors.
Some endpoints are returning i18n keys instead of translated messages
and with these changes, the site_texts endpoint can help translating
those.
Pagination part is needed for better wildcard support. For example,
looking for 'js.notifications' would set 'has_more' to true, but return
only the first 50 messages with no way of fetching the remaining.
* Support for custom messages and redirects when creating posts
When a post/topic is created Discourse serializes a `NewPostResult`
object. Normally this contains a status like `created_post` or
errors describing why the post could not be created.
There are times when a plugin might want to take the inputted post
and do something in the background. In this case, the plugin
can return a custom `message` and `route_to` attribute in the
`NewPostResult`.
If present, the message will be displayed in an alert, and when "Ok" is
clicked the user will be routed to the new URL.
* Destroy the draft in parallel
This reverts commit 700bd280e4.
Oops looks like this breaks tests:
```
Module Failed: widget:quick-access-item
Test Failed: escapedContent attribute is not escaped
Assertion Failed: TypeError: Cannot read property 'match' of undefined
Expected: true, Actual: false
Test Failed: anonymous
Assertion Failed: failed, expected argument to be truthy, was: 0
Expected: true, Actual: 0
Assertion Failed: Element .enable-anonymous not found.
Test Failed: anonymous - switch back
Assertion Failed: failed, expected argument to be truthy, was: 0
Expected: true, Actual: 0
Assertion Failed: Element .disable-anonymous not found.
Test Failed: log out
Assertion Failed: failed, expected argument to be truthy, was: 0
Expected: true, Actual: 0
Assertion Failed: Element .logout not found.
Test Failed: content attribute is escaped
Assertion Failed: TypeError: Cannot read property 'match' of undefined
Expected: true, Actual: false
```
* FEATURE: Ability to add components to all themes
This is the first and functional step from that topic https://dev.discourse.org/t/adding-a-theme-component-is-too-much-work/15398/16
The idea here is that when a new component is added, the user can easily assign it to all themes (parents).
To achieve that, I needed to change a site-setting component to accept `setDefaultValues` action and `setDefaultValuesLabel` translated label.
Also, I needed to add `allowAny` option to disable that for theme selector.
I also refactored backend to accept both parent and child ids with one method to avoid duplication (Renamed `add_child_theme!` to more general `add_relative_theme!`)
* FIX: Improvement after code review
* FIX: Improvement after code review2
* FIX: use mapBy and filterBy directly
Note:
```
def foo(bar: 1)
end
foo({bar: 2})
# raises a deprecation, instead use:
foo(**{bar: 2})
```
Additionally when matching regexes always use strings. It does not make
sense to match a non string to a regex.
I could not replicate the failure locally, but it was consistently
failing on CI with:
```
Assertion Failed: it should escape watched words
Expected: <img src="x">, Actual: <img src="x">
```
This commit removes an extra space that was added originally, but I
don't think it is really needed after double checking how it displays in
the UI. The `x` icon and the word have sufficient spacing between them.
If we need to we can tweak it in css instead.
Follow up to: bb31e7f5b6
This commit fixes this failing test:
`Assertion Failed: it should escape watched words`
Now that we have a handlebars template we can us it for escaping because
it does that for us.
This is another refactoring in the multi-step process to remove all uses
of our custom Render Buffer.
Previous commit: 2673cad142 in this
series.
This commit affects the display of watched words on the admin watched
word page. It is just a refactor and does not change any functionality.
We already cache failed onebox URL requests client-side, we now want to cache this on the server-side for extra protection. failed onebox previews will be cached for 1 hour, and any more requests for that URL will fail with a 404 status. Forcing a rebake via the Rebake HTML action will delete the failed URL cache (like how the oneboxer preview cache is deleted).
When uploading a file to a theme component, and that file is existing and has already been marked as secure, we now automatically mark the file as secure: false, change the ACL, and log the action as the user (also rebake the posts for the upload)
If a user has more than 60 active sessions, the oldest sessions will be terminated automatically. This protects performance when logging in and when loading the list of recently used devices.
This affects login_required sites which use SSO or have only one authenticator enabled. Previously, logging out would redirect to the homepage, which would then redirect to the identity provider. Now, users will be redirected to the Discourse login page. This avoids the confusing situation where a user appears to remain logged in after clicking logout.
Sites which have explicitly defined a logout_redirect url are not affected by this change.
For context, see https://meta.discourse.org/t/134138/2
This is a bottom up rewrite of Discourse cache to support faster performance
and a limited surface area.
ActiveSupport::Cache::Store accepts many options we do not use, this partial
implementation only picks the bits out that we do use and want to support.
Additionally params are named which avoids typos such as "expires_at" vs "expires_in"
This also moves a few spots in Discourse to use Discourse.cache over setex
Performance of setex and Discourse.cache.write is similar.
Discourse.cache is a more consistent method to use and offers clean fallback
if you are skipping redis
This is part of a larger change that both optimizes Discoruse.cache and omits
use of setex on $redis in favor of consistently using discourse cache
Bench does reveal that use of Rails.cache and Discourse.cache is 1.25x slower
than redis.setex / get so a re-implementation will follow prior to porting
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
This is another refactoring in the multi-step process to remove all uses
of our custom Render Buffer.
Previous commit: e0199e8094 in this
series.
This commit affects the table header sorting on the user directory page.
It is just a refactor and should not change any functionality.
* UX: adds hover effect on lightboxed images
This commits also adds two scss functions:
- is-light-color-scheme()
- is-dark-color-scheme()
This hover effect won't be added on dark color schemes, as images already standout nicely on dark backgrounds.
Co-Authored-By: David Taylor <david@taylorhq.com>
This commit corresponds to d84c34ad which applies the same changes to
the server-side. This changes the category routes, except for the routes
that contain tags.
This amends our API so we provide it with the draft key when saving a post
this means post creator can clean up the draft consistently even if we are
doing fancy stuff like replying to a new topic or new pm or whatever.
There will be some followup work to clean it up so client never calls destroy
on draft during normal operation and the #create/#update endpoints takes care of it
every time
This is another refactoring in the multi-step process to remove all uses
of our custom Render Buffer.
Previous commit: d0ad5ecc6d in this
series.
This commit affects the table header sorting on the admin directory page.
It is just a refactor and should not change any functionality.
If current value is nil we should use `&.` combined with `dig` to protect diff from erroring
It is happening when for example theme is delete (new value is empty)
* DEV: Remove buffered rendering from group-index-toggle
This is the first step in a refactor to remove all uses of our Buffered
Renderer:
01e2d5a670/app/assets/javascripts/discourse-common/lib/buffered-render.js.es6 (L3)
This commit affects the header sorting on the group member and the group
requests pages. It is a refactor only with no change in functionality.
When we receive a list of categories, we should store them so that we
are able to query them in the browser without a page refresh.
This removes a previous fix for the same issue that was much less
general.
This commit attempts to fix two issues that affect quoted images.
The first issue is observed while loading. The 'position: absolute' CSS
property makes 'width' and 'height' behave differently. Instead of using
the known image size, this makes it use the computed width and height of
the image, which should be the right size, as shown to the user.
The second issue is caused by 'object-fit: cover' property which trimmed
the left and right sides of wide pictures to make them fit inside the
quote.
* instead of using encodeURIComponent in imageNameFromFileName,
we just replace the bad characters that we wanted to get rid
of in the first place where we introduced encodeURIComponent.
as per review
Meta: https://meta.discourse.org/t/image-name-has-20-in-file-name/134136
We were ending up with [file%20name](url) in the markdown preview, which looked weird and
affected the alt text. this is because we were calling encodeURIComponent, which has been left in place because this is a valid thing to do for some cases. (e.g. f674b9e)
* Add timezone to user_options table
* Also migrate existing timezone values from UserCustomField,
which is where the discourse-calendar plugin is storing them
* Allow user to change their core timezone from Profile
* Auto guess & set timezone on login & invite accept & signup
* Serialize user_options.timezone for group members. this is so discourse-group-timezones can access the core user timezone, as it is being removed in discourse-calendar.
* Annotate user_option with timezone
* Validate timezone values
When category is dismissed, `dismiss_new` message is sent to fronted to clean state.
In addition, I noticed that when old dismiss new button is clicked, no message is sent so I decided to kill two birds with one stone.
In non-login-required sites, we prevent secure uploads already used in PMs from being used in public topics.
In login_required sites, secure uploads should be reusable in any topic, PM or not.
The plan is to switch over all cases where filterMode is set, but, to
prevent breaking plugins and themes, the category and noSubcategories
need to be inferred from any given filterMode before that can happen.
- Show old and new email address during the process
- Ensure correct user is logged on when attempting to make email changes
- Support reloading a page during the email reset process without resubmit
of form
- Improve tests
- Fixed issue where redirect back to site was not linking correctly in
subfolder setups
Internal refactor of single action into 4 distinct actions that are simpler
to reason about.
This also removes the step that logs on an account after you confirm an
email change, since it is no longer needed which leaves us with safer
internals.
This left me no choice but to amend translations cause the old route was
removed.
* FEATURE: Normalize the service worker route
Update cache headers so they are not immutable outside of the rails app
Add the ability to purge the service worker cache from localhost
Rails -> nginx will pass immutable flags so the file is cached until reloaded.
In most cases, nginx will have its cache flushed on rebuild (new image)
For those needing dynamic re-caching (such as upgrading via the UI),
a rake task for flushing the service worker script is provided
through `assets:flush_sw`
The secure media functionality relied on `SiteSetting.enable_s3_uploads?` which, as we found in dev, did not take into account global S3 settings via `GlobalSetting.use_s3?`. We now use `SiteSetting.Upload.enable_s3_uploads` instead to be more consistent.
Also, we now validate `enable_s3_uploads` changes, because if `GlobalSetting.use_s3?` is true users should NOT be enabling S3 uploads manually.
If a post starts with a post quote and has no other text content,
then the email excerpt was the name of the person quoted and
nothing else. The intention was to show the contents of the
first paragraph or div after the quote.
With this change, a quote followed by an image will use the
image as the excerpt. A quote followed by a onebox will use the
onebox.
- Avoid using User#find and then fetching the user_stat association just to update a counter - We did this for every post in the topic.
- Avoid having to query the topic_allowed_user table everytime we want add a new topic_allowed_user
- Use pluck to fetch just what we need.
The group card and group members page were affecting each other and were
leaking members list and the query parameters which led to bad UX
experience and sub-optimal performance (client made more queries because
it was loading fewer members).
This commit refactors the group model to make it more consistent, remove
dead code, move error handling outside of model.
isPrivateMessages represents that the tag list is shown in the context
of private messages and pmOnly represents that the tag is used only in
private messages.
This PR introduces a new secure media setting. When enabled, it prevent unathorized access to media uploads (files of type image, video and audio). When the `login_required` setting is enabled, then all media uploads will be protected from unauthorized (anonymous) access. When `login_required`is disabled, only media in private messages will be protected from unauthorized access.
A few notes:
- the `prevent_anons_from_downloading_files` setting no longer applies to audio and video uploads
- the `secure_media` setting can only be enabled if S3 uploads are already enabled and configured
- upload records have a new column, `secure`, which is a boolean `true/false` of the upload's secure status
- when creating a public post with an upload that has already been uploaded and is marked as secure, the post creator will raise an error
- when enabling or disabling the setting on a site with existing uploads, the rake task `uploads:ensure_correct_acl` should be used to update all uploads' secure status and their ACL on S3
This is a fix for this bug:
https://meta.discourse.org/t/-/133185?u=blake
where rails would throw a missing template error when trying to confirm
a new email address when you had two factor backup codes enabled.
Apparently this feature broke during this commit:
68d35b14f4
when a partial that contained a lot of javascript was removed most
likely because it didn't comply with our Content Security Policy, so as
a fix I rewrote the previous js functionality without using any
javascript and then added a spec to verify that the correct backup code
form is displayed when that page is loaded.
Disables jumping to bottom of the page (added in 87f0b56) for mobile devices.
Fixes a regression with the mobile jump tool, and avoids users having to scroll up lots on mobile, since suggested topics and site footers can be lengthy.
* When viewing a tag, the search widget will now show a checkbox to scope the search by tag, which will limit search results to that tag on desktop and mobile
This brings the behavior in line with native Discourse SSO. If login is required, and a user tries to visit the forum, they will be directed straight to the external login page without requiring any clicks.
According to eviltrout, commas and pipes were the delimiters of a
Discourse specific microformat, but this is no longer the case and
hasn't been for some time.
Code should decide when to do something with the event value, and maybe cause a re-rerender but it shouldn't be automatic. This is currently a gigantic waste of resources.
This method had grown into a monster. Its query had bugs
that I couldn't fix, and new features would be hard to add.
Also I don't understand how it all works anymore...
Replace it with common table expressions that can be queried
to generate the results we need, instead of subtracting
results using lots of "NOT IN" clauses.
Fixed are bugs with tag schemas that use combinations of
tag groups, parent tags, and one-tag-per-topic restrictions.
For example: https://meta.discourse.org/t/130991/6
If there is any other whitespace in the container, then Firefox will add a leading/trailing space when double clicking the key. This commit wraps the key in a div with no whitespace, to work around the problem.
* 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
I made a regression here 17366d3bcc (diff-ddeebb36d131f89ca91be9d04c2baefaR10)
When the tag is added, people watching specific tag are notified but also people watching specific category.
Therefore, `notify_post_users` should accept options who should be notified.
So when `category` is added to the topic, users watching topic and users watching category are notified.
When `tag` is added to the topic, users watching topic and users watching tag are notified
Finally, when a new post is created, everybody is notified, topic watchers, category watchers, tag watchers.
Previous versions of the mail-receiver used query based api credentials,
if we detect this we will show a message in the admin panel to update
the mail receiver.
* Fix user title logic when badge name customized
* Fix an issue where a user's title was not considered a badge granted title when the user used a badge for their title and the badge name was customized. this affected the effectiveness of revoke_ungranted_titles! which only operates on badge_granted_titles.
* When a user's title is set now it is considered a badge_granted_title if the badge name OR the badge custom name from TranslationOverride is the same as the title
* When a user's badge is revoked we now also revoke their title if the user's title matches the badge name OR the badge custom name from TranslationOverride
* Add a user history log when the title is revoked to remove confusion about why titles are revoked
* Add granted_title_badge_id to user_profile, now when we set badge_granted_title on a user profile when updating a user's title based on a badge, we also remember which badge matched the title
* When badge name (or custom text) changes update titles of users in a background job
* When the name of a badge changes, or in the case of system badges when their custom translation text changes, then we need to update the title of all corresponding users who have a badge_granted_title and matching granted_title_badge_id. In the case of system badges we need to first get the proper badge ID based on the translation key e.g. badges.regular.name
* Add migration to backfill all granted_title_badge_ids for both normal badge name titles and titles using custom badge text.
* If a staff user created only a security key as their single 2FA option. they continued to be prompted to create a 2FA option because we only considered this condition satisfied if a TOTP was added.
* The condition is now satisfied if TOTP OR security keys are enabled.
Instead of enabling `suppress_from_latest` setting on many categories now we can enable `mute_all_categories_by_default` site setting. Then users should opt-in to categories for them to appear in the latest and categories pages.
Previously our index was non unique, causing situations where a user could
have multiple drafts stored in the table for the same exact entity.
This does not properly reflect reality and needed to change as in certain
cases duplicate drafts could be created causing internal data inconsistency
This change adds a message to the admin panel if it detects an api
requests that doesn't use the new header based authentication method.
The message is to warn people to switch to header based auth and links
to the api documention topic on meta for more info.