Merge pull request #1712 from ClearlyClaire/glitch-soc/merge-upstream

Merge upstream changes
local
Claire 2 years ago committed by GitHub
commit f03148f441
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      app/controllers/api/v1/accounts_controller.rb
  2. 2
      app/controllers/api/v1/blocks_controller.rb
  3. 4
      app/controllers/api/v1/domain_blocks_controller.rb
  4. 6
      app/controllers/api/v1/follow_requests_controller.rb
  5. 2
      app/controllers/api/v1/media_controller.rb
  6. 2
      app/controllers/api/v1/mutes_controller.rb
  7. 17
      app/javascript/mastodon/features/getting_started/index.js
  8. 3
      app/javascript/mastodon/features/ui/components/link_footer.js
  9. 3
      app/javascript/mastodon/features/ui/components/navigation_panel.js
  10. 2
      app/lib/activitypub/activity/announce.rb
  11. 4
      app/lib/activitypub/activity/follow.rb
  12. 2
      app/lib/activitypub/activity/like.rb
  13. 5
      app/lib/activitypub/activity/update.rb
  14. 2
      app/lib/formatter.rb
  15. 1
      app/models/account_statuses_cleanup_policy.rb
  16. 2
      app/services/bootstrap_timeline_service.rb
  17. 2
      app/services/favourite_service.rb
  18. 10
      app/views/about/_logged_in.html.haml
  19. 28
      app/views/about/_registration.html.haml
  20. 5
      app/views/about/show.html.haml
  21. 2
      app/workers/feed_insert_worker.rb
  22. 8
      app/workers/poll_expiration_notify_worker.rb
  23. 4
      config/locales/en.yml
  24. 1
      spec/views/about/show.html.haml_spec.rb

@ -2,9 +2,9 @@
class Api::V1::AccountsController < Api::BaseController
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, except: [:create, :follow, :unfollow, :remove_from_followers, :block, :unblock, :mute, :unmute]
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
before_action -> { doorkeeper_authorize! :follow, :'write:mutes' }, only: [:mute, :unmute]
before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, only: [:block, :unblock]
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, only: [:follow, :unfollow, :remove_from_followers]
before_action -> { doorkeeper_authorize! :follow, :write, :'write:mutes' }, only: [:mute, :unmute]
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, only: [:block, :unblock]
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, only: [:create]
before_action :require_user!, except: [:show, :create]

@ -1,7 +1,7 @@
# frozen_string_literal: true
class Api::V1::BlocksController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }
before_action -> { doorkeeper_authorize! :follow, :read, :'read:blocks' }
before_action :require_user!
after_action :insert_pagination_headers

@ -3,8 +3,8 @@
class Api::V1::DomainBlocksController < Api::BaseController
BLOCK_LIMIT = 100
before_action -> { doorkeeper_authorize! :follow, :'read:blocks' }, only: :show
before_action -> { doorkeeper_authorize! :follow, :'write:blocks' }, except: :show
before_action -> { doorkeeper_authorize! :follow, :read, :'read:blocks' }, only: :show
before_action -> { doorkeeper_authorize! :follow, :write, :'write:blocks' }, except: :show
before_action :require_user!
after_action :insert_pagination_headers, only: :show

@ -1,8 +1,8 @@
# frozen_string_literal: true
class Api::V1::FollowRequestsController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'read:follows' }, only: :index
before_action -> { doorkeeper_authorize! :follow, :'write:follows' }, except: :index
before_action -> { doorkeeper_authorize! :follow, :read, :'read:follows' }, only: :index
before_action -> { doorkeeper_authorize! :follow, :write, :'write:follows' }, except: :index
before_action :require_user!
after_action :insert_pagination_headers, only: :index
@ -13,7 +13,7 @@ class Api::V1::FollowRequestsController < Api::BaseController
def authorize
AuthorizeFollowService.new.call(account, current_account)
NotifyService.new.call(current_account, :follow, Follow.find_by(account: account, target_account: current_account))
LocalNotificationWorker.perform_async(current_account.id, Follow.find_by(account: account, target_account: current_account).id, 'Follow', 'follow')
render json: account, serializer: REST::RelationshipSerializer, relationships: relationships
end

@ -31,7 +31,7 @@ class Api::V1::MediaController < Api::BaseController
end
def set_media_attachment
@media_attachment = current_account.media_attachments.unattached.find(params[:id])
@media_attachment = current_account.media_attachments.where(status_id: nil).find(params[:id])
end
def check_processing

@ -1,7 +1,7 @@
# frozen_string_literal: true
class Api::V1::MutesController < Api::BaseController
before_action -> { doorkeeper_authorize! :follow, :'read:mutes' }
before_action -> { doorkeeper_authorize! :follow, :read, :'read:mutes' }
before_action :require_user!
after_action :insert_pagination_headers

@ -7,7 +7,7 @@ import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { me, profile_directory, showTrends } from '../../initial_state';
import { me, showTrends } from '../../initial_state';
import { fetchFollowRequests } from 'mastodon/actions/accounts';
import { List as ImmutableList } from 'immutable';
import NavigationContainer from '../compose/containers/navigation_container';
@ -35,7 +35,6 @@ const messages = defineMessages({
personal: { id: 'navigation_bar.personal', defaultMessage: 'Personal' },
security: { id: 'navigation_bar.security', defaultMessage: 'Security' },
menu: { id: 'getting_started.heading', defaultMessage: 'Getting started' },
profile_directory: { id: 'getting_started.directory', defaultMessage: 'Profile directory' },
});
const mapStateToProps = state => ({
@ -104,25 +103,11 @@ class GettingStarted extends ImmutablePureComponent {
height += 34 + 48*2;
if (profile_directory) {
navItems.push(
<ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
);
height += 48;
}
navItems.push(
<ColumnSubheading key='header-personal' text={intl.formatMessage(messages.personal)} />,
);
height += 34;
} else if (profile_directory) {
navItems.push(
<ColumnLink key='directory' icon='address-book' text={intl.formatMessage(messages.profile_directory)} to='/directory' />,
);
height += 48;
}
if (multiColumn && !columns.find(item => item.get('id') === 'HOME')) {

@ -3,7 +3,7 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import { invitesEnabled, limitedFederationMode, version, repository, source_url } from 'mastodon/initial_state';
import { invitesEnabled, limitedFederationMode, version, repository, source_url, profile_directory as profileDirectory } from 'mastodon/initial_state';
import { logOut } from 'mastodon/utils/log_out';
import { openModal } from 'mastodon/actions/modal';
@ -52,6 +52,7 @@ class LinkFooter extends React.PureComponent {
{withHotkeys && <li><Link to='/keyboard-shortcuts'><FormattedMessage id='navigation_bar.keyboard_shortcuts' defaultMessage='Hotkeys' /></Link> · </li>}
<li><a href='/auth/edit'><FormattedMessage id='getting_started.security' defaultMessage='Security' /></a> · </li>
{!limitedFederationMode && <li><a href='/about/more' target='_blank'><FormattedMessage id='navigation_bar.info' defaultMessage='About this server' /></a> · </li>}
{profileDirectory && <li><Link to='/directory'><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></Link> · </li>}
<li><a href='https://joinmastodon.org/apps' target='_blank'><FormattedMessage id='navigation_bar.apps' defaultMessage='Mobile apps' /></a> · </li>
<li><a href='/terms' target='_blank'><FormattedMessage id='getting_started.terms' defaultMessage='Terms of service' /></a> · </li>
<li><a href='/settings/applications' target='_blank'><FormattedMessage id='getting_started.developers' defaultMessage='Developers' /></a> · </li>

@ -2,7 +2,7 @@ import React from 'react';
import { NavLink, withRouter } from 'react-router-dom';
import { FormattedMessage } from 'react-intl';
import Icon from 'mastodon/components/icon';
import { profile_directory, showTrends } from 'mastodon/initial_state';
import { showTrends } from 'mastodon/initial_state';
import NotificationsCounterIcon from './notifications_counter_icon';
import FollowRequestsNavLink from './follow_requests_nav_link';
import ListPanel from './list_panel';
@ -20,7 +20,6 @@ const NavigationPanel = () => (
<NavLink className='column-link column-link--transparent' to='/favourites'><Icon className='column-link__icon' id='star' fixedWidth /><FormattedMessage id='navigation_bar.favourites' defaultMessage='Favourites' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/bookmarks'><Icon className='column-link__icon' id='bookmark' fixedWidth /><FormattedMessage id='navigation_bar.bookmarks' defaultMessage='Bookmarks' /></NavLink>
<NavLink className='column-link column-link--transparent' to='/lists'><Icon className='column-link__icon' id='list-ul' fixedWidth /><FormattedMessage id='navigation_bar.lists' defaultMessage='Lists' /></NavLink>
{profile_directory && <NavLink className='column-link column-link--transparent' to='/directory'><Icon className='column-link__icon' id='address-book-o' fixedWidth /><FormattedMessage id='getting_started.directory' defaultMessage='Profile directory' /></NavLink>}
<ListPanel />

@ -35,7 +35,7 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
def distribute
# Notify the author of the original status if that status is local
NotifyService.new.call(@status.reblog.account, :reblog, @status) if reblog_of_local_account?(@status) && !reblog_by_following_group_account?(@status)
LocalNotificationWorker.perform_async(@status.reblog.account_id, @status.id, 'Status', 'reblog') if reblog_of_local_account?(@status) && !reblog_by_following_group_account?(@status)
# Distribute into home and list feeds
::DistributionWorker.perform_async(@status.id) if @options[:override_timestamps] || @status.within_realtime_window?

@ -31,10 +31,10 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
follow_request = FollowRequest.create!(account: @account, target_account: target_account, uri: @json['id'])
if target_account.locked? || @account.silenced?
NotifyService.new.call(target_account, :follow_request, follow_request)
LocalNotificationWorker.perform_async(target_account.id, follow_request.id, 'FollowRequest', 'follow_request')
else
AuthorizeFollowService.new.call(@account, target_account)
NotifyService.new.call(target_account, :follow, ::Follow.find_by(account: @account, target_account: target_account))
LocalNotificationWorker.perform_async(target_account.id, ::Follow.find_by(account: @account, target_account: target_account).id, 'Follow', 'follow')
end
end

@ -8,7 +8,7 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
favourite = original_status.favourites.create!(account: @account)
NotifyService.new.call(original_status.account, :favourite, favourite)
LocalNotificationWorker.perform_async(original_status.account_id, favourite.id, 'Favourite', 'favourite')
Trends.statuses.register(original_status)
end
end

@ -26,11 +26,6 @@ class ActivityPub::Activity::Update < ActivityPub::Activity
return if @status.nil?
forwarder.forward! if forwarder.forwardable?
ActivityPub::ProcessStatusUpdateService.new.call(@status, @object)
end
def forwarder
@forwarder ||= ActivityPub::Forwarder.new(@account, @json, @status)
end
end

@ -90,6 +90,8 @@ class Formatter
end
def simplified_format(account, **options)
return '' if account.note.blank?
html = account.local? ? linkify(account.note) : reformat(account.note)
html = encode_custom_emojis(html, account.emojis, options[:autoplay]) if options[:custom_emojify]
html.html_safe # rubocop:disable Rails/OutputSafety

@ -23,6 +23,7 @@ class AccountStatusesCleanupPolicy < ApplicationRecord
include Redisable
ALLOWED_MIN_STATUS_AGE = [
1.week.seconds,
2.weeks.seconds,
1.month.seconds,
2.months.seconds,

@ -18,7 +18,7 @@ class BootstrapTimelineService < BaseService
def notify_staff!
User.staff.includes(:account).find_each do |user|
NotifyService.new.call(user.account, :'admin.sign_up', @source_account)
LocalNotificationWorker.perform_async(user.account_id, @source_account.id, 'Account', 'admin.sign_up')
end
end
end

@ -31,7 +31,7 @@ class FavouriteService < BaseService
status = favourite.status
if status.account.local?
NotifyService.new.call(status.account, :favourite, favourite)
LocalNotificationWorker.perform_async(status.account_id, favourite.id, 'Favourite', 'favourite')
elsif status.account.activitypub?
ActivityPub::DeliveryWorker.perform_async(build_json(favourite), favourite.account_id, status.account.inbox_url)
end

@ -0,0 +1,10 @@
.simple_form
%p.lead= t('about.logged_in_as_html', username: content_tag(:strong, current_account.username))
.actions
= link_to t('about.continue_to_web'), root_url, class: 'button button-primary'
.form-footer
%ul.no-list
%li= link_to t('about.get_apps'), 'https://joinmastodon.org/apps', target: '_blank', rel: 'noopener noreferrer'
%li= link_to t('auth.logout'), destroy_user_session_path, data: { method: :delete }

@ -1,17 +1,20 @@
.simple_form__overlay-area{ class: (closed_registrations? && @instance_presenter.closed_registrations_message.present?) ? 'simple_form__overlay-area__blurred' : '' }
- disabled = closed_registrations? || omniauth_only? || current_account.present?
- show_message = disabled && (current_user.present? || @instance_presenter.closed_registrations_message.present?)
.simple_form__overlay-area{ class: show_message ? 'simple_form__overlay-area__blurred' : '' }
= simple_form_for(new_user, url: user_registration_path, namespace: 'registration', html: { novalidate: false }) do |f|
%p.lead= t('about.federation_hint_html', instance: content_tag(:strong, site_hostname))
.fields-group
= f.simple_fields_for :account do |account_fields|
= account_fields.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false, disabled: closed_registrations?
= account_fields.input :username, wrapper: :with_label, label: false, required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.username'), :autocomplete => 'off', placeholder: t('simple_form.labels.defaults.username'), pattern: '[a-zA-Z0-9_]+', maxlength: 30 }, append: "@#{site_hostname}", hint: false, disabled: disabled
= f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
= f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: false, disabled: closed_registrations?
= f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
= f.input :email, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email'), :autocomplete => 'off' }, hint: false, disabled: disabled
= f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off', :minlength => User.password_length.first, :maxlength => User.password_length.last }, hint: false, disabled: disabled
= f.input :password_confirmation, placeholder: t('simple_form.labels.defaults.confirm_password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.confirm_password'), :autocomplete => 'off' }, hint: false, disabled: disabled
= f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
= f.input :website, as: :url, placeholder: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' }, hint: false, disabled: closed_registrations?
= f.input :confirm_password, as: :string, placeholder: t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: t('simple_form.labels.defaults.password')), :autocomplete => 'off' }, hint: false, disabled: disabled
= f.input :website, as: :url, placeholder: t('simple_form.labels.defaults.honeypot', label: 'Website'), required: false, input_html: { 'aria-label' => t('simple_form.labels.defaults.honeypot', label: 'Website'), :autocomplete => 'off' }, hint: false, disabled: disabled
- if approved_registrations?
.fields-group
@ -19,13 +22,16 @@
= invite_request_fields.input :text, as: :text, wrapper: :with_block_label, required: Setting.require_invite_text
.fields-group
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path), required: true, disabled: closed_registrations?
= f.input :agreement, as: :boolean, wrapper: :with_label, label: t('auth.checkbox_agreement_html', rules_path: about_more_path, terms_path: terms_path), required: true, disabled: disabled
.actions
= f.button :button, sign_up_message, type: :submit, class: 'button button-primary', disabled: closed_registrations?
= f.button :button, sign_up_message, type: :submit, class: 'button button-primary', disabled: disabled
- if closed_registrations? && @instance_presenter.closed_registrations_message.present?
- if show_message
.simple_form__overlay-area__overlay
.simple_form__overlay-area__overlay__content.rich-formatting
.block-icon= fa_icon 'warning'
= @instance_presenter.closed_registrations_message.html_safe
- if current_account.present?
= t('about.logout_before_registering')
- else
= @instance_presenter.closed_registrations_message.html_safe

@ -46,7 +46,10 @@
.landing__grid__column.landing__grid__column-login
.box-widget
= render 'login'
- if current_user.present?
= render 'logged_in'
- else
= render 'login'
.hero-widget
.hero-widget__img

@ -74,7 +74,7 @@ class FeedInsertWorker
end
def perform_notify
NotifyService.new.call(@follower, :status, @status)
LocalNotificationWorker.perform_async(@follower.id, @status.id, 'Status', 'status')
end
def update?

@ -38,12 +38,14 @@ class PollExpirationNotifyWorker
def notify_remote_voters_and_owner!
ActivityPub::DistributePollUpdateWorker.perform_async(@poll.status.id)
NotifyService.new.call(@poll.account, :poll, @poll)
LocalNotificationWorker.perform_async(@poll.account_id, @poll.id, 'Poll', 'poll')
end
def notify_local_voters!
@poll.voters.merge(Account.local).find_each do |account|
NotifyService.new.call(account, :poll, @poll)
@poll.voters.merge(Account.local).select(:id).find_in_batches do |accounts|
LocalNotificationWorker.push_bulk(accounts) do |account|
[account.id, @poll.id, 'Poll', 'poll']
end
end
end
end

@ -16,6 +16,7 @@ en:
contact: Contact
contact_missing: Not set
contact_unavailable: N/A
continue_to_web: Continue to web app
discover_users: Discover users
documentation: Documentation
federation_hint_html: With an account on %{instance} you'll be able to follow people on any Mastodon server and beyond.
@ -25,6 +26,8 @@ en:
This account is a virtual actor used to represent the server itself and not any individual user.
It is used for federation purposes and should not be blocked unless you want to block the whole instance, in which case you should use a domain block.
learn_more: Learn more
logged_in_as_html: You are currently logged in as %{username}.
logout_before_registering: You are already logged in.
privacy_policy: Privacy policy
rules: Server rules
rules_html: 'Below is a summary of rules you need to follow if you want to have an account on this server of Mastodon:'
@ -1484,6 +1487,7 @@ en:
'2629746': 1 month
'31556952': 1 year
'5259492': 2 months
'604800': 1 week
'63113904': 2 years
'7889238': 3 months
min_age_label: Age threshold

@ -10,6 +10,7 @@ describe 'about/show.html.haml', without_verify_partial_doubles: true do
allow(view).to receive(:site_title).and_return('example site')
allow(view).to receive(:new_user).and_return(User.new)
allow(view).to receive(:use_seamless_external_login?).and_return(false)
allow(view).to receive(:current_account).and_return(nil)
end
it 'has valid open graph tags' do

Loading…
Cancel
Save