Skip to content

Commit

Permalink
Merge tag 'v4.2.1' into mstdn-vodka
Browse files Browse the repository at this point in the history
  • Loading branch information
gol-cha committed Oct 10, 2023
2 parents 36ac50f + 74dd325 commit 2e2975e
Show file tree
Hide file tree
Showing 142 changed files with 2,270 additions and 1,669 deletions.
4 changes: 0 additions & 4 deletions .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -289,10 +289,6 @@ RSpec/MultipleMemoizedHelpers:
RSpec/NestedGroups:
Max: 6

RSpec/PendingWithoutReason:
Exclude:
- 'spec/models/account_spec.rb'

# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/ApplicationController:
Exclude:
Expand Down
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,46 @@

All notable changes to this project will be documented in this file.

## [4.2.1] - 2023-10-10

### Added

- Add redirection on `/deck` URLs for logged-out users ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27128))
- Add support for v4.2.0 migrations to `tootctl maintenance fix-duplicates` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27147))

### Changed

- Change some worker lock TTLs to be shorter-lived ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27246))
- Change user archive export allowed period from 7 days to 6 days ([suddjian](https://github.com/mastodon/mastodon/pull/27200))

### Fixed

- Fix duplicate reports being sent when reporting some remote posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27355))
- Fix clicking on already-opened thread post scrolling to the top of the thread ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27331), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27338), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27350))
- Fix some remote posts getting truncated ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27307))
- Fix some cases of infinite scroll code trying to fetch inaccessible posts in a loop ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27286))
- Fix `Vary` headers not being set on some redirects ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27272))
- Fix mentions being matched in some URL query strings ([mjankowski](https://github.com/mastodon/mastodon/pull/25656))
- Fix unexpected linebreak in version string in the Web UI ([vmstan](https://github.com/mastodon/mastodon/pull/26986))
- Fix double scroll bars in some columns in advanced interface ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27187))
- Fix boosts of local users being filtered in account timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27204))
- Fix multiple instances of the trend refresh scheduler sometimes running at once ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27253))
- Fix importer returning negative row estimates ([jgillich](https://github.com/mastodon/mastodon/pull/27258))
- Fix incorrectly keeping outdated update notices absent from the API endpoint ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27021))
- Fix import progress not updating on certain failures ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27247))
- Fix websocket connections being incorrectly decremented twice on errors ([ThisIsMissEm](https://github.com/mastodon/mastodon/pull/27238))
- Fix explore prompt appearing because of posts being received out of order ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27211))
- Fix explore prompt sometimes showing up when the home TL is loading ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27062))
- Fix link handling of mentions in user profiles when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27185))
- Fix filtering audit log for entries about disabling 2FA ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27186))
- Fix notification toasts not respecting reduce-motion ([c960657](https://github.com/mastodon/mastodon/pull/27178))
- Fix retention dashboard not displaying correct month ([vmstan](https://github.com/mastodon/mastodon/pull/27180))
- Fix tIME chunk not being properly removed from PNG uploads ([TheEssem](https://github.com/mastodon/mastodon/pull/27111))
- Fix division by zero in video in bitrate computation code ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27129))
- Fix inefficient queries in “Follows and followers” as well as several admin pages ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27116), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27306))
- Fix ActiveRecord using two connection pools when no replica is defined ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27061))
- Fix the search documentation URL in system checks ([renchap](https://github.com/mastodon/mastodon/pull/27036))

## [4.2.0] - 2023-09-21

The following changelog entries focus on changes visible to users, administrators, client developers or federated software developers, but there has also been a lot of code modernization, refactoring, and tooling work, in particular by [@danielmbrasil](https://github.com/danielmbrasil), [@mjankowski](https://github.com/mjankowski), [@nschonni](https://github.com/nschonni), [@renchap](https://github.com/renchap), and [@takayamaki](https://github.com/takayamaki).
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -691,7 +691,7 @@ GEM
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semantic_range (3.0.0)
sidekiq (6.5.9)
sidekiq (6.5.10)
connection_pool (>= 2.2.5, < 3)
rack (~> 2.0)
redis (>= 4.5.0, < 5)
Expand Down
1 change: 1 addition & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through

| Version | Supported |
| ------- | ---------------- |
| 4.2.x | Yes |
| 4.1.x | Yes |
| 4.0.x | Until 2023-10-31 |
| 3.5.x | Until 2023-12-31 |
Expand Down
10 changes: 6 additions & 4 deletions app/controllers/concerns/web_app_controller_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ module WebAppControllerConcern
extend ActiveSupport::Concern

included do
prepend_before_action :redirect_unauthenticated_to_permalinks!
before_action :set_app_body_class

vary_by 'Accept, Accept-Language, Cookie'

before_action :redirect_unauthenticated_to_permalinks!
before_action :set_app_body_class
end

def skip_csrf_meta_tags?
Expand All @@ -22,7 +22,9 @@ def redirect_unauthenticated_to_permalinks!
return if user_signed_in? && current_account.moved_to_account_id.nil?

redirect_path = PermalinkRedirector.new(request.path).redirect_path
return if redirect_path.blank?

redirect_to(redirect_path) if redirect_path.present?
expires_in(15.seconds, public: true, stale_while_revalidate: 30.seconds, stale_if_error: 1.day) unless user_signed_in?
redirect_to(redirect_path)
end
end
1 change: 0 additions & 1 deletion app/controllers/follower_accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
class FollowerAccountsController < ApplicationController
include AccountControllerConcern
include SignatureVerification
include WebAppControllerConcern

vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' }

Expand Down
1 change: 0 additions & 1 deletion app/controllers/following_accounts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
class FollowingAccountsController < ApplicationController
include AccountControllerConcern
include SignatureVerification
include WebAppControllerConcern

vary_by -> { public_fetch_mode? ? 'Accept, Accept-Language, Cookie' : 'Accept, Accept-Language, Cookie, Signature' }

Expand Down
17 changes: 15 additions & 2 deletions app/helpers/database_helper.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# frozen_string_literal: true

module DatabaseHelper
def replica_enabled?
ENV['REPLICA_DB_NAME'] || ENV.fetch('REPLICA_DATABASE_URL', nil)
end
module_function :replica_enabled?

def with_read_replica(&block)
ApplicationRecord.connected_to(role: :reading, prevent_writes: true, &block)
if replica_enabled?
ApplicationRecord.connected_to(role: :reading, prevent_writes: true, &block)
else
yield
end
end

def with_primary(&block)
ApplicationRecord.connected_to(role: :writing, &block)
if replica_enabled?
ApplicationRecord.connected_to(role: :writing, &block)
else
yield
end
end
end
4 changes: 4 additions & 0 deletions app/javascript/mastodon/actions/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ export const openURL = (value, history, onFailure) => (dispatch, getState) => {
const signedIn = !!getState().getIn(['meta', 'me']);

if (!signedIn) {
if (onFailure) {
onFailure();
}

return;
}

Expand Down
15 changes: 15 additions & 0 deletions app/javascript/mastodon/components/__tests__/hashtag_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ describe('computeHashtagBarForStatus', () => {
);
});

it('does not truncate the contents when the last child is a text node', () => {
const status = createStatus(
'this is a #<a class="zrl" href="https://example.com/search?tag=test">test</a>. Some more text',
['test'],
);

const { hashtagsInBar, statusContentProps } =
computeHashtagBarForStatus(status);

expect(hashtagsInBar).toEqual([]);
expect(statusContentProps.statusContent).toMatchInlineSnapshot(
`"this is a #<a class="zrl" href="https://example.com/search?tag=test">test</a>. Some more text"`,
);
});

it('extract tags from the last line', () => {
const status = createStatus(
'<p>Simple text</p><p><a href="test">#hashtag</a></p>',
Expand Down
5 changes: 3 additions & 2 deletions app/javascript/mastodon/components/admin/Retention.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import api from 'mastodon/api';
import { roundTo10 } from 'mastodon/utils/numbers';

const dateForCohort = cohort => {
const timeZone = 'UTC';
switch(cohort.frequency) {
case 'day':
return <FormattedDate value={cohort.period} month='long' day='2-digit' />;
return <FormattedDate value={cohort.period} month='long' day='2-digit' timeZone={timeZone} />;
default:
return <FormattedDate value={cohort.period} month='long' year='numeric' />;
return <FormattedDate value={cohort.period} month='long' year='numeric' timeZone={timeZone} />;
}
};

Expand Down
6 changes: 0 additions & 6 deletions app/javascript/mastodon/components/column.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,6 @@ export default class Column extends PureComponent {
scrollable = document.scrollingElement;
} else {
scrollable = this.node.querySelector('.scrollable');

// Some columns have nested `.scrollable` containers, with the outer one
// being a wrapper while the actual scrollable content is deeper.
if (scrollable.classList.contains('scrollable--flex')) {
scrollable = scrollable?.querySelector('.scrollable') || scrollable;
}
}

if (!scrollable) {
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/components/hashtag_bar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ export function computeHashtagBarForStatus(status: StatusLike): {

const lastChild = template.content.lastChild;

if (!lastChild) return defaultResult;
if (!lastChild || lastChild.nodeType === Node.TEXT_NODE) return defaultResult;

template.content.removeChild(lastChild);
const contentWithoutLastLine = template;
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/components/scrollable_list.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ class ScrollableList extends PureComponent {
const clientHeight = this.getClientHeight();
const offset = scrollHeight - scrollTop - clientHeight;

if (400 > offset && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
if (scrollTop > 0 && offset < 400 && this.props.onLoadMore && this.props.hasMore && !this.props.isLoading) {
this.props.onLoadMore();
}

Expand Down
78 changes: 38 additions & 40 deletions app/javascript/mastodon/features/explore/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -67,47 +67,45 @@ class Explore extends PureComponent {
<Search />
</div>

<div className='scrollable scrollable--flex' data-nosnippet>
{isSearching ? (
<SearchResults />
) : (
<>
<div className='account__section-headline'>
<NavLink exact to='/explore'>
<FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
{isSearching ? (
<SearchResults />
) : (
<>
<div className='account__section-headline'>
<NavLink exact to='/explore'>
<FormattedMessage tagName='div' id='explore.trending_statuses' defaultMessage='Posts' />
</NavLink>

<NavLink exact to='/explore/tags'>
<FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
</NavLink>

{signedIn && (
<NavLink exact to='/explore/suggestions'>
<FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='People' />
</NavLink>

<NavLink exact to='/explore/tags'>
<FormattedMessage tagName='div' id='explore.trending_tags' defaultMessage='Hashtags' />
</NavLink>

{signedIn && (
<NavLink exact to='/explore/suggestions'>
<FormattedMessage tagName='div' id='explore.suggested_follows' defaultMessage='People' />
</NavLink>
)}

<NavLink exact to='/explore/links'>
<FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
</NavLink>
</div>

<Switch>
<Route path='/explore/tags' component={Tags} />
<Route path='/explore/links' component={Links} />
<Route path='/explore/suggestions' component={Suggestions} />
<Route exact path={['/explore', '/explore/posts', '/search']}>
<Statuses multiColumn={multiColumn} />
</Route>
</Switch>

<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content={isSearching ? 'noindex' : 'all'} />
</Helmet>
</>
)}
</div>
)}

<NavLink exact to='/explore/links'>
<FormattedMessage tagName='div' id='explore.trending_links' defaultMessage='News' />
</NavLink>
</div>

<Switch>
<Route path='/explore/tags' component={Tags} />
<Route path='/explore/links' component={Links} />
<Route path='/explore/suggestions' component={Suggestions} />
<Route exact path={['/explore', '/explore/posts', '/search']}>
<Statuses multiColumn={multiColumn} />
</Route>
</Switch>

<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content={isSearching ? 'noindex' : 'all'} />
</Helmet>
</>
)}
</Column>
);
}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/features/explore/links.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Links extends PureComponent {
}

return (
<div className='explore__links'>
<div className='explore__links scrollable' data-nosnippet>
{banner}

{isLoading ? (<LoadingIndicator />) : links.map((link, i) => (
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/features/explore/results.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ class Results extends PureComponent {
<button onClick={this.handleSelectStatuses} className={type === 'statuses' ? 'active' : undefined}><FormattedMessage id='search_results.statuses' defaultMessage='Posts' /></button>
</div>

<div className='explore__search-results'>
<div className='explore__search-results' data-nosnippet>
<ScrollableList
scrollKey='search-results'
isLoading={isLoading}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/features/explore/suggestions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class Suggestions extends PureComponent {
}

return (
<div className='explore__suggestions'>
<div className='explore__suggestions scrollable' data-nosnippet>
{isLoading ? <LoadingIndicator /> : suggestions.map(suggestion => (
<AccountCard key={suggestion.get('account')} id={suggestion.get('account')} />
))}
Expand Down
2 changes: 1 addition & 1 deletion app/javascript/mastodon/features/explore/tags.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class Tags extends PureComponent {
}

return (
<div className='explore__links'>
<div className='scrollable explore__links' data-nosnippet>
{banner}

{isLoading ? (<LoadingIndicator />) : hashtags.map(hashtag => (
Expand Down
46 changes: 22 additions & 24 deletions app/javascript/mastodon/features/firehose/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -169,32 +169,30 @@ const Firehose = ({ feedType, multiColumn }) => {
<ColumnSettings />
</ColumnHeader>

<div className='scrollable scrollable--flex'>
<div className='account__section-headline'>
<NavLink exact to='/public/local'>
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
</NavLink>

<NavLink exact to='/public/remote'>
<FormattedMessage tagName='div' id='firehose.remote' defaultMessage='Other servers' />
</NavLink>

<NavLink exact to='/public'>
<FormattedMessage tagName='div' id='firehose.all' defaultMessage='All' />
</NavLink>
</div>

<StatusListContainer
prepend={prependBanner}
timelineId={`${feedType}${onlyMedia ? ':media' : ''}`}
onLoadMore={handleLoadMore}
trackScroll
scrollKey='firehose'
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
/>
<div className='account__section-headline'>
<NavLink exact to='/public/local'>
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
</NavLink>

<NavLink exact to='/public/remote'>
<FormattedMessage tagName='div' id='firehose.remote' defaultMessage='Other servers' />
</NavLink>

<NavLink exact to='/public'>
<FormattedMessage tagName='div' id='firehose.all' defaultMessage='All' />
</NavLink>
</div>

<StatusListContainer
prepend={prependBanner}
timelineId={`${feedType}${onlyMedia ? ':media' : ''}`}
onLoadMore={handleLoadMore}
trackScroll
scrollKey='firehose'
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
/>

<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<meta name='robots' content='noindex' />
Expand Down

0 comments on commit 2e2975e

Please sign in to comment.