Merge branch 'master' into glitch-soc/merge-upstream

master
Thibaut Girka 5 years ago
commit 3baacf6993
  1. 4
      .rubocop.yml
  2. 2
      Gemfile
  3. 18
      Gemfile.lock
  4. 14
      app/controllers/concerns/localized.rb
  5. 1
      app/javascript/images/logo_transparent_white.svg
  6. 2
      app/javascript/mastodon/features/account/components/header.js
  7. 8
      app/javascript/mastodon/features/compose/components/poll_form.js
  8. 5
      app/javascript/styles/mastodon/statuses.scss
  9. 7
      app/lib/proof_provider/keybase/config_serializer.rb
  10. 10
      app/models/web/push_subscription.rb
  11. 13
      app/services/batched_remove_status_service.rb
  12. 12
      app/services/fan_out_on_write_service.rb
  13. 12
      app/services/remove_status_service.rb
  14. 2
      app/views/about/show.html.haml
  15. 2
      app/views/directories/index.html.haml
  16. 4
      app/views/statuses/_detailed_status.html.haml
  17. 4
      app/views/statuses/_simple_status.html.haml
  18. 2
      app/workers/redownload_media_worker.rb
  19. 4
      config/application.rb
  20. 2
      config/locales/en.yml
  21. 15
      db/migrate/20200510110808_reset_web_app_secret.rb
  22. 2
      db/schema.rb
  23. 12
      package.json
  24. 2
      spec/controllers/api/v1/accounts_controller_spec.rb
  25. 8
      spec/controllers/concerns/localized_spec.rb
  26. 10
      spec/controllers/oauth/authorizations_controller_spec.rb
  27. 5
      spec/controllers/oauth/tokens_controller_spec.rb
  28. 1324
      yarn.lock

@ -2,7 +2,7 @@ require:
- rubocop-rails
AllCops:
TargetRubyVersion: 2.3
TargetRubyVersion: 2.4
Exclude:
- 'spec/**/*'
- 'db/**/*'
@ -46,7 +46,7 @@ Metrics/ClassLength:
Metrics/CyclomaticComplexity:
Max: 25
Metrics/LineLength:
Layout/LineLength:
AllowURI: true
Enabled: false

@ -49,7 +49,7 @@ gem 'omniauth-saml', '~> 1.10'
gem 'omniauth', '~> 1.9'
gem 'discard', '~> 1.2'
gem 'doorkeeper', '~> 5.3'
gem 'doorkeeper', '~> 5.4'
gem 'fast_blank', '~> 1.0'
gem 'fastimage'
gem 'goldfinger', '~> 2.1'

@ -92,7 +92,7 @@ GEM
av (0.9.0)
cocaine (~> 0.5.3)
aws-eventstream (1.1.0)
aws-partitions (1.311.0)
aws-partitions (1.312.0)
aws-sdk-core (3.95.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
@ -119,7 +119,7 @@ GEM
bootsnap (1.4.6)
msgpack (~> 1.0)
brakeman (4.8.1)
browser (4.0.0)
browser (4.1.0)
builder (3.2.4)
bullet (6.1.0)
activesupport (>= 3.0.0)
@ -194,7 +194,7 @@ GEM
docile (1.3.2)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
doorkeeper (5.3.3)
doorkeeper (5.4.0)
railties (>= 5)
dotenv (2.7.5)
dotenv-rails (2.7.5)
@ -410,7 +410,7 @@ GEM
parser (2.7.1.2)
ast (~> 2.4.0)
parslet (2.0.0)
pastel (0.7.3)
pastel (0.7.4)
equatable (~> 0.6)
tty-color (~> 0.5)
pg (1.2.3)
@ -433,12 +433,12 @@ GEM
pry (~> 0.13.0)
pry-rails (0.3.9)
pry (>= 0.10.4)
public_suffix (4.0.4)
public_suffix (4.0.5)
puma (4.3.3)
nio4r (~> 2.0)
pundit (2.1.0)
activesupport (>= 3.0.0)
raabro (1.1.6)
raabro (1.3.1)
rack (2.2.2)
rack-attack (6.3.0)
rack (>= 1.0, < 3)
@ -525,7 +525,7 @@ GEM
rqrcode_core (0.1.2)
rspec-core (3.9.2)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.1)
rspec-expectations (3.9.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
@ -610,7 +610,7 @@ GEM
stoplight (2.2.0)
streamio-ffmpeg (3.0.2)
multi_json (~> 1.8)
strong_migrations (0.6.5)
strong_migrations (0.6.6)
activerecord (>= 5)
temple (0.8.2)
terminal-table (1.8.0)
@ -698,7 +698,7 @@ DEPENDENCIES
devise-two-factor (~> 3.1)
devise_pam_authenticatable2 (~> 9.2)
discard (~> 1.2)
doorkeeper (~> 5.3)
doorkeeper (~> 5.4)
dotenv-rails (~> 2.7)
e2mmap (~> 0.1.0)
fabrication (~> 2.21)

@ -28,18 +28,6 @@ module Localized
end
def request_locale
preferred_locale || compatible_locale
end
def preferred_locale
http_accept_language.preferred_language_from(available_locales)
end
def compatible_locale
http_accept_language.compatible_language_from(available_locales)
end
def available_locales
I18n.available_locales.reverse
http_accept_language.language_region_compatible_from(I18n.available_locales)
end
end

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 216.4144 232.00976"><path d="M107.86523 0C78.203984.2425 49.672422 3.4535937 33.044922 11.089844c0 0-32.97656262 14.752031-32.97656262 65.082031 0 11.525-.224375 25.306175.140625 39.919925 1.19750002 49.22 9.02375002 97.72843 54.53124962 109.77343 20.9825 5.55375 38.99711 6.71547 53.505856 5.91797 26.31125-1.45875 41.08203-9.38867 41.08203-9.38867l-.86914-19.08984s-18.80171 5.92758-39.91796 5.20508c-20.921254-.7175-43.006879-2.25516-46.390629-27.94141-.3125-2.25625-.46875-4.66938-.46875-7.20313 0 0 20.536953 5.0204 46.564449 6.21289 15.915.73001 30.8393-.93343 45.99805-2.74218 29.07-3.47125 54.38125-21.3818 57.5625-37.74805 5.0125-25.78125 4.59961-62.916015 4.59961-62.916015 0-50.33-32.97461-65.082031-32.97461-65.082031C166.80539 3.4535938 138.255.2425 108.59375 0h-.72852zM74.296875 39.326172c12.355 0 21.710234 4.749297 27.896485 14.248047l6.01367 10.080078 6.01563-10.080078c6.185-9.49875 15.54023-14.248047 27.89648-14.248047 10.6775 0 19.28156 3.753672 25.85156 11.076172 6.36875 7.3225 9.53907 17.218828 9.53907 29.673828v60.941408h-24.14454V81.869141c0-12.46875-5.24453-18.798829-15.73828-18.798829-11.6025 0-17.41797 7.508516-17.41797 22.353516v32.375002H96.207031V85.423828c0-14.845-5.815468-22.353515-17.417969-22.353516-10.49375 0-15.740234 6.330079-15.740234 18.798829v59.148439H38.904297V80.076172c0-12.455 3.171016-22.351328 9.541015-29.673828 6.568751-7.3225 15.172813-11.076172 25.851563-11.076172z" fill="#fff"/></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -192,11 +192,13 @@ class Header extends ImmutablePureComponent {
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
} else {
if (account.getIn(['relationship', 'following'])) {
if (!account.getIn(['relationship', 'muting'])) {
if (account.getIn(['relationship', 'showing_reblogs'])) {
menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
} else {
menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
}
}
menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle });
menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList });

@ -27,6 +27,7 @@ class Option extends React.PureComponent {
title: PropTypes.string.isRequired,
index: PropTypes.number.isRequired,
isPollMultiple: PropTypes.bool,
autoFocus: PropTypes.bool,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onToggleMultiple: PropTypes.func.isRequired,
@ -71,7 +72,7 @@ class Option extends React.PureComponent {
}
render () {
const { isPollMultiple, title, index, intl } = this.props;
const { isPollMultiple, title, index, autoFocus, intl } = this.props;
return (
<li>
@ -96,6 +97,7 @@ class Option extends React.PureComponent {
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
onSuggestionSelected={this.onSuggestionSelected}
searchTokens={[':']}
autoFocus={autoFocus}
/>
</label>
@ -146,10 +148,12 @@ class PollForm extends ImmutablePureComponent {
return null;
}
const autoFocusIndex = options.indexOf('');
return (
<div className='compose-form__poll-wrapper'>
<ul>
{options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} {...other} />)}
{options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} autoFocus={i === autoFocusIndex} {...other} />)}
</ul>
<div className='poll__footer'>

@ -149,6 +149,11 @@
&__avatar {
left: 15px;
top: 17px;
.account__avatar {
width: 48px;
height: 48px;
}
}
&__content {

@ -22,7 +22,12 @@ class ProofProvider::Keybase::ConfigSerializer < ActiveModel::Serializer
end
def logo
{ svg_black: full_asset_url(asset_pack_path('media/images/logo_transparent_black.svg')), svg_full: full_asset_url(asset_pack_path('media/images/logo.svg')) }
{
svg_black: full_asset_url(asset_pack_path('media/images/logo_transparent_black.svg')),
svg_white: full_asset_url(asset_pack_path('media/images/logo_transparent_white.svg')),
svg_full: full_asset_url(asset_pack_path('media/images/logo.svg')),
svg_full_darkmode: full_asset_url(asset_pack_path('media/images/logo.svg')),
}
end
def brand_color

@ -94,11 +94,11 @@ class Web::PushSubscription < ApplicationRecord
def find_or_create_access_token
Doorkeeper::AccessToken.find_or_create_for(
Doorkeeper::Application.find_by(superapp: true),
session_activation.user_id,
Doorkeeper::OAuth::Scopes.from_string('read write follow push'),
Doorkeeper.configuration.access_token_expires_in,
Doorkeeper.configuration.refresh_token_enabled?
application: Doorkeeper::Application.find_by(superapp: true),
resource_owner: session_activation.user_id,
scopes: Doorkeeper::OAuth::Scopes.from_string('read write follow push'),
expires_in: Doorkeeper.configuration.access_token_expires_in,
use_refresh_token: Doorkeeper.configuration.refresh_token_enabled?
)
end
end

@ -73,11 +73,18 @@ class BatchedRemoveStatusService < BaseService
redis.pipelined do
redis.publish('timeline:public', payload)
redis.publish('timeline:public:local', payload) if status.local?
if status.local?
redis.publish('timeline:public:local', payload)
else
redis.publish('timeline:public:remote', payload)
end
if status.media_attachments.any?
redis.publish('timeline:public:media', payload)
redis.publish('timeline:public:local:media', payload) if status.local?
if status.local?
redis.publish('timeline:public:local:media', payload)
else
redis.publish('timeline:public:remote:media', payload)
end
end
@tags[status.id].each do |hashtag|

@ -86,14 +86,22 @@ class FanOutOnWriteService < BaseService
Rails.logger.debug "Delivering status #{status.id} to public timeline"
Redis.current.publish('timeline:public', @payload)
Redis.current.publish('timeline:public:local', @payload) if status.local?
if status.local?
Redis.current.publish('timeline:public:local', @payload)
else
Redis.current.publish('timeline:public:remote', @payload)
end
end
def deliver_to_media(status)
Rails.logger.debug "Delivering status #{status.id} to media timeline"
Redis.current.publish('timeline:public:media', @payload)
Redis.current.publish('timeline:public:local:media', @payload) if status.local?
if status.local?
Redis.current.publish('timeline:public:local:media', @payload)
else
Redis.current.publish('timeline:public:remote:media', @payload)
end
end
def deliver_to_direct_timelines(status)

@ -142,14 +142,22 @@ class RemoveStatusService < BaseService
return unless @status.public_visibility?
redis.publish('timeline:public', @payload)
redis.publish('timeline:public:local', @payload) if @status.local?
if @status.local?
redis.publish('timeline:public:local', @payload)
else
redis.publish('timeline:public:remote', @payload)
end
end
def remove_from_media
return unless @status.public_visibility?
redis.publish('timeline:public:media', @payload)
redis.publish('timeline:public:local:media', @payload) if @status.local?
if @status.local?
redis.publish('timeline:public:local:media', @payload)
else
redis.publish('timeline:public:remote:media', @payload)
end
end
def remove_from_direct

@ -27,7 +27,7 @@
.avatar-stack
- @instance_presenter.sample_accounts.each do |account|
= image_tag current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar'
= image_tag current_account&.user&.setting_auto_play_gif ? account.avatar_original_url : account.avatar_static_url, alt: '', class: 'account__avatar'
- if Setting.timeline_preview
.directory__tag

@ -25,7 +25,7 @@
.directory__card__bar
= link_to TagManager.instance.url_for(account), class: 'directory__card__bar__name' do
.avatar
= image_tag account.avatar.url, alt: '', width: 48, height: 48, class: 'u-photo'
= image_tag account.avatar.url, alt: '', class: 'u-photo'
.display-name
%bdi

@ -3,9 +3,9 @@
= link_to ActivityPub::TagManager.instance.url_for(status.account), class: 'detailed-status__display-name u-url', target: stream_link_target, rel: 'noopener' do
.detailed-status__display-avatar
- if current_account&.user&.setting_auto_play_gif || autoplay
= image_tag status.account.avatar_original_url, width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
= image_tag status.account.avatar_original_url, alt: '', class: 'account__avatar u-photo'
- else
= image_tag status.account.avatar_static_url, width: 48, height: 48, alt: '', class: 'account__avatar u-photo'
= image_tag status.account.avatar_static_url, alt: '', class: 'account__avatar u-photo'
%span.display-name
%bdi
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: autoplay)

@ -9,9 +9,9 @@
.status__avatar
%div
- if current_account&.user&.setting_auto_play_gif || autoplay
= image_tag status.account.avatar_original_url, width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
= image_tag status.account.avatar_original_url, alt: '', class: 'u-photo account__avatar'
- else
= image_tag status.account.avatar_static_url, width: 48, height: 48, alt: '', class: 'u-photo account__avatar'
= image_tag status.account.avatar_static_url, alt: '', class: 'u-photo account__avatar'
%span.display-name
%bdi
%strong.display-name__html.p-name.emojify= display_name(status.account, custom_emojify: true, autoplay: autoplay)

@ -11,7 +11,7 @@ class RedownloadMediaWorker
return if media_attachment.remote_url.blank?
media_attachment.reset_file!
media_attachment.file_remote_url = media_attachment.remote_url
media_attachment.save
rescue ActiveRecord::RecordNotFound
true

@ -55,8 +55,8 @@ module Mastodon
:el,
:en,
:eo,
:'es-AR',
:es,
:'es-AR',
:et,
:eu,
:fa,
@ -97,8 +97,8 @@ module Mastodon
:sk,
:sl,
:sq,
:'sr-Latn',
:sr,
:'sr-Latn',
:sv,
:ta,
:te,

@ -920,7 +920,7 @@ en:
cancelled_msg: Successfully cancelled the redirect.
errors:
already_moved: is the same account you have already moved to
missing_also_known_as: is not back-referencing this account
missing_also_known_as: is not an alias of this account
move_to_self: cannot be current account
not_found: could not be found
on_cooldown: You are on cooldown

@ -0,0 +1,15 @@
class ResetWebAppSecret < ActiveRecord::Migration[5.2]
disable_ddl_transaction!
def up
web_app = Doorkeeper::Application.find_by(superapp: true)
return if web_app.nil?
web_app.renew_secret
web_app.save!
end
def down
end
end

@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2020_05_08_212852) do
ActiveRecord::Schema.define(version: 2020_05_10_110808) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

@ -68,9 +68,9 @@
"@babel/preset-env": "^7.9.6",
"@babel/preset-react": "^7.9.4",
"@babel/runtime": "^7.8.4",
"@clusterws/cws": "^0.17.3",
"@clusterws/cws": "^2.0.0",
"@gamestdio/websocket": "^0.3.2",
"@rails/ujs": "^6.0.2",
"@rails/ujs": "^6.0.3",
"array-includes": "^3.1.1",
"arrow-key-navigation": "^1.1.0",
"atrament": "0.2.4",
@ -128,7 +128,7 @@
"prop-types": "^15.5.10",
"punycode": "^2.1.0",
"react": "^16.13.1",
"react-dom": "^16.13.0",
"react-dom": "^16.13.1",
"react-hotkeys": "^1.1.4",
"react-immutable-proptypes": "^2.2.0",
"react-immutable-pure-component": "^1.1.1",
@ -159,13 +159,13 @@
"stacktrace-js": "^2.0.2",
"stringz": "^2.1.0",
"substring-trie": "^1.0.2",
"terser-webpack-plugin": "^2.3.5",
"terser-webpack-plugin": "^3.0.1",
"tesseract.js": "^2.0.0-alpha.16",
"throng": "^4.0.0",
"tiny-queue": "^0.2.1",
"uuid": "^8.0.0",
"wavesurfer.js": "^3.3.3",
"webpack": "^4.42.1",
"webpack": "^4.43.0",
"webpack-assets-manifest": "^3.1.1",
"webpack-bundle-analyzer": "^3.7.0",
"webpack-cli": "^3.3.11",
@ -185,7 +185,7 @@
"jest": "^25.4.0",
"raf": "^3.4.1",
"react-intl-translations-manager": "^5.0.3",
"react-test-renderer": "^16.13.0",
"react-test-renderer": "^16.13.1",
"sass-lint": "^1.13.1",
"webpack-dev-server": "^3.10.3",
"yargs": "^15.3.1"

@ -21,7 +21,7 @@ RSpec.describe Api::V1::AccountsController, type: :controller do
describe 'POST #create' do
let(:app) { Fabricate(:application) }
let(:token) { Doorkeeper::AccessToken.find_or_create_for(app, nil, 'read write', nil, false) }
let(:token) { Doorkeeper::AccessToken.find_or_create_for(application: app, resource_owner: nil, scopes: 'read write', use_refresh_token: false) }
let(:agreement) { nil }
before do

@ -16,10 +16,16 @@ describe ApplicationController, type: :controller do
end
shared_examples 'default locale' do
it 'sets available and preferred language' do
request.headers['Accept-Language'] = 'sr-Latn'
get 'success'
expect(response.body).to eq 'sr-Latn'
end
it 'sets available and preferred language' do
request.headers['Accept-Language'] = 'ca-ES, fa'
get 'success'
expect(response.body).to eq 'fa'
expect(response.body).to eq 'ca'
end
it 'sets available and compatible language if none of available languages are preferred' do

@ -41,11 +41,11 @@ RSpec.describe Oauth::AuthorizationsController, type: :controller do
context 'when app is already authorized' do
before do
Doorkeeper::AccessToken.find_or_create_for(
app,
user.id,
app.scopes,
Doorkeeper.configuration.access_token_expires_in,
Doorkeeper.configuration.refresh_token_enabled?
application: app,
resource_owner: user.id,
scopes: app.scopes,
expires_in: Doorkeeper.configuration.access_token_expires_in,
use_refresh_token: Doorkeeper.configuration.refresh_token_enabled?
)
end

@ -5,11 +5,12 @@ require 'rails_helper'
RSpec.describe Oauth::TokensController, type: :controller do
describe 'POST #revoke' do
let!(:user) { Fabricate(:user) }
let!(:access_token) { Fabricate(:accessible_access_token, resource_owner_id: user.id) }
let!(:application) { Fabricate(:application, confidential: false) }
let!(:access_token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, application: application) }
let!(:web_push_subscription) { Fabricate(:web_push_subscription, user: user, access_token: access_token) }
before do
post :revoke, params: { token: access_token.token }
post :revoke, params: { client_id: application.uid, token: access_token.token }
end
it 'revokes the token' do

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save