Compare commits
No commits in common. "25e28f4f05c9740dca1237b55ff037d970e86f31" and "ec1f61e4b49f7f5758fb078a2d3d3ca9c0613225" have entirely different histories.
25e28f4f05
...
ec1f61e4b4
46 changed files with 74 additions and 232 deletions
|
@ -17,7 +17,7 @@ jobs:
|
|||
- name: Login to gitea container registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: git.wir-sind-auch-menschen.de
|
||||
registry: git.rabbithole.cyou
|
||||
username: alice-bot
|
||||
password: ${{ secrets.GT_TOKEN }}
|
||||
|
||||
|
@ -26,4 +26,4 @@ jobs:
|
|||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: git.wir-sind-auch-menschen.de/paravielfalt/mastodon:${{ gitea.ref_name }}
|
||||
tags: git.rabbithole.cyou/paravielfalt/mastodon:${{ gitea.ref_name }}
|
||||
|
|
39
CHANGELOG.md
39
CHANGELOG.md
|
@ -2,45 +2,6 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.2.12] - 2024-08-19
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix broken notifications for mentions from local moderators ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31484))
|
||||
|
||||
## [4.2.11] - 2024-08-16
|
||||
|
||||
### Added
|
||||
|
||||
- Add support for incoming `<s>` tag ([mediaformat](https://github.com/mastodon/mastodon/pull/31375))
|
||||
|
||||
### Changed
|
||||
|
||||
- Change logic of block/mute bypass for mentions from moderators to only apply to visible roles with moderation powers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31271))
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix incorrect rate limit on PUT requests ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31356))
|
||||
- Fix presence of `ß` in adjacent word preventing mention and hashtag matching ([adamniedzielski](https://github.com/mastodon/mastodon/pull/31122))
|
||||
- Fix processing of webfinger responses with multiple `self` links ([adamniedzielski](https://github.com/mastodon/mastodon/pull/31110))
|
||||
- Fix duplicate `orderedItems` in user archive's `outbox.json` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31099))
|
||||
- Fix click event handling when clicking outside of an open dropdown menu ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31251))
|
||||
- Fix status processing failing halfway when a remote post has a malformed `replies` attribute ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/31246))
|
||||
- Fix `--verbose` option of `tootctl media remove`, which was previously erroneously removed ([mjankowski](https://github.com/mastodon/mastodon/pull/30536))
|
||||
- Fix division by zero on some video/GIF files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30600))
|
||||
- Fix Web UI trying to save user settings despite being logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30324))
|
||||
- Fix hashtag regexp matching some link anchors ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/30190))
|
||||
- Fix local account search on LDAP login being case-sensitive ([raucao](https://github.com/mastodon/mastodon/pull/30113))
|
||||
- Fix development environment admin account not being auto-approved ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29958))
|
||||
- Fix report reason selector in moderation interface not unselecting rules when changing category ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29026))
|
||||
- Fix already-invalid reports failing to resolve ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/29027))
|
||||
- Fix OCR when using S3/CDN for assets ([vmstan](https://github.com/mastodon/mastodon/pull/28551))
|
||||
- Fix error when encountering malformed `Tag` objects from Kbin ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/28235))
|
||||
- Fix not all allowed image formats showing in file picker when uploading custom emoji ([june128](https://github.com/mastodon/mastodon/pull/28076))
|
||||
- Fix search popout listing unusable search options when logged out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27918))
|
||||
- Fix processing of featured collections lacking an `items` attribute ([tribela](https://github.com/mastodon/mastodon/pull/27581))
|
||||
- Fix `mastodon:stats` decoration of stats rake task ([mjankowski](https://github.com/mastodon/mastodon/pull/31104))
|
||||
|
||||
## [4.2.10] - 2024-07-04
|
||||
|
||||
### Security
|
||||
|
|
|
@ -604,8 +604,8 @@ GEM
|
|||
responders (3.1.0)
|
||||
actionpack (>= 5.2)
|
||||
railties (>= 5.2)
|
||||
rexml (3.3.5)
|
||||
strscan
|
||||
rexml (3.2.8)
|
||||
strscan (>= 3.0.9)
|
||||
rotp (6.3.0)
|
||||
rouge (4.1.2)
|
||||
rpam2 (4.0.2)
|
||||
|
@ -731,7 +731,7 @@ GEM
|
|||
redlock (~> 1.0)
|
||||
strong_migrations (0.8.0)
|
||||
activerecord (>= 5.2)
|
||||
strscan (3.1.0)
|
||||
strscan (3.0.9)
|
||||
swd (1.3.0)
|
||||
activesupport (>= 3)
|
||||
attr_required (>= 0.0.5)
|
||||
|
|
|
@ -4,13 +4,16 @@ Dieses Repository enthält den Quellcode für [paravielfalt.zone](https://paravi
|
|||
|
||||
Die Instanz basiert auf Mastodon und ist vom offiziellen Quellcode-Repository geforkt: <https://github.com/mastodon/mastodon>.
|
||||
|
||||
|
||||
## Änderungsübersicht
|
||||
|
||||
Gegenüber der Mastodon-Standardinstallation gibt es folgende Änderungen.
|
||||
|
||||
- Zeichenlimit von 500 auf 1500 Zeichen erhöht
|
||||
|
||||
[Vollständige Liste aller Änderungen](https://git.wir-sind-auch-menschen.de/paravielfalt/mastodon/compare/stable-4.1...paravielfalt-4.1).
|
||||
|
||||
[Vollständige Liste aller Änderungen](https://git.rabbithole.cyou/paravielfalt/mastodon/compare/stable-4.1...paravielfalt-4.1).
|
||||
|
||||
|
||||
## Neue Version bauen
|
||||
|
||||
|
@ -21,3 +24,5 @@ git tag v4.2.0-pvz$(date '+%y%m%d%H%M')
|
|||
```sh
|
||||
git push --tag
|
||||
```
|
||||
|
||||
Build in Drone aktzeptieren.
|
||||
|
|
|
@ -20,7 +20,7 @@ export function changeSetting(path, value) {
|
|||
}
|
||||
|
||||
const debouncedSave = debounce((dispatch, getState) => {
|
||||
if (getState().getIn(['settings', 'saved']) || !getState().getIn(['meta', 'me'])) {
|
||||
if (getState().getIn(['settings', 'saved'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ class ReportReasonSelector extends PureComponent {
|
|||
|
||||
api().put(`/api/v1/admin/reports/${id}`, {
|
||||
category,
|
||||
rule_ids: category === 'violation' ? rule_ids : [],
|
||||
rule_ids,
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
});
|
||||
|
|
|
@ -40,7 +40,6 @@ class DropdownMenu extends PureComponent {
|
|||
if (this.node && !this.node.contains(e.target)) {
|
||||
this.props.onClose();
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -274,7 +274,6 @@ class Search extends PureComponent {
|
|||
}
|
||||
|
||||
_calculateOptions (value) {
|
||||
const { signedIn } = this.context.identity;
|
||||
const trimmedValue = value.trim();
|
||||
const options = [];
|
||||
|
||||
|
@ -299,7 +298,7 @@ class Search extends PureComponent {
|
|||
|
||||
const couldBeStatusSearch = searchEnabled;
|
||||
|
||||
if (couldBeStatusSearch && signedIn) {
|
||||
if (couldBeStatusSearch) {
|
||||
options.push({ key: 'status-search', label: <FormattedMessage id='search.quick_action.status_search' defaultMessage='Posts matching {x}' values={{ x: <mark>{trimmedValue}</mark> }} />, action: this.handleStatusSearch });
|
||||
}
|
||||
|
||||
|
@ -376,7 +375,7 @@ class Search extends PureComponent {
|
|||
|
||||
<h4><FormattedMessage id='search_popout.options' defaultMessage='Search options' /></h4>
|
||||
|
||||
{searchEnabled && signedIn ? (
|
||||
{searchEnabled ? (
|
||||
<div className='search__popout__menu'>
|
||||
{this.defaultOptions.map(({ key, label, action }, i) => (
|
||||
<button key={key} onMouseDown={action} className={classNames('search__popout__menu__item', { selected: selectedOption === ((options.length || recent.size) + i) })}>
|
||||
|
@ -386,11 +385,7 @@ class Search extends PureComponent {
|
|||
</div>
|
||||
) : (
|
||||
<div className='search__popout__menu__message'>
|
||||
{searchEnabled ? (
|
||||
<FormattedMessage id='search_popout.full_text_search_logged_out_message' defaultMessage='Only available when logged in.' />
|
||||
) : (
|
||||
<FormattedMessage id='search_popout.full_text_search_disabled_message' defaultMessage='Not available on {domain}.' values={{ domain }} />
|
||||
)}
|
||||
<FormattedMessage id='search_popout.full_text_search_disabled_message' defaultMessage='Not available on {domain}.' values={{ domain }} />
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
|
@ -221,7 +221,7 @@ class FocalPointModal extends ImmutablePureComponent {
|
|||
const worker = createWorker({
|
||||
workerPath: tesseractWorkerPath,
|
||||
corePath: tesseractCorePath,
|
||||
langPath: `${assetHost}/ocr/lang-data`,
|
||||
langPath: `${assetHost}/ocr/lang-data/`,
|
||||
logger: ({ status, progress }) => {
|
||||
if (status === 'recognizing text') {
|
||||
this.setState({ ocrStatus: 'detecting', progress });
|
||||
|
|
|
@ -591,7 +591,6 @@
|
|||
"search.quick_action.status_search": "Posts matching {x}",
|
||||
"search.search_or_paste": "Search or paste URL",
|
||||
"search_popout.full_text_search_disabled_message": "Not available on {domain}.",
|
||||
"search_popout.full_text_search_logged_out_message": "Only available when logged in.",
|
||||
"search_popout.language_code": "ISO language code",
|
||||
"search_popout.options": "Search options",
|
||||
"search_popout.quick_actions": "Quick actions",
|
||||
|
|
|
@ -332,15 +332,13 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
|
|||
|
||||
def fetch_replies(status)
|
||||
collection = @object['replies']
|
||||
return if collection.blank?
|
||||
return if collection.nil?
|
||||
|
||||
replies = ActivityPub::FetchRepliesService.new.call(status, collection, allow_synchronous_requests: false, request_id: @options[:request_id])
|
||||
return unless replies.nil?
|
||||
|
||||
uri = value_or_id(collection)
|
||||
ActivityPub::FetchRepliesWorker.perform_async(status.id, uri, { 'request_id' => @options[:request_id] }) unless uri.nil?
|
||||
rescue => e
|
||||
Rails.logger.warn "Error fetching replies: #{e}"
|
||||
end
|
||||
|
||||
def conversation_from_uri(uri)
|
||||
|
|
|
@ -20,6 +20,6 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base
|
|||
serialized_hash = serialized_hash.select { |k, _| options[:fields].include?(k) } if options[:fields]
|
||||
serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options)
|
||||
|
||||
{ '@context': serialized_context(named_contexts, context_extensions) }.merge(serialized_hash)
|
||||
{ '@context' => serialized_context(named_contexts, context_extensions) }.merge(serialized_hash)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -41,8 +41,8 @@ class VideoMetadataExtractor
|
|||
@colorspace = video_stream[:pix_fmt]
|
||||
@width = video_stream[:width]
|
||||
@height = video_stream[:height]
|
||||
@frame_rate = parse_framerate(video_stream[:avg_frame_rate])
|
||||
@r_frame_rate = parse_framerate(video_stream[:r_frame_rate])
|
||||
@frame_rate = video_stream[:avg_frame_rate] == '0/0' ? nil : Rational(video_stream[:avg_frame_rate])
|
||||
@r_frame_rate = video_stream[:r_frame_rate] == '0/0' ? nil : Rational(video_stream[:r_frame_rate])
|
||||
# For some video streams the frame_rate reported by `ffprobe` will be 0/0, but for these streams we
|
||||
# should use `r_frame_rate` instead. Video screencast generated by Gnome Screencast have this issue.
|
||||
@frame_rate ||= @r_frame_rate
|
||||
|
@ -55,10 +55,4 @@ class VideoMetadataExtractor
|
|||
|
||||
@invalid = true if @metadata.key?(:error)
|
||||
end
|
||||
|
||||
def parse_framerate(raw)
|
||||
Rational(raw)
|
||||
rescue ZeroDivisionError
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,8 +6,6 @@ class Webfinger
|
|||
class RedirectError < Error; end
|
||||
|
||||
class Response
|
||||
ACTIVITYPUB_READY_TYPE = ['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].freeze
|
||||
|
||||
attr_reader :uri
|
||||
|
||||
def initialize(uri, body)
|
||||
|
@ -22,28 +20,17 @@ class Webfinger
|
|||
end
|
||||
|
||||
def link(rel, attribute)
|
||||
links.dig(rel, 0, attribute)
|
||||
end
|
||||
|
||||
def self_link_href
|
||||
self_link.fetch('href')
|
||||
links.dig(rel, attribute)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def links
|
||||
@links ||= @json.fetch('links', []).group_by { |link| link['rel'] }
|
||||
end
|
||||
|
||||
def self_link
|
||||
links.fetch('self', []).find do |link|
|
||||
ACTIVITYPUB_READY_TYPE.include?(link['type'])
|
||||
end
|
||||
@links ||= @json['links'].index_by { |link| link['rel'] }
|
||||
end
|
||||
|
||||
def validate_response!
|
||||
raise Webfinger::Error, "Missing subject in response for #{@uri}" if subject.blank?
|
||||
raise Webfinger::Error, "Missing self link in response for #{@uri}" if self_link.blank?
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ class Account < ApplicationRecord
|
|||
BACKGROUND_REFRESH_INTERVAL = 1.week.freeze
|
||||
|
||||
USERNAME_RE = /[a-z0-9_]+([a-z0-9_.-]+[a-z0-9_]+)?/i
|
||||
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}
|
||||
MENTION_RE = %r{(?<![=/[:word:]])@((#{USERNAME_RE})(?:@[[:word:].-]+[[:word:]]+)?)}i
|
||||
URL_PREFIX_RE = %r{\Ahttp(s?)://[^/]+}
|
||||
USERNAME_ONLY_RE = /\A#{USERNAME_RE}\z/i
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ module LdapAuthenticable
|
|||
safe_username = safe_username.gsub(keys, replacement)
|
||||
end
|
||||
|
||||
resource = joins(:account).merge(Account.where(Account.arel_table[:username].lower.eq safe_username.downcase)).take
|
||||
resource = joins(:account).find_by(accounts: { username: safe_username })
|
||||
|
||||
if resource.blank?
|
||||
resource = new(email: attributes[Devise.ldap_mail.to_sym].first, agreement: true, account_attributes: { username: safe_username }, admin: false, external: true, confirmed_at: Time.now.utc)
|
||||
|
|
|
@ -44,9 +44,9 @@ class Report < ApplicationRecord
|
|||
delegate :local?, to: :account
|
||||
|
||||
validates :comment, length: { maximum: 1_000 }, if: :local?
|
||||
validates :rule_ids, absence: true, if: -> { (category_changed? || rule_ids_changed?) && !violation? }
|
||||
validates :rule_ids, absence: true, unless: :violation?
|
||||
|
||||
validate :validate_rule_ids, if: -> { (category_changed? || rule_ids_changed?) && violation? }
|
||||
validate :validate_rule_ids
|
||||
|
||||
# entries here need to be kept in sync with the front-end:
|
||||
# - app/javascript/mastodon/features/notifications/components/report.jsx
|
||||
|
@ -154,6 +154,8 @@ class Report < ApplicationRecord
|
|||
end
|
||||
|
||||
def validate_rule_ids
|
||||
return unless violation?
|
||||
|
||||
errors.add(:rule_ids, I18n.t('reports.errors.invalid_rules')) unless rules.size == rule_ids&.size
|
||||
end
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ class Tag < ApplicationRecord
|
|||
HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)'
|
||||
HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}"
|
||||
|
||||
HASHTAG_RE = %r{(?<![=/)\p{Alnum}])#(#{HASHTAG_NAME_PAT})}
|
||||
HASHTAG_RE = %r{(?<![=/)\w])#(#{HASHTAG_NAME_PAT})}i
|
||||
HASHTAG_NAME_RE = /\A(#{HASHTAG_NAME_PAT})\z/i
|
||||
HASHTAG_INVALID_CHARS_RE = /[^[:alnum:]#{HASHTAG_SEPARATORS}]/
|
||||
|
||||
|
|
|
@ -37,8 +37,6 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService
|
|||
end
|
||||
|
||||
def process_items(items)
|
||||
return if items.nil?
|
||||
|
||||
process_note_items(items) if @options[:note]
|
||||
process_hashtag_items(items) if @options[:hashtag]
|
||||
end
|
||||
|
|
|
@ -49,7 +49,7 @@ class ActivityPub::FetchRemoteActorService < BaseService
|
|||
confirmed_username, confirmed_domain = split_acct(webfinger.subject)
|
||||
|
||||
if @username.casecmp(confirmed_username).zero? && @domain.casecmp(confirmed_domain).zero?
|
||||
raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.self_link_href != @uri
|
||||
raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.link('self', 'href') != @uri
|
||||
|
||||
return
|
||||
end
|
||||
|
@ -58,7 +58,8 @@ class ActivityPub::FetchRemoteActorService < BaseService
|
|||
@username, @domain = split_acct(webfinger.subject)
|
||||
|
||||
raise Webfinger::RedirectError, "Too many webfinger redirects for URI #{@uri} (stopped at #{@username}@#{@domain})" unless confirmed_username.casecmp(@username).zero? && confirmed_domain.casecmp(@domain).zero?
|
||||
raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.self_link_href != @uri
|
||||
|
||||
raise Error, "Webfinger response for #{@username}@#{@domain} does not loop back to #{@uri}" if webfinger.link('self', 'href') != @uri
|
||||
rescue Webfinger::RedirectError => e
|
||||
raise Error, e.message
|
||||
rescue Webfinger::Error => e
|
||||
|
|
|
@ -172,9 +172,9 @@ class ActivityPub::ProcessStatusUpdateService < BaseService
|
|||
|
||||
as_array(@json['tag']).each do |tag|
|
||||
if equals_or_includes?(tag['type'], 'Hashtag')
|
||||
@raw_tags << tag['name'] if tag['name'].present?
|
||||
@raw_tags << tag['name']
|
||||
elsif equals_or_includes?(tag['type'], 'Mention')
|
||||
@raw_mentions << tag['href'] if tag['href'].present?
|
||||
@raw_mentions << tag['href']
|
||||
elsif equals_or_includes?(tag['type'], 'Emoji')
|
||||
@raw_emojis << tag
|
||||
end
|
||||
|
|
|
@ -19,8 +19,8 @@ class BackupService < BaseService
|
|||
|
||||
def build_outbox_json!(file)
|
||||
skeleton = serialize(collection_presenter, ActivityPub::CollectionSerializer)
|
||||
skeleton[:@context] = full_context
|
||||
skeleton[:orderedItems] = ['!PLACEHOLDER!']
|
||||
skeleton['@context'] = full_context
|
||||
skeleton['orderedItems'] = ['!PLACEHOLDER!']
|
||||
skeleton = Oj.dump(skeleton)
|
||||
prepend, append = skeleton.split('"!PLACEHOLDER!"')
|
||||
add_comma = false
|
||||
|
@ -33,7 +33,7 @@ class BackupService < BaseService
|
|||
|
||||
file.write(statuses.map do |status|
|
||||
item = serialize_payload(ActivityPub::ActivityPresenter.from_status(status), ActivityPub::ActivitySerializer)
|
||||
item.delete(:@context)
|
||||
item.delete('@context')
|
||||
|
||||
unless item[:type] == 'Announce' || item[:object][:attachment].blank?
|
||||
item[:object][:attachment].each do |attachment|
|
||||
|
|
|
@ -86,8 +86,7 @@ class NotifyService < BaseService
|
|||
end
|
||||
|
||||
def from_staff?
|
||||
sender = @notification.from_account
|
||||
sender.local? && sender.user.present? && sender.user_role&.overrides?(@recipient.user_role) && sender.user_role&.highlighted? && sender.user_role&.can?(*UserRole::Flags::CATEGORIES[:moderation].map(&:to_sym))
|
||||
@notification.from_account.local? && @notification.from_account.user.present? && @notification.from_account.user_role&.overrides?(@recipient.user_role)
|
||||
end
|
||||
|
||||
def optional_non_following_and_direct?
|
||||
|
|
|
@ -104,6 +104,8 @@ class ResolveAccountService < BaseService
|
|||
end
|
||||
|
||||
def fetch_account!
|
||||
return unless activitypub_ready?
|
||||
|
||||
with_redis_lock("resolve:#{@username}@#{@domain}") do
|
||||
@account = ActivityPub::FetchRemoteAccountService.new.call(actor_url, suppress_errors: @options[:suppress_errors])
|
||||
end
|
||||
|
@ -118,8 +120,12 @@ class ResolveAccountService < BaseService
|
|||
@options[:skip_cache] || @account.nil? || @account.possibly_stale?
|
||||
end
|
||||
|
||||
def activitypub_ready?
|
||||
['application/activity+json', 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"'].include?(@webfinger.link('self', 'type'))
|
||||
end
|
||||
|
||||
def actor_url
|
||||
@actor_url ||= @webfinger.self_link_href
|
||||
@actor_url ||= @webfinger.link('self', 'href')
|
||||
end
|
||||
|
||||
def gone_from_origin?
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
.fields-group
|
||||
= f.input :shortcode, wrapper: :with_label, label: t('admin.custom_emojis.shortcode'), hint: t('admin.custom_emojis.shortcode_hint')
|
||||
.fields-group
|
||||
= f.input :image, wrapper: :with_label, input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(',') }, hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT))
|
||||
= f.input :image, wrapper: :with_label, input_html: { accept: CustomEmoji::IMAGE_MIME_TYPES.join(' ') }, hint: t('admin.custom_emojis.image_hint', size: number_to_human_size(CustomEmoji::LIMIT))
|
||||
|
||||
.actions
|
||||
= f.button :button, t('admin.custom_emojis.upload'), type: :submit
|
||||
|
|
|
@ -142,7 +142,7 @@ class Rack::Attack
|
|||
end
|
||||
|
||||
throttle('throttle_password_change/account', limit: 10, period: 10.minutes) do |req|
|
||||
req.warden_user_id if (req.put? || req.patch?) && (req.path_matches?('/auth') || req.path_matches?('/auth/password'))
|
||||
req.warden_user_id if req.put? || (req.patch? && req.path_matches?('/auth'))
|
||||
end
|
||||
|
||||
self.throttled_responder = lambda do |request|
|
||||
|
|
|
@ -7,7 +7,5 @@ if Rails.env.development?
|
|||
admin = Account.where(username: 'admin').first_or_initialize(username: 'admin')
|
||||
admin.save(validate: false)
|
||||
|
||||
user = User.where(email: "admin@#{domain}").first_or_initialize(email: "admin@#{domain}", password: 'mastodonadmin', password_confirmation: 'mastodonadmin', confirmed_at: Time.now.utc, role: UserRole.find_by(name: 'Owner'), account: admin, agreement: true, approved: true)
|
||||
user.save!
|
||||
user.approve!
|
||||
User.where(email: "admin@#{domain}").first_or_initialize(email: "admin@#{domain}", password: 'mastodonadmin', password_confirmation: 'mastodonadmin', confirmed_at: Time.now.utc, role: UserRole.find_by(name: 'Owner'), account: admin, agreement: true, approved: true).save!
|
||||
end
|
||||
|
|
|
@ -56,7 +56,7 @@ services:
|
|||
|
||||
web:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.12
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.10
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||
|
@ -77,7 +77,7 @@ services:
|
|||
|
||||
streaming:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.12
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.10
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: node ./streaming
|
||||
|
@ -95,7 +95,7 @@ services:
|
|||
|
||||
sidekiq:
|
||||
build: .
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.12
|
||||
image: ghcr.io/mastodon/mastodon:v4.2.10
|
||||
restart: always
|
||||
env_file: .env.production
|
||||
command: bundle exec sidekiq
|
||||
|
|
|
@ -13,7 +13,6 @@ module Mastodon::CLI
|
|||
option :remove_headers, type: :boolean, default: false
|
||||
option :include_follows, type: :boolean, default: false
|
||||
option :concurrency, type: :numeric, default: 5, aliases: [:c]
|
||||
option :verbose, type: :boolean, default: false, aliases: [:v]
|
||||
option :dry_run, type: :boolean, default: false
|
||||
desc 'remove', 'Remove remote media files, headers or avatars'
|
||||
long_desc <<-DESC
|
||||
|
|
|
@ -13,7 +13,7 @@ module Mastodon
|
|||
end
|
||||
|
||||
def patch
|
||||
12
|
||||
10
|
||||
end
|
||||
|
||||
def default_prerelease
|
||||
|
|
|
@ -65,7 +65,7 @@ class Sanitize
|
|||
end
|
||||
|
||||
MASTODON_STRICT ||= freeze_config(
|
||||
elements: %w(p br span a del s pre blockquote code b strong u i em ul ol li),
|
||||
elements: %w(p br span a del pre blockquote code b strong u i em ul ol li),
|
||||
|
||||
attributes: {
|
||||
'a' => %w(href rel class translate),
|
||||
|
|
|
@ -9,13 +9,11 @@ namespace :mastodon do
|
|||
[
|
||||
['App Libraries', 'app/lib'],
|
||||
%w(Presenters app/presenters),
|
||||
%w(Policies app/policies),
|
||||
%w(Serializers app/serializers),
|
||||
%w(Services app/services),
|
||||
%w(Validators app/validators),
|
||||
%w(Workers app/workers),
|
||||
].each do |name, dir|
|
||||
STATS_DIRECTORIES << [name, dir]
|
||||
STATS_DIRECTORIES << [name, Rails.root.join(dir)]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,4 +4,4 @@ Content-Type: application/jrd+json; charset=utf-8
|
|||
X-Content-Type-Options: nosniff
|
||||
Date: Sun, 17 Sep 2017 06:22:50 GMT
|
||||
|
||||
{"subject":"acct:foo@ap.example.com","aliases":["https://ap.example.com/@foo","https://ap.example.com/users/foo"],"links":[{"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://ap.example.com/@foo"},{"rel":"http://schemas.google.com/g/2010#updates-from","type":"application/atom+xml","href":"https://ap.example.com/users/foo.atom"},{"rel":"self","type":"application/html","href":"https://ap.example.com/users/foo.html"},{"rel":"self","type":"application/activity+json","href":"https://ap.example.com/users/foo"},{"rel":"self","type":"application/json","href":"https://ap.example.com/users/foo.json"},{"rel":"salmon","href":"https://ap.example.com/api/salmon/1"},{"rel":"magic-public-key","href":"data:application/magic-public-key,RSA.u3L4vnpNLzVH31MeWI394F0wKeJFsLDAsNXGeOu0QF2x-h1zLWZw_agqD2R3JPU9_kaDJGPIV2Sn5zLyUA9S6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh8lDET6X4Pyw-ZJU0_OLo_41q9w-OrGtlsTm_PuPIeXnxa6BLqnDaxC-4IcjG_FiPahNCTINl_1F_TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq-t8nhQYkgAkt64euWpva3qL5KD1mTIZQEP-LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3QvuHQ==.AQAB"},{"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://ap.example.com/authorize_follow?acct={uri}"}]}
|
||||
{"subject":"acct:foo@ap.example.com","aliases":["https://ap.example.com/@foo","https://ap.example.com/users/foo"],"links":[{"rel":"http://webfinger.net/rel/profile-page","type":"text/html","href":"https://ap.example.com/@foo"},{"rel":"http://schemas.google.com/g/2010#updates-from","type":"application/atom+xml","href":"https://ap.example.com/users/foo.atom"},{"rel":"self","type":"application/activity+json","href":"https://ap.example.com/users/foo"},{"rel":"salmon","href":"https://ap.example.com/api/salmon/1"},{"rel":"magic-public-key","href":"data:application/magic-public-key,RSA.u3L4vnpNLzVH31MeWI394F0wKeJFsLDAsNXGeOu0QF2x-h1zLWZw_agqD2R3JPU9_kaDJGPIV2Sn5zLyUA9S6swCCMOtn7BBR9g9sucgXJmUFB0tACH2QSgHywMAybGfmSb3LsEMNKsGJ9VsvYoh8lDET6X4Pyw-ZJU0_OLo_41q9w-OrGtlsTm_PuPIeXnxa6BLqnDaxC-4IcjG_FiPahNCTINl_1F_TgSSDZ4Taf4U9XFEIFw8wmgploELozzIzKq-t8nhQYkgAkt64euWpva3qL5KD1mTIZQEP-LZvh3s2WHrLi3fhbdRuwQ2c0KkJA2oSTFPDpqqbPGZ3QvuHQ==.AQAB"},{"rel":"http://ostatus.org/schema/1.0/subscribe","template":"https://ap.example.com/authorize_follow?acct={uri}"}]}
|
2
spec/fixtures/requests/webfinger.txt
vendored
2
spec/fixtures/requests/webfinger.txt
vendored
|
@ -8,4 +8,4 @@ Access-Control-Allow-Origin: *
|
|||
Vary: Accept-Encoding,Cookie
|
||||
Strict-Transport-Security: max-age=31536000; includeSubdomains;
|
||||
|
||||
{"subject":"acct:gargron@quitter.no","aliases":["https:\/\/quitter.no\/user\/7477","https:\/\/quitter.no\/gargron","https:\/\/quitter.no\/index.php\/user\/7477","https:\/\/quitter.no\/index.php\/gargron"],"links":[{"rel":"http:\/\/webfinger.net\/rel\/profile-page","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/gmpg.org\/xfn\/11","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"describedby","type":"application\/rdf+xml","href":"https:\/\/quitter.no\/gargron\/foaf"},{"rel":"self","type":"application/activity+json","href":"https://ap.example.com/users/foo"},{"rel":"http:\/\/apinamespace.org\/atom","type":"application\/atomsvc+xml","href":"https:\/\/quitter.no\/api\/statusnet\/app\/service\/gargron.xml"},{"rel":"http:\/\/apinamespace.org\/twitter","href":"https:\/\/quitter.no\/api\/"},{"rel":"http:\/\/specs.openid.net\/auth\/2.0\/provider","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/schemas.google.com\/g\/2010#updates-from","type":"application\/atom+xml","href":"https:\/\/quitter.no\/api\/statuses\/user_timeline\/7477.atom"},{"rel":"magic-public-key","href":"data:application\/magic-public-key,RSA.1ZBkHTavLvxH3FzlKv4O6WtlILKRFfNami3_Rcu8EuogtXSYiS-bB6hElZfUCSHbC4uLemOA34PEhz__CDMozax1iI_t8dzjDnh1x0iFSup7pSfW9iXk_WU3Dm74yWWW2jildY41vWgrEstuQ1dJ8vVFfSJ9T_tO4c-T9y8vDI8=.AQAB"},{"rel":"salmon","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-replies","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-mention","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/ostatus.org\/schema\/1.0\/subscribe","template":"https:\/\/quitter.no\/main\/ostatussub?profile={uri}"}]}
|
||||
{"subject":"acct:gargron@quitter.no","aliases":["https:\/\/quitter.no\/user\/7477","https:\/\/quitter.no\/gargron","https:\/\/quitter.no\/index.php\/user\/7477","https:\/\/quitter.no\/index.php\/gargron"],"links":[{"rel":"http:\/\/webfinger.net\/rel\/profile-page","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/gmpg.org\/xfn\/11","type":"text\/html","href":"https:\/\/quitter.no\/gargron"},{"rel":"describedby","type":"application\/rdf+xml","href":"https:\/\/quitter.no\/gargron\/foaf"},{"rel":"http:\/\/apinamespace.org\/atom","type":"application\/atomsvc+xml","href":"https:\/\/quitter.no\/api\/statusnet\/app\/service\/gargron.xml"},{"rel":"http:\/\/apinamespace.org\/twitter","href":"https:\/\/quitter.no\/api\/"},{"rel":"http:\/\/specs.openid.net\/auth\/2.0\/provider","href":"https:\/\/quitter.no\/gargron"},{"rel":"http:\/\/schemas.google.com\/g\/2010#updates-from","type":"application\/atom+xml","href":"https:\/\/quitter.no\/api\/statuses\/user_timeline\/7477.atom"},{"rel":"magic-public-key","href":"data:application\/magic-public-key,RSA.1ZBkHTavLvxH3FzlKv4O6WtlILKRFfNami3_Rcu8EuogtXSYiS-bB6hElZfUCSHbC4uLemOA34PEhz__CDMozax1iI_t8dzjDnh1x0iFSup7pSfW9iXk_WU3Dm74yWWW2jildY41vWgrEstuQ1dJ8vVFfSJ9T_tO4c-T9y8vDI8=.AQAB"},{"rel":"salmon","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-replies","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/salmon-protocol.org\/ns\/salmon-mention","href":"https:\/\/quitter.no\/main\/salmon\/user\/7477"},{"rel":"http:\/\/ostatus.org\/schema\/1.0\/subscribe","template":"https:\/\/quitter.no\/main\/ostatussub?profile={uri}"}]}
|
||||
|
|
|
@ -59,7 +59,7 @@ RSpec.describe ActivityPub::Adapter do
|
|||
let(:serializer_class) { TestWithBasicContextSerializer }
|
||||
|
||||
it 'renders a basic @context' do
|
||||
expect(subject).to include({ '@context': 'https://www.w3.org/ns/activitystreams' })
|
||||
expect(subject).to include({ '@context' => 'https://www.w3.org/ns/activitystreams' })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -67,7 +67,7 @@ RSpec.describe ActivityPub::Adapter do
|
|||
let(:serializer_class) { TestWithNamedContextSerializer }
|
||||
|
||||
it 'renders a @context with both items' do
|
||||
expect(subject).to include({ '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
|
||||
expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -75,7 +75,7 @@ RSpec.describe ActivityPub::Adapter do
|
|||
let(:serializer_class) { TestWithNestedNamedContextSerializer }
|
||||
|
||||
it 'renders a @context with both items' do
|
||||
expect(subject).to include({ '@context': ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
|
||||
expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', 'https://w3id.org/security/v1'] })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -83,7 +83,7 @@ RSpec.describe ActivityPub::Adapter do
|
|||
let(:serializer_class) { TestWithContextExtensionSerializer }
|
||||
|
||||
it 'renders a @context with the extension' do
|
||||
expect(subject).to include({ '@context': ['https://www.w3.org/ns/activitystreams', { 'sensitive' => 'as:sensitive' }] })
|
||||
expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', { 'sensitive' => 'as:sensitive' }] })
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -91,7 +91,7 @@ RSpec.describe ActivityPub::Adapter do
|
|||
let(:serializer_class) { TestWithNestedContextExtensionSerializer }
|
||||
|
||||
it 'renders a @context with both extensions' do
|
||||
expect(subject).to include({ '@context': ['https://www.w3.org/ns/activitystreams', { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', 'sensitive' => 'as:sensitive' }] })
|
||||
expect(subject).to include({ '@context' => ['https://www.w3.org/ns/activitystreams', { 'manuallyApprovesFollowers' => 'as:manuallyApprovesFollowers', 'sensitive' => 'as:sensitive' }] })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'rails_helper'
|
||||
|
||||
RSpec.describe Webfinger do
|
||||
describe 'self link' do
|
||||
context 'when self link is specified with type application/activity+json' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
|
||||
it 'correctly parses the response' do
|
||||
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
|
||||
|
||||
response = described_class.new('acct:alice@example.com').perform
|
||||
|
||||
expect(response.self_link_href).to eq 'https://example.com/alice'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when self link is specified with type application/ld+json' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' }] } }
|
||||
|
||||
it 'correctly parses the response' do
|
||||
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
|
||||
|
||||
response = described_class.new('acct:alice@example.com').perform
|
||||
|
||||
expect(response.self_link_href).to eq 'https://example.com/alice'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when self link is specified with incorrect type' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/json"' }] } }
|
||||
|
||||
it 'raises an error' do
|
||||
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' })
|
||||
|
||||
expect { described_class.new('acct:alice@example.com').perform }.to raise_error(Webfinger::Error)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -703,14 +703,6 @@ RSpec.describe Account do
|
|||
it 'does not match URL query string' do
|
||||
expect(subject.match('https://example.com/?x=@alice')).to be_nil
|
||||
end
|
||||
|
||||
it 'matches usernames immediately following the letter ß' do
|
||||
expect(subject.match('Hello toß @alice from me')[1]).to eq 'alice'
|
||||
end
|
||||
|
||||
it 'matches usernames containing uppercase characters' do
|
||||
expect(subject.match('Hello to @aLice@Example.com from me')[1]).to eq 'aLice@Example.com'
|
||||
end
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
|
|
|
@ -133,18 +133,5 @@ describe Report do
|
|||
report = Fabricate.build(:report, account: remote_account, comment: Faker::Lorem.characters(number: 1001))
|
||||
expect(report.valid?).to be true
|
||||
end
|
||||
|
||||
it 'is invalid if it references invalid rules' do
|
||||
report = Fabricate.build(:report, category: :violation, rule_ids: [-1])
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:rule_ids)
|
||||
end
|
||||
|
||||
it 'is invalid if it references rules but category is not "violation"' do
|
||||
rule = Fabricate(:rule)
|
||||
report = Fabricate.build(:report, category: :spam, rule_ids: rule.id)
|
||||
expect(report.valid?).to be false
|
||||
expect(report).to model_have_error_on_field(:rule_ids)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -36,10 +36,6 @@ RSpec.describe Tag do
|
|||
expect(subject.match('https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111895#c4')).to be_nil
|
||||
end
|
||||
|
||||
it 'does not match URLs with hashtag-like anchors after a non-ascii character' do
|
||||
expect(subject.match('https://example.org/testé#foo')).to be_nil
|
||||
end
|
||||
|
||||
it 'does not match URLs with hashtag-like anchors after an empty query parameter' do
|
||||
expect(subject.match('https://en.wikipedia.org/wiki/Ghostbusters_(song)?foo=#Lawsuit')).to be_nil
|
||||
end
|
||||
|
@ -95,14 +91,6 @@ RSpec.describe Tag do
|
|||
it 'does not match purely-numeric hashtags' do
|
||||
expect(subject.match('hello #0123456')).to be_nil
|
||||
end
|
||||
|
||||
it 'matches hashtags immediately following the letter ß' do
|
||||
expect(subject.match('Hello toß #ruby').to_s).to eq '#ruby'
|
||||
end
|
||||
|
||||
it 'matches hashtags containing uppercase characters' do
|
||||
expect(subject.match('Hello #rubyOnRails').to_s).to eq '#rubyOnRails'
|
||||
end
|
||||
end
|
||||
|
||||
describe '#to_param' do
|
||||
|
|
|
@ -42,22 +42,12 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do
|
|||
}
|
||||
end
|
||||
|
||||
let(:featured_with_null) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'https://example.com/account/collections/featured',
|
||||
totalItems: 0,
|
||||
type: 'OrderedCollection',
|
||||
}
|
||||
end
|
||||
|
||||
let(:items) do
|
||||
[
|
||||
'https://example.com/account/pinned/known', # known
|
||||
status_json_pinned_unknown_inlined, # unknown inlined
|
||||
'https://example.com/account/pinned/unknown-unreachable', # unknown unreachable
|
||||
'https://example.com/account/pinned/unknown-reachable', # unknown reachable
|
||||
'https://example.com/account/collections/featured', # featured with null
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -76,7 +66,6 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do
|
|||
stub_request(:get, 'https://example.com/account/pinned/unknown-inlined').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_inlined), headers: { 'Content-Type': 'application/activity+json' })
|
||||
stub_request(:get, 'https://example.com/account/pinned/unknown-unreachable').to_return(status: 404)
|
||||
stub_request(:get, 'https://example.com/account/pinned/unknown-reachable').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_reachable), headers: { 'Content-Type': 'application/activity+json' })
|
||||
stub_request(:get, 'https://example.com/account/collections/featured').to_return(status: 200, body: Oj.dump(featured_with_null), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
||||
subject.call(actor, note: true, hashtag: false)
|
||||
end
|
||||
|
|
|
@ -39,7 +39,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||
end
|
||||
|
||||
context 'when the account does not have a inbox' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
actor[:inbox] = nil
|
||||
|
@ -64,7 +64,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||
end
|
||||
|
||||
context 'when URI and WebFinger share the same host' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -90,7 +90,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -122,7 +122,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -145,7 +145,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI after a redirection' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -39,7 +39,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do
|
|||
end
|
||||
|
||||
context 'when the account does not have a inbox' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
actor[:inbox] = nil
|
||||
|
@ -64,7 +64,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do
|
|||
end
|
||||
|
||||
context 'when URI and WebFinger share the same host' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -90,7 +90,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger presents different domain than URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -122,7 +122,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
@ -145,7 +145,7 @@ RSpec.describe ActivityPub::FetchRemoteActorService, type: :service do
|
|||
end
|
||||
|
||||
context 'when WebFinger returns a different URI after a redirection' do
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob', type: 'application/activity+json' }] } }
|
||||
let!(:webfinger) { { subject: 'acct:alice@iscool.af', links: [{ rel: 'self', href: 'https://example.com/bob' }] } }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor), headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -5,7 +5,7 @@ require 'rails_helper'
|
|||
RSpec.describe ActivityPub::FetchRemoteKeyService, type: :service do
|
||||
subject { described_class.new }
|
||||
|
||||
let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice', type: 'application/activity+json' }] } }
|
||||
let(:webfinger) { { subject: 'acct:alice@example.com', links: [{ rel: 'self', href: 'https://example.com/alice' }] } }
|
||||
|
||||
let(:public_key_pem) do
|
||||
<<~TEXT
|
||||
|
|
|
@ -217,7 +217,7 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
|
|||
}.with_indifferent_access
|
||||
webfinger = {
|
||||
subject: "acct:user#{i}@foo.test",
|
||||
links: [{ rel: 'self', href: "https://foo.test/users/#{i}", type: 'application/activity+json' }],
|
||||
links: [{ rel: 'self', href: "https://foo.test/users/#{i}" }],
|
||||
}.with_indifferent_access
|
||||
stub_request(:get, "https://foo.test/users/#{i}").to_return(status: 200, body: actor_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
|
||||
stub_request(:get, "https://foo.test/users/#{i}/featured").to_return(status: 200, body: featured_json.to_json, headers: { 'Content-Type': 'application/activity+json' })
|
||||
|
|
|
@ -60,7 +60,6 @@ RSpec.describe BackupService, type: :service do
|
|||
|
||||
aggregate_failures do
|
||||
expect(body.scan('@context').count).to eq 1
|
||||
expect(body.scan('orderedItems').count).to eq 1
|
||||
expect(json['@context']).to_not be_nil
|
||||
expect(json['type']).to eq 'OrderedCollection'
|
||||
expect(json['totalItems']).to eq 2
|
||||
|
|
|
@ -18,17 +18,6 @@ RSpec.describe NotifyService, type: :service do
|
|||
expect { subject }.to_not change(Notification, :count)
|
||||
end
|
||||
|
||||
context 'when the sender is a local moderator' do
|
||||
let(:sender) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')).account }
|
||||
let(:type) { :mention }
|
||||
let(:activity) { Fabricate(:mention, account: recipient, status: Fabricate(:status, account: sender)) }
|
||||
|
||||
it 'does notify when the sender is blocked' do
|
||||
recipient.block!(sender)
|
||||
expect { subject }.to change(Notification, :count).by(1)
|
||||
end
|
||||
end
|
||||
|
||||
it 'does not notify when sender is muted with hide_notifications' do
|
||||
recipient.mute!(sender, notifications: true)
|
||||
expect { subject }.to_not change(Notification, :count)
|
||||
|
|
Loading…
Reference in a new issue