thredded 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +16 -16
- data/app/commands/thredded/create_messageboard.rb +2 -2
- data/app/forms/thredded/private_topic_form.rb +1 -1
- data/app/helpers/thredded/application_helper.rb +2 -2
- data/app/mailer_previews/thredded/base_mailer_preview.rb +5 -5
- data/app/models/concerns/thredded/friendly_id_reserved_words_and_pagination.rb +1 -1
- data/app/models/concerns/thredded/notifier_preference.rb +1 -1
- data/app/models/concerns/thredded/post_common.rb +3 -3
- data/app/models/thredded/post_moderation_record.rb +4 -4
- data/app/views/thredded/moderation/_post_moderation_record.html.erb +3 -3
- data/app/views/thredded/shared/nav/_standalone.html.erb +2 -2
- data/bin/rubocop +29 -0
- data/config/i18n-tasks.yml +1 -1
- data/db/upgrade_migrations/20161019150201_upgrade_v0_7_to_v0_8.rb +5 -5
- data/lib/generators/thredded/install/templates/initializer.rb +1 -1
- data/lib/thredded/arel_compat.rb +1 -1
- data/lib/thredded/base_migration.rb +1 -1
- data/lib/thredded/content_formatter.rb +30 -8
- data/lib/thredded/db_tools.rb +1 -1
- data/lib/thredded/engine.rb +1 -1
- data/lib/thredded/formatting_demo_content.rb +21 -21
- data/lib/thredded/html_pipeline/at_mention_filter.rb +1 -1
- data/lib/thredded/html_pipeline/onebox_filter.rb +3 -3
- data/lib/thredded/html_pipeline/utils.rb +1 -1
- data/lib/thredded/version.rb +1 -1
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c38b0b431b19a2a3bcb74955be64a67835d60870754e65436e8498ca67729bc8
|
4
|
+
data.tar.gz: 1b9827d5ed79af58f52c86e5badb430e1b44dfaff0381fde2390ad08ce436b26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43a2362878a9949d88097d77efe90c7997483e1c70f0fb505ffff1fa06e2097036d6ae6aff829120a406bac06b9e1cbb0879c1b614cf0c8205f837044a6fb105
|
7
|
+
data.tar.gz: 6f59d7de62c088da6ef53bb474ab02bdc666313ff5e050f86c3a1414a7371d93d60874008dc2ce68b8df8a7601754fe9771fef1804e11e1a4060620968465917
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
# Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=
|
1
|
+
# Thredded [![Code Climate](https://codeclimate.com/github/thredded/thredded/badges/gpa.svg)](https://codeclimate.com/github/thredded/thredded) [![Travis-CI](https://api.travis-ci.org/thredded/thredded.svg?branch=main)](https://travis-ci.org/thredded/thredded/) [![Test Coverage](https://codeclimate.com/github/thredded/thredded/badges/coverage.svg)](https://codeclimate.com/github/thredded/thredded/coverage) [![Inline docs](http://inch-ci.org/github/thredded/thredded.svg?branch=main)](http://inch-ci.org/github/thredded/thredded) [![Gitter](https://badges.gitter.im/thredded/thredded.svg)](https://gitter.im/thredded/thredded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
|
2
2
|
|
3
|
-
_Thredded_ is a Rails
|
3
|
+
_Thredded_ is a Rails 5.2+ forum/messageboard engine. Its goal is to be as simple and feature rich as possible.
|
4
4
|
|
5
5
|
Some of the features currently in Thredded:
|
6
6
|
|
@@ -352,7 +352,7 @@ with a "themed" version of thredded.
|
|
352
352
|
#### Styles
|
353
353
|
|
354
354
|
Thredded comes with a light Sass theme controlled by a handful of variables that can be found here:
|
355
|
-
https://github.com/thredded/thredded/blob/
|
355
|
+
https://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/base/_variables.scss.
|
356
356
|
|
357
357
|
To override the styles, override the variables *before* importing Thredded styles, e.g.:
|
358
358
|
|
@@ -366,8 +366,8 @@ If you are writing a Thredded plugin, import the [`thredded/base`][thredded-scss
|
|
366
366
|
The `base` package only defines variables, mixins, and %-placeholders, so it can be imported safely without producing
|
367
367
|
any duplicate CSS.
|
368
368
|
|
369
|
-
[thredded-scss-dependencies]: https://github.com/thredded/thredded/blob/
|
370
|
-
[thredded-scss-base]: https://github.com/thredded/thredded/blob/
|
369
|
+
[thredded-scss-dependencies]: https://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/_dependencies.scss
|
370
|
+
[thredded-scss-base]: https://github.com/thredded/thredded/blob/main/app/assets/stylesheets/thredded/_base.scss
|
371
371
|
|
372
372
|
### Email and other notifications
|
373
373
|
|
@@ -513,35 +513,35 @@ Below is an overview of the default permissions, with links to the implementatio
|
|
513
513
|
<tbody>
|
514
514
|
<tr>
|
515
515
|
<th align="center">Logged in</th>
|
516
|
-
<td align="center" rowspan="2"><a href="https://github.com/thredded/thredded/blob/
|
516
|
+
<td align="center" rowspan="2"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/read/all.rb">
|
517
517
|
✅ All
|
518
518
|
</a></td>
|
519
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
519
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/write/all.rb">
|
520
520
|
✅ All
|
521
521
|
</a></td>
|
522
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
522
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb">
|
523
523
|
Readers of the messageboards<br>the user can post in
|
524
524
|
</a></td>
|
525
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
525
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/moderate/if_moderator_column_true.rb">
|
526
526
|
<code>moderator_column</code>
|
527
527
|
</a></td>
|
528
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
528
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/admin/if_admin_column_true.rb">
|
529
529
|
<code>admin_column</code>
|
530
530
|
</a></td>
|
531
531
|
</tr>
|
532
532
|
<tr>
|
533
533
|
<th align="center">Not logged in</th>
|
534
534
|
<!-- rowspan -->
|
535
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
535
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/write/none.rb">
|
536
536
|
❌ No
|
537
537
|
</a></td>
|
538
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
538
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/message/readers_of_writeable_boards.rb">
|
539
539
|
❌ No
|
540
540
|
</a></td>
|
541
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
541
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/moderate/none.rb">
|
542
542
|
❌ No
|
543
543
|
</a></td>
|
544
|
-
<td align="center"><a href="https://github.com/thredded/thredded/blob/
|
544
|
+
<td align="center"><a href="https://github.com/thredded/thredded/blob/main/app/models/thredded/user_permissions/admin/none.rb">
|
545
545
|
❌ No
|
546
546
|
</a></td>
|
547
547
|
</tr>
|
@@ -551,7 +551,7 @@ Below is an overview of the default permissions, with links to the implementatio
|
|
551
551
|
### Handling "Permission denied" and "Not found" errors
|
552
552
|
|
553
553
|
Thredded defines a number of Exception classes for not found / permission denied errors.
|
554
|
-
The complete list can be found [here](https://github.com/thredded/thredded/blob/
|
554
|
+
The complete list can be found [here](https://github.com/thredded/thredded/blob/main/app/controllers/thredded/application_controller.rb#L18-L40).
|
555
555
|
|
556
556
|
Currently, the default behaviour is to render an error message with an appropriate response code within the Thredded
|
557
557
|
layout. You may want to override the handling for `Thredded::Errors::LoginRequired` to render a login form instead.
|
@@ -809,4 +809,4 @@ docker-compose run web bundle exec rake
|
|
809
809
|
|
810
810
|
The docker container uses PostgreSQL.
|
811
811
|
|
812
|
-
[initializer]: https://github.com/thredded/thredded/blob/
|
812
|
+
[initializer]: https://github.com/thredded/thredded/blob/main/lib/generators/thredded/install/templates/initializer.rb
|
@@ -34,8 +34,8 @@ module Thredded
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def first_topic_content
|
37
|
-
|
38
|
-
#{I18n.t('thredded.messageboard_first_topic.content', thredded_version: Thredded::VERSION)}
|
37
|
+
<<~MARKDOWN
|
38
|
+
#{I18n.t('thredded.messageboard_first_topic.content', thredded_version: Thredded::VERSION)}
|
39
39
|
MARKDOWN
|
40
40
|
end
|
41
41
|
end
|
@@ -130,7 +130,7 @@ module Thredded
|
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
133
|
-
def parse_names(text) # rubocop:disable Metrics/
|
133
|
+
def parse_names(text) # rubocop:disable Metrics/MethodLength
|
134
134
|
result = []
|
135
135
|
current = +''
|
136
136
|
in_name = in_quoted = false
|
@@ -108,9 +108,9 @@ module Thredded
|
|
108
108
|
# @param follow_reason ['manual', 'posted', 'mentioned', 'auto', nil]
|
109
109
|
def topic_follow_reason_text(follow_reason)
|
110
110
|
if follow_reason
|
111
|
-
# rubocop:disable
|
111
|
+
# rubocop:disable Layout/LineLength
|
112
112
|
# i18n-tasks-use t('thredded.topics.following.manual') t('thredded.topics.following.posted') t('thredded.topics.following.mentioned') t('thredded.topics.following.auto')
|
113
|
-
# rubocop:enable
|
113
|
+
# rubocop:enable Layout/LineLength
|
114
114
|
t("thredded.topics.following.#{follow_reason}")
|
115
115
|
else
|
116
116
|
t('thredded.topics.not_following')
|
@@ -11,13 +11,13 @@ module Thredded
|
|
11
11
|
protected
|
12
12
|
|
13
13
|
def mock_content(mention_users: [])
|
14
|
-
|
15
|
-
Hey #{mention_users.map { |u| "@#{u}" } * ', '}!
|
16
|
-
All of the basic [Markdown](https://kramdown.gettalong.org/quickref.html) formatting is supported (powered by [Kramdown](https://kramdown.gettalong.org)).
|
14
|
+
<<~MARKDOWN
|
15
|
+
Hey #{mention_users.map { |u| "@#{u}" } * ', '}!
|
16
|
+
All of the basic [Markdown](https://kramdown.gettalong.org/quickref.html) formatting is supported (powered by [Kramdown](https://kramdown.gettalong.org)).
|
17
17
|
|
18
|
-
Additionally, Markdown is extended to support the following:
|
18
|
+
Additionally, Markdown is extended to support the following:
|
19
19
|
|
20
|
-
#{Thredded::FormattingDemoContent.parts.join("\n")}
|
20
|
+
#{Thredded::FormattingDemoContent.parts.join("\n")}
|
21
21
|
MARKDOWN
|
22
22
|
end
|
23
23
|
|
@@ -8,7 +8,7 @@ module Thredded
|
|
8
8
|
delegate :human_name, to: :notifier, prefix: true
|
9
9
|
|
10
10
|
def self.detect_or_default(prefs, notifier)
|
11
|
-
(prefs
|
11
|
+
(prefs&.find { |pref| pref.notifier_key == notifier.key }) || default(notifier)
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
@@ -26,8 +26,8 @@ module Thredded
|
|
26
26
|
preloader = Thredded::Compat.association_preloader(
|
27
27
|
records: owners_by_id.values, associations: [:first_post],
|
28
28
|
scope: unscoped.where(<<~SQL.delete("\n"))
|
29
|
-
|
30
|
-
|
29
|
+
#{posts_table_name}.created_at = (
|
30
|
+
SELECT MAX(p2.created_at) from #{posts_table_name} p2 WHERE p2.postable_id = #{posts_table_name}.postable_id)
|
31
31
|
SQL
|
32
32
|
)
|
33
33
|
preloader[0].preloaded_records.each do |post|
|
@@ -68,7 +68,7 @@ module Thredded
|
|
68
68
|
def mark_as_unread(user)
|
69
69
|
if previous_post.nil?
|
70
70
|
read_state = postable.user_read_states.find_by(user_id: user.id)
|
71
|
-
read_state
|
71
|
+
read_state&.destroy
|
72
72
|
else
|
73
73
|
postable.user_read_states.touch!(user.id, previous_post, overwrite_newer: true)
|
74
74
|
end
|
@@ -33,12 +33,12 @@ module Thredded
|
|
33
33
|
h[r.post.postable_id] = r.post.postable if r.post
|
34
34
|
end
|
35
35
|
next result if owners_by_id.empty?
|
36
|
-
preloader =
|
37
|
-
owners_by_id.values, :first_post,
|
38
|
-
Thredded::Post.unscoped.where(<<~SQL.delete("\n"))
|
36
|
+
preloader = Thredded::Compat.association_preloader(
|
37
|
+
records: owners_by_id.values, associations: [:first_post],
|
38
|
+
scope: Thredded::Post.unscoped.where(<<~SQL.delete("\n"))
|
39
39
|
#{posts_table_name}.created_at = (
|
40
40
|
SELECT MAX(p2.created_at) from #{posts_table_name} p2 WHERE p2.postable_id = #{posts_table_name}.postable_id)
|
41
|
-
|
41
|
+
SQL
|
42
42
|
)
|
43
43
|
preloader[0].preloaded_records.each do |post|
|
44
44
|
topic = owners_by_id.delete(post.postable_id)
|
@@ -13,13 +13,13 @@
|
|
13
13
|
time_ago: time_ago(record.created_at)
|
14
14
|
}
|
15
15
|
%>
|
16
|
-
<article class="thredded--post-moderation-record thredded--post-moderation-record-<%= record.moderation_state %>">
|
16
|
+
<article id="<%= dom_id(post) %>" class="thredded--post-moderation-record thredded--post-moderation-record-<%= record.moderation_state %>">
|
17
17
|
<header class="thredded--post-moderation-record--header">
|
18
18
|
<p class="thredded--post-moderation-record--moderation-state-notice">
|
19
19
|
<% if record.approved? %>
|
20
|
-
<%= t('thredded.moderation.post_approved_html', moderation_state_notice_args) %>
|
20
|
+
<%= t('thredded.moderation.post_approved_html', **moderation_state_notice_args) %>
|
21
21
|
<% elsif record.blocked? %>
|
22
|
-
<%= t('thredded.moderation.post_blocked_html', moderation_state_notice_args) %>
|
22
|
+
<%= t('thredded.moderation.post_blocked_html', **moderation_state_notice_args) %>
|
23
23
|
<% end %>
|
24
24
|
</p>
|
25
25
|
<% if post && post.content != record.post_content %>
|
@@ -2,11 +2,11 @@
|
|
2
2
|
<% resource_name = Thredded.user_class_name.demodulize.underscore %>
|
3
3
|
<% if thredded_signed_in? %>
|
4
4
|
<%= link_to main_app.send(:"destroy_#{resource_name}_session_path"), method: :delete do %>
|
5
|
-
t('thredded.nav.sign_out')
|
5
|
+
<%= t('thredded.nav.sign_out') %>
|
6
6
|
<% end %>
|
7
7
|
<% else %>
|
8
8
|
<%= link_to main_app.send(:"new_#{resource_name}_session_path") do %>
|
9
|
-
t('thredded.nav.sign_in')
|
9
|
+
<%= t('thredded.nav.sign_in') %>
|
10
10
|
<% end %>
|
11
11
|
<% end %>
|
12
12
|
</li>
|
data/bin/rubocop
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
#
|
5
|
+
# This file was generated by Bundler.
|
6
|
+
#
|
7
|
+
# The application 'rubocop' is installed as part of a gem, and
|
8
|
+
# this file is here to facilitate running it.
|
9
|
+
#
|
10
|
+
|
11
|
+
require 'pathname'
|
12
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile',
|
13
|
+
Pathname.new(__FILE__).realpath)
|
14
|
+
|
15
|
+
bundle_binstub = File.expand_path('bundle', __dir__)
|
16
|
+
|
17
|
+
if File.file?(bundle_binstub)
|
18
|
+
if /This file was generated by Bundler/.match?(File.read(bundle_binstub, 300))
|
19
|
+
load(bundle_binstub)
|
20
|
+
else
|
21
|
+
abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run.
|
22
|
+
Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.")
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
require 'rubygems'
|
27
|
+
require 'bundler/setup'
|
28
|
+
|
29
|
+
load Gem.bin_path('rubocop', 'rubocop')
|
data/config/i18n-tasks.yml
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# i18n-tasks finds and manages missing and unused translations
|
2
|
-
# See https://github.com/glebm/i18n-tasks/blob/
|
2
|
+
# See https://github.com/glebm/i18n-tasks/blob/main/templates/config/i18n-tasks.yml
|
3
3
|
|
4
4
|
# Do not consider these keys missing:
|
5
5
|
ignore_missing:
|
@@ -6,11 +6,11 @@ class UpgradeV07ToV08 < Thredded::BaseMigration
|
|
6
6
|
def up
|
7
7
|
closed_messageboards = Thredded::Messageboard.unscoped.where(closed: true).to_a
|
8
8
|
if closed_messageboards.present?
|
9
|
-
fail ActiveRecord::MigrationError,
|
10
|
-
There are #{closed_messageboards.length} closed Messageboards:
|
11
|
-
#{closed_messageboards.map { |m| "#{m.name} (id=#{m.id})" }.join("\n")}
|
12
|
-
Support for closed messageboards has been removed in thredded v0.8.0.
|
13
|
-
Delete or un-close these messageboards and consider using the "paranoia" gem to support soft deletion instead.
|
9
|
+
fail ActiveRecord::MigrationError, <<~TEXT
|
10
|
+
There are #{closed_messageboards.length} closed Messageboards:
|
11
|
+
#{closed_messageboards.map { |m| "#{m.name} (id=#{m.id})" }.join("\n")}
|
12
|
+
Support for closed messageboards has been removed in thredded v0.8.0.
|
13
|
+
Delete or un-close these messageboards and consider using the "paranoia" gem to support soft deletion instead.
|
14
14
|
TEXT
|
15
15
|
end
|
16
16
|
remove_index :thredded_messageboards, name: :index_thredded_messageboards_on_closed
|
@@ -124,7 +124,7 @@ Thredded.layout = 'thredded/application'
|
|
124
124
|
# Change the HTML sanitization settings used by Thredded.
|
125
125
|
# See the Sanitize docs for more information on the underlying library: https://github.com/rgrove/sanitize/#readme
|
126
126
|
# E.g. to allow a custom element <custom-element>:
|
127
|
-
# Thredded::ContentFormatter.
|
127
|
+
# Thredded::ContentFormatter.allowlist[:elements] += %w(custom-element)
|
128
128
|
|
129
129
|
# ==> User autocompletion (Private messages and @-mentions)
|
130
130
|
# Thredded.autocomplete_min_length = 2 lower to 1 if have 1-letter names -- increase if you want
|
data/lib/thredded/arel_compat.rb
CHANGED
@@ -9,7 +9,7 @@ module Thredded
|
|
9
9
|
# @param [Arel::Nodes::Node] b integer node
|
10
10
|
# @return [Arel::Nodes::Node] a / b
|
11
11
|
def integer_division(engine, a, b)
|
12
|
-
if
|
12
|
+
if /mysql|mariadb/i.match?(engine.connection.adapter_name)
|
13
13
|
Arel::Nodes::InfixOperation.new('DIV', a, b)
|
14
14
|
else
|
15
15
|
Arel::Nodes::Division.new(a, b)
|
@@ -15,7 +15,7 @@ module Thredded
|
|
15
15
|
|
16
16
|
# @return [Integer, nil] the maximum number of codepoints that can be indexed for a primary key or index.
|
17
17
|
def max_key_length
|
18
|
-
return nil unless
|
18
|
+
return nil unless /mysql|maria/i.match?(connection.adapter_name)
|
19
19
|
# Conservatively assume that innodb_large_prefix is **disabled**.
|
20
20
|
# If it were enabled, the maximum key length would instead be 768 utf8mb4 characters.
|
21
21
|
191
|
@@ -4,8 +4,11 @@ module Thredded
|
|
4
4
|
# Generates HTML from content source.
|
5
5
|
class ContentFormatter
|
6
6
|
class << self
|
7
|
-
# Sanitization
|
8
|
-
attr_accessor :
|
7
|
+
# Sanitization allowlist options.
|
8
|
+
attr_accessor :allowlist
|
9
|
+
|
10
|
+
# TODO: v2.0: drop alias and just use allowlist
|
11
|
+
alias_attribute :whitelist, :allowlist
|
9
12
|
|
10
13
|
# Filters that run before processing the markup.
|
11
14
|
# input: markup, output: markup.
|
@@ -26,16 +29,29 @@ module Thredded
|
|
26
29
|
# Filters that run after sanitization
|
27
30
|
# input: sanitized html, output: html
|
28
31
|
attr_accessor :after_sanitization_filters
|
32
|
+
|
33
|
+
# TODO: v1.1: only allow html-pipeline >= 2.14.1 and drop this
|
34
|
+
def sanitization_filter_uses_allowlist?
|
35
|
+
defined?(HTML::Pipeline::SanitizationFilter::ALLOWLIST)
|
36
|
+
end
|
37
|
+
|
38
|
+
def sanitization_filter_allowlist_config
|
39
|
+
if sanitization_filter_uses_allowlist?
|
40
|
+
HTML::Pipeline::SanitizationFilter::ALLOWLIST
|
41
|
+
else
|
42
|
+
HTML::Pipeline::SanitizationFilter::WHITELIST
|
43
|
+
end
|
44
|
+
end
|
29
45
|
end
|
30
46
|
|
31
|
-
self.
|
32
|
-
elements:
|
33
|
-
transformers:
|
47
|
+
self.allowlist = sanitization_filter_allowlist_config.deep_merge(
|
48
|
+
elements: sanitization_filter_allowlist_config[:elements] + %w[abbr iframe span figure figcaption],
|
49
|
+
transformers: sanitization_filter_allowlist_config[:transformers] + [
|
34
50
|
->(env) {
|
35
51
|
next unless env[:node_name] == 'a'
|
36
52
|
a_tag = env[:node]
|
37
53
|
a_tag['href'] ||= '#'
|
38
|
-
if
|
54
|
+
if %r{^(?:[a-z]+:)?//}.match?(a_tag['href'])
|
39
55
|
a_tag['target'] = '_blank'
|
40
56
|
a_tag['rel'] = 'nofollow noopener'
|
41
57
|
end
|
@@ -49,7 +65,7 @@ module Thredded
|
|
49
65
|
'img' => %w[src longdesc class],
|
50
66
|
'th' => %w[style],
|
51
67
|
'td' => %w[style],
|
52
|
-
:all =>
|
68
|
+
:all => sanitization_filter_allowlist_config[:attributes][:all] +
|
53
69
|
%w[aria-expanded aria-label aria-labelledby aria-live aria-hidden aria-pressed role],
|
54
70
|
},
|
55
71
|
css: {
|
@@ -134,9 +150,15 @@ module Thredded
|
|
134
150
|
|
135
151
|
# @return [Hash] options for HTML::Pipeline.new
|
136
152
|
def content_pipeline_options
|
153
|
+
option = if self.class.sanitization_filter_uses_allowlist?
|
154
|
+
:allowlist
|
155
|
+
else
|
156
|
+
# TODO: v1.1: only allow html-pipeline >= 2.14.1 and drop this
|
157
|
+
:whitelist
|
158
|
+
end
|
137
159
|
{
|
138
160
|
asset_root: Rails.application.config.action_controller.asset_host || '',
|
139
|
-
|
161
|
+
option => ContentFormatter.allowlist
|
140
162
|
}
|
141
163
|
end
|
142
164
|
end
|
data/lib/thredded/db_tools.rb
CHANGED
@@ -59,7 +59,7 @@ module Thredded
|
|
59
59
|
silence_active_record do
|
60
60
|
ActiveRecord::Base.transaction do
|
61
61
|
statements.each do |statement|
|
62
|
-
connection.execute(statement) unless
|
62
|
+
connection.execute(statement) unless /(BEGIN TRANSACTION|COMMIT)/.match?(statement)
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
data/lib/thredded/engine.rb
CHANGED
@@ -12,7 +12,7 @@ module Thredded
|
|
12
12
|
|
13
13
|
config.to_prepare do
|
14
14
|
Thredded::AllViewHooks.reset_instance!
|
15
|
-
Thredded.user_class
|
15
|
+
Thredded.user_class&.send(:include, Thredded::UserExtender)
|
16
16
|
end
|
17
17
|
|
18
18
|
initializer 'thredded.setup_assets' do
|
@@ -7,35 +7,35 @@ module Thredded
|
|
7
7
|
attr_accessor :parts
|
8
8
|
end
|
9
9
|
self.parts = [
|
10
|
-
|
11
|
-
#### Spoilers
|
10
|
+
<<~'MARKDOWN',
|
11
|
+
#### Spoilers
|
12
12
|
|
13
|
-
Use `<spoiler></spoiler>` tags to create spoiler boxes like this one:
|
13
|
+
Use `<spoiler></spoiler>` tags to create spoiler boxes like this one:
|
14
14
|
|
15
|
-
<spoiler>
|
16
|
-
Harry Potter books are better than the movies.
|
15
|
+
<spoiler>
|
16
|
+
Harry Potter books are better than the movies.
|
17
17
|
|
18
|
-
![nyancat](https://storage.googleapis.com/glebm-stuff/nyancat.gif)
|
18
|
+
![nyancat](https://storage.googleapis.com/glebm-stuff/nyancat.gif)
|
19
19
|
|
20
|
-
https://www.youtube.com/watch?v=5lBBUPVuusM
|
21
|
-
</spoiler>
|
20
|
+
https://www.youtube.com/watch?v=5lBBUPVuusM
|
21
|
+
</spoiler>
|
22
22
|
|
23
|
-
#### Oneboxes
|
23
|
+
#### Oneboxes
|
24
24
|
|
25
|
-
URLs of supported resources are replaced with boxes like these:
|
25
|
+
URLs of supported resources are replaced with boxes like these:
|
26
26
|
|
27
|
-
**Twitter** `https://twitter.com/thredded/status/838824533477982209`:
|
28
|
-
https://twitter.com/thredded/status/838824533477982209
|
29
|
-
**StackExchange** `http://codegolf.stackexchange.com/questions/45701`:
|
30
|
-
http://codegolf.stackexchange.com/questions/45701
|
31
|
-
**Amazon** `https://www.amazon.co.uk/dp/0521797071`:
|
32
|
-
https://www.amazon.co.uk/dp/0521797071
|
33
|
-
**YouTube** `https://www.youtube.com/watch?v=1QP7elXwpLw`:
|
34
|
-
https://www.youtube.com/watch?v=1QP7elXwpLw
|
35
|
-
**Google Maps** `https://goo.gl/maps/R6nj3Qwf2LR2`:
|
36
|
-
https://goo.gl/maps/R6nj3Qwf2LR2
|
27
|
+
**Twitter** `https://twitter.com/thredded/status/838824533477982209`:
|
28
|
+
https://twitter.com/thredded/status/838824533477982209
|
29
|
+
**StackExchange** `http://codegolf.stackexchange.com/questions/45701`:
|
30
|
+
http://codegolf.stackexchange.com/questions/45701
|
31
|
+
**Amazon** `https://www.amazon.co.uk/dp/0521797071`:
|
32
|
+
https://www.amazon.co.uk/dp/0521797071
|
33
|
+
**YouTube** `https://www.youtube.com/watch?v=1QP7elXwpLw`:
|
34
|
+
https://www.youtube.com/watch?v=1QP7elXwpLw
|
35
|
+
**Google Maps** `https://goo.gl/maps/R6nj3Qwf2LR2`:
|
36
|
+
https://goo.gl/maps/R6nj3Qwf2LR2
|
37
37
|
|
38
|
-
Many more resources are [supported](https://github.com/discourse/onebox/tree/
|
38
|
+
Many more resources are [supported](https://github.com/discourse/onebox/tree/main/lib/onebox/engine). Powered by the [onebox](https://github.com/discourse/onebox) library.
|
39
39
|
MARKDOWN
|
40
40
|
]
|
41
41
|
end
|
@@ -47,7 +47,7 @@ module Thredded
|
|
47
47
|
return if names.blank? || @users_provider.nil?
|
48
48
|
@users_provider.call(names, @users_provider_scope).each do |user|
|
49
49
|
name = user.send(Thredded.user_name_column)
|
50
|
-
maybe_quoted_name =
|
50
|
+
maybe_quoted_name = /[., ()]/.match?(name) ? %("#{name}") : name
|
51
51
|
url = Thredded.user_path(@view_context, user)
|
52
52
|
text_node_html.gsub!(
|
53
53
|
/(^|[\s>])(@#{Regexp.escape maybe_quoted_name})([^a-z\d]|$)/i,
|
@@ -24,7 +24,7 @@ module Thredded
|
|
24
24
|
next unless env[:node_name] == 'a'
|
25
25
|
a_tag = env[:node]
|
26
26
|
a_tag['href'] ||= '#'
|
27
|
-
if
|
27
|
+
if %r{^(?:[a-z]+:)?//}.match?(a_tag['href'])
|
28
28
|
a_tag['target'] = '_blank'
|
29
29
|
a_tag['rel'] = 'nofollow noopener'
|
30
30
|
else
|
@@ -68,9 +68,9 @@ module Thredded
|
|
68
68
|
|
69
69
|
def render_onebox(url)
|
70
70
|
preview = Onebox.preview(url, onebox_options(url))
|
71
|
-
if context[:onebox_placeholders]
|
71
|
+
if context[:onebox_placeholders] && (placeholder_html = preview.placeholder_html.presence)
|
72
72
|
%(<p><a href="#{ERB::Util.html_escape(url)}" target="_blank" rel="nofollow noopener">) \
|
73
|
-
"#{
|
73
|
+
"#{placeholder_html}</a></p>"
|
74
74
|
else
|
75
75
|
preview.to_s.strip
|
76
76
|
end
|
data/lib/thredded/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: thredded
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joel Oliveira
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-06-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: active_record_union
|
@@ -129,7 +129,7 @@ dependencies:
|
|
129
129
|
requirements:
|
130
130
|
- - ">="
|
131
131
|
- !ruby/object:Gem::Version
|
132
|
-
version:
|
132
|
+
version: 5.2.0
|
133
133
|
- - "!="
|
134
134
|
- !ruby/object:Gem::Version
|
135
135
|
version: 6.0.0.rc2
|
@@ -139,7 +139,7 @@ dependencies:
|
|
139
139
|
requirements:
|
140
140
|
- - ">="
|
141
141
|
- !ruby/object:Gem::Version
|
142
|
-
version:
|
142
|
+
version: 5.2.0
|
143
143
|
- - "!="
|
144
144
|
- !ruby/object:Gem::Version
|
145
145
|
version: 6.0.0.rc2
|
@@ -311,6 +311,20 @@ dependencies:
|
|
311
311
|
- - "~>"
|
312
312
|
- !ruby/object:Gem::Version
|
313
313
|
version: '3.0'
|
314
|
+
- !ruby/object:Gem::Dependency
|
315
|
+
name: capybara-screenshot
|
316
|
+
requirement: !ruby/object:Gem::Requirement
|
317
|
+
requirements:
|
318
|
+
- - ">="
|
319
|
+
- !ruby/object:Gem::Version
|
320
|
+
version: '0'
|
321
|
+
type: :development
|
322
|
+
prerelease: false
|
323
|
+
version_requirements: !ruby/object:Gem::Requirement
|
324
|
+
requirements:
|
325
|
+
- - ">="
|
326
|
+
- !ruby/object:Gem::Version
|
327
|
+
version: '0'
|
314
328
|
- !ruby/object:Gem::Dependency
|
315
329
|
name: cuprite
|
316
330
|
requirement: !ruby/object:Gem::Requirement
|
@@ -620,7 +634,7 @@ dependencies:
|
|
620
634
|
- !ruby/object:Gem::Version
|
621
635
|
version: '0'
|
622
636
|
description: |-
|
623
|
-
The best Rails
|
637
|
+
The best Rails 5.2+ forums engine ever. Its goal is to be as simple and feature rich as possible.
|
624
638
|
Thredded works with SQLite, MySQL (v5.6.4+), and PostgreSQL. See the demo at https://thredded.org/.
|
625
639
|
email:
|
626
640
|
- joel@thredded.com
|
@@ -970,6 +984,7 @@ files:
|
|
970
984
|
- app/views/thredded/users/_posts.html.erb
|
971
985
|
- bin/create_migration_fixture
|
972
986
|
- bin/rails
|
987
|
+
- bin/rubocop
|
973
988
|
- config/i18n-tasks.yml
|
974
989
|
- config/locales/de.yml
|
975
990
|
- config/locales/en.yml
|
@@ -1049,7 +1064,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1049
1064
|
- !ruby/object:Gem::Version
|
1050
1065
|
version: '0'
|
1051
1066
|
requirements: []
|
1052
|
-
rubygems_version: 3.
|
1067
|
+
rubygems_version: 3.2.32
|
1053
1068
|
signing_key:
|
1054
1069
|
specification_version: 4
|
1055
1070
|
summary: The best Rails forums engine ever.
|