Compare commits
No commits in common. "382713019a18975dfddc8ccd0edd33c6b883c80c" and "e75ad1de0f95f38b45748cafb1212560fe7587f5" have entirely different histories.
382713019a
...
e75ad1de0f
56
CHANGELOG.md
|
@ -3,62 +3,6 @@ Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [4.1.4] - 2023-07-07
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix branding:generate_app_icons failing because of disallowed ICO coder ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25794))
|
|
||||||
- Fix crash in admin interface when viewing a remote user with verified links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25796))
|
|
||||||
- Fix processing of media files with unusual names ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25788))
|
|
||||||
|
|
||||||
## [4.1.3] - 2023-07-06
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Add fallback redirection when getting a webfinger query `LOCAL_DOMAIN@LOCAL_DOMAIN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23600))
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
- Change OpenGraph-based embeds to allow fullscreen ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25058))
|
|
||||||
- Change AccessTokensVacuum to also delete expired tokens ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24868))
|
|
||||||
- Change profile updates to be sent to recently-mentioned servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24852))
|
|
||||||
- Change automatic post deletion thresholds and load detection ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24614))
|
|
||||||
- Change `/api/v1/statuses/:id/history` to always return at least one item ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25510))
|
|
||||||
- Change auto-linking to allow carets in URL query params ([renchap](https://github.com/mastodon/mastodon/pull/25216))
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
- Remove invalid `X-Frame-Options: ALLOWALL` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25070))
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
- Fix wrong view being displayed when a webhook fails validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25464))
|
|
||||||
- Fix soft-deleted post cleanup scheduler overwhelming the streaming server ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25519))
|
|
||||||
- Fix incorrect pagination headers in `/api/v2/admin/accounts` ([danielmbrasil](https://github.com/mastodon/mastodon/pull/25477))
|
|
||||||
- Fix multiple inefficiencies in automatic post cleanup worker ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24607), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24785), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/24840))
|
|
||||||
- Fix performance of streaming by parsing message JSON once ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25278), [ThisIsMissEm](https://github.com/mastodon/mastodon/pull/25361))
|
|
||||||
- Fix CSP headers when `S3_ALIAS_HOST` includes a path component ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25273))
|
|
||||||
- Fix `tootctl accounts approve --number N` not approving N earliest registrations ([danielmbrasil](https://github.com/mastodon/mastodon/pull/24605))
|
|
||||||
- Fix reports not being closed when performing batch suspensions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24988))
|
|
||||||
- Fix being able to vote on your own polls ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25015))
|
|
||||||
- Fix race condition when reblogging a status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25016))
|
|
||||||
- Fix “Authorized applications” inefficiently and incorrectly getting last use date ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25060))
|
|
||||||
- Fix “Authorized applications” crashing when listing apps with certain admin API scopes ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25713))
|
|
||||||
- Fix multiple N+1s in ConversationsController ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25134), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25399), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/25499))
|
|
||||||
- Fix user archive takeouts when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/24431))
|
|
||||||
- Fix searching for remote content by URL not working under certain conditions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25637))
|
|
||||||
- Fix inefficiencies in indexing content for search ([VyrCossont](https://github.com/mastodon/mastodon/pull/24285), [VyrCossont](https://github.com/mastodon/mastodon/pull/24342))
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
- Add finer permission requirements for managing webhooks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25463))
|
|
||||||
- Update dependencies
|
|
||||||
- Add hardening headers for user-uploaded files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/25756))
|
|
||||||
- Fix verified links possibly hiding important parts of the URL (CVE-2023-36462)
|
|
||||||
- Fix timeout handling of outbound HTTP requests (CVE-2023-36461)
|
|
||||||
- Fix arbitrary file creation through media processing (CVE-2023-36460)
|
|
||||||
- Fix possible XSS in preview cards (CVE-2023-36459)
|
|
||||||
|
|
||||||
## [4.1.2] - 2023-04-04
|
## [4.1.2] - 2023-04-04
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
|
@ -627,7 +627,7 @@ GEM
|
||||||
fugit (~> 1.1, >= 1.1.6)
|
fugit (~> 1.1, >= 1.1.6)
|
||||||
safety_net_attestation (0.4.0)
|
safety_net_attestation (0.4.0)
|
||||||
jwt (~> 2.0)
|
jwt (~> 2.0)
|
||||||
sanitize (6.0.2)
|
sanitize (6.0.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
scenic (1.7.0)
|
scenic (1.7.0)
|
||||||
|
|
|
@ -11,7 +11,7 @@ module BrandingHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def _logo_as_symbol_wordmark
|
def _logo_as_symbol_wordmark
|
||||||
content_tag(:svg, tag(:use, href: '#logo-symbol-wordmark'), viewBox: '0 0 112 30', class: 'logo logo--wordmark')
|
content_tag(:svg, tag(:use, href: '#logo-symbol-wordmark'), viewBox: '0 0 261 66', class: 'logo logo--wordmark')
|
||||||
end
|
end
|
||||||
|
|
||||||
def _logo_as_symbol_icon
|
def _logo_as_symbol_icon
|
||||||
|
|
|
@ -58,10 +58,6 @@ module FormattingHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def account_field_value_format(field, with_rel_me: true)
|
def account_field_value_format(field, with_rel_me: true)
|
||||||
if field.verified? && !field.account.local?
|
html_aware_format(field.value, field.account.local?, with_rel_me: with_rel_me, with_domains: true, multiline: false)
|
||||||
TextFormatter.shortened_link(field.value_for_verification)
|
|
||||||
else
|
|
||||||
html_aware_format(field.value, field.account.local?, with_rel_me: with_rel_me, with_domains: true, multiline: false)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 8.5 KiB |
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 950 B |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 7.9 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 8.4 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 6.9 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 5.0 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 7.3 KiB |
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const Logo = () => (
|
const Logo = () => (
|
||||||
<svg viewBox='0 0 112 30' className='logo' role='img'>
|
<svg viewBox='0 0 261 66' className='logo' role='img'>
|
||||||
<title>Mastodon</title>
|
<title>Mastodon</title>
|
||||||
<use xlinkHref='#logo-symbol-wordmark' />
|
<use xlinkHref='#logo-symbol-wordmark' />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
@ -90,7 +90,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
const fulltext = this.getFulltextForCharacterCounting();
|
const fulltext = this.getFulltextForCharacterCounting();
|
||||||
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
||||||
|
|
||||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 2500 || (isOnlyWhitespace && !anyMedia));
|
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > 500 || (isOnlyWhitespace && !anyMedia));
|
||||||
};
|
};
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (e) => {
|
||||||
|
@ -280,7 +280,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className='character-counter__wrapper'>
|
<div className='character-counter__wrapper'>
|
||||||
<CharacterCounter max={2500} text={this.getFulltextForCharacterCounting()} />
|
<CharacterCounter max={500} text={this.getFulltextForCharacterCounting()} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
|
|
||||||
.logo {
|
.logo {
|
||||||
height: 42px;
|
height: 42px;
|
||||||
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
|
@ -48,26 +48,6 @@ class TextFormatter
|
||||||
html.html_safe # rubocop:disable Rails/OutputSafety
|
html.html_safe # rubocop:disable Rails/OutputSafety
|
||||||
end
|
end
|
||||||
|
|
||||||
class << self
|
|
||||||
include ERB::Util
|
|
||||||
|
|
||||||
def shortened_link(url, rel_me: false)
|
|
||||||
url = Addressable::URI.parse(url).to_s
|
|
||||||
rel = rel_me ? (DEFAULT_REL + %w(me)) : DEFAULT_REL
|
|
||||||
|
|
||||||
prefix = url.match(URL_PREFIX_REGEX).to_s
|
|
||||||
display_url = url[prefix.length, 30]
|
|
||||||
suffix = url[prefix.length + 30..-1]
|
|
||||||
cutoff = url[prefix.length..-1].length > 30
|
|
||||||
|
|
||||||
<<~HTML.squish.html_safe # rubocop:disable Rails/OutputSafety
|
|
||||||
<a href="#{h(url)}" target="_blank" rel="#{rel.join(' ')}"><span class="invisible">#{h(prefix)}</span><span class="#{cutoff ? 'ellipsis' : ''}">#{h(display_url)}</span><span class="invisible">#{h(suffix)}</span></a>
|
|
||||||
HTML
|
|
||||||
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
|
|
||||||
h(url)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def rewrite
|
def rewrite
|
||||||
|
@ -90,7 +70,19 @@ class TextFormatter
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_url(entity)
|
def link_to_url(entity)
|
||||||
TextFormatter.shortened_link(entity[:url], rel_me: with_rel_me?)
|
url = Addressable::URI.parse(entity[:url]).to_s
|
||||||
|
rel = with_rel_me? ? (DEFAULT_REL + %w(me)) : DEFAULT_REL
|
||||||
|
|
||||||
|
prefix = url.match(URL_PREFIX_REGEX).to_s
|
||||||
|
display_url = url[prefix.length, 30]
|
||||||
|
suffix = url[prefix.length + 30..-1]
|
||||||
|
cutoff = url[prefix.length..-1].length > 30
|
||||||
|
|
||||||
|
<<~HTML.squish
|
||||||
|
<a href="#{h(url)}" target="_blank" rel="#{rel.join(' ')}"><span class="invisible">#{h(prefix)}</span><span class="#{cutoff ? 'ellipsis' : ''}">#{h(display_url)}</span><span class="invisible">#{h(suffix)}</span></a>
|
||||||
|
HTML
|
||||||
|
rescue Addressable::URI::InvalidURIError, IDN::Idna::IdnaError
|
||||||
|
h(entity[:url])
|
||||||
end
|
end
|
||||||
|
|
||||||
def link_to_hashtag(entity)
|
def link_to_hashtag(entity)
|
||||||
|
|
|
@ -24,7 +24,7 @@ module Attachmentable
|
||||||
def self.has_attached_file(name, options = {}) # rubocop:disable Naming/PredicateName
|
def self.has_attached_file(name, options = {}) # rubocop:disable Naming/PredicateName
|
||||||
super(name, options)
|
super(name, options)
|
||||||
|
|
||||||
send(:"before_#{name}_validate", prepend: true) do
|
send(:"before_#{name}_validate") do
|
||||||
attachment = send(name)
|
attachment = send(name)
|
||||||
check_image_dimension(attachment)
|
check_image_dimension(attachment)
|
||||||
set_file_content_type(attachment)
|
set_file_content_type(attachment)
|
||||||
|
|
|
@ -39,7 +39,7 @@ class MediaAttachment < ApplicationRecord
|
||||||
MAX_DESCRIPTION_LENGTH = 1_500
|
MAX_DESCRIPTION_LENGTH = 1_500
|
||||||
|
|
||||||
IMAGE_LIMIT = 10.megabytes
|
IMAGE_LIMIT = 10.megabytes
|
||||||
VIDEO_LIMIT = 80.megabytes
|
VIDEO_LIMIT = 40.megabytes
|
||||||
|
|
||||||
MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px
|
MAX_VIDEO_MATRIX_LIMIT = 2_304_000 # 1920x1200px
|
||||||
MAX_VIDEO_FRAME_RATE = 60
|
MAX_VIDEO_FRAME_RATE = 60
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class StatusLengthValidator < ActiveModel::Validator
|
class StatusLengthValidator < ActiveModel::Validator
|
||||||
MAX_CHARS = 2500
|
MAX_CHARS = 500
|
||||||
URL_PLACEHOLDER_CHARS = 23
|
URL_PLACEHOLDER_CHARS = 23
|
||||||
URL_PLACEHOLDER = 'x' * 23
|
URL_PLACEHOLDER = 'x' * 23
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ module Mastodon
|
||||||
end
|
end
|
||||||
|
|
||||||
def patch
|
def patch
|
||||||
4
|
2
|
||||||
end
|
end
|
||||||
|
|
||||||
def flags
|
def flags
|
||||||
|
@ -21,7 +21,7 @@ module Mastodon
|
||||||
end
|
end
|
||||||
|
|
||||||
def suffix
|
def suffix
|
||||||
'-gh23188'
|
''
|
||||||
end
|
end
|
||||||
|
|
||||||
def to_a
|
def to_a
|
||||||
|
|
|
@ -40,7 +40,7 @@ namespace :branding do
|
||||||
output_dest = Rails.root.join('app', 'javascript', 'icons')
|
output_dest = Rails.root.join('app', 'javascript', 'icons')
|
||||||
|
|
||||||
rsvg_convert = Terrapin::CommandLine.new('rsvg-convert', '-w :size -h :size --keep-aspect-ratio :input -o :output')
|
rsvg_convert = Terrapin::CommandLine.new('rsvg-convert', '-w :size -h :size --keep-aspect-ratio :input -o :output')
|
||||||
convert = Terrapin::CommandLine.new('convert', ':input :output', environment: { 'MAGICK_CONFIGURE_PATH' => nil })
|
convert = Terrapin::CommandLine.new('convert', ':input :output')
|
||||||
|
|
||||||
favicon_sizes = [16, 32, 48]
|
favicon_sizes = [16, 32, 48]
|
||||||
apple_icon_sizes = [57, 60, 72, 76, 114, 120, 144, 152, 167, 180, 1024]
|
apple_icon_sizes = [57, 60, 72, 76, 114, 120, 144, 152, 167, 180, 1024]
|
||||||
|
|
Before Width: | Height: | Size: 60 KiB |
|
@ -1,18 +0,0 @@
|
||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe 'Media API', paperclip_processing: true do
|
|
||||||
let(:user) { Fabricate(:user) }
|
|
||||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
|
||||||
let(:scopes) { 'write' }
|
|
||||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
|
||||||
|
|
||||||
describe 'POST /api/v2/media' do
|
|
||||||
it 'returns http success' do
|
|
||||||
post '/api/v2/media', headers: headers, params: { file: fixture_file_upload('attachment-jpg.123456_abcd', 'image/jpeg') }
|
|
||||||
expect(File.exist?(user.account.media_attachments.first.file.path(:small))).to be true
|
|
||||||
expect(response).to have_http_status(200)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|