Merge remote-tracking branch 'upstream/main' into attribution-domains-api

This commit is contained in:
Christian Schmidt 2024-10-31 23:24:41 +01:00
commit 7974cc9c2e
62 changed files with 371 additions and 216 deletions

View File

@ -124,7 +124,6 @@ jobs:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
steps:
@ -226,7 +225,6 @@ jobs:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
steps:
@ -305,7 +303,6 @@ jobs:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
@ -422,7 +419,6 @@ jobs:
fail-fast: false
matrix:
ruby-version:
- '3.1'
- '3.2'
- '.ruby-version'
search-image:

2
.nvmrc
View File

@ -1 +1 @@
20.18
22.11

View File

@ -8,7 +8,7 @@ AllCops:
- lib/mastodon/migration_helpers.rb
ExtraDetails: true
NewCops: enable
TargetRubyVersion: 3.1 # Oldest supported ruby version
TargetRubyVersion: 3.2 # Oldest supported ruby version
inherit_from:
- .rubocop/layout.yml

View File

@ -15,7 +15,7 @@ ARG BUILDPLATFORM=${BUILDPLATFORM}
ARG RUBY_VERSION="3.3.5"
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
# renovate: datasource=node-version depName=node
ARG NODE_MAJOR_VERSION="20"
ARG NODE_MAJOR_VERSION="22"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
@ -191,7 +191,7 @@ FROM build AS libvips
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
ARG VIPS_VERSION=8.15.5
ARG VIPS_VERSION=8.16.0
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
source 'https://rubygems.org'
ruby '>= 3.1.0'
ruby '>= 3.2.0'
gem 'propshaft'
gem 'puma', '~> 6.3'
@ -18,8 +18,8 @@ gem 'aws-sdk-s3', '~> 1.123', require: false
gem 'blurhash', '~> 0.1'
gem 'fog-core', '<= 2.6.0'
gem 'fog-openstack', '~> 1.0', require: false
gem 'jd-paperclip-azure', '~> 3.0', require: false
gem 'kt-paperclip', '~> 7.2'
gem 'md-paperclip-azure', '~> 2.2', require: false
gem 'ruby-vips', '~> 2.2', require: false
gem 'active_model_serializers', '~> 0.10'

View File

@ -115,14 +115,8 @@ GEM
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-eventstream (~> 1, >= 1.0.2)
azure-storage-blob (2.0.3)
azure-storage-common (~> 2.0)
nokogiri (~> 1, >= 1.10.8)
azure-storage-common (2.0.4)
faraday (~> 1.0)
faraday_middleware (~> 1.0, >= 1.0.0.rc1)
net-http-persistent (~> 4.0)
nokogiri (~> 1, >= 1.10.8)
azure-blob (0.5.2)
rexml
base64 (0.2.0)
bcp47_spec (0.2.1)
bcrypt (3.1.20)
@ -258,8 +252,6 @@ GEM
faraday-patron (1.0.0)
faraday-rack (1.0.0)
faraday-retry (1.0.3)
faraday_middleware (1.2.0)
faraday (~> 1.0)
fast_blank (1.0.1)
fastimage (2.3.1)
ffi (1.17.0)
@ -350,6 +342,10 @@ GEM
irb (1.14.1)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jd-paperclip-azure (3.0.0)
addressable (~> 2.5)
azure-blob (~> 0.5.2)
hashie (~> 5.0)
jmespath (1.6.2)
json (2.7.4)
json-canonicalization (1.0.0)
@ -424,10 +420,6 @@ GEM
mario-redis-lock (1.2.1)
redis (>= 3.0.5)
matrix (0.4.2)
md-paperclip-azure (2.2.0)
addressable (~> 2.5)
azure-storage-blob (~> 2.0.1)
hashie (~> 5.0)
memory_profiler (1.1.0)
mime-types (3.6.0)
logger
@ -442,8 +434,6 @@ GEM
mutex_m (0.2.0)
net-http (0.4.1)
uri
net-http-persistent (4.0.2)
connection_pool (~> 2.2)
net-imap (0.5.0)
date
net-protocol
@ -664,7 +654,7 @@ GEM
rails-html-sanitizer (1.6.0)
loofah (~> 2.21)
nokogiri (~> 1.14)
rails-i18n (7.0.9)
rails-i18n (7.0.10)
i18n (>= 0.7, < 2)
railties (>= 6.0.0, < 8)
railties (7.1.4.2)
@ -782,7 +772,7 @@ GEM
scenic (1.8.0)
activerecord (>= 4.0.0)
railties (>= 4.0.0)
selenium-webdriver (4.25.0)
selenium-webdriver (4.26.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
@ -823,7 +813,7 @@ GEM
stoplight (4.1.0)
redlock (~> 1.0)
stringio (3.1.1)
strong_migrations (2.0.1)
strong_migrations (2.0.2)
activerecord (>= 6.1)
swd (1.3.0)
activesupport (>= 3)
@ -903,7 +893,7 @@ GEM
xorcist (1.1.3)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.6.18)
zeitwerk (2.7.1)
PLATFORMS
ruby
@ -958,6 +948,7 @@ DEPENDENCIES
idn-ruby
inline_svg
irb (~> 1.8)
jd-paperclip-azure (~> 3.0)
json-ld
json-ld-preloaded (~> 3.2)
json-schema (~> 5.0)
@ -969,7 +960,6 @@ DEPENDENCIES
lograge (~> 0.12)
mail (~> 2.8)
mario-redis-lock (~> 1.2)
md-paperclip-azure (~> 2.2)
memory_profiler
mime-types (~> 3.6.0)
net-http (~> 0.4.0)

View File

@ -69,7 +69,7 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre
- **PostgreSQL** 12+
- **Redis** 4+
- **Ruby** 3.1+
- **Ruby** 3.2+
- **Node.js** 18+
The repository includes deployment configurations for **Docker and docker-compose** as well as specific platforms like **Heroku**, and **Scalingo**. For Helm charts, reference the [mastodon/chart repository](https://github.com/mastodon/chart). The [**standalone** installation guide](https://docs.joinmastodon.org/admin/install/) is available in the documentation.

View File

@ -41,11 +41,11 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
end
end
def outbox_url(**kwargs)
def outbox_url(**)
if params[:account_username].present?
account_outbox_url(@account, **kwargs)
account_outbox_url(@account, **)
else
instance_actor_outbox_url(**kwargs)
instance_actor_outbox_url(**)
end
end

View File

@ -106,8 +106,8 @@ class Api::V1::AccountsController < Api::BaseController
render json: { error: I18n.t('accounts.self_follow_error') }, status: 403 if current_user.account.id == @account.id
end
def relationships(**options)
AccountRelationshipsPresenter.new([@account], current_user.account_id, **options)
def relationships(**)
AccountRelationshipsPresenter.new([@account], current_user.account_id, **)
end
def account_ids

View File

@ -28,8 +28,8 @@ class Api::V1::FollowRequestsController < Api::BaseController
@account ||= Account.find(params[:id])
end
def relationships(**options)
AccountRelationshipsPresenter.new([account], current_user.account_id, **options)
def relationships(**)
AccountRelationshipsPresenter.new([account], current_user.account_id, **)
end
def load_accounts

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class Oauth::UserinfoController < Api::BaseController
before_action -> { doorkeeper_authorize! :profile }, only: [:show]
before_action :require_user!
def show
@account = current_account
render json: @account, serializer: OauthUserinfoSerializer
end
end

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
module MediaComponentHelper
def render_video_component(status, **options)
def render_video_component(status, **)
video = status.ordered_media_attachments.first
meta = video.file.meta || {}
@ -18,14 +18,14 @@ module MediaComponentHelper
media: [
serialize_media_attachment(video),
].as_json,
}.merge(**options)
}.merge(**)
react_component :video, component_params do
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
end
end
def render_audio_component(status, **options)
def render_audio_component(status, **)
audio = status.ordered_media_attachments.first
meta = audio.file.meta || {}
@ -38,19 +38,19 @@ module MediaComponentHelper
foregroundColor: meta.dig('colors', 'foreground'),
accentColor: meta.dig('colors', 'accent'),
duration: meta.dig('original', 'duration'),
}.merge(**options)
}.merge(**)
react_component :audio, component_params do
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }
end
end
def render_media_gallery_component(status, **options)
def render_media_gallery_component(status, **)
component_params = {
sensitive: sensitive_viewer?(status, current_account),
autoplay: prefers_autoplay?,
media: status.ordered_media_attachments.map { |a| serialize_media_attachment(a).as_json },
}.merge(**options)
}.merge(**)
react_component :media_gallery, component_params do
render partial: 'statuses/attachment_list', locals: { attachments: status.ordered_media_attachments }

View File

@ -14,8 +14,8 @@ module RoutingHelper
end
end
def full_asset_url(source, **options)
source = ActionController::Base.helpers.asset_url(source, **options) unless use_storage?
def full_asset_url(source, **)
source = ActionController::Base.helpers.asset_url(source, **) unless use_storage?
URI.join(asset_host, source).to_s
end
@ -24,12 +24,12 @@ module RoutingHelper
Rails.configuration.action_controller.asset_host || root_url
end
def frontend_asset_path(source, **options)
asset_pack_path("media/#{source}", **options)
def frontend_asset_path(source, **)
asset_pack_path("media/#{source}", **)
end
def frontend_asset_url(source, **options)
full_asset_url(frontend_asset_path(source, **options))
def frontend_asset_url(source, **)
full_asset_url(frontend_asset_path(source, **))
end
def use_storage?

View File

@ -152,7 +152,7 @@ export const DetailedStatus: React.FC<{
media = <PictureInPicturePlaceholder aspectRatio={attachmentAspectRatio} />;
} else if (status.get('media_attachments').size > 0) {
if (
['image', 'gifv'].includes(
['image', 'gifv', 'unknown'].includes(
status.getIn(['media_attachments', 0, 'type']) as string,
) ||
status.get('media_attachments').size > 1

View File

@ -13,7 +13,7 @@
"about.rules": "Rheolau'r gweinydd",
"account.account_note_header": "Nodyn personol",
"account.add_or_remove_from_list": "Ychwanegu neu Ddileu o'r rhestrau",
"account.badges.bot": "Bot",
"account.badges.bot": "Awtomataidd",
"account.badges.group": "Grŵp",
"account.block": "Blocio @{name}",
"account.block_domain": "Blocio parth {domain}",
@ -386,6 +386,7 @@
"interaction_modal.description.follow": "Gyda chyfrif ar Mastodon, gallwch ddilyn {name} i dderbyn eu postiadau yn eich ffrwd gartref.",
"interaction_modal.description.reblog": "Gyda chyfrif ar Mastodon, gallwch hybu'r postiad hwn i'w rannu â'ch dilynwyr.",
"interaction_modal.description.reply": "Gyda chyfrif ar Mastodon, gallwch ymateb i'r postiad hwn.",
"interaction_modal.description.vote": "Gyda chyfrif ar Mastodon, gallwch bleidleisio yn y bleidlais hon.",
"interaction_modal.login.action": "Mynd i'm ffrwd gartref",
"interaction_modal.login.prompt": "Parth eich gweinydd cartref, e.e. mastodon.social",
"interaction_modal.no_account_yet": "Dim ar Mastodon?",
@ -397,6 +398,7 @@
"interaction_modal.title.follow": "Dilyn {name}",
"interaction_modal.title.reblog": "Hybu postiad {name}",
"interaction_modal.title.reply": "Ymateb i bostiad {name}",
"interaction_modal.title.vote": "Pleidleisiwch ym mhleidlais {name}",
"intervals.full.days": "{number, plural, one {# diwrnod} two {# ddiwrnod} other {# diwrnod}}",
"intervals.full.hours": "{number, plural, one {# awr} other {# o oriau}}",
"intervals.full.minutes": "{number, plural, one {# funud} other {# o funudau}}",

View File

@ -386,7 +386,7 @@
"interaction_modal.description.follow": "Con una cuenta en Mastodon, podés seguir a {name} para recibir sus mensajes en tu línea temporal principal.",
"interaction_modal.description.reblog": "Con una cuenta en Mastodon, podés adherir a este mensaje para compartirlo con tus propios seguidores.",
"interaction_modal.description.reply": "Con una cuenta en Mastodon, podés responder a este mensaje.",
"interaction_modal.description.vote": "Con una cuenta en Mastodon, puedes votar en esta encuesta.",
"interaction_modal.description.vote": "Con una cuenta en Mastodon, podés votar en esta encuesta.",
"interaction_modal.login.action": "Llevame al comienzo",
"interaction_modal.login.prompt": "Dominio de su servidor de inicio, p. ej., mastodon.social",
"interaction_modal.no_account_yet": "¿No tenés cuenta en Mastodon?",
@ -398,7 +398,7 @@
"interaction_modal.title.follow": "Seguir a {name}",
"interaction_modal.title.reblog": "Adherir al mensaje de {name}",
"interaction_modal.title.reply": "Responder al mensaje de {name}",
"interaction_modal.title.vote": "Vota en la encuesta de {name}",
"interaction_modal.title.vote": "Votá en la encuesta de {name}",
"intervals.full.days": "{number, plural, one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",

View File

@ -398,7 +398,7 @@
"interaction_modal.title.follow": "Seguir a {name}",
"interaction_modal.title.reblog": "Impulsar la publicación de {name}",
"interaction_modal.title.reply": "Responder la publicación de {name}",
"interaction_modal.title.vote": "Vota en la encuesta de {name}",
"interaction_modal.title.vote": "Votar en la encuesta de {name}",
"intervals.full.days": "{number, plural, one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",

View File

@ -158,6 +158,7 @@
"compose_form.poll.duration": "Küsitluse kestus",
"compose_form.poll.multiple": "Mitu vastust",
"compose_form.poll.option_placeholder": "Valik {number}",
"compose_form.poll.single": "Üks valik",
"compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks",
"compose_form.poll.switch_to_single": "Muuda küsitlust ainult ühe valiku lubamiseks",
"compose_form.poll.type": "Stiil",
@ -196,6 +197,7 @@
"confirmations.unfollow.title": "Ei jälgi enam kasutajat?",
"content_warning.hide": "Peida postitus",
"content_warning.show": "Näita ikkagi",
"content_warning.show_more": "Näita rohkem",
"conversation.delete": "Kustuta vestlus",
"conversation.mark_as_read": "Märgi loetuks",
"conversation.open": "Vaata vestlust",
@ -304,6 +306,7 @@
"filter_modal.select_filter.subtitle": "Kasuta olemasolevat kategooriat või loo uus",
"filter_modal.select_filter.title": "Filtreeri seda postitust",
"filter_modal.title.status": "Postituse filtreerimine",
"filter_warning.matches_filter": "Sobib filtriga “<span>{title}</span>”",
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {Mitte üheltki inimeselt} one {Ühelt inimeselt} other {# inimeselt}}, keda võid teada",
"filtered_notifications_banner.title": "Filtreeritud teavitused",
"firehose.all": "Kõik",
@ -383,6 +386,7 @@
"interaction_modal.description.follow": "Mastodoni kontoga saad jälgida kasutajat {name}, et tema postitusi oma koduvoos näha.",
"interaction_modal.description.reblog": "Mastodoni kontoga saad seda postitust levitada, jagades seda oma jälgijatele.",
"interaction_modal.description.reply": "Mastodoni kontoga saad sellele postitusele vastata.",
"interaction_modal.description.vote": "Mastodoni kontoga saad sellest küsitlusest osa võtta.",
"interaction_modal.login.action": "Vii mind avalehele",
"interaction_modal.login.prompt": "Sinu koduserveri domeen, näiteks mastodon.social",
"interaction_modal.no_account_yet": "Pole Mastodonis?",
@ -394,6 +398,7 @@
"interaction_modal.title.follow": "Jälgi kontot {name}",
"interaction_modal.title.reblog": "Jaga {name} postitust",
"interaction_modal.title.reply": "Vasta kasutaja {name} postitusele",
"interaction_modal.title.vote": "Hääleta {name} küsitluses",
"intervals.full.days": "{number, plural, one {# päev} other {# päeva}}",
"intervals.full.hours": "{number, plural, one {# tund} other {# tundi}}",
"intervals.full.minutes": "{number, plural, one {# minut} other {# minutit}}",
@ -506,6 +511,7 @@
"notification.favourite": "{name} märkis su postituse lemmikuks",
"notification.favourite.name_and_others_with_link": "{name} ja <a>{count, plural, one {# veel} other {# teist}}</a> märkis su postituse lemmikuks",
"notification.follow": "{name} alustas su jälgimist",
"notification.follow.name_and_others": "{name} ja veel {count, plural, one {# kasutaja} other {# kasutajat}} hakkas sind jälgima",
"notification.follow_request": "{name} soovib sind jälgida",
"notification.follow_request.name_and_others": "{name} ja {count, plural, one {# veel} other {# teist}} taotles sinu jälgimist",
"notification.label.mention": "Mainimine",
@ -564,6 +570,7 @@
"notifications.column_settings.filter_bar.category": "Kiirfiltri riba",
"notifications.column_settings.follow": "Uued jälgijad:",
"notifications.column_settings.follow_request": "Uued jälgimistaotlused:",
"notifications.column_settings.group": "Grupp",
"notifications.column_settings.mention": "Mainimised:",
"notifications.column_settings.poll": "Küsitluse tulemused:",
"notifications.column_settings.push": "Push teated",

View File

@ -158,7 +158,7 @@
"compose_form.poll.duration": "Äänestyksen kesto",
"compose_form.poll.multiple": "Monivalinta",
"compose_form.poll.option_placeholder": "Vaihtoehto {number}",
"compose_form.poll.single": "Yksittäisvalinta",
"compose_form.poll.single": "Yksi vaihtoehto",
"compose_form.poll.switch_to_multiple": "Muuta äänestys monivalinnaksi",
"compose_form.poll.switch_to_single": "Muuta äänestys yksittäisvalinnaksi",
"compose_form.poll.type": "Tyyli",
@ -386,7 +386,7 @@
"interaction_modal.description.follow": "Mastodon-tilillä voit seurata käyttäjää {name} saadaksesi hänen julkaisunsa kotisyötteeseesi.",
"interaction_modal.description.reblog": "Mastodon-tilillä voit tehostaa tätä julkaisua jakaaksesi sen seuraajiesi kanssa.",
"interaction_modal.description.reply": "Mastodon-tilillä voit vastata tähän julkaisuun.",
"interaction_modal.description.vote": "Mastodon-tilillä voit osallistua tähän äänestykseen.",
"interaction_modal.description.vote": "Osallistuminen äänestykseen onnistuu Mastodon-tilillä.",
"interaction_modal.login.action": "Siirry kotiin",
"interaction_modal.login.prompt": "Kotipalvelimesi verkkotunnus, kuten mastodon.social",
"interaction_modal.no_account_yet": "Etkö ole vielä Mastodonissa?",
@ -439,8 +439,8 @@
"lightbox.close": "Sulje",
"lightbox.next": "Seuraava",
"lightbox.previous": "Edellinen",
"lightbox.zoom_in": "Zoomaa todelliseen kokoon",
"lightbox.zoom_out": "Zoomaa mahtumaan",
"lightbox.zoom_in": "Näytä todellisen kokoisena",
"lightbox.zoom_out": "Näytä sovitettuna",
"limited_account_hint.action": "Näytä profiili joka tapauksessa",
"limited_account_hint.title": "Palvelimen {domain} moderaattorit ovat piilottaneet tämän profiilin.",
"link_preview.author": "Tehnyt {name}",

View File

@ -129,6 +129,7 @@
"confirmations.discard_edit_media.confirm": "Ipagpaliban",
"confirmations.edit.confirm": "Baguhin",
"confirmations.reply.confirm": "Tumugon",
"content_warning.show_more": "Magpakita ng higit pa",
"conversation.mark_as_read": "Markahan bilang nabasa na",
"conversation.open": "Tingnan ang pag-uusap",
"copy_icon_button.copied": "Sinipi sa clipboard",
@ -190,6 +191,7 @@
"explore.title": "Tuklasin",
"explore.trending_links": "Mga balita",
"filter_modal.select_filter.search": "Hanapin o gumawa",
"filter_warning.matches_filter": "Tinutugma ang pangsala \"<span>{title}</span>\"",
"firehose.all": "Lahat",
"firehose.local": "Itong serbiro",
"firehose.remote": "Ibang mga serbiro",
@ -218,6 +220,7 @@
"interaction_modal.on_another_server": "Sa ibang serbiro",
"interaction_modal.on_this_server": "Sa serbirong ito",
"interaction_modal.title.follow": "Sundan si {name}",
"interaction_modal.title.vote": "Bumoto sa botohan ni {name}",
"intervals.full.days": "{number, plural, one {# araw} other {# na araw}}",
"intervals.full.hours": "{number, plural, one {# oras} other {# na oras}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# na minuto}}",
@ -256,6 +259,7 @@
"navigation_bar.search": "Maghanap",
"notification.admin.report": "Iniulat ni {name} si {target}",
"notification.follow": "Sinundan ka ni {name}",
"notification.follow.name_and_others": "Sinundan ka ng/nina {name} at <a>{count, plural, one {# iba pa} other {# na iba pa}}</a>",
"notification.follow_request": "Hinihiling ni {name} na sundan ka",
"notification.label.private_mention": "Palihim na banggit",
"notification.mentioned_you": "Binanggit ka ni {name}",
@ -270,6 +274,7 @@
"notifications.column_settings.alert": "Mga abiso sa Desktop",
"notifications.column_settings.favourite": "Mga paborito:",
"notifications.column_settings.follow": "Mga bagong tagasunod:",
"notifications.column_settings.group": "Pangkat",
"notifications.column_settings.poll": "Resulta ng botohan:",
"notifications.column_settings.unread_notifications.category": "Hindi Nabasang mga Abiso",
"notifications.column_settings.update": "Mga pagbago:",

View File

@ -197,6 +197,7 @@
"confirmations.unfollow.title": "A bheil thu airson sgur de leantainn a chleachdaiche?",
"content_warning.hide": "Falaich am post",
"content_warning.show": "Seall e co-dhiù",
"content_warning.show_more": "Seall barrachd dheth",
"conversation.delete": "Sguab às an còmhradh",
"conversation.mark_as_read": "Cuir comharra gun deach a leughadh",
"conversation.open": "Seall an còmhradh",
@ -305,6 +306,7 @@
"filter_modal.select_filter.subtitle": "Cleachd roinn-seòrsa a tha ann no cruthaich tè ùr",
"filter_modal.select_filter.title": "Criathraich am post seo",
"filter_modal.title.status": "Criathraich post",
"filter_warning.matches_filter": "A maidseadh na criathraige “<span>{title}</span>”",
"filtered_notifications_banner.pending_requests": "{count, plural, =0 {Chan eil gin ann} one {O # neach} two {O # neach} few {O # daoine} other {O # duine}} air a bheil thu eòlach s dòcha",
"filtered_notifications_banner.title": "Brathan criathraichte",
"firehose.all": "Na h-uile",
@ -384,6 +386,7 @@
"interaction_modal.description.follow": "Le cunntas air Mastodon, s urrainn dhut {name} a leantainn ach am faigh thu na postaichean aca nad dhachaigh.",
"interaction_modal.description.reblog": "Le cunntas air Mastodon, s urrainn dhut am post seo a bhrosnachadh gus a cho-roinneadh leis an luchd-leantainn agad fhèin.",
"interaction_modal.description.reply": "Le cunntas air Mastodon, s urrainn dhut freagairt a chur dhan phost seo.",
"interaction_modal.description.vote": "Le cunntas air Mastodon, s urrainn dhut bhòtadh sa chunntas-bheachd seo.",
"interaction_modal.login.action": "Thoir dhachaigh mi",
"interaction_modal.login.prompt": "Àrainn-lìn an fhrithealaiche dachaigh agad, can ailbhean.co-shaoghal.net",
"interaction_modal.no_account_yet": "Nach eil thu air Mastodon?",
@ -395,6 +398,7 @@
"interaction_modal.title.follow": "Lean {name}",
"interaction_modal.title.reblog": "Brosnaich am post aig {name}",
"interaction_modal.title.reply": "Freagair dhan phost aig {name}",
"interaction_modal.title.vote": "Bhòt sa chunntas-bheachd aig {name}",
"intervals.full.days": "{number, plural, one {# latha} two {# latha} few {# làithean} other {# latha}}",
"intervals.full.hours": "{number, plural, one {# uair a thìde} two {# uair a thìde} few {# uairean a thìde} other {# uair a thìde}}",
"intervals.full.minutes": "{number, plural, one {# mhionaid} two {# mhionaid} few {# mionaidean} other {# mionaid}}",
@ -461,7 +465,7 @@
"media_gallery.hide": "Falaich",
"moved_to_account_banner.text": "Tha an cunntas {disabledAccount} agad à comas on a rinn thu imrich gu {movedToAccount}.",
"mute_modal.hide_from_notifications": "Falaich o na brathan",
"mute_modal.hide_options": "Roghainnean falaich",
"mute_modal.hide_options": "Falaich na roghainnean",
"mute_modal.indefinite": "Gus an dì-mhùch mi iad",
"mute_modal.show_options": "Seall na roghainnean",
"mute_modal.they_can_mention_and_follow": "S urrainn dhaibh iomradh a thoirt ort agus do leantainn ach chan fhaic thu iad-san.",

View File

@ -386,6 +386,7 @@
"interaction_modal.description.follow": "Cunha conta en Mastodon, poderás seguir a {name} e recibir as súas publicacións na túa cronoloxía de inicio.",
"interaction_modal.description.reblog": "Cunha conta en Mastodon, poderás promover esta publicación para compartila con quen te siga.",
"interaction_modal.description.reply": "Cunha conta en Mastodon, poderás responder a esta publicación.",
"interaction_modal.description.vote": "Podes votar nesta enquisa se tes unha conta en Mastodon.",
"interaction_modal.login.action": "Lévame ao inicio",
"interaction_modal.login.prompt": "Dominio do teu servidor de inicio, ex. mastodon.social",
"interaction_modal.no_account_yet": "Aínda non tes unha conta?",
@ -397,6 +398,7 @@
"interaction_modal.title.follow": "Seguir a {name}",
"interaction_modal.title.reblog": "Promover a publicación de {name}",
"interaction_modal.title.reply": "Responder á publicación de {name}",
"interaction_modal.title.vote": "Vota na enquisa de {name}",
"intervals.full.days": "{number, plural,one {# día} other {# días}}",
"intervals.full.hours": "{number, plural, one {# hora} other {# horas}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minutos}}",

View File

@ -386,6 +386,7 @@
"interaction_modal.description.follow": "Con un profilo di Mastodon, puoi seguire {name} per ricevere i suoi post nel feed della tua home.",
"interaction_modal.description.reblog": "Con un profilo di Mastodon, puoi rebloggare questo post per condividerlo con i tuoi seguaci.",
"interaction_modal.description.reply": "Con un profilo di Mastodon, puoi rispondere a questo post.",
"interaction_modal.description.vote": "Con un account su Mastodon puoi votare in questo sondaggio.",
"interaction_modal.login.action": "Portami alla pagina iniziale",
"interaction_modal.login.prompt": "Dominio del tuo server principale, ad esempio mastodon.social",
"interaction_modal.no_account_yet": "Non su Mastodon?",
@ -397,6 +398,7 @@
"interaction_modal.title.follow": "Segui {name}",
"interaction_modal.title.reblog": "Reblogga il post di {name}",
"interaction_modal.title.reply": "Rispondi al post di {name}",
"interaction_modal.title.vote": "Vota nel sondaggio di {name}",
"intervals.full.days": "{number, plural, one {# giorno} other {# giorni}}",
"intervals.full.hours": "{number, plural, one {# ora} other {# ore}}",
"intervals.full.minutes": "{number, plural, one {# minuto} other {# minuti}}",

View File

@ -386,6 +386,7 @@
"interaction_modal.description.follow": "Mastodonのアカウントで{name}さんをフォローしてホームフィードで投稿を受け取れます。",
"interaction_modal.description.reblog": "Mastodonのアカウントでこの投稿をブーストして自分のフォロワーに共有できます。",
"interaction_modal.description.reply": "Mastodonのアカウントでこの投稿に反応できます。",
"interaction_modal.description.vote": "Mastodonのアカウントでこのアンケートに票を入れることができます。",
"interaction_modal.login.action": "サーバーに移動",
"interaction_modal.login.prompt": "登録したサーバーのドメイン (例: mastodon.social)",
"interaction_modal.no_account_yet": "Mastodonにアカウントがない場合は",
@ -397,6 +398,7 @@
"interaction_modal.title.follow": "{name}さんをフォロー",
"interaction_modal.title.reblog": "{name}さんの投稿をブースト",
"interaction_modal.title.reply": "{name}さんの投稿にリプライ",
"interaction_modal.title.vote": "{name}さんのアンケートに投票",
"intervals.full.days": "{number}日",
"intervals.full.hours": "{number}時間",
"intervals.full.minutes": "{number}分",

View File

@ -191,6 +191,7 @@
"confirmations.unfollow.title": "Desige utilizador?",
"content_warning.hide": "Eskonde puvlikasyon",
"content_warning.show": "Amostra entanto",
"content_warning.show_more": "Amostra mas",
"conversation.delete": "Efasa konversasyon",
"conversation.mark_as_read": "Marka komo meldado",
"conversation.open": "Ve konversasyon",

View File

@ -384,6 +384,7 @@
"interaction_modal.description.follow": "Med ein konto på Mastodon kan du fylgja {name} for å sjå innlegga deira i din heimestraum.",
"interaction_modal.description.reblog": "Med ein konto på Mastodon kan du framheva dette innlegget for å dela det med dine eigne fylgjarar.",
"interaction_modal.description.reply": "Med ein konto på Mastodon kan du svara på dette innlegget.",
"interaction_modal.description.vote": "Med ein konto på Mastodon kan du røyste i denne avrøystinga.",
"interaction_modal.login.action": "Ta meg heim",
"interaction_modal.login.prompt": "Domenenamnet til din heime-tenar. t.d. mastodon.social",
"interaction_modal.no_account_yet": "Ikkje på Mastodon?",
@ -395,6 +396,7 @@
"interaction_modal.title.follow": "Fylg {name}",
"interaction_modal.title.reblog": "Framhev {name} sitt innlegg",
"interaction_modal.title.reply": "Svar på innlegge til {name}",
"interaction_modal.title.vote": "Røyst i {name} si avrøysting",
"intervals.full.days": "{number, plural, one {# dag} other {# dagar}}",
"intervals.full.hours": "{number, plural, one {# time} other {# timar}}",
"intervals.full.minutes": "{number, plural, one {# minutt} other {# minutt}}",

View File

@ -398,6 +398,7 @@
"interaction_modal.title.follow": "Följ {name}",
"interaction_modal.title.reblog": "Boosta {name}s inlägg",
"interaction_modal.title.reply": "Svara på {name}s inlägg",
"interaction_modal.title.vote": "Rösta i {name}s enkät",
"intervals.full.days": "{number, plural, one {# dag} other {# dagar}}",
"intervals.full.hours": "{number, plural, one {# timme} other {# timmar}}",
"intervals.full.minutes": "{number, plural, one {# minut} other {# minuter}}",

View File

@ -44,7 +44,7 @@
"account.joined_short": "เข้าร่วมเมื่อ",
"account.languages": "เปลี่ยนภาษาที่บอกรับ",
"account.link_verified_on": "ตรวจสอบความเป็นเจ้าของของลิงก์นี้เมื่อ {date}",
"account.locked_info": "มีการตั้งสถานะความเป็นส่วนตัวของบัญชีนี้เป็นล็อคอยู่ เจ้าของตรวจทานผู้ที่สามารถติดตามเขาด้วยตนเอง",
"account.locked_info": "สถานะความเป็นส่วนตัวของบัญชีนี้ถูกตั้งค่าเป็นล็อค เจ้าของตรวจสอบด้วยตนเองว่าใครสามารถติดตามพวกเขาได้",
"account.media": "สื่อ",
"account.mention": "กล่าวถึง @{name}",
"account.moved_to": "{name} ได้ระบุว่าบัญชีใหม่ของเขาในตอนนี้คือ:",

View File

@ -383,10 +383,10 @@
"ignore_notifications_modal.not_following_title": "是否忽略你未关注的人的通知?",
"ignore_notifications_modal.private_mentions_title": "是否忽略不请自来的私下提及?",
"interaction_modal.description.favourite": "只需一个 Mastodon 账号,即可喜欢这条嘟文,对嘟文的作者展示您欣赏的态度,并保存嘟文以供日后使用。",
"interaction_modal.description.follow": "拥有一个 Mastodon 账号,你可以关注 {name} 并在自己的主页上接收对方的新嘟文。",
"interaction_modal.description.reblog": "拥有一个 Mastodon 账号,你可以向自己的关注者们转发此嘟文。",
"interaction_modal.description.reply": "拥有一个 Mastodon 账号,你可以回复此嘟文。",
"interaction_modal.description.vote": "拥有一个 Mastodon 账号,你可以参与此投票。",
"interaction_modal.description.follow": "拥有一个 Mastodon 账号,你可以关注 {name} 并在自己的主页上接收对方的新嘟文。",
"interaction_modal.description.reblog": "拥有一个 Mastodon 账号,你可以向自己的关注者们转发此嘟文。",
"interaction_modal.description.reply": "拥有一个 Mastodon 账号,你可以回复此嘟文。",
"interaction_modal.description.vote": "拥有一个 Mastodon 账号,你可以参与此投票。",
"interaction_modal.login.action": "转到主页",
"interaction_modal.login.prompt": "您所入驻的服务器域名mastodon.social",
"interaction_modal.no_account_yet": "不在 Mastodon 上?",

View File

@ -2759,6 +2759,7 @@ a.account__display-name {
flex: 0 1 auto;
display: flex;
flex-direction: column;
contain: inline-size layout paint style;
@media screen and (min-width: $no-gap-breakpoint) {
max-width: 600px;
@ -4032,6 +4033,7 @@ $ui-header-logo-wordmark-width: 99px;
overflow: hidden;
border: 1px solid var(--background-border-color);
border-radius: 8px;
contain: inline-size layout paint style;
&.bottomless {
border-radius: 8px 8px 0 0;

View File

@ -20,9 +20,9 @@ class ActivityPub::Activity
end
class << self
def factory(json, account, **options)
def factory(json, account, **)
@json = json
klass&.new(json, account, **options)
klass&.new(json, account, **)
end
private

View File

@ -7,7 +7,7 @@ class AnnualReport::CommonlyInteractedWithAccounts < AnnualReport::Source
{
commonly_interacted_with_accounts: commonly_interacted_with_accounts.map do |(account_id, count)|
{
account_id: account_id,
account_id: account_id.to_s,
count: count,
}
end,

View File

@ -7,7 +7,7 @@ class AnnualReport::MostRebloggedAccounts < AnnualReport::Source
{
most_reblogged_accounts: most_reblogged_accounts.map do |(account_id, count)|
{
account_id: account_id,
account_id: account_id.to_s,
count: count,
}
end,

View File

@ -8,9 +8,9 @@ class AnnualReport::TopStatuses < AnnualReport::Source
{
top_statuses: {
by_reblogs: top_reblogs,
by_favourites: top_favourites,
by_replies: top_replies,
by_reblogs: top_reblogs&.to_s,
by_favourites: top_favourites&.to_s,
by_replies: top_replies&.to_s,
},
}
end

View File

@ -1,8 +1,8 @@
# frozen_string_literal: true
class RSS::Element
def self.with(*args, &block)
new(*args).tap(&block).to_element
def self.with(*, &block)
new(*).tap(&block).to_element
end
def create_element(name, content = nil)

View File

@ -42,8 +42,8 @@ class TranslationService::DeepL < TranslationService
subtags.join('-')
end
def request(verb, path, **options)
req = Request.new(verb, "#{base_url}#{path}", **options)
def request(verb, path, **)
req = Request.new(verb, "#{base_url}#{path}", **)
req.add_headers(Authorization: "DeepL-Auth-Key #{@api_key}")
req.perform do |res|
case res.code

View File

@ -27,8 +27,8 @@ class TranslationService::LibreTranslate < TranslationService
private
def request(verb, path, **options)
req = Request.new(verb, "#{@base_url}#{path}", allow_local: true, **options)
def request(verb, path, **)
req = Request.new(verb, "#{@base_url}#{path}", allow_local: true, **)
req.add_headers('Content-Type': 'application/json')
req.perform do |res|
case res.code

View File

@ -29,7 +29,7 @@ module Status::SnapshotConcern
)
end
def snapshot!(**options)
build_snapshot(**options).save!
def snapshot!(**)
build_snapshot(**).save!
end
end

View File

@ -35,8 +35,8 @@ class SessionActivation < ApplicationRecord
id && exists?(session_id: id)
end
def activate(**options)
activation = create!(**options)
def activate(**)
activation = create!(**)
purge_old
activation
end

View File

@ -14,4 +14,6 @@
class Tombstone < ApplicationRecord
belongs_to :account
validates :uri, presence: true
end

View File

@ -405,8 +405,8 @@ class User < ApplicationRecord
@pending_devise_notifications ||= []
end
def render_and_send_devise_message(notification, *args, **kwargs)
devise_mailer.send(notification, self, *args, **kwargs).deliver_later
def render_and_send_devise_message(notification, *, **)
devise_mailer.send(notification, self, *, **).deliver_later
end
def set_approved

View File

@ -26,6 +26,10 @@ class OauthMetadataPresenter < ActiveModelSerializers::Model
oauth_token_url
end
def userinfo_endpoint
oauth_userinfo_url
end
# As the api_v1_apps route doesn't technically conform to the specification
# for OAuth 2.0 Dynamic Client Registration defined in RFC 7591 we use a
# non-standard property for now to indicate the mastodon specific registration

View File

@ -2,7 +2,7 @@
class OauthMetadataSerializer < ActiveModel::Serializer
attributes :issuer, :authorization_endpoint, :token_endpoint,
:revocation_endpoint, :scopes_supported,
:revocation_endpoint, :userinfo_endpoint, :scopes_supported,
:response_types_supported, :response_modes_supported,
:grant_types_supported, :token_endpoint_auth_methods_supported,
:code_challenge_methods_supported,

View File

@ -0,0 +1,31 @@
# frozen_string_literal: true
class OauthUserinfoSerializer < ActiveModel::Serializer
include RoutingHelper
attributes :iss, :sub, :name, :preferred_username, :profile, :picture
def iss
root_url
end
def sub
ActivityPub::TagManager.instance.uri_for(object)
end
def name
object.display_name
end
def preferred_username
object.username
end
def profile
ActivityPub::TagManager.instance.url_for(object)
end
def picture
full_asset_url(object.avatar_original_url)
end
end

View File

@ -23,6 +23,7 @@ Rails.application.config.middleware.insert_before 0, Rack::Cors do
methods: %i(post put delete get patch options)
resource '/oauth/token', methods: [:post]
resource '/oauth/revoke', methods: [:post]
resource '/oauth/userinfo', methods: [:get, :post]
end
end
end

View File

@ -239,6 +239,7 @@ eo:
confirm_user_html: "%{name} konfirmis retadreson de uzanto %{target}"
create_account_warning_html: "%{name} sendis averton al %{target}"
create_announcement_html: "%{name} kreis novan anoncon %{target}"
create_canonical_email_block_html: "%{name} blokis retpoŝtadreson per krado %{target}"
create_custom_emoji_html: "%{name} alŝutis novan emoĝion %{target}"
create_domain_allow_html: "%{name} aldonis domajnon %{target} al la blanka listo"
create_domain_block_html: "%{name} blokis domajnon %{target}"
@ -248,6 +249,7 @@ eo:
create_user_role_html: "%{name} kreis rolon de %{target}"
demote_user_html: "%{name} degradis uzanton %{target}"
destroy_announcement_html: "%{name} forigis anoncon %{target}"
destroy_canonical_email_block_html: "%{name} malblokis retpoŝtadreson per krado %{target}"
destroy_custom_emoji_html: "%{name} forigis emoĝion %{target}"
destroy_domain_allow_html: "%{name} forigis domajnon %{target} el la blanka listo"
destroy_domain_block_html: "%{name} malblokis domajnon %{target}"
@ -282,6 +284,7 @@ eo:
update_custom_emoji_html: "%{name} ĝisdatigis la emoĝion %{target}"
update_domain_block_html: "%{name} ĝisdatigis domajnblokon por %{target}"
update_ip_block_html: "%{name} ŝanĝis regulon por IP %{target}"
update_report_html: "%{name} ĝisdatigis la raporton %{target}"
update_status_html: "%{name} ĝisdatigis afiŝon de %{target}"
update_user_role_html: "%{name} ŝanĝis la rolon %{target}"
deleted_account: forigita konto
@ -788,6 +791,7 @@ eo:
types:
major: Ĉefa eldono
minor: Neĉefa eldono
patch: Eldono de flikaĵo — korektoj de eraroj kaj facile apliki ŝanĝojn
version: Versio
statuses:
account: Skribanto
@ -1106,6 +1110,7 @@ eo:
title: Ni pretigu vin ĉe %{domain}.
status:
account_status: Statuso de la konto
confirming: Atendante ke retpoŝta konfirmo estos kompletigita.
functional: Via konto estas tute funkcia.
redirecting_to: Via konto estas neaktiva ĉar ĝi nun alidirektas al %{acct}.
view_strikes: Vidi antauaj admonoj kontra via konto
@ -1155,6 +1160,8 @@ eo:
before: 'Antau ol dauri, legu ĉi tiujn notojn zorgeme:'
caches: Enhavo kiu kaŝmemorigitas de aliaj serviloj eble restas
data_removal: Viaj afiŝoj kaj aliaj informoj estos forigita por eterne
email_change_html: Vi povas <a href="%{path}">ŝanĝi vian retadreson</a> sen forigi vian konton
email_contact_html: Se ĝi ankoraŭ ne alvenas, vi povas retpoŝti al <a href="mailto:%{email}">%{email}</a> por helpo
irreversible: Vi ne povas regajni au reaktivigi vian konton
more_details_html: Por pli da detaloj, vidi la <a href="%{terms_path}">privatecan politikon</a>.
username_available: Via uzantnomo iĝos denove disponebla

View File

@ -1166,8 +1166,11 @@ et:
use_security_key: Kasuta turvavõtit
author_attribution:
example_title: Näidistekst
hint_html: Kirjutad uudiseid või blogisid Mastodonist väljapool? Määra, kuidas sinule viidatakse, kui neid lehti jagatakse Mastodonis.
instructions: 'Vaata, et artikli HTML sisus oleks see kood sees:'
more_from_html: Rohkem kasutajalt %{name}
s_blog: Kasutaja %{name} blogi
then_instructions: Siis lisa avaldaja domeeninimi allolevasse välja.
title: Autori tunnustamine
challenge:
confirm: Jätka

View File

@ -1202,8 +1202,11 @@ gd:
use_security_key: Cleachd iuchair tèarainteachd
author_attribution:
example_title: Ball-sampaill teacsa
hint_html: An sgrìobh thu naidheachdan no bloga taobh a-muigh Mhastodon? Stiùirich mar a thèid iomradh a thoirt ort nuair a bhios na h-artaigilean agad gan co-roinneadh air Mastodon.
instructions: 'Dèan cinnteach gu bheil an còd seo am broinn HTML an artaigil agad:'
more_from_html: Barrachd o %{name}
s_blog: Bloga aig %{name}
then_instructions: An uair sin, cuir ainm àrainn an fhoillseachaidh ris an raon gu h-ìosal.
title: Aithris air an ùghdar
challenge:
confirm: Lean air adhart

View File

@ -3,6 +3,7 @@ et:
simple_form:
hints:
account:
attribution_domains_as_text: Üks rea peal. See kaitseb pahatahtlike viidete eest.
discoverable: Su profiili ja avalikke postitusi võidakse Mastodoni erinevates piirkondades esile tõsta või soovitada ning su profiili soovitada teistele kasutajatele.
display_name: Su täisnimi või naljanimi.
fields: Su koduleht, sugu, vanus. Mistahes, mida soovid.
@ -143,6 +144,7 @@ et:
url: Kuhu sündmused saadetakse
labels:
account:
attribution_domains_as_text: Sinule viidata lubatud veebilehed
discoverable: Tõsta postitused ja profiil avastamise algoritmides esile
fields:
name: Nimetus

View File

@ -3,6 +3,7 @@ gd:
simple_form:
hints:
account:
attribution_domains_as_text: Loidhne fa leth do gach fear. Dìonaidh seo o iomraidhean meallta.
discoverable: Dhfhaoidte gun dèid na postaichean poblach s a phròifil agad a bhrosnachadh no a mholadh ann an caochladh roinnean de Mhastodon agus gun dèid a phròifil agad a mholadh do chàch.
display_name: D ainm slàn no spòrsail.
fields: An duilleag-dhachaigh agad, roimhearan, aois, rud sam bith a thogras tu.
@ -143,6 +144,7 @@ gd:
url: Far an dèid na tachartasan a chur
labels:
account:
attribution_domains_as_text: Na làraichean-lìn a dhfhaodas iomradh a thoirt ort
discoverable: Brosnaich a phròifil is postaichean agad sna h-algairimean rùrachaidh
fields:
name: Leubail

View File

@ -64,6 +64,13 @@ Rails.application.routes.draw do
tokens: 'oauth/tokens'
end
namespace :oauth do
# As this is borrowed from OpenID, the specification says we must also support
# POST for the userinfo endpoint:
# https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
match 'userinfo', via: [:get, :post], to: 'userinfo#show', defaults: { format: 'json' }
end
scope path: '.well-known' do
scope module: :well_known do
get 'oauth-authorization-server', to: 'oauth_metadata#show', as: :oauth_metadata, defaults: { format: 'json' }

View File

@ -1,6 +1,5 @@
# frozen_string_literal: true
require 'set'
require_relative 'base'
module Mastodon::CLI

View File

@ -0,0 +1,6 @@
# frozen_string_literal: true
Fabricator(:tombstone) do
account
uri { sequence(:uri) { |i| "https://host.example/value/#{i}" } }
end

View File

@ -32,7 +32,7 @@ RSpec.describe AnnualReport::CommonlyInteractedWithAccounts do
expect(subject.generate)
.to include(
commonly_interacted_with_accounts: contain_exactly(
include(account_id: other_account.id, count: 2)
include(account_id: other_account.id.to_s, count: 2)
)
)
end

View File

@ -32,7 +32,7 @@ RSpec.describe AnnualReport::MostRebloggedAccounts do
expect(subject.generate)
.to include(
most_reblogged_accounts: contain_exactly(
include(account_id: other_account.id, count: 2)
include(account_id: other_account.id.to_s, count: 2)
)
)
end

View File

@ -39,9 +39,9 @@ RSpec.describe AnnualReport::TopStatuses do
expect(subject.generate)
.to include(
top_statuses: include(
by_reblogs: reblogged_status.id,
by_favourites: favourited_status.id,
by_replies: replied_status.id
by_reblogs: reblogged_status.id.to_s,
by_favourites: favourited_status.id.to_s,
by_replies: replied_status.id.to_s
)
)
end

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Tombstone do
describe 'Associations' do
it { is_expected.to belong_to(:account).required }
end
describe 'Validations' do
subject { Fabricate.build :tombstone }
it { is_expected.to validate_presence_of(:uri) }
end
end

View File

@ -0,0 +1,51 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Oauth Userinfo Endpoint' do
include RoutingHelper
let(:user) { Fabricate(:user) }
let(:account) { user.account }
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
let(:scopes) { 'profile' }
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
shared_examples 'returns successfully' do
it 'returns http success' do
subject
expect(response).to have_http_status(:success)
expect(response.content_type).to start_with('application/json')
expect(response.parsed_body).to include({
iss: root_url,
sub: account_url(account),
name: account.display_name,
preferred_username: account.username,
profile: short_account_url(account),
picture: full_asset_url(account.avatar_original_url),
})
end
end
describe 'GET /oauth/userinfo' do
subject do
get '/oauth/userinfo', headers: headers
end
it_behaves_like 'forbidden for wrong scope', 'read:accounts'
it_behaves_like 'returns successfully'
end
# As this is borrowed from OpenID, the specification says we must also support
# POST for the userinfo endpoint:
# https://openid.net/specs/openid-connect-core-1_0.html#UserInfo
describe 'POST /oauth/userinfo' do
subject do
post '/oauth/userinfo', headers: headers
end
it_behaves_like 'forbidden for wrong scope', 'read:accounts'
it_behaves_like 'returns successfully'
end
end

View File

@ -3,12 +3,6 @@
require 'rails_helper'
RSpec.describe 'The /.well-known/oauth-authorization-server request' do
let(:protocol) { ENV.fetch('LOCAL_HTTPS', true) ? :https : :http }
before do
host! Rails.configuration.x.local_domain
end
it 'returns http success with valid JSON response' do
get '/.well-known/oauth-authorization-server'
@ -22,11 +16,12 @@ RSpec.describe 'The /.well-known/oauth-authorization-server request' do
grant_types_supported << 'refresh_token' if Doorkeeper.configuration.refresh_token_enabled?
expect(response.parsed_body).to include(
issuer: root_url(protocol: protocol),
issuer: root_url,
service_documentation: 'https://docs.joinmastodon.org/',
authorization_endpoint: oauth_authorization_url(protocol: protocol),
token_endpoint: oauth_token_url(protocol: protocol),
revocation_endpoint: oauth_revoke_url(protocol: protocol),
authorization_endpoint: oauth_authorization_url,
token_endpoint: oauth_token_url,
userinfo_endpoint: oauth_userinfo_url,
revocation_endpoint: oauth_revoke_url,
scopes_supported: Doorkeeper.configuration.scopes.map(&:to_s),
response_types_supported: Doorkeeper.configuration.authorization_response_types,
response_modes_supported: Doorkeeper.configuration.authorization_response_flows.flat_map(&:response_mode_matches).uniq,
@ -34,7 +29,7 @@ RSpec.describe 'The /.well-known/oauth-authorization-server request' do
grant_types_supported: grant_types_supported,
code_challenge_methods_supported: ['S256'],
# non-standard extension:
app_registration_endpoint: api_v1_apps_url(protocol: protocol)
app_registration_endpoint: api_v1_apps_url
)
end
end

View File

@ -1,9 +1,9 @@
# frozen_string_literal: true
module CommandLineHelpers
def output_results(*args)
def output_results(*)
output(
include(*args)
include(*)
).to_stdout
end
end

View File

@ -9,7 +9,7 @@ ARG BUILDPLATFORM=${BUILDPLATFORM}
# Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
# renovate: datasource=node-version depName=node
ARG NODE_MAJOR_VERSION="20"
ARG NODE_MAJOR_VERSION="22"
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
ARG DEBIAN_VERSION="bookworm"
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)

220
yarn.lock
View File

@ -6373,9 +6373,9 @@ __metadata:
linkType: hard
"core-js@npm:^3.30.2":
version: 3.38.1
resolution: "core-js@npm:3.38.1"
checksum: 10c0/7df063b6f13a54e46515817ac3e235c6c598a4d3de65cd188a061fc250642be313b895fb9fb2f36e1e31890a1bb4ef61d82666a340413f540b7ce3c65689739b
version: 3.39.0
resolution: "core-js@npm:3.39.0"
checksum: 10c0/f7602069b6afb2e3298eec612a5c1e0c3e6a458930fbfc7a4c5f9ac03426507f49ce395eecdd2d9bae9024f820e44582b67ffe16f2272395af26964f174eeb6b
languageName: node
linkType: hard
@ -18218,28 +18218,28 @@ __metadata:
languageName: node
linkType: hard
"workbox-background-sync@npm:7.1.0":
version: 7.1.0
resolution: "workbox-background-sync@npm:7.1.0"
"workbox-background-sync@npm:7.3.0":
version: 7.3.0
resolution: "workbox-background-sync@npm:7.3.0"
dependencies:
idb: "npm:^7.0.1"
workbox-core: "npm:7.1.0"
checksum: 10c0/9538c49a377d8eb06acee3848fbca09bac1940a2ca9e904fed765c39aa32f77c20d72c3ba6fa1eb47bee81289b1d527556a1cd3e02728960a4c40400ce6d0e91
workbox-core: "npm:7.3.0"
checksum: 10c0/cc982d62702847fb16c4ef372a8bd243348a80c2d5da1649a860b0187b45060a799a65582c2d36f1a32e31d5d68dedcb037698c41d3b2f171ea5d54d73453cf1
languageName: node
linkType: hard
"workbox-broadcast-update@npm:7.1.0":
version: 7.1.0
resolution: "workbox-broadcast-update@npm:7.1.0"
"workbox-broadcast-update@npm:7.3.0":
version: 7.3.0
resolution: "workbox-broadcast-update@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/4a6e201cedcbc11b9d2f63f63477ba4564a35ce07bd54640198db6ff6a3b8347a65e0b4973c8f8463e8a622fd1ad93d7b3bab42338608811d23c7db01fef475e
workbox-core: "npm:7.3.0"
checksum: 10c0/25007acd3e845b5ca1f4c9ac9888ce661431723f7419cfa56b3029b6c56cbeca24902dae015c42a2d6f554f956274743e331d03ceeb4b0e3879cb7b908d0e82f
languageName: node
linkType: hard
"workbox-build@npm:7.1.0":
version: 7.1.0
resolution: "workbox-build@npm:7.1.0"
"workbox-build@npm:7.3.0":
version: 7.3.0
resolution: "workbox-build@npm:7.3.0"
dependencies:
"@apideck/better-ajv-errors": "npm:^0.3.1"
"@babel/core": "npm:^7.24.4"
@ -18263,163 +18263,163 @@ __metadata:
strip-comments: "npm:^2.0.1"
tempy: "npm:^0.6.0"
upath: "npm:^1.2.0"
workbox-background-sync: "npm:7.1.0"
workbox-broadcast-update: "npm:7.1.0"
workbox-cacheable-response: "npm:7.1.0"
workbox-core: "npm:7.1.0"
workbox-expiration: "npm:7.1.0"
workbox-google-analytics: "npm:7.1.0"
workbox-navigation-preload: "npm:7.1.0"
workbox-precaching: "npm:7.1.0"
workbox-range-requests: "npm:7.1.0"
workbox-recipes: "npm:7.1.0"
workbox-routing: "npm:7.1.0"
workbox-strategies: "npm:7.1.0"
workbox-streams: "npm:7.1.0"
workbox-sw: "npm:7.1.0"
workbox-window: "npm:7.1.0"
checksum: 10c0/c482fde713bad582bd7d4861113d7367ab4722eba9c102864c71048815792c623e9117a8f79957e0388d0c08e8303962d1fb23931456da73909e87d06638d101
workbox-background-sync: "npm:7.3.0"
workbox-broadcast-update: "npm:7.3.0"
workbox-cacheable-response: "npm:7.3.0"
workbox-core: "npm:7.3.0"
workbox-expiration: "npm:7.3.0"
workbox-google-analytics: "npm:7.3.0"
workbox-navigation-preload: "npm:7.3.0"
workbox-precaching: "npm:7.3.0"
workbox-range-requests: "npm:7.3.0"
workbox-recipes: "npm:7.3.0"
workbox-routing: "npm:7.3.0"
workbox-strategies: "npm:7.3.0"
workbox-streams: "npm:7.3.0"
workbox-sw: "npm:7.3.0"
workbox-window: "npm:7.3.0"
checksum: 10c0/cb396f9c2a53429d1e11b4c1da2e21c9e1c98473ce15f20ae53277e47bd7ccbcb3f1f843694e588bb70b12d9332faafd098ca05b93abb0293d373f38a8de3ca8
languageName: node
linkType: hard
"workbox-cacheable-response@npm:7.1.0":
version: 7.1.0
resolution: "workbox-cacheable-response@npm:7.1.0"
"workbox-cacheable-response@npm:7.3.0":
version: 7.3.0
resolution: "workbox-cacheable-response@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/52ea73bb184c9ef9280cc8f00a1ab7d103d495e12a7a6378fae02fd0aa1a9b893aac5d8074f14ed8c198527123e4401f4703fbfd2be98e184ca783b9216cb4c5
workbox-core: "npm:7.3.0"
checksum: 10c0/192c8a8878c53a205c55398bac78f2c32c0f36e55c95cab282d8a716ddf2fa72563afaed690d34d3438cc8df5fb0df4d98dcb2d93cc6d67c69a9ae592f7bf246
languageName: node
linkType: hard
"workbox-core@npm:7.1.0":
version: 7.1.0
resolution: "workbox-core@npm:7.1.0"
checksum: 10c0/fb0b6e23a52e085da00b7a74b1f1854f06c695eb2bd4c244aa335165f59156a4febb4f116b9893b9fb7e0e8bac092d32eecceb4d00f930a93f64737cb2be9531
"workbox-core@npm:7.3.0":
version: 7.3.0
resolution: "workbox-core@npm:7.3.0"
checksum: 10c0/b7dce640cd9665ed207f65f5b08a50e2e24e5599790c6ea4fec987539b9d2ef81765d8c5f94acfee3a8a45d5ade8e1a4ebd0b8847a1471302ef75a5b93c7bd04
languageName: node
linkType: hard
"workbox-expiration@npm:7.1.0, workbox-expiration@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-expiration@npm:7.1.0"
"workbox-expiration@npm:7.3.0, workbox-expiration@npm:^7.0.0":
version: 7.3.0
resolution: "workbox-expiration@npm:7.3.0"
dependencies:
idb: "npm:^7.0.1"
workbox-core: "npm:7.1.0"
checksum: 10c0/669d76f87c1550ce9b425232c3202a26fdea4c4c9bdc1b71c1cee741a5d011423098994452e508576174d3c0b4bec0f4b35012b6d7257e300684c87fdddb7949
workbox-core: "npm:7.3.0"
checksum: 10c0/6040d72122ece901becfcc59974586e9cc9b6309840b83b652c9f9aafe32ff89783404a431cadf6f888f80e5371252820e425ced499742964d6d68687f6fad1a
languageName: node
linkType: hard
"workbox-google-analytics@npm:7.1.0":
version: 7.1.0
resolution: "workbox-google-analytics@npm:7.1.0"
"workbox-google-analytics@npm:7.3.0":
version: 7.3.0
resolution: "workbox-google-analytics@npm:7.3.0"
dependencies:
workbox-background-sync: "npm:7.1.0"
workbox-core: "npm:7.1.0"
workbox-routing: "npm:7.1.0"
workbox-strategies: "npm:7.1.0"
checksum: 10c0/4178d94fb7f3f7b789f117c104b2ff33945256dc550418b0e9c81130c1e2c2bcd72ec6a1661d91326c04de360e6592edd505f0e2142e8e1043fe0c45f9c1a3fe
workbox-background-sync: "npm:7.3.0"
workbox-core: "npm:7.3.0"
workbox-routing: "npm:7.3.0"
workbox-strategies: "npm:7.3.0"
checksum: 10c0/5317a4bcc01f1aa87480f9708d7d382c15fb37d6119e71e0a2909dfd683f6060b5cc4f7b016a81fc67098f51a5d0cfd1cda20e228f2f3778ee3caf649b59996b
languageName: node
linkType: hard
"workbox-navigation-preload@npm:7.1.0":
version: 7.1.0
resolution: "workbox-navigation-preload@npm:7.1.0"
"workbox-navigation-preload@npm:7.3.0":
version: 7.3.0
resolution: "workbox-navigation-preload@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/b667a3ba0cae4d43a53a6e211f0f33f6ebc1d9fec6cbb93de83f72a37b81cc39d887b969db9b1cd5c396a1ce34636c89c3b157cc64a5265635d0b274e362db0e
workbox-core: "npm:7.3.0"
checksum: 10c0/69e4d43c68c06889987e9fa437995378b0632c83bad8c7044b4ed812b05b94b3a4aa8700ea4c26b2ecf68ee6858e94ff41dfa3279815c1bc385ac19c0edfb200
languageName: node
linkType: hard
"workbox-precaching@npm:7.1.0, workbox-precaching@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-precaching@npm:7.1.0"
"workbox-precaching@npm:7.3.0, workbox-precaching@npm:^7.0.0":
version: 7.3.0
resolution: "workbox-precaching@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
workbox-routing: "npm:7.1.0"
workbox-strategies: "npm:7.1.0"
checksum: 10c0/53b2d0a658109b4d83ee2b1913f884ee1c757a12b8931a7102272bd1e228d29f9430e7d060f328f465bca2aa24bf0719d026eef4f4d21395fa1f678f8d6a3c06
workbox-core: "npm:7.3.0"
workbox-routing: "npm:7.3.0"
workbox-strategies: "npm:7.3.0"
checksum: 10c0/15c4c5cf5dfec684711ce3536bbfa6873f7af16b712d02ded81d3ff490ea4097e46602705548f5872c49f06e3516fd69f17e72a7fc60631ff6d68460e48f7648
languageName: node
linkType: hard
"workbox-range-requests@npm:7.1.0":
version: 7.1.0
resolution: "workbox-range-requests@npm:7.1.0"
"workbox-range-requests@npm:7.3.0":
version: 7.3.0
resolution: "workbox-range-requests@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/bf4aa597d04cbb533796af64f4006a1f472f8a14ea91f96fe37b2d5e63ffe86dcb944dab9a41317e69d368d83bee20f03ff32b339ae5addef50f325703ad4b77
workbox-core: "npm:7.3.0"
checksum: 10c0/d48e1484866442864d66b1891c4965b71e997a83a7634f11452ec1a73a30a5e642e6a95d5cff45578bef4dec7a5f57bc598aeedb6189d17ca210e2c5f2898244
languageName: node
linkType: hard
"workbox-recipes@npm:7.1.0":
version: 7.1.0
resolution: "workbox-recipes@npm:7.1.0"
"workbox-recipes@npm:7.3.0":
version: 7.3.0
resolution: "workbox-recipes@npm:7.3.0"
dependencies:
workbox-cacheable-response: "npm:7.1.0"
workbox-core: "npm:7.1.0"
workbox-expiration: "npm:7.1.0"
workbox-precaching: "npm:7.1.0"
workbox-routing: "npm:7.1.0"
workbox-strategies: "npm:7.1.0"
checksum: 10c0/5a8c2444f6338c6092be87cc6fd69c8b0cbb413bfc0a11a8f10961bfb2b8059359c4be0264ffa0c01deff3ab5dba15bbcf61d4dedbc93d8bfe1f8a2841b1657c
workbox-cacheable-response: "npm:7.3.0"
workbox-core: "npm:7.3.0"
workbox-expiration: "npm:7.3.0"
workbox-precaching: "npm:7.3.0"
workbox-routing: "npm:7.3.0"
workbox-strategies: "npm:7.3.0"
checksum: 10c0/c8146ece4247cbcbefba36a14f2cb65b5f74b2412f64cfc7955ff75ff653857161a1f1d94c987fbae4812f5b770eedcf99af965e512cc375fbc7fb5421bdc99c
languageName: node
linkType: hard
"workbox-routing@npm:7.1.0, workbox-routing@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-routing@npm:7.1.0"
"workbox-routing@npm:7.3.0, workbox-routing@npm:^7.0.0":
version: 7.3.0
resolution: "workbox-routing@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/efd630fff594bd50276770840bce274660972587e79c097a9f1a84e8347351736aac13f11c6d7655ff550b13195d370d5c3b81a075bf452f358fc144ee868ad9
workbox-core: "npm:7.3.0"
checksum: 10c0/8ac1824211d0fbe0e916ecb2c2427bcb0ef8783f9225d8114fe22e6c326f2d8a040a089bead58064e8b096ec95abe070c04cd7353dd8830dba3ab8d608a053aa
languageName: node
linkType: hard
"workbox-strategies@npm:7.1.0, workbox-strategies@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-strategies@npm:7.1.0"
"workbox-strategies@npm:7.3.0, workbox-strategies@npm:^7.0.0":
version: 7.3.0
resolution: "workbox-strategies@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
checksum: 10c0/b08712a69b1b13e354345cc228c29f0c759043f7ca7cf6ce9b82fe79c9d423142bfa4a118f91f1a57054047a730127fa4474d59d9306fb2ed42fe9ef568be01a
workbox-core: "npm:7.3.0"
checksum: 10c0/50f3c28b46b54885a9461ad6559010d9abb2a7e35e0128d05c268f3ea0a96b1a747934758121d0e821f7af63946d9db8f4d2d7e0146f12555fb05c768e6b82bb
languageName: node
linkType: hard
"workbox-streams@npm:7.1.0":
version: 7.1.0
resolution: "workbox-streams@npm:7.1.0"
"workbox-streams@npm:7.3.0":
version: 7.3.0
resolution: "workbox-streams@npm:7.3.0"
dependencies:
workbox-core: "npm:7.1.0"
workbox-routing: "npm:7.1.0"
checksum: 10c0/1d75c046fcb7b25e1cf85457e3610309dd5513f68752ef333529fcf155df2114b72f3d6f416bb68393e51b5396e3f6df7171e8e2889d0e9e1805e315754b771e
workbox-core: "npm:7.3.0"
workbox-routing: "npm:7.3.0"
checksum: 10c0/2ae541343d187eb7a50da2cfd74051f15771d1ddd1cad6856ffd530f7cccdb8eed9a8af94ff7540b710fef73eeec37d652123ae42b0206fbbd0679dc25e66ff4
languageName: node
linkType: hard
"workbox-sw@npm:7.1.0":
version: 7.1.0
resolution: "workbox-sw@npm:7.1.0"
checksum: 10c0/2084f1b58c8509d7ca53ce8a13d93e57d1f13307e0279fedc87942e83c8cb96bc2e5ed3992a89af6245ad2a66897a92908cb60d0717fb90492056eb6fbf20dc6
"workbox-sw@npm:7.3.0":
version: 7.3.0
resolution: "workbox-sw@npm:7.3.0"
checksum: 10c0/9ae275e31dd5ec51245773b6d90fda16d0b7f70d59f3a71aec732814b5aedf08aedc7fcce57739e7e89d9e1479ef97e3a202a542a511d732cf5e8b5d1c293870
languageName: node
linkType: hard
"workbox-webpack-plugin@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-webpack-plugin@npm:7.1.0"
version: 7.3.0
resolution: "workbox-webpack-plugin@npm:7.3.0"
dependencies:
fast-json-stable-stringify: "npm:^2.1.0"
pretty-bytes: "npm:^5.4.1"
upath: "npm:^1.2.0"
webpack-sources: "npm:^1.4.3"
workbox-build: "npm:7.1.0"
workbox-build: "npm:7.3.0"
peerDependencies:
webpack: ^4.4.0 || ^5.91.0
checksum: 10c0/516fa68a6a6958ee1560299dd1146032dda68474a2ab01643cbde78fc65b75a3157aef60cb45dcc1984cc458ce44d4e3090cda08dd7cefd0952351270e963a00
checksum: 10c0/dd3625544fe08b099fd2b783584c6c2c5da3f0e0c3096fc1a86a0b96a26df5055dd178d3c60ab4cde4099474ab23d51c292356c6910dfa16a974c8a95f351c93
languageName: node
linkType: hard
"workbox-window@npm:7.1.0, workbox-window@npm:^7.0.0":
version: 7.1.0
resolution: "workbox-window@npm:7.1.0"
"workbox-window@npm:7.3.0, workbox-window@npm:^7.0.0":
version: 7.3.0
resolution: "workbox-window@npm:7.3.0"
dependencies:
"@types/trusted-types": "npm:^2.0.2"
workbox-core: "npm:7.1.0"
checksum: 10c0/c989a6e3a0488f049eead3892f8249387604fb04898aa79d0cf14cd7b684f0758f1edf1996745f4755bd30c31c449f628803e507d39b2ea91cc9c36f7d5e9c72
workbox-core: "npm:7.3.0"
checksum: 10c0/dbda33c4761ec40051cfe6e3f1701b2381b4f3b191f7a249c32f683503ea35cf8b42d1f99df5ba3b693fac78705d8ed0c191488bdd178c525d1291d0161ec8ff
languageName: node
linkType: hard