Skip to content

Commit ffc19a8

Browse files
committed
Merge branch 'main' into mobile-columns-pt-iii
* main: Only hide the blank slate when there are no cards present Support local installations where the app is loaded over HTTP Revert "Make sure new card drafts are refreshed when reused" Make sure new card drafts are refreshed when reused Add a "*" to the queues handled by the solid queue worker pool Remove unnecessary recurring execution cleanup task Refactor: Replace pluck(:id) with ids method
2 parents a966622 + 047dca4 commit ffc19a8

File tree

9 files changed

+33
-103
lines changed

9 files changed

+33
-103
lines changed

app/assets/stylesheets/blank-slates.css

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@
2424
border: 2px dashed var(--color-ink-light);
2525
border-radius: 1ch;
2626
color: var(--color-ink-dark);
27-
margin-block-start: 5dvh;
27+
margin-block-start: 2dvh;
2828
padding: 1ch 2ch;
2929
rotate: -3deg;
3030
font-weight: 500;
3131

32-
.cards:not(.cards--grid) & {
32+
.cards:has(.card) & {
3333
display: none;
3434
}
3535
}

app/controllers/boards_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def create
3030
end
3131

3232
def edit
33-
selected_user_ids = @board.users.pluck :id
33+
selected_user_ids = @board.users.ids
3434
@selected_users, @unselected_users = \
3535
@board.account.users.active.alphabetically.includes(:identity).partition { |user| selected_user_ids.include? user.id }
3636
end

app/controllers/concerns/request_forgery_protection.rb

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,19 @@ module RequestForgeryProtection
22
extend ActiveSupport::Concern
33

44
included do
5-
after_action :append_sec_fetch_site_to_vary_header
5+
protect_from_forgery using: :header_only, with: :exception
66
end
77

88
private
9-
def append_sec_fetch_site_to_vary_header
10-
vary_header = response.headers["Vary"].to_s.split(",").map(&:strip).reject(&:blank?)
11-
response.headers["Vary"] = (vary_header + [ "Sec-Fetch-Site" ]).join(",")
9+
def verified_via_header_only?
10+
super || allowed_api_request? || allowed_insecure_context_request?
1211
end
1312

14-
def verified_request?
15-
request.get? || request.head? || !protect_against_forgery? ||
16-
(valid_request_origin? && safe_fetch_site?)
13+
def allowed_api_request?
14+
sec_fetch_site_value.nil? && request.format.json?
1715
end
1816

19-
SAFE_FETCH_SITES = %w[ same-origin same-site ]
20-
21-
def safe_fetch_site?
22-
SAFE_FETCH_SITES.include?(sec_fetch_site_value) || (sec_fetch_site_value.nil? && api_request?)
23-
end
24-
25-
def api_request?
26-
request.format.json?
27-
end
28-
29-
def sec_fetch_site_value
30-
request.headers["Sec-Fetch-Site"].to_s.downcase.presence
17+
def allowed_insecure_context_request?
18+
sec_fetch_site_value.nil? && !request.ssl? && !Rails.configuration.force_ssl
3119
end
3220
end

app/models/board/storage.rb

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ def calculate_real_storage_bytes
2121
end
2222

2323
def card_ids
24-
@card_ids ||= cards.pluck(:id)
24+
@card_ids ||= cards.ids
2525
end
2626

2727
def card_image_bytes
@@ -36,7 +36,7 @@ def card_embed_bytes
3636

3737
def comment_embed_bytes
3838
card_ids.each_slice(BATCH_SIZE).sum do |batch|
39-
sum_embed_bytes_for "Comment", Comment.where(card_id: batch).pluck(:id)
39+
sum_embed_bytes_for "Comment", Comment.where(card_id: batch).ids
4040
end
4141
end
4242

@@ -46,8 +46,7 @@ def board_embed_bytes
4646

4747
def sum_embed_bytes_for(record_type, record_ids)
4848
rich_text_ids = ActionText::RichText \
49-
.where(record_type: record_type, record_id: record_ids)
50-
.pluck(:id)
49+
.where(record_type: record_type, record_id: record_ids).ids
5150

5251
sum_blob_bytes_in_batches \
5352
ActiveStorage::Attachment.where(record_type: "ActionText::RichText", name: "embeds"),

app/models/user/accessor.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ module User::Accessor
1313

1414
private
1515
def grant_access_to_boards
16-
Access.insert_all account.boards.all_access.pluck(:id).collect { |board_id| { id: ActiveRecord::Type::Uuid.generate, board_id: board_id, user_id: id, account_id: account.id } }
16+
Access.insert_all account.boards.all_access.ids.collect { |board_id| { id: ActiveRecord::Type::Uuid.generate, board_id: board_id, user_id: id, account_id: account.id } }
1717
end
1818
end

config/queue.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ default: &default
33
- polling_interval: 1
44
batch_size: 500
55
workers:
6-
- queues: [ "default", "solid_queue_recurring", "backend", "webhooks" ]
6+
- queues: [ "default", "solid_queue_recurring", "backend", "webhooks", "*" ]
77
threads: 3
88
processes: <%= Integer(ENV.fetch("JOB_CONCURRENCY") { Concurrent.physical_processor_count }) %>
99
polling_interval: 0.1

config/recurring.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@ production: &production
1818
clear_solid_queue_finished_jobs:
1919
command: "SolidQueue::Job.clear_finished_in_batches(sleep_between_batches: 0.3)"
2020
schedule: every hour at minute 12
21-
clear_solid_queue_recurring_executions:
22-
command: "SolidQueue::RecurringExecution.clear_in_batches"
23-
schedule: every hour at minute 52
2421
cleanup_webhook_deliveries:
2522
command: "Webhook::Delivery.cleanup"
2623
schedule: every 4 hours at minute 51
@@ -43,9 +40,6 @@ beta:
4340
clear_solid_queue_finished_jobs:
4441
command: "SolidQueue::Job.clear_finished_in_batches(sleep_between_batches: 0.3)"
4542
schedule: every hour at minute 12
46-
clear_solid_queue_recurring_executions:
47-
command: "SolidQueue::RecurringExecution.clear_in_batches"
48-
schedule: every hour at minute 52
4943

5044
staging: *production
5145
development: *production

db/queue_schema.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
t.index ["key"], name: "index_solid_queue_semaphores_on_key", unique: true
133133
end
134134

135+
# If these FKs are removed, make sure to periodically run `RecurringExecution.clear_in_batches`
135136
add_foreign_key "solid_queue_blocked_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
136137
add_foreign_key "solid_queue_claimed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade
137138
add_foreign_key "solid_queue_failed_executions", "solid_queue_jobs", column: "job_id", on_delete: :cascade

test/controllers/concerns/request_forgery_protection_test.rb

Lines changed: 17 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -6,108 +6,56 @@ class RequestForgeryProtectionTest < ActionDispatch::IntegrationTest
66

77
@original_allow_forgery_protection = ActionController::Base.allow_forgery_protection
88
ActionController::Base.allow_forgery_protection = true
9+
10+
@original_force_ssl = Rails.configuration.force_ssl
911
end
1012

1113
teardown do
1214
ActionController::Base.allow_forgery_protection = @original_allow_forgery_protection
15+
Rails.configuration.force_ssl = @original_force_ssl
1316
end
1417

15-
test "fails if Sec-Fetch-Site is cross-site" do
16-
assert_no_difference -> { Board.count } do
17-
post boards_path,
18-
params: { board: { name: "Test Board" } },
19-
headers: { "Sec-Fetch-Site" => "cross-site" }
20-
end
21-
22-
assert_response :unprocessable_entity
23-
end
24-
25-
test "succeeds with same-origin Sec-Fetch-Site" do
18+
test "JSON request succeeds with missing Sec-Fetch-Site header" do
2619
assert_difference -> { Board.count }, +1 do
2720
post boards_path,
2821
params: { board: { name: "Test Board" } },
29-
headers: { "Sec-Fetch-Site" => "same-origin" }
22+
as: :json
3023
end
3124

32-
assert_response :redirect
25+
assert_response :created
3326
end
3427

35-
test "succeeds with same-site Sec-Fetch-Site" do
28+
test "HTTP request succeeds with missing Sec-Fetch-Site header when force_ssl is disabled" do
29+
Rails.configuration.force_ssl = false
30+
3631
assert_difference -> { Board.count }, +1 do
3732
post boards_path,
38-
params: { board: { name: "Test Board" } },
39-
headers: { "Sec-Fetch-Site" => "same-site" }
33+
params: { board: { name: "Test Board" } }
4034
end
4135

4236
assert_response :redirect
4337
end
4438

45-
test "fails with none Sec-Fetch-Site" do
46-
assert_no_difference -> { Board.count } do
47-
post boards_path,
48-
params: { board: { name: "Test Board" } },
49-
headers: { "Sec-Fetch-Site" => "none" }
50-
end
39+
test "HTTP request fails with missing Sec-Fetch-Site header when force_ssl is enabled" do
40+
Rails.configuration.force_ssl = true
5141

52-
assert_response :unprocessable_entity
53-
end
54-
55-
test "fails when Sec-Fetch-Site header is missing" do
5642
assert_no_difference -> { Board.count } do
57-
post boards_path, params: { board: { name: "Test Board" } }
43+
post boards_path,
44+
params: { board: { name: "Test Board" } }
5845
end
5946

6047
assert_response :unprocessable_entity
6148
end
6249

63-
test "GET requests succeed regardless of Sec-Fetch-Site header" do
64-
get board_path(boards(:writebook)), headers: { "Sec-Fetch-Site" => "cross-site" }
50+
test "HTTPS request fails with missing Sec-Fetch-Site header" do
51+
Rails.configuration.force_ssl = false
6552

66-
assert_response :success
67-
end
68-
69-
test "appends Sec-Fetch-Site to Vary header on GET requests" do
70-
get board_path(boards(:writebook))
71-
72-
assert_response :success
73-
assert_includes response.headers["Vary"], "Sec-Fetch-Site"
74-
end
75-
76-
test "appends Sec-Fetch-Site to Vary header on POST requests" do
77-
post boards_path,
78-
params: { board: { name: "Test Board" } },
79-
headers: { "Sec-Fetch-Site" => "same-origin" }
80-
81-
assert_response :redirect
82-
assert_includes response.headers["Vary"], "Sec-Fetch-Site"
83-
end
84-
85-
test "JSON request succeeds with missing Sec-Fetch-Site" do
86-
assert_difference -> { Board.count }, +1 do
87-
post boards_path,
88-
params: { board: { name: "Test Board" } },
89-
as: :json
90-
end
91-
92-
assert_response :created
93-
end
94-
95-
test "JSON request fails with cross-site Sec-Fetch-Site" do
9653
assert_no_difference -> { Board.count } do
9754
post boards_path,
9855
params: { board: { name: "Test Board" } },
99-
headers: { "Sec-Fetch-Site" => "cross-site" },
100-
as: :json
56+
headers: { "X-Forwarded-Proto" => "https" }
10157
end
10258

10359
assert_response :unprocessable_entity
10460
end
105-
106-
private
107-
def csrf_token
108-
@csrf_token ||= begin
109-
get new_board_path
110-
response.body[/name="authenticity_token" value="([^"]+)"/, 1]
111-
end
112-
end
11361
end

0 commit comments

Comments
 (0)