Merge commit '5f87ae101c5e0e940e148d493eaac1ce31fe24c1' into glitch-soc/merge-upstream

This commit is contained in:
Claire 2025-04-04 20:00:24 +02:00
commit 99e3ea232f
60 changed files with 667 additions and 512 deletions

View file

@ -15,6 +15,8 @@
// to `null` after any other rule set it to something. // to `null` after any other rule set it to something.
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).', dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
postUpdateOptions: ['yarnDedupeHighest'], postUpdateOptions: ['yarnDedupeHighest'],
// The types are now included in recent versions,we ignore them here until we upgrade and remove the dependency
ignoreDeps: ['@types/emoji-mart'],
packageRules: [ packageRules: [
{ {
// Require Dependency Dashboard Approval for major version bumps of these node packages // Require Dependency Dashboard Approval for major version bumps of these node packages

View file

@ -94,7 +94,7 @@ GEM
ast (2.4.3) ast (2.4.3)
attr_required (1.0.2) attr_required (1.0.2)
aws-eventstream (1.3.2) aws-eventstream (1.3.2)
aws-partitions (1.1066.0) aws-partitions (1.1080.0)
aws-sdk-core (3.215.1) aws-sdk-core (3.215.1)
aws-eventstream (~> 1, >= 1.3.0) aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0) aws-partitions (~> 1, >= 1.992.0)
@ -126,7 +126,7 @@ GEM
blurhash (0.1.8) blurhash (0.1.8)
bootsnap (1.18.4) bootsnap (1.18.4)
msgpack (~> 1.2) msgpack (~> 1.2)
brakeman (7.0.0) brakeman (7.0.1)
racc racc
browser (6.2.0) browser (6.2.0)
brpoplpush-redis_script (0.1.3) brpoplpush-redis_script (0.1.3)
@ -194,7 +194,7 @@ GEM
devise_pam_authenticatable2 (9.2.0) devise_pam_authenticatable2 (9.2.0)
devise (>= 4.0.0) devise (>= 4.0.0)
rpam2 (~> 4.0) rpam2 (~> 4.0)
diff-lcs (1.6.0) diff-lcs (1.6.1)
discard (1.4.0) discard (1.4.0)
activerecord (>= 4.2, < 9.0) activerecord (>= 4.2, < 9.0)
docile (1.4.1) docile (1.4.1)
@ -266,10 +266,10 @@ GEM
raabro (~> 1.4) raabro (~> 1.4)
globalid (1.2.1) globalid (1.2.1)
activesupport (>= 6.1) activesupport (>= 6.1)
google-protobuf (4.30.1) google-protobuf (4.30.2)
bigdecimal bigdecimal
rake (>= 13) rake (>= 13)
googleapis-common-protos-types (1.18.0) googleapis-common-protos-types (1.19.0)
google-protobuf (>= 3.18, < 5.a) google-protobuf (>= 3.18, < 5.a)
haml (6.3.0) haml (6.3.0)
temple (>= 0.8.2) temple (>= 0.8.2)
@ -328,7 +328,7 @@ GEM
activesupport (>= 3.0) activesupport (>= 3.0)
nokogiri (>= 1.6) nokogiri (>= 1.6)
io-console (0.8.0) io-console (0.8.0)
irb (1.15.1) irb (1.15.2)
pp (>= 0.6.0) pp (>= 0.6.0)
rdoc (>= 4.0.0) rdoc (>= 4.0.0)
reline (>= 0.4.2) reline (>= 0.4.2)
@ -426,7 +426,7 @@ GEM
mime-types (3.6.2) mime-types (3.6.2)
logger logger
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2025.0318) mime-types-data (3.2025.0402)
mini_mime (1.1.5) mini_mime (1.1.5)
mini_portile2 (2.8.8) mini_portile2 (2.8.8)
minitest (5.25.5) minitest (5.25.5)
@ -569,7 +569,7 @@ GEM
opentelemetry-instrumentation-redis (0.26.1) opentelemetry-instrumentation-redis (0.26.1)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0) opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-instrumentation-sidekiq (0.26.0) opentelemetry-instrumentation-sidekiq (0.26.1)
opentelemetry-api (~> 1.0) opentelemetry-api (~> 1.0)
opentelemetry-instrumentation-base (~> 0.23.0) opentelemetry-instrumentation-base (~> 0.23.0)
opentelemetry-registry (0.4.0) opentelemetry-registry (0.4.0)
@ -688,7 +688,7 @@ GEM
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.7.0) rdf-normalize (0.7.0)
rdf (~> 3.3) rdf (~> 3.3)
rdoc (6.12.0) rdoc (6.13.1)
psych (>= 4.0.0) psych (>= 4.0.0)
redcarpet (3.6.1) redcarpet (3.6.1)
redis (4.8.1) redis (4.8.1)
@ -740,7 +740,7 @@ GEM
rspec-mocks (~> 3.0) rspec-mocks (~> 3.0)
sidekiq (>= 5, < 9) sidekiq (>= 5, < 9)
rspec-support (3.13.2) rspec-support (3.13.2)
rubocop (1.75.1) rubocop (1.75.2)
json (~> 2.3) json (~> 2.3)
language_server-protocol (~> 3.17.0.2) language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0) lint_roller (~> 1.1.0)
@ -748,10 +748,10 @@ GEM
parser (>= 3.3.0.2) parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0) regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.43.0, < 2.0) rubocop-ast (>= 1.44.0, < 2.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0) unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.43.0) rubocop-ast (1.44.0)
parser (>= 3.3.7.2) parser (>= 3.3.7.2)
prism (~> 1.4) prism (~> 1.4)
rubocop-capybara (2.22.1) rubocop-capybara (2.22.1)
@ -840,7 +840,7 @@ GEM
stoplight (4.1.1) stoplight (4.1.1)
redlock (~> 1.0) redlock (~> 1.0)
stringio (3.1.6) stringio (3.1.6)
strong_migrations (2.2.1) strong_migrations (2.3.0)
activerecord (>= 7) activerecord (>= 7)
swd (2.0.3) swd (2.0.3)
activesupport (>= 3) activesupport (>= 3)
@ -851,7 +851,7 @@ GEM
temple (0.10.3) temple (0.10.3)
terminal-table (4.0.0) terminal-table (4.0.0)
unicode-display_width (>= 1.1.1, < 4) unicode-display_width (>= 1.1.1, < 4)
terrapin (1.0.1) terrapin (1.1.0)
climate_control climate_control
test-prof (1.4.4) test-prof (1.4.4)
thor (1.3.2) thor (1.3.2)
@ -1085,4 +1085,4 @@ RUBY VERSION
ruby 3.4.1p0 ruby 3.4.1p0
BUNDLED WITH BUNDLED WITH
2.6.6 2.6.7

View file

@ -10,8 +10,6 @@ module SignatureVerification
EXPIRATION_WINDOW_LIMIT = 12.hours EXPIRATION_WINDOW_LIMIT = 12.hours
CLOCK_SKEW_MARGIN = 1.hour CLOCK_SKEW_MARGIN = 1.hour
class SignatureVerificationError < StandardError; end
def require_account_signature! def require_account_signature!
render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account render json: signature_verification_failure_reason, status: signature_verification_failure_code unless signed_request_account
end end
@ -34,7 +32,7 @@ module SignatureVerification
def signature_key_id def signature_key_id
signature_params['keyId'] signature_params['keyId']
rescue SignatureVerificationError rescue Mastodon::SignatureVerificationError
nil nil
end end
@ -45,17 +43,17 @@ module SignatureVerification
def signed_request_actor def signed_request_actor
return @signed_request_actor if defined?(@signed_request_actor) return @signed_request_actor if defined?(@signed_request_actor)
raise SignatureVerificationError, 'Request not signed' unless signed_request? raise Mastodon::SignatureVerificationError, 'Request not signed' unless signed_request?
raise SignatureVerificationError, 'Incompatible request signature. keyId and signature are required' if missing_required_signature_parameters? raise Mastodon::SignatureVerificationError, 'Incompatible request signature. keyId and signature are required' if missing_required_signature_parameters?
raise SignatureVerificationError, 'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)' unless %w(rsa-sha256 hs2019).include?(signature_algorithm) raise Mastodon::SignatureVerificationError, 'Unsupported signature algorithm (only rsa-sha256 and hs2019 are supported)' unless %w(rsa-sha256 hs2019).include?(signature_algorithm)
raise SignatureVerificationError, 'Signed request date outside acceptable time window' unless matches_time_window? raise Mastodon::SignatureVerificationError, 'Signed request date outside acceptable time window' unless matches_time_window?
verify_signature_strength! verify_signature_strength!
verify_body_digest! verify_body_digest!
actor = actor_from_key_id(signature_params['keyId']) actor = actor_from_key_id(signature_params['keyId'])
raise SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil? raise Mastodon::SignatureVerificationError, "Public key not found for key #{signature_params['keyId']}" if actor.nil?
signature = Base64.decode64(signature_params['signature']) signature = Base64.decode64(signature_params['signature'])
compare_signed_string = build_signed_string(include_query_string: true) compare_signed_string = build_signed_string(include_query_string: true)
@ -68,7 +66,7 @@ module SignatureVerification
actor = stoplight_wrapper.run { actor_refresh_key!(actor) } actor = stoplight_wrapper.run { actor_refresh_key!(actor) }
raise SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil? raise Mastodon::SignatureVerificationError, "Could not refresh public key #{signature_params['keyId']}" if actor.nil?
compare_signed_string = build_signed_string(include_query_string: true) compare_signed_string = build_signed_string(include_query_string: true)
return actor unless verify_signature(actor, signature, compare_signed_string).nil? return actor unless verify_signature(actor, signature, compare_signed_string).nil?
@ -78,7 +76,7 @@ module SignatureVerification
return actor unless verify_signature(actor, signature, compare_signed_string).nil? return actor unless verify_signature(actor, signature, compare_signed_string).nil?
fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature'] fail_with! "Verification failed for #{actor.to_log_human_identifier} #{actor.uri} using rsa-sha256 (RSASSA-PKCS1-v1_5 with SHA-256)", signed_string: compare_signed_string, signature: signature_params['signature']
rescue SignatureVerificationError => e rescue Mastodon::SignatureVerificationError => e
fail_with! e.message fail_with! e.message
rescue *Mastodon::HTTP_CONNECTION_ERRORS => e rescue *Mastodon::HTTP_CONNECTION_ERRORS => e
fail_with! "Failed to fetch remote data: #{e.message}" fail_with! "Failed to fetch remote data: #{e.message}"
@ -104,7 +102,7 @@ module SignatureVerification
def signature_params def signature_params
@signature_params ||= SignatureParser.parse(request.headers['Signature']) @signature_params ||= SignatureParser.parse(request.headers['Signature'])
rescue SignatureParser::ParsingError rescue SignatureParser::ParsingError
raise SignatureVerificationError, 'Error parsing signature parameters' raise Mastodon::SignatureVerificationError, 'Error parsing signature parameters'
end end
def signature_algorithm def signature_algorithm
@ -116,31 +114,31 @@ module SignatureVerification
end end
def verify_signature_strength! def verify_signature_strength!
raise SignatureVerificationError, 'Mastodon requires the Date header or (created) pseudo-header to be signed' unless signed_headers.include?('date') || signed_headers.include?('(created)') raise Mastodon::SignatureVerificationError, 'Mastodon requires the Date header or (created) pseudo-header to be signed' unless signed_headers.include?('date') || signed_headers.include?('(created)')
raise SignatureVerificationError, 'Mastodon requires the Digest header or (request-target) pseudo-header to be signed' unless signed_headers.include?(HttpSignatureDraft::REQUEST_TARGET) || signed_headers.include?('digest') raise Mastodon::SignatureVerificationError, 'Mastodon requires the Digest header or (request-target) pseudo-header to be signed' unless signed_headers.include?(HttpSignatureDraft::REQUEST_TARGET) || signed_headers.include?('digest')
raise SignatureVerificationError, 'Mastodon requires the Host header to be signed when doing a GET request' if request.get? && !signed_headers.include?('host') raise Mastodon::SignatureVerificationError, 'Mastodon requires the Host header to be signed when doing a GET request' if request.get? && !signed_headers.include?('host')
raise SignatureVerificationError, 'Mastodon requires the Digest header to be signed when doing a POST request' if request.post? && !signed_headers.include?('digest') raise Mastodon::SignatureVerificationError, 'Mastodon requires the Digest header to be signed when doing a POST request' if request.post? && !signed_headers.include?('digest')
end end
def verify_body_digest! def verify_body_digest!
return unless signed_headers.include?('digest') return unless signed_headers.include?('digest')
raise SignatureVerificationError, 'Digest header missing' unless request.headers.key?('Digest') raise Mastodon::SignatureVerificationError, 'Digest header missing' unless request.headers.key?('Digest')
digests = request.headers['Digest'].split(',').map { |digest| digest.split('=', 2) }.map { |key, value| [key.downcase, value] } digests = request.headers['Digest'].split(',').map { |digest| digest.split('=', 2) }.map { |key, value| [key.downcase, value] }
sha256 = digests.assoc('sha-256') sha256 = digests.assoc('sha-256')
raise SignatureVerificationError, "Mastodon only supports SHA-256 in Digest header. Offered algorithms: #{digests.map(&:first).join(', ')}" if sha256.nil? raise Mastodon::SignatureVerificationError, "Mastodon only supports SHA-256 in Digest header. Offered algorithms: #{digests.map(&:first).join(', ')}" if sha256.nil?
return if body_digest == sha256[1] return if body_digest == sha256[1]
digest_size = begin digest_size = begin
Base64.strict_decode64(sha256[1].strip).length Base64.strict_decode64(sha256[1].strip).length
rescue ArgumentError rescue ArgumentError
raise SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a valid base64 string. Given digest: #{sha256[1]}" raise Mastodon::SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a valid base64 string. Given digest: #{sha256[1]}"
end end
raise SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a SHA-256 digest. Given digest: #{sha256[1]}" if digest_size != 32 raise Mastodon::SignatureVerificationError, "Invalid Digest value. The provided Digest value is not a SHA-256 digest. Given digest: #{sha256[1]}" if digest_size != 32
raise SignatureVerificationError, "Invalid Digest value. Computed SHA-256 digest: #{body_digest}; given: #{sha256[1]}" raise Mastodon::SignatureVerificationError, "Invalid Digest value. Computed SHA-256 digest: #{body_digest}; given: #{sha256[1]}"
end end
def verify_signature(actor, signature, compare_signed_string) def verify_signature(actor, signature, compare_signed_string)
@ -165,13 +163,13 @@ module SignatureVerification
"#{HttpSignatureDraft::REQUEST_TARGET}: #{request.method.downcase} #{request.path}" "#{HttpSignatureDraft::REQUEST_TARGET}: #{request.method.downcase} #{request.path}"
end end
when '(created)' when '(created)'
raise SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019' raise Mastodon::SignatureVerificationError, 'Invalid pseudo-header (created) for rsa-sha256' unless signature_algorithm == 'hs2019'
raise SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank? raise Mastodon::SignatureVerificationError, 'Pseudo-header (created) used but corresponding argument missing' if signature_params['created'].blank?
"(created): #{signature_params['created']}" "(created): #{signature_params['created']}"
when '(expires)' when '(expires)'
raise SignatureVerificationError, 'Invalid pseudo-header (expires) for rsa-sha256' unless signature_algorithm == 'hs2019' raise Mastodon::SignatureVerificationError, 'Invalid pseudo-header (expires) for rsa-sha256' unless signature_algorithm == 'hs2019'
raise SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank? raise Mastodon::SignatureVerificationError, 'Pseudo-header (expires) used but corresponding argument missing' if signature_params['expires'].blank?
"(expires): #{signature_params['expires']}" "(expires): #{signature_params['expires']}"
else else
@ -193,7 +191,7 @@ module SignatureVerification
expires_time = Time.at(signature_params['expires'].to_i).utc if signature_params['expires'].present? expires_time = Time.at(signature_params['expires'].to_i).utc if signature_params['expires'].present?
rescue ArgumentError => e rescue ArgumentError => e
raise SignatureVerificationError, "Invalid Date header: #{e.message}" raise Mastodon::SignatureVerificationError, "Invalid Date header: #{e.message}"
end end
expires_time ||= created_time + 5.minutes unless created_time.nil? expires_time ||= created_time + 5.minutes unless created_time.nil?
@ -233,9 +231,9 @@ module SignatureVerification
account account
end end
rescue Mastodon::PrivateNetworkAddressError => e rescue Mastodon::PrivateNetworkAddressError => e
raise SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})" raise Mastodon::SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, ActivityPub::FetchRemoteKeyService::Error, Webfinger::Error => e rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, ActivityPub::FetchRemoteKeyService::Error, Webfinger::Error => e
raise SignatureVerificationError, e.message raise Mastodon::SignatureVerificationError, e.message
end end
def stoplight_wrapper def stoplight_wrapper
@ -251,8 +249,8 @@ module SignatureVerification
ActivityPub::FetchRemoteActorService.new.call(actor.uri, only_key: true, suppress_errors: false) ActivityPub::FetchRemoteActorService.new.call(actor.uri, only_key: true, suppress_errors: false)
rescue Mastodon::PrivateNetworkAddressError => e rescue Mastodon::PrivateNetworkAddressError => e
raise SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})" raise Mastodon::SignatureVerificationError, "Requests to private network addresses are disallowed (tried to query #{e.host})"
rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, Webfinger::Error => e rescue Mastodon::HostValidationError, ActivityPub::FetchRemoteActorService::Error, Webfinger::Error => e
raise SignatureVerificationError, e.message raise Mastodon::SignatureVerificationError, e.message
end end
end end

View file

@ -12,14 +12,6 @@ export const DOMAIN_BLOCK_FAIL = 'DOMAIN_BLOCK_FAIL';
export const DOMAIN_UNBLOCK_REQUEST = 'DOMAIN_UNBLOCK_REQUEST'; export const DOMAIN_UNBLOCK_REQUEST = 'DOMAIN_UNBLOCK_REQUEST';
export const DOMAIN_UNBLOCK_FAIL = 'DOMAIN_UNBLOCK_FAIL'; export const DOMAIN_UNBLOCK_FAIL = 'DOMAIN_UNBLOCK_FAIL';
export const DOMAIN_BLOCKS_FETCH_REQUEST = 'DOMAIN_BLOCKS_FETCH_REQUEST';
export const DOMAIN_BLOCKS_FETCH_SUCCESS = 'DOMAIN_BLOCKS_FETCH_SUCCESS';
export const DOMAIN_BLOCKS_FETCH_FAIL = 'DOMAIN_BLOCKS_FETCH_FAIL';
export const DOMAIN_BLOCKS_EXPAND_REQUEST = 'DOMAIN_BLOCKS_EXPAND_REQUEST';
export const DOMAIN_BLOCKS_EXPAND_SUCCESS = 'DOMAIN_BLOCKS_EXPAND_SUCCESS';
export const DOMAIN_BLOCKS_EXPAND_FAIL = 'DOMAIN_BLOCKS_EXPAND_FAIL';
export function blockDomain(domain) { export function blockDomain(domain) {
return (dispatch, getState) => { return (dispatch, getState) => {
dispatch(blockDomainRequest(domain)); dispatch(blockDomainRequest(domain));
@ -79,80 +71,6 @@ export function unblockDomainFail(domain, error) {
}; };
} }
export function fetchDomainBlocks() {
return (dispatch) => {
dispatch(fetchDomainBlocksRequest());
api().get('/api/v1/domain_blocks').then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(fetchDomainBlocksSuccess(response.data, next ? next.uri : null));
}).catch(err => {
dispatch(fetchDomainBlocksFail(err));
});
};
}
export function fetchDomainBlocksRequest() {
return {
type: DOMAIN_BLOCKS_FETCH_REQUEST,
};
}
export function fetchDomainBlocksSuccess(domains, next) {
return {
type: DOMAIN_BLOCKS_FETCH_SUCCESS,
domains,
next,
};
}
export function fetchDomainBlocksFail(error) {
return {
type: DOMAIN_BLOCKS_FETCH_FAIL,
error,
};
}
export function expandDomainBlocks() {
return (dispatch, getState) => {
const url = getState().getIn(['domain_lists', 'blocks', 'next']);
if (!url) {
return;
}
dispatch(expandDomainBlocksRequest());
api().get(url).then(response => {
const next = getLinks(response).refs.find(link => link.rel === 'next');
dispatch(expandDomainBlocksSuccess(response.data, next ? next.uri : null));
}).catch(err => {
dispatch(expandDomainBlocksFail(err));
});
};
}
export function expandDomainBlocksRequest() {
return {
type: DOMAIN_BLOCKS_EXPAND_REQUEST,
};
}
export function expandDomainBlocksSuccess(domains, next) {
return {
type: DOMAIN_BLOCKS_EXPAND_SUCCESS,
domains,
next,
};
}
export function expandDomainBlocksFail(error) {
return {
type: DOMAIN_BLOCKS_EXPAND_FAIL,
error,
};
}
export const initDomainBlockModal = account => dispatch => dispatch(openModal({ export const initDomainBlockModal = account => dispatch => dispatch(openModal({
modalType: 'DOMAIN_BLOCK', modalType: 'DOMAIN_BLOCK',
modalProps: { modalProps: {

View file

@ -0,0 +1,13 @@
import api, { getLinks } from 'mastodon/api';
export const apiGetDomainBlocks = async (url?: string) => {
const response = await api().request<string[]>({
method: 'GET',
url: url ?? '/api/v1/domain_blocks',
});
return {
domains: response.data,
links: getLinks(response),
};
};

View file

@ -1,29 +1,36 @@
import PropTypes from 'prop-types';
import { useState, useCallback } from 'react'; import { useState, useCallback } from 'react';
import { defineMessages } from 'react-intl'; import { defineMessages } from 'react-intl';
import classNames from 'classnames'; import classNames from 'classnames';
import { useDispatch } from 'react-redux';
import ContentCopyIcon from '@/material-icons/400-24px/content_copy.svg?react'; import ContentCopyIcon from '@/material-icons/400-24px/content_copy.svg?react';
import { showAlert } from 'mastodon/actions/alerts'; import { showAlert } from 'mastodon/actions/alerts';
import { IconButton } from 'mastodon/components/icon_button'; import { IconButton } from 'mastodon/components/icon_button';
import { useAppDispatch } from 'mastodon/store';
const messages = defineMessages({ const messages = defineMessages({
copied: { id: 'copy_icon_button.copied', defaultMessage: 'Copied to clipboard' }, copied: {
id: 'copy_icon_button.copied',
defaultMessage: 'Copied to clipboard',
},
}); });
export const CopyIconButton = ({ title, value, className }) => { export const CopyIconButton: React.FC<{
title: string;
value: string;
className: string;
}> = ({ title, value, className }) => {
const [copied, setCopied] = useState(false); const [copied, setCopied] = useState(false);
const dispatch = useDispatch(); const dispatch = useAppDispatch();
const handleClick = useCallback(() => { const handleClick = useCallback(() => {
navigator.clipboard.writeText(value); void navigator.clipboard.writeText(value);
setCopied(true); setCopied(true);
dispatch(showAlert({ message: messages.copied })); dispatch(showAlert({ message: messages.copied }));
setTimeout(() => setCopied(false), 700); setTimeout(() => {
setCopied(false);
}, 700);
}, [setCopied, value, dispatch]); }, [setCopied, value, dispatch]);
return ( return (
@ -31,13 +38,8 @@ export const CopyIconButton = ({ title, value, className }) => {
className={classNames(className, copied ? 'copied' : 'copyable')} className={classNames(className, copied ? 'copied' : 'copyable')}
title={title} title={title}
onClick={handleClick} onClick={handleClick}
icon=''
iconComponent={ContentCopyIcon} iconComponent={ContentCopyIcon}
/> />
); );
}; };
CopyIconButton.propTypes = {
title: PropTypes.string,
value: PropTypes.string,
className: PropTypes.string,
};

View file

@ -1,24 +1,15 @@
import { useCallback } from 'react'; import { useCallback } from 'react';
import { defineMessages, useIntl } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import LockOpenIcon from '@/material-icons/400-24px/lock_open.svg?react';
import { unblockDomain } from 'mastodon/actions/domain_blocks'; import { unblockDomain } from 'mastodon/actions/domain_blocks';
import { useAppDispatch } from 'mastodon/store'; import { useAppDispatch } from 'mastodon/store';
import { IconButton } from './icon_button'; import { Button } from './button';
const messages = defineMessages({
unblockDomain: {
id: 'account.unblock_domain',
defaultMessage: 'Unblock domain {domain}',
},
});
export const Domain: React.FC<{ export const Domain: React.FC<{
domain: string; domain: string;
}> = ({ domain }) => { }> = ({ domain }) => {
const intl = useIntl();
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const handleDomainUnblock = useCallback(() => { const handleDomainUnblock = useCallback(() => {
@ -27,20 +18,17 @@ export const Domain: React.FC<{
return ( return (
<div className='domain'> <div className='domain'>
<div className='domain__wrapper'> <div className='domain__domain-name'>
<span className='domain__domain-name'> <strong>{domain}</strong>
<strong>{domain}</strong> </div>
</span>
<div className='domain__buttons'> <div className='domain__buttons'>
<IconButton <Button onClick={handleDomainUnblock}>
active <FormattedMessage
icon='unlock' id='account.unblock_domain_short'
iconComponent={LockOpenIcon} defaultMessage='Unblock'
title={intl.formatMessage(messages.unblockDomain, { domain })}
onClick={handleDomainUnblock}
/> />
</div> </Button>
</div> </div>
</div> </div>
); );

View file

@ -1,85 +0,0 @@
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import { Helmet } from 'react-helmet';
import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { connect } from 'react-redux';
import { debounce } from 'lodash';
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
import { Domain } from 'mastodon/components/domain';
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';
import Column from '../ui/components/column';
const messages = defineMessages({
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
});
const mapStateToProps = state => ({
domains: state.getIn(['domain_lists', 'blocks', 'items']),
hasMore: !!state.getIn(['domain_lists', 'blocks', 'next']),
});
class Blocks extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
hasMore: PropTypes.bool,
domains: ImmutablePropTypes.orderedSet,
intl: PropTypes.object.isRequired,
multiColumn: PropTypes.bool,
};
UNSAFE_componentWillMount () {
this.props.dispatch(fetchDomainBlocks());
}
handleLoadMore = debounce(() => {
this.props.dispatch(expandDomainBlocks());
}, 300, { leading: true });
render () {
const { intl, domains, hasMore, multiColumn } = this.props;
if (!domains) {
return (
<Column>
<LoadingIndicator />
</Column>
);
}
const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
return (
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<ScrollableList
scrollKey='domain_blocks'
onLoadMore={this.handleLoadMore}
hasMore={hasMore}
emptyMessage={emptyMessage}
bindToDocument={!multiColumn}
>
{domains.map(domain =>
<Domain key={domain} domain={domain} />,
)}
</ScrollableList>
<Helmet>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
}
}
export default connect(mapStateToProps)(injectIntl(Blocks));

View file

@ -0,0 +1,113 @@
import { useEffect, useRef, useCallback, useState } from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import { Helmet } from 'react-helmet';
import BlockIcon from '@/material-icons/400-24px/block-fill.svg?react';
import { apiGetDomainBlocks } from 'mastodon/api/domain_blocks';
import { Column } from 'mastodon/components/column';
import type { ColumnRef } from 'mastodon/components/column';
import { ColumnHeader } from 'mastodon/components/column_header';
import { Domain } from 'mastodon/components/domain';
import ScrollableList from 'mastodon/components/scrollable_list';
const messages = defineMessages({
heading: { id: 'column.domain_blocks', defaultMessage: 'Blocked domains' },
});
const Blocks: React.FC<{ multiColumn: boolean }> = ({ multiColumn }) => {
const intl = useIntl();
const [domains, setDomains] = useState<string[]>([]);
const [loading, setLoading] = useState(false);
const [next, setNext] = useState<string | undefined>();
const hasMore = !!next;
const columnRef = useRef<ColumnRef>(null);
useEffect(() => {
setLoading(true);
void apiGetDomainBlocks()
.then(({ domains, links }) => {
const next = links.refs.find((link) => link.rel === 'next');
setLoading(false);
setDomains(domains);
setNext(next?.uri);
return '';
})
.catch(() => {
setLoading(false);
});
}, [setLoading, setDomains, setNext]);
const handleLoadMore = useCallback(() => {
setLoading(true);
void apiGetDomainBlocks(next)
.then(({ domains, links }) => {
const next = links.refs.find((link) => link.rel === 'next');
setLoading(false);
setDomains((previousDomains) => [...previousDomains, ...domains]);
setNext(next?.uri);
return '';
})
.catch(() => {
setLoading(false);
});
}, [setLoading, setDomains, setNext, next]);
const handleHeaderClick = useCallback(() => {
columnRef.current?.scrollTop();
}, []);
const emptyMessage = (
<FormattedMessage
id='empty_column.domain_blocks'
defaultMessage='There are no blocked domains yet.'
/>
);
return (
<Column
bindToDocument={!multiColumn}
ref={columnRef}
label={intl.formatMessage(messages.heading)}
>
<ColumnHeader
icon='ban'
iconComponent={BlockIcon}
title={intl.formatMessage(messages.heading)}
onClick={handleHeaderClick}
multiColumn={multiColumn}
showBackButton
/>
<ScrollableList
scrollKey='domain_blocks'
onLoadMore={handleLoadMore}
hasMore={hasMore}
isLoading={loading}
showLoading={loading && domains.length === 0}
emptyMessage={emptyMessage}
trackScroll={!multiColumn}
bindToDocument={!multiColumn}
>
{domains.map((domain) => (
<Domain key={domain} domain={domain} />
))}
</ScrollableList>
<Helmet>
<title>{intl.formatMessage(messages.heading)}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>
);
};
// eslint-disable-next-line import/no-default-export
export default Blocks;

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} publicació} other {{counter} publicacions}}", "account.statuses_counter": "{count, plural, one {{counter} publicació} other {{counter} publicacions}}",
"account.unblock": "Desbloca @{name}", "account.unblock": "Desbloca @{name}",
"account.unblock_domain": "Desbloca el domini {domain}", "account.unblock_domain": "Desbloca el domini {domain}",
"account.unblock_domain_short": "Desbloca",
"account.unblock_short": "Desbloca", "account.unblock_short": "Desbloca",
"account.unendorse": "No recomanis en el perfil", "account.unendorse": "No recomanis en el perfil",
"account.unfollow": "Deixa de seguir", "account.unfollow": "Deixa de seguir",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} příspěvek} few {{counter} příspěvky} many {{counter} příspěvků} other {{counter} příspěvků}}", "account.statuses_counter": "{count, plural, one {{counter} příspěvek} few {{counter} příspěvky} many {{counter} příspěvků} other {{counter} příspěvků}}",
"account.unblock": "Odblokovat @{name}", "account.unblock": "Odblokovat @{name}",
"account.unblock_domain": "Odblokovat doménu {domain}", "account.unblock_domain": "Odblokovat doménu {domain}",
"account.unblock_domain_short": "Odblokovat",
"account.unblock_short": "Odblokovat", "account.unblock_short": "Odblokovat",
"account.unendorse": "Nezvýrazňovat na profilu", "account.unendorse": "Nezvýrazňovat na profilu",
"account.unfollow": "Přestat sledovat", "account.unfollow": "Přestat sledovat",
@ -79,7 +80,7 @@
"admin.dashboard.retention.cohort_size": "Noví uživatelé", "admin.dashboard.retention.cohort_size": "Noví uživatelé",
"admin.impact_report.instance_accounts": "Profily účtů, které by byli odstaněny", "admin.impact_report.instance_accounts": "Profily účtů, které by byli odstaněny",
"admin.impact_report.instance_followers": "Sledující, o které by naši uživatelé přišli", "admin.impact_report.instance_followers": "Sledující, o které by naši uživatelé přišli",
"admin.impact_report.instance_follows": "Sledující, o které by naši uživatelé přišli", "admin.impact_report.instance_follows": "Sledující, o které by jejich uživatelé přišli",
"admin.impact_report.title": "Shrnutí dopadu", "admin.impact_report.title": "Shrnutí dopadu",
"alert.rate_limited.message": "Zkuste to prosím znovu po {retry_time, time, medium}.", "alert.rate_limited.message": "Zkuste to prosím znovu po {retry_time, time, medium}.",
"alert.rate_limited.title": "Spojení omezena", "alert.rate_limited.title": "Spojení omezena",
@ -101,7 +102,7 @@
"annual_report.summary.archetype.replier": "Sociální motýlek", "annual_report.summary.archetype.replier": "Sociální motýlek",
"annual_report.summary.followers.followers": "sledujících", "annual_report.summary.followers.followers": "sledujících",
"annual_report.summary.followers.total": "{count} celkem", "annual_report.summary.followers.total": "{count} celkem",
"annual_report.summary.here_it_is": "Zde je tvůj {year} v přehledu:", "annual_report.summary.here_it_is": "Zde je tvůj rok {year} v přehledu:",
"annual_report.summary.highlighted_post.by_favourites": "nejvíce oblíbený příspěvek", "annual_report.summary.highlighted_post.by_favourites": "nejvíce oblíbený příspěvek",
"annual_report.summary.highlighted_post.by_reblogs": "nejvíce boostovaný příspěvek", "annual_report.summary.highlighted_post.by_reblogs": "nejvíce boostovaný příspěvek",
"annual_report.summary.highlighted_post.by_replies": "příspěvek s nejvíce odpověďmi", "annual_report.summary.highlighted_post.by_replies": "příspěvek s nejvíce odpověďmi",
@ -267,7 +268,7 @@
"domain_pill.activitypub_like_language": "ActivityPub je jako jazyk, kterým Mastodon mluví s jinými sociálními sítěmi.", "domain_pill.activitypub_like_language": "ActivityPub je jako jazyk, kterým Mastodon mluví s jinými sociálními sítěmi.",
"domain_pill.server": "Server", "domain_pill.server": "Server",
"domain_pill.their_handle": "Handle:", "domain_pill.their_handle": "Handle:",
"domain_pill.their_server": "Jejich digitální domov, kde žijí jejich všechny příspěvky.", "domain_pill.their_server": "Jejich digitální domov, kde žijí všechny jejich příspěvky.",
"domain_pill.their_username": "Jejich jedinečný identifikátor na jejich serveru. Je možné, že na jiných serverech jsou uživatelé se stejným uživatelským jménem.", "domain_pill.their_username": "Jejich jedinečný identifikátor na jejich serveru. Je možné, že na jiných serverech jsou uživatelé se stejným uživatelským jménem.",
"domain_pill.username": "Uživatelské jméno", "domain_pill.username": "Uživatelské jméno",
"domain_pill.whats_in_a_handle": "Co obsahuje handle?", "domain_pill.whats_in_a_handle": "Co obsahuje handle?",
@ -572,7 +573,7 @@
"notification.label.private_reply": "Privátní odpověď", "notification.label.private_reply": "Privátní odpověď",
"notification.label.reply": "Odpověď", "notification.label.reply": "Odpověď",
"notification.mention": "Zmínka", "notification.mention": "Zmínka",
"notification.mentioned_you": "{name} vás zmínil", "notification.mentioned_you": "{name} vás zmínil*a",
"notification.moderation-warning.learn_more": "Zjistit více", "notification.moderation-warning.learn_more": "Zjistit více",
"notification.moderation_warning": "Obdrželi jste varování od moderátorů", "notification.moderation_warning": "Obdrželi jste varování od moderátorů",
"notification.moderation_warning.action_delete_statuses": "Některé z vašich příspěvků byly odstraněny.", "notification.moderation_warning.action_delete_statuses": "Některé z vašich příspěvků byly odstraněny.",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} postiad} two {{counter} bostiad} few {{counter} phostiad} many {{counter} postiad} other {{counter} postiad}}", "account.statuses_counter": "{count, plural, one {{counter} postiad} two {{counter} bostiad} few {{counter} phostiad} many {{counter} postiad} other {{counter} postiad}}",
"account.unblock": "Dadrwystro @{name}", "account.unblock": "Dadrwystro @{name}",
"account.unblock_domain": "Dadrwystro parth {domain}", "account.unblock_domain": "Dadrwystro parth {domain}",
"account.unblock_domain_short": "Dadrwystro",
"account.unblock_short": "Dadrwystro", "account.unblock_short": "Dadrwystro",
"account.unendorse": "Peidio a'i ddangos ar fy mhroffil", "account.unendorse": "Peidio a'i ddangos ar fy mhroffil",
"account.unfollow": "Dad-ddilyn", "account.unfollow": "Dad-ddilyn",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} indlæg} other {{counter} indlæg}}", "account.statuses_counter": "{count, plural, one {{counter} indlæg} other {{counter} indlæg}}",
"account.unblock": "Fjern blokering af @{name}", "account.unblock": "Fjern blokering af @{name}",
"account.unblock_domain": "Fjern blokering af domænet {domain}", "account.unblock_domain": "Fjern blokering af domænet {domain}",
"account.unblock_domain_short": "Afblokér",
"account.unblock_short": "Fjern blokering", "account.unblock_short": "Fjern blokering",
"account.unendorse": "Fjern visning på din profil", "account.unendorse": "Fjern visning på din profil",
"account.unfollow": "Følg ikke længere", "account.unfollow": "Følg ikke længere",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}", "account.statuses_counter": "{count, plural, one {{counter} Beitrag} other {{counter} Beiträge}}",
"account.unblock": "{name} nicht mehr blockieren", "account.unblock": "{name} nicht mehr blockieren",
"account.unblock_domain": "Blockierung von {domain} aufheben", "account.unblock_domain": "Blockierung von {domain} aufheben",
"account.unblock_domain_short": "Entsperren",
"account.unblock_short": "Blockierung aufheben", "account.unblock_short": "Blockierung aufheben",
"account.unendorse": "Im Profil nicht mehr empfehlen", "account.unendorse": "Im Profil nicht mehr empfehlen",
"account.unfollow": "Entfolgen", "account.unfollow": "Entfolgen",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}", "account.statuses_counter": "{count, plural, one {{counter} post} other {{counter} posts}}",
"account.unblock": "Unblock @{name}", "account.unblock": "Unblock @{name}",
"account.unblock_domain": "Unblock domain {domain}", "account.unblock_domain": "Unblock domain {domain}",
"account.unblock_domain_short": "Unblock",
"account.unblock_short": "Unblock", "account.unblock_short": "Unblock",
"account.unendorse": "Don't feature on profile", "account.unendorse": "Don't feature on profile",
"account.unfollow": "Unfollow", "account.unfollow": "Unfollow",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}}", "account.statuses_counter": "{count, plural, one {{counter} mensaje} other {{counter} mensajes}}",
"account.unblock": "Desbloquear a @{name}", "account.unblock": "Desbloquear a @{name}",
"account.unblock_domain": "Desbloquear dominio {domain}", "account.unblock_domain": "Desbloquear dominio {domain}",
"account.unblock_domain_short": "Desbloquear",
"account.unblock_short": "Desbloquear", "account.unblock_short": "Desbloquear",
"account.unendorse": "No destacar en el perfil", "account.unendorse": "No destacar en el perfil",
"account.unfollow": "Dejar de seguir", "account.unfollow": "Dejar de seguir",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}", "account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
"account.unblock": "Desbloquear a @{name}", "account.unblock": "Desbloquear a @{name}",
"account.unblock_domain": "Mostrar a {domain}", "account.unblock_domain": "Mostrar a {domain}",
"account.unblock_domain_short": "Desbloquear",
"account.unblock_short": "Desbloquear", "account.unblock_short": "Desbloquear",
"account.unendorse": "No mostrar en el perfil", "account.unendorse": "No mostrar en el perfil",
"account.unfollow": "Dejar de seguir", "account.unfollow": "Dejar de seguir",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}", "account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicaciones}}",
"account.unblock": "Desbloquear a @{name}", "account.unblock": "Desbloquear a @{name}",
"account.unblock_domain": "Desbloquear dominio {domain}", "account.unblock_domain": "Desbloquear dominio {domain}",
"account.unblock_domain_short": "Desbloquear",
"account.unblock_short": "Desbloquear", "account.unblock_short": "Desbloquear",
"account.unendorse": "No mostrar en el perfil", "account.unendorse": "No mostrar en el perfil",
"account.unfollow": "Dejar de seguir", "account.unfollow": "Dejar de seguir",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}", "account.statuses_counter": "{count, plural, one {{counter} julkaisu} other {{counter} julkaisua}}",
"account.unblock": "Kumoa käyttäjän @{name} esto", "account.unblock": "Kumoa käyttäjän @{name} esto",
"account.unblock_domain": "Kumoa verkkotunnuksen {domain} esto", "account.unblock_domain": "Kumoa verkkotunnuksen {domain} esto",
"account.unblock_domain_short": "Kumoa esto",
"account.unblock_short": "Kumoa esto", "account.unblock_short": "Kumoa esto",
"account.unendorse": "Kumoa suosittelu profiilissasi", "account.unendorse": "Kumoa suosittelu profiilissasi",
"account.unfollow": "Älä seuraa", "account.unfollow": "Älä seuraa",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} postur} other {{counter} postar}}", "account.statuses_counter": "{count, plural, one {{counter} postur} other {{counter} postar}}",
"account.unblock": "Banna ikki @{name}", "account.unblock": "Banna ikki @{name}",
"account.unblock_domain": "Banna ikki økisnavnið {domain}", "account.unblock_domain": "Banna ikki økisnavnið {domain}",
"account.unblock_domain_short": "Banna ikki",
"account.unblock_short": "Banna ikki", "account.unblock_short": "Banna ikki",
"account.unendorse": "Vís ikki á vanga", "account.unendorse": "Vís ikki á vanga",
"account.unfollow": "Fylg ikki", "account.unfollow": "Fylg ikki",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicacións}}", "account.statuses_counter": "{count, plural, one {{counter} publicación} other {{counter} publicacións}}",
"account.unblock": "Desbloquear @{name}", "account.unblock": "Desbloquear @{name}",
"account.unblock_domain": "Amosar {domain}", "account.unblock_domain": "Amosar {domain}",
"account.unblock_domain_short": "Desbloquear",
"account.unblock_short": "Desbloquear", "account.unblock_short": "Desbloquear",
"account.unendorse": "Non amosar no perfil", "account.unendorse": "Non amosar no perfil",
"account.unfollow": "Deixar de seguir", "account.unfollow": "Deixar de seguir",

View file

@ -64,8 +64,9 @@
"account.show_reblogs": "הצג הדהודים מאת @{name}", "account.show_reblogs": "הצג הדהודים מאת @{name}",
"account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}", "account.statuses_counter": "{count, plural, one {הודעה אחת} two {הודעותיים} many {{counter} הודעות} other {{counter} הודעות}}",
"account.unblock": "להסיר חסימה ל- @{name}", "account.unblock": "להסיר חסימה ל- @{name}",
"account.unblock_domain": "הסירי את החסימה של קהילת {domain}", "account.unblock_domain": "הסרת החסימה של קהילת {domain}",
"account.unblock_short": "הסר חסימה", "account.unblock_domain_short": "הסרת חסימה",
"account.unblock_short": "הסרת חסימה",
"account.unendorse": "אל תקדם בפרופיל", "account.unendorse": "אל תקדם בפרופיל",
"account.unfollow": "הפסקת מעקב", "account.unfollow": "הפסקת מעקב",
"account.unmute": "הפסקת השתקת @{name}", "account.unmute": "הפסקת השתקת @{name}",
@ -905,6 +906,12 @@
"video.expand": "להרחיב וידאו", "video.expand": "להרחיב וידאו",
"video.fullscreen": "מסך מלא", "video.fullscreen": "מסך מלא",
"video.hide": "להסתיר וידאו", "video.hide": "להסתיר וידאו",
"video.mute": "השתקה",
"video.pause": "השהיה", "video.pause": "השהיה",
"video.play": "ניגון" "video.play": "ניגון",
"video.skip_backward": "דילוג אחורה",
"video.skip_forward": "דילוג קדימה",
"video.unmute": "ביטול השתקה",
"video.volume_down": "הנמכת עוצמת השמע",
"video.volume_up": "הגברת עוצמת שמע"
} }

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} bejegyzés} other {{counter} bejegyzés}}", "account.statuses_counter": "{count, plural, one {{counter} bejegyzés} other {{counter} bejegyzés}}",
"account.unblock": "@{name} letiltásának feloldása", "account.unblock": "@{name} letiltásának feloldása",
"account.unblock_domain": "{domain} domain tiltásának feloldása", "account.unblock_domain": "{domain} domain tiltásának feloldása",
"account.unblock_domain_short": "Tiltás feloldása",
"account.unblock_short": "Tiltás feloldása", "account.unblock_short": "Tiltás feloldása",
"account.unendorse": "Ne jelenjen meg a profilodon", "account.unendorse": "Ne jelenjen meg a profilodon",
"account.unfollow": "Követés megszüntetése", "account.unfollow": "Követés megszüntetése",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} færsla} other {{counter} færslur}}", "account.statuses_counter": "{count, plural, one {{counter} færsla} other {{counter} færslur}}",
"account.unblock": "Aflétta útilokun af @{name}", "account.unblock": "Aflétta útilokun af @{name}",
"account.unblock_domain": "Aflétta útilokun lénsins {domain}", "account.unblock_domain": "Aflétta útilokun lénsins {domain}",
"account.unblock_domain_short": "Aflétta útilokun",
"account.unblock_short": "Hætta að loka á", "account.unblock_short": "Hætta að loka á",
"account.unendorse": "Ekki birta á notandasniði", "account.unendorse": "Ekki birta á notandasniði",
"account.unfollow": "Hætta að fylgja", "account.unfollow": "Hætta að fylgja",

View file

@ -70,7 +70,7 @@
"account.unfollow": "Smetti di seguire", "account.unfollow": "Smetti di seguire",
"account.unmute": "Riattiva @{name}", "account.unmute": "Riattiva @{name}",
"account.unmute_notifications_short": "Riattiva notifiche", "account.unmute_notifications_short": "Riattiva notifiche",
"account.unmute_short": "Riattiva", "account.unmute_short": "Attiva audio",
"account_note.placeholder": "Clicca per aggiungere una nota", "account_note.placeholder": "Clicca per aggiungere una nota",
"admin.dashboard.daily_retention": "Tasso di ritenzione dell'utente per giorno, dopo la registrazione", "admin.dashboard.daily_retention": "Tasso di ritenzione dell'utente per giorno, dopo la registrazione",
"admin.dashboard.monthly_retention": "Tasso di ritenzione dell'utente per mese, dopo la registrazione", "admin.dashboard.monthly_retention": "Tasso di ritenzione dell'utente per mese, dopo la registrazione",
@ -905,6 +905,12 @@
"video.expand": "Espandi il video", "video.expand": "Espandi il video",
"video.fullscreen": "Schermo intero", "video.fullscreen": "Schermo intero",
"video.hide": "Nascondi il video", "video.hide": "Nascondi il video",
"video.mute": "Muta",
"video.pause": "Pausa", "video.pause": "Pausa",
"video.play": "Riproduci" "video.play": "Riproduci",
"video.skip_backward": "Vai indietro",
"video.skip_forward": "Vai avanti",
"video.unmute": "Muta",
"video.volume_down": "Abbassa volume",
"video.volume_up": "Alza volume"
} }

View file

@ -61,6 +61,7 @@
"account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}", "account.statuses_counter": "{count, plural, one {{counter} n tsuffeɣt} other {{counter} n tsuffaɣ}}",
"account.unblock": "Serreḥ i @{name}", "account.unblock": "Serreḥ i @{name}",
"account.unblock_domain": "Ssken-d {domain}", "account.unblock_domain": "Ssken-d {domain}",
"account.unblock_domain_short": "Serreḥ",
"account.unblock_short": "Serreḥ", "account.unblock_short": "Serreḥ",
"account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek", "account.unendorse": "Ur ttwellih ara fell-as deg umaɣnu-inek",
"account.unfollow": "Ur ṭṭafaṛ ara", "account.unfollow": "Ur ṭṭafaṛ ara",
@ -77,6 +78,7 @@
"alt_text_modal.cancel": "Semmet", "alt_text_modal.cancel": "Semmet",
"alt_text_modal.done": "Immed", "alt_text_modal.done": "Immed",
"announcement.announcement": "Ulɣu", "announcement.announcement": "Ulɣu",
"annual_report.summary.most_used_app.most_used_app": "asnas yettwasqedcen s waṭas",
"annual_report.summary.most_used_hashtag.none": "Ula yiwen", "annual_report.summary.most_used_hashtag.none": "Ula yiwen",
"annual_report.summary.new_posts.new_posts": "tisuffaɣ timaynutin", "annual_report.summary.new_posts.new_posts": "tisuffaɣ timaynutin",
"audio.hide": "Ffer amesli", "audio.hide": "Ffer amesli",
@ -162,6 +164,7 @@
"confirmations.discard_edit_media.confirm": "Sefsex", "confirmations.discard_edit_media.confirm": "Sefsex",
"confirmations.edit.confirm": "Ẓreg", "confirmations.edit.confirm": "Ẓreg",
"confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreḍ akka tura. Tetḥeqqeḍ tebɣiḍ ad tkemmleḍ?", "confirmations.edit.message": "Abeddel tura ad d-yaru izen-nni i d-tegreḍ akka tura. Tetḥeqqeḍ tebɣiḍ ad tkemmleḍ?",
"confirmations.follow_to_list.confirm": "Ḍfeṛ-it sakin rnu-t ɣer tebdart",
"confirmations.logout.confirm": "Ffeɣ", "confirmations.logout.confirm": "Ffeɣ",
"confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?", "confirmations.logout.message": "D tidet tebɣiḍ ad teffɣeḍ?",
"confirmations.logout.title": "Tebɣiḍ ad teffɣeḍ ssya?", "confirmations.logout.title": "Tebɣiḍ ad teffɣeḍ ssya?",
@ -245,6 +248,7 @@
"filter_modal.select_filter.search": "Nadi neɣ snulfu-d", "filter_modal.select_filter.search": "Nadi neɣ snulfu-d",
"filter_modal.select_filter.title": "Sizdeg tassufeɣt-a", "filter_modal.select_filter.title": "Sizdeg tassufeɣt-a",
"filter_modal.title.status": "Sizdeg tassufeɣt", "filter_modal.title.status": "Sizdeg tassufeɣt",
"filtered_notifications_banner.title": "Ilɣa yettwasizdgen",
"firehose.all": "Akk", "firehose.all": "Akk",
"firehose.local": "Deg uqeddac-ayi", "firehose.local": "Deg uqeddac-ayi",
"firehose.remote": "Iqeddacen nniḍen", "firehose.remote": "Iqeddacen nniḍen",
@ -350,9 +354,12 @@
"lists.add_to_lists": "Rnu {name} ɣer tebdarin", "lists.add_to_lists": "Rnu {name} ɣer tebdarin",
"lists.create": "Snulfu-d", "lists.create": "Snulfu-d",
"lists.delete": "Kkes tabdart", "lists.delete": "Kkes tabdart",
"lists.done": "Immed",
"lists.edit": "Ẓreg tabdart", "lists.edit": "Ẓreg tabdart",
"lists.list_name": "Isem n tebdart", "lists.list_name": "Isem n tebdart",
"lists.new_list_name": "Isem n tebdart tamaynut", "lists.new_list_name": "Isem n tebdart tamaynut",
"lists.no_lists_yet": "Ulac tibdarin akka tura.",
"lists.no_results_found": "Ulac igemmad.",
"lists.remove_member": "Kkes", "lists.remove_member": "Kkes",
"lists.replies_policy.followed": "Kra n useqdac i yettwaḍefren", "lists.replies_policy.followed": "Kra n useqdac i yettwaḍefren",
"lists.replies_policy.list": "Iɛeggalen n tebdart", "lists.replies_policy.list": "Iɛeggalen n tebdart",
@ -389,6 +396,7 @@
"navigation_bar.follows_and_followers": "Imeḍfaṛen akked wid i teṭṭafaṛeḍ", "navigation_bar.follows_and_followers": "Imeḍfaṛen akked wid i teṭṭafaṛeḍ",
"navigation_bar.lists": "Tibdarin", "navigation_bar.lists": "Tibdarin",
"navigation_bar.logout": "Ffeɣ", "navigation_bar.logout": "Ffeɣ",
"navigation_bar.moderation": "Aseɣyed",
"navigation_bar.mutes": "Iseqdacen yettwasusmen", "navigation_bar.mutes": "Iseqdacen yettwasusmen",
"navigation_bar.opened_in_classic_interface": "Tisuffaɣ, imiḍanen akked isebtar-nniḍen igejdanen ldin-d s wudem amezwer deg ugrudem web aklasiki.", "navigation_bar.opened_in_classic_interface": "Tisuffaɣ, imiḍanen akked isebtar-nniḍen igejdanen ldin-d s wudem amezwer deg ugrudem web aklasiki.",
"navigation_bar.personal": "Udmawan", "navigation_bar.personal": "Udmawan",
@ -419,6 +427,7 @@
"notification_requests.edit_selection": "Ẓreg", "notification_requests.edit_selection": "Ẓreg",
"notification_requests.exit_selection": "Immed", "notification_requests.exit_selection": "Immed",
"notification_requests.notifications_from": "Alɣuten sɣur {name}", "notification_requests.notifications_from": "Alɣuten sɣur {name}",
"notification_requests.title": "Ilɣa yettwasizdgen",
"notifications.clear": "Sfeḍ alɣuten", "notifications.clear": "Sfeḍ alɣuten",
"notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk alɣuten-inek·em i lebda?", "notifications.clear_confirmation": "Tebɣiḍ s tidet ad tekkseḍ akk alɣuten-inek·em i lebda?",
"notifications.column_settings.admin.report": "Ineqqisen imaynuten:", "notifications.column_settings.admin.report": "Ineqqisen imaynuten:",
@ -463,6 +472,7 @@
"onboarding.follows.back": "Uɣal", "onboarding.follows.back": "Uɣal",
"onboarding.follows.done": "Immed", "onboarding.follows.done": "Immed",
"onboarding.follows.search": "Nadi", "onboarding.follows.search": "Nadi",
"onboarding.follows.title": "Ḍfeṛ walbɛaḍ i wakken ad ttebdud",
"onboarding.profile.display_name": "Isem ara d-yettwaskanen", "onboarding.profile.display_name": "Isem ara d-yettwaskanen",
"onboarding.profile.display_name_hint": "Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer…", "onboarding.profile.display_name_hint": "Isem-ik·im ummid neɣ isem-ik·im n uqeṣṣer…",
"onboarding.profile.note": "Tameddurt", "onboarding.profile.note": "Tameddurt",
@ -484,15 +494,18 @@
"poll_button.remove_poll": "Kkes asenqed", "poll_button.remove_poll": "Kkes asenqed",
"privacy.change": "Seggem tabaḍnit n yizen", "privacy.change": "Seggem tabaḍnit n yizen",
"privacy.direct.long": "Wid akk i d-yettwabdaren deg tsuffeɣt", "privacy.direct.long": "Wid akk i d-yettwabdaren deg tsuffeɣt",
"privacy.direct.short": "Abdar uslig",
"privacy.private.long": "Ala wid i k·m-yeṭṭafaṛen", "privacy.private.long": "Ala wid i k·m-yeṭṭafaṛen",
"privacy.private.short": "Imeḍfaren", "privacy.private.short": "Imeḍfaren",
"privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s", "privacy.public.long": "Kra n win yellan deg Masṭudun neɣ berra-s",
"privacy.public.short": "Azayez", "privacy.public.short": "Azayez",
"privacy.unlisted.long": "Kra kan yiwarzimen", "privacy.unlisted.long": "Kra kan yiwarzimen",
"privacy.unlisted.short": "Azayez asusam",
"privacy_policy.last_updated": "Aleqqem aneggaru {date}", "privacy_policy.last_updated": "Aleqqem aneggaru {date}",
"privacy_policy.title": "Tasertit tabaḍnit", "privacy_policy.title": "Tasertit tabaḍnit",
"recommended": "Yettuwelleh", "recommended": "Yettuwelleh",
"refresh": "Smiren", "refresh": "Smiren",
"regeneration_indicator.please_stand_by": "Ttxil rǧu.",
"relative_time.days": "{number}u", "relative_time.days": "{number}u",
"relative_time.full.just_now": "tura kan", "relative_time.full.just_now": "tura kan",
"relative_time.hours": "{number}isr", "relative_time.hours": "{number}isr",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} bericht} other {{counter} berichten}}", "account.statuses_counter": "{count, plural, one {{counter} bericht} other {{counter} berichten}}",
"account.unblock": "@{name} deblokkeren", "account.unblock": "@{name} deblokkeren",
"account.unblock_domain": "{domain} niet langer blokkeren", "account.unblock_domain": "{domain} niet langer blokkeren",
"account.unblock_domain_short": "Deblokkeren",
"account.unblock_short": "Deblokkeren", "account.unblock_short": "Deblokkeren",
"account.unendorse": "Niet op profiel weergeven", "account.unendorse": "Niet op profiel weergeven",
"account.unfollow": "Ontvolgen", "account.unfollow": "Ontvolgen",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} publicação} other {{counter} publicações}}", "account.statuses_counter": "{count, plural, one {{counter} publicação} other {{counter} publicações}}",
"account.unblock": "Desbloquear @{name}", "account.unblock": "Desbloquear @{name}",
"account.unblock_domain": "Desbloquear o domínio {domain}", "account.unblock_domain": "Desbloquear o domínio {domain}",
"account.unblock_domain_short": "Desbloquear",
"account.unblock_short": "Desbloquear", "account.unblock_short": "Desbloquear",
"account.unendorse": "Não destacar no perfil", "account.unendorse": "Não destacar no perfil",
"account.unfollow": "Deixar de seguir", "account.unfollow": "Deixar de seguir",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} postim} other {{counter} postime}}", "account.statuses_counter": "{count, plural, one {{counter} postim} other {{counter} postime}}",
"account.unblock": "Zhbllokoje @{name}", "account.unblock": "Zhbllokoje @{name}",
"account.unblock_domain": "Zhblloko përkatësinë {domain}", "account.unblock_domain": "Zhblloko përkatësinë {domain}",
"account.unblock_domain_short": "Zhbllokoje",
"account.unblock_short": "Zhbllokoje", "account.unblock_short": "Zhbllokoje",
"account.unendorse": "Mos e përfshi në profil", "account.unendorse": "Mos e përfshi në profil",
"account.unfollow": "Resht së ndjekuri", "account.unfollow": "Resht së ndjekuri",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} gönderi} other {{counter} gönderi}}", "account.statuses_counter": "{count, plural, one {{counter} gönderi} other {{counter} gönderi}}",
"account.unblock": "@{name} adlı kişinin engelini kaldır", "account.unblock": "@{name} adlı kişinin engelini kaldır",
"account.unblock_domain": "{domain} alan adının engelini kaldır", "account.unblock_domain": "{domain} alan adının engelini kaldır",
"account.unblock_domain_short": "Engeli kaldır",
"account.unblock_short": "Engeli kaldır", "account.unblock_short": "Engeli kaldır",
"account.unendorse": "Profilimde öne çıkarma", "account.unendorse": "Profilimde öne çıkarma",
"account.unfollow": "Takibi bırak", "account.unfollow": "Takibi bırak",
@ -905,6 +906,12 @@
"video.expand": "Videoyu genişlet", "video.expand": "Videoyu genişlet",
"video.fullscreen": "Tam ekran", "video.fullscreen": "Tam ekran",
"video.hide": "Videoyu gizle", "video.hide": "Videoyu gizle",
"video.mute": "Sessiz",
"video.pause": "Duraklat", "video.pause": "Duraklat",
"video.play": "Oynat" "video.play": "Oynat",
"video.skip_backward": "Geriye atla",
"video.skip_forward": "İleriye atla",
"video.unmute": "Sesi aç",
"video.volume_down": "Sesi kıs",
"video.volume_up": "Sesi yükselt"
} }

View file

@ -1,21 +1,34 @@
{ {
"about.blocks": "ئوتتۇراھال مۇلازىمېتىر", "about.blocks": "باشقۇرۇلىدىغان مۇلازىمېتىر",
"about.contact": "ئالاقىلاشقۇچى:", "about.contact": "ئالاقە:",
"account.badges.bot": "Bot", "about.disclaimer": "Mastodon ھەقسىز، ئوچۇق كودلۇق يۇمشاق دېتال تاۋار ماركىسى Mastodon gGmbH غا تەۋە.",
"account.cancel_follow_request": "Withdraw follow request", "about.domain_blocks.no_reason_available": "سەۋەبىنى ئىشلەتكىلى بولمايدۇ",
"account.posts": "Toots", "account.badges.bot": "ماشىنا ئادەم",
"account.posts_with_replies": "Toots and replies", "account.cancel_follow_request": "ئەگىشىش ئىلتىماسىدىن ۋاز كەچ",
"account.posts": "يازما",
"account.posts_with_replies": "يازما ۋە ئىنكاس",
"account.report": "@{name} نى پاش قىل",
"account.requested": "Awaiting approval", "account.requested": "Awaiting approval",
"account_note.placeholder": "Click to add a note", "account_note.placeholder": "چېكىلسە ئىزاھات قوشىدۇ",
"column.pins": "Pinned toot", "column.pins": "چوققىلانغان يازما",
"community.column_settings.media_only": "Media only", "community.column_settings.media_only": "ۋاسىتەلا",
"compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.", "compose_form.encryption_warning": "Posts on Mastodon are not end-to-end encrypted. Do not share any dangerous information over Mastodon.",
"compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.", "compose_form.hashtag_warning": "This post won't be listed under any hashtag as it is unlisted. Only public posts can be searched by hashtag.",
"compose_form.placeholder": "What is on your mind?", "compose_form.placeholder": "What is on your mind?",
"compose_form.publish_form": "Publish", "compose_form.publish_form": "يېڭى يازما",
"compose_form.spoiler.marked": "Text is hidden behind warning", "compose_form.reply": "جاۋاب",
"compose_form.save_changes": "يېڭىلا",
"compose_form.spoiler.marked": "مەزمۇن ئاگاھلاندۇرۇشىنى چىقىرىۋەت",
"compose_form.spoiler.unmarked": "Text is not hidden", "compose_form.spoiler.unmarked": "Text is not hidden",
"confirmations.delete.message": "Are you sure you want to delete this status?", "compose_form.spoiler_placeholder": "مەزمۇن ئاگاھلاندۇرۇشى (تاللاشچان)",
"confirmation_modal.cancel": "ۋاز كەچ",
"confirmations.block.confirm": "توس",
"confirmations.delete.message": "بۇ يازمىنى راستىنلا ئۆچۈرەمسىز؟",
"confirmations.delete.title": "يازما ئۆچۈرەمدۇ؟",
"confirmations.delete_list.confirm": "ئۆچۈر",
"confirmations.delete_list.message": "بۇ تىزىمنى راستتىنلا مەڭگۈلۈك ئۆچۈرەمسىز؟",
"confirmations.delete_list.title": "تىزىمنى ئۆچۈرەمدۇ؟",
"confirmations.discard_edit_media.confirm": "تاشلىۋەت",
"embed.instructions": "Embed this status on your website by copying the code below.", "embed.instructions": "Embed this status on your website by copying the code below.",
"empty_column.account_timeline": "No toots here!", "empty_column.account_timeline": "No toots here!",
"empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.", "empty_column.bookmarked_statuses": "You don't have any bookmarked toots yet. When you bookmark one, it will show up here.",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} допис}}", "account.statuses_counter": "{count, plural, one {{counter} допис} few {{counter} дописи} many {{counter} дописів} other {{counter} допис}}",
"account.unblock": "Розблокувати @{name}", "account.unblock": "Розблокувати @{name}",
"account.unblock_domain": "Розблокувати {domain}", "account.unblock_domain": "Розблокувати {domain}",
"account.unblock_domain_short": "Розблокувати",
"account.unblock_short": "Розблокувати", "account.unblock_short": "Розблокувати",
"account.unendorse": "Не публікувати у профілі", "account.unendorse": "Не публікувати у профілі",
"account.unfollow": "Відписатися", "account.unfollow": "Відписатися",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, other {{counter} Tút}}", "account.statuses_counter": "{count, plural, other {{counter} Tút}}",
"account.unblock": "Bỏ chặn @{name}", "account.unblock": "Bỏ chặn @{name}",
"account.unblock_domain": "Bỏ ẩn {domain}", "account.unblock_domain": "Bỏ ẩn {domain}",
"account.unblock_domain_short": "Bỏ chặn",
"account.unblock_short": "Bỏ chặn", "account.unblock_short": "Bỏ chặn",
"account.unendorse": "Ngưng tôn vinh người này", "account.unendorse": "Ngưng tôn vinh người này",
"account.unfollow": "Bỏ theo dõi", "account.unfollow": "Bỏ theo dõi",

View file

@ -65,6 +65,7 @@
"account.statuses_counter": "{count, plural, other {{count} 則嘟文}}", "account.statuses_counter": "{count, plural, other {{count} 則嘟文}}",
"account.unblock": "解除封鎖 @{name}", "account.unblock": "解除封鎖 @{name}",
"account.unblock_domain": "解除封鎖網域 {domain}", "account.unblock_domain": "解除封鎖網域 {domain}",
"account.unblock_domain_short": "解除封鎖",
"account.unblock_short": "解除封鎖", "account.unblock_short": "解除封鎖",
"account.unendorse": "取消於個人檔案推薦對方", "account.unendorse": "取消於個人檔案推薦對方",
"account.unfollow": "取消跟隨", "account.unfollow": "取消跟隨",

View file

@ -1,26 +0,0 @@
import { Map as ImmutableMap, OrderedSet as ImmutableOrderedSet } from 'immutable';
import {
DOMAIN_BLOCKS_FETCH_SUCCESS,
DOMAIN_BLOCKS_EXPAND_SUCCESS,
unblockDomainSuccess
} from '../actions/domain_blocks';
const initialState = ImmutableMap({
blocks: ImmutableMap({
items: ImmutableOrderedSet(),
}),
});
export default function domainLists(state = initialState, action) {
switch(action.type) {
case DOMAIN_BLOCKS_FETCH_SUCCESS:
return state.setIn(['blocks', 'items'], ImmutableOrderedSet(action.domains)).setIn(['blocks', 'next'], action.next);
case DOMAIN_BLOCKS_EXPAND_SUCCESS:
return state.updateIn(['blocks', 'items'], set => set.union(action.domains)).setIn(['blocks', 'next'], action.next);
case unblockDomainSuccess.type:
return state.updateIn(['blocks', 'items'], set => set.delete(action.payload.domain));
default:
return state;
}
}

View file

@ -11,7 +11,6 @@ import { composeReducer } from './compose';
import contexts from './contexts'; import contexts from './contexts';
import conversations from './conversations'; import conversations from './conversations';
import custom_emojis from './custom_emojis'; import custom_emojis from './custom_emojis';
import domain_lists from './domain_lists';
import { dropdownMenuReducer } from './dropdown_menu'; import { dropdownMenuReducer } from './dropdown_menu';
import filters from './filters'; import filters from './filters';
import followed_tags from './followed_tags'; import followed_tags from './followed_tags';
@ -49,7 +48,6 @@ const reducers = {
loadingBar: loadingBarReducer, loadingBar: loadingBarReducer,
modal: modalReducer, modal: modalReducer,
user_lists, user_lists,
domain_lists,
status_lists, status_lists,
accounts: accountsReducer, accounts: accountsReducer,
accounts_map, accounts_map,

View file

@ -1882,29 +1882,21 @@ body > [data-popper-placement] {
} }
.domain { .domain {
padding: 10px; padding: 16px;
border-bottom: 1px solid var(--background-border-color); border-bottom: 1px solid var(--background-border-color);
display: flex;
align-items: center;
gap: 8px;
.domain__domain-name { &__domain-name {
flex: 1 1 auto; flex: 1 1 auto;
display: block;
color: $primary-text-color; color: $primary-text-color;
text-decoration: none; font-size: 15px;
font-size: 14px; line-height: 21px;
font-weight: 500; font-weight: 500;
} }
} }
.domain__wrapper {
display: flex;
}
.domain_buttons {
height: 18px;
padding: 10px;
white-space: nowrap;
}
.account { .account {
padding: 16px; padding: 16px;
border-bottom: 1px solid var(--background-border-color); border-bottom: 1px solid var(--background-border-color);

View file

@ -130,12 +130,7 @@ class ActivityPub::Activity
def first_mentioned_local_account def first_mentioned_local_account
audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq
local_usernames = audience.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) } ActivityPub::TagManager.instance.uris_to_local_accounts(audience).first
.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
return if local_usernames.empty?
Account.local.where(username: local_usernames).first
end end
def first_local_follower def first_local_follower

View file

@ -412,11 +412,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def addresses_local_accounts? def addresses_local_accounts?
return true if @options[:delivered_to_account_id] return true if @options[:delivered_to_account_id]
local_usernames = (audience_to + audience_cc).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) } ActivityPub::TagManager.instance.uris_to_local_accounts((audience_to + audience_cc).uniq).exists?
return false if local_usernames.empty?
Account.local.exists?(username: local_usernames)
end end
def tombstone_exists? def tombstone_exists?

View file

@ -203,6 +203,19 @@ class ActivityPub::TagManager
path_params[param] path_params[param]
end end
def uris_to_local_accounts(uris)
usernames = []
ids = []
uris.each do |uri|
param, value = uri_to_local_account_params(uri)
usernames << value.downcase if param == :username
ids << value if param == :id
end
Account.local.with_username(usernames).or(Account.local.where(id: ids))
end
def uri_to_actor(uri) def uri_to_actor(uri)
uri_to_resource(uri, Account) uri_to_resource(uri, Account)
end end
@ -213,7 +226,7 @@ class ActivityPub::TagManager
if local_uri?(uri) if local_uri?(uri)
case klass.name case klass.name
when 'Account' when 'Account'
klass.find_local(uri_to_local_id(uri, :username)) uris_to_local_accounts([uri]).first
else else
StatusFinder.new(uri).status StatusFinder.new(uri).status
end end
@ -225,4 +238,20 @@ class ActivityPub::TagManager
rescue ActiveRecord::RecordNotFound rescue ActiveRecord::RecordNotFound
nil nil
end end
private
def uri_to_local_account_params(uri)
return unless local_uri?(uri)
path_params = Rails.application.routes.recognize_path(uri)
# TODO: handle numeric IDs
case path_params[:controller]
when 'accounts'
[:username, path_params[:username]]
when 'instance_actors'
[:id, -99]
end
end
end end

View file

@ -53,11 +53,11 @@ class Fasp::Request
def validate!(response) def validate!(response)
content_digest_header = response.headers['content-digest'] content_digest_header = response.headers['content-digest']
raise SignatureVerification::SignatureVerificationError, 'content-digest missing' if content_digest_header.blank? raise Mastodon::SignatureVerificationError, 'content-digest missing' if content_digest_header.blank?
raise SignatureVerification::SignatureVerificationError, 'content-digest does not match' if content_digest_header != content_digest(response.body) raise Mastodon::SignatureVerificationError, 'content-digest does not match' if content_digest_header != content_digest(response.body)
signature_input = response.headers['signature-input']&.encode('UTF-8') signature_input = response.headers['signature-input']&.encode('UTF-8')
raise SignatureVerification::SignatureVerificationError, 'signature-input is missing' if signature_input.blank? raise Mastodon::SignatureVerificationError, 'signature-input is missing' if signature_input.blank?
linzer_response = Linzer.new_response( linzer_response = Linzer.new_response(
response.body, response.body,

View file

@ -23,6 +23,8 @@
class Poll < ApplicationRecord class Poll < ApplicationRecord
include Expireable include Expireable
MAKE_FETCH_HAPPEN = 1.minute
belongs_to :account belongs_to :account
belongs_to :status belongs_to :status
@ -113,7 +115,7 @@ class Poll < ApplicationRecord
end end
def time_passed_since_last_fetch? def time_passed_since_last_fetch?
last_fetched_at.nil? || last_fetched_at < 1.minute.ago last_fetched_at.nil? || last_fetched_at < MAKE_FETCH_HAPPEN.ago
end end
def show_totals_now? def show_totals_now?

View file

@ -30,10 +30,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
# Account record, and should we not do that, we should have sent a Delete. # Account record, and should we not do that, we should have sent a Delete.
# In any case there is not much we can do if that occurs. # In any case there is not much we can do if that occurs.
# TODO: this will need changes when switching to numeric IDs ActivityPub::TagManager.instance.uris_to_local_accounts(items)
usernames = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username)&.downcase }
Account.local.with_username(usernames)
end end
def remove_unexpected_local_followers! def remove_unexpected_local_followers!

View file

@ -79,6 +79,8 @@ br:
public: Publik public: Publik
reject: Nac'hañ reject: Nac'hañ
remove_header: Dilemel an talbenn remove_header: Dilemel an talbenn
resend_confirmation:
send: Adkas al liamm-kadarnaat
reset: Adderaouekaat reset: Adderaouekaat
reset_password: Adderaouekaat ar ger-tremen reset_password: Adderaouekaat ar ger-tremen
resubscribe: Adkoumanantiñ resubscribe: Adkoumanantiñ
@ -99,6 +101,12 @@ br:
web: Web web: Web
action_logs: action_logs:
action_types: action_types:
approve_user: Aprouiñ an implijer
change_role_user: Kemmañ perzh an implijer
confirm_user: Aprouiñ an implijer
create_ip_block: Krouiñ ur reolenn IP
create_user_role: Krouiñ ur perzh
destroy_ip_block: Dilemel ar reolenn IP
destroy_status: Dilemel ar c'hannad destroy_status: Dilemel ar c'hannad
reset_password_user: Adderaouekaat ar ger-tremen reset_password_user: Adderaouekaat ar ger-tremen
update_status: Hizivaat ar c'hannad update_status: Hizivaat ar c'hannad
@ -141,12 +149,15 @@ br:
export: Ezporzhiañ export: Ezporzhiañ
import: Enporzhiañ import: Enporzhiañ
domain_blocks: domain_blocks:
confirm_suspension:
cancel: Nullañ
domain: Domani domain: Domani
new: new:
create: Sevel ur stanker create: Sevel ur stanker
severity: severity:
noop: Hini ebet noop: Hini ebet
suspend: Astalañ suspend: Astalañ
public_comment: Evezhiadenn foran
email_domain_blocks: email_domain_blocks:
add_new: Ouzhpenniñ unan nevez add_new: Ouzhpenniñ unan nevez
delete: Dilemel delete: Dilemel
@ -158,6 +169,18 @@ br:
create: Ouzhpenniñ un domani create: Ouzhpenniñ un domani
export_domain_allows: export_domain_allows:
no_file: Restr ebet diuzet no_file: Restr ebet diuzet
fasp:
debug:
callbacks:
delete: Dilemel
ip: Chomlec'h IP
providers:
active: Oberiant
delete: Dilemel
name: Anv
registrations:
confirm: Kadarnaat
status: Statud
follow_recommendations: follow_recommendations:
status: Statud status: Statud
suppressed: Dilamet suppressed: Dilamet
@ -172,6 +195,7 @@ br:
suspend: Astalañ suspend: Astalañ
policy: Reolennoù policy: Reolennoù
dashboard: dashboard:
instance_languages_dimension: Yezhoù pennañ
instance_statuses_measure: toudoù stoket instance_statuses_measure: toudoù stoket
delivery: delivery:
all: Pep tra all: Pep tra
@ -182,6 +206,9 @@ br:
title: Habaskadur title: Habaskadur
purge: Spurjañ purge: Spurjañ
title: Kevread title: Kevread
total_blocked_by_us: Stanket ganeomp
total_followed_by_them: Heuliet ganto
total_followed_by_us: Heuliet ganeomp
total_storage: Restroù media stag total_storage: Restroù media stag
invites: invites:
filter: filter:
@ -191,6 +218,7 @@ br:
title: Sil title: Sil
title: Pedadennoù title: Pedadennoù
ip_blocks: ip_blocks:
add_new: Krouiñ ur reolenn
delete: Dilemel delete: Dilemel
expires_in: expires_in:
'1209600': 2 sizhunvezh '1209600': 2 sizhunvezh
@ -198,6 +226,9 @@ br:
'31556952': 1 bloavezh '31556952': 1 bloavezh
'86400': 1 devezh '86400': 1 devezh
'94670856': 3 bloavezh '94670856': 3 bloavezh
new:
title: Krouiñ ur reolenn IP nevez
title: Reolennoù IP
relays: relays:
delete: Dilemel delete: Dilemel
disable: Diweredekaat disable: Diweredekaat
@ -218,6 +249,7 @@ br:
are_you_sure: Ha sur oc'h? are_you_sure: Ha sur oc'h?
comment: comment:
none: Hini ebet none: Hini ebet
confirm: Kadarnaat
delete_and_resolve: Dilemel ar c'hannadoù delete_and_resolve: Dilemel ar c'hannadoù
forwarded: Treuzkaset forwarded: Treuzkaset
no_one_assigned: Den ebet no_one_assigned: Den ebet

View file

@ -232,7 +232,7 @@ he:
silence_account: הגבלת חשבון silence_account: הגבלת חשבון
suspend_account: השעיית חשבון suspend_account: השעיית חשבון
unassigned_report: ביטול הקצאת דו"ח unassigned_report: ביטול הקצאת דו"ח
unblock_email_account: ביטול חסימת כתובת דוא"ל unblock_email_account: הסרת חסימת כתובת דוא"ל
unsensitive_account: ביטול Force-Sensitive לחשבון unsensitive_account: ביטול Force-Sensitive לחשבון
unsilence_account: ביטול השתקת חשבון unsilence_account: ביטול השתקת חשבון
unsuspend_account: ביטול השעיית חשבון unsuspend_account: ביטול השעיית חשבון
@ -263,11 +263,11 @@ he:
create_user_role_html: "%{name} יצר את התפקיד של %{target}" create_user_role_html: "%{name} יצר את התפקיד של %{target}"
demote_user_html: "%{name} הוריד/ה בדרגה את המשתמש %{target}" demote_user_html: "%{name} הוריד/ה בדרגה את המשתמש %{target}"
destroy_announcement_html: "%{name} מחק/ה את ההכרזה %{target}" destroy_announcement_html: "%{name} מחק/ה את ההכרזה %{target}"
destroy_canonical_email_block_html: "%{name} הסיר חסימה מדואל %{target}" destroy_canonical_email_block_html: "%{name} הסירו חסימה מדואל %{target}"
destroy_custom_emoji_html: "%{name} מחק אמוג'י של %{target}" destroy_custom_emoji_html: "%{name} מחק אמוג'י של %{target}"
destroy_domain_allow_html: "%{name} לא התיר/ה פדרציה עם הדומיין %{target}" destroy_domain_allow_html: "%{name} לא התיר/ה פדרציה עם הדומיין %{target}"
destroy_domain_block_html: "%{name} הסיר/ה חסימה מהדומיין %{target}" destroy_domain_block_html: החסימה על מתחם %{target} הוסרה ע"י %{name}
destroy_email_domain_block_html: '%{name} הסיר/ה חסימה מדומיין הדוא"ל %{target}' destroy_email_domain_block_html: הוסרה חסימת מתחם דוא"ל %{target} בידי %{name}
destroy_instance_html: "%{name} טיהר/ה את הדומיין %{target}" destroy_instance_html: "%{name} טיהר/ה את הדומיין %{target}"
destroy_ip_block_html: "%{name} מחק/ה את הכלל עבור IP %{target}" destroy_ip_block_html: "%{name} מחק/ה את הכלל עבור IP %{target}"
destroy_relay_html: "%{name} מחקו את הממסר %{target}" destroy_relay_html: "%{name} מחקו את הממסר %{target}"
@ -495,6 +495,36 @@ he:
new: new:
title: יבוא רשימת שרתים חסומים title: יבוא רשימת שרתים חסומים
no_file: לא נבחר קובץ no_file: לא נבחר קובץ
fasp:
debug:
callbacks:
created_at: תאריך יצירה
delete: מחיקה
ip: כתובת IP
request_body: גוף הבקשה
title: ניפוי תקלות בקריאות חוזרות
providers:
active: פעילים
base_url: קישור בסיס
callback: קריאה חוזרת
delete: מחיקה
edit: עריכת ספק
finish_registration: סיום הרשמה
name: שם
providers: ספקים
public_key_fingerprint: טביעת האצבע של המפתח הציבורי
registration_requested: נדרשת הרשמה
registrations:
confirm: אישור
description: קיבלת הרשמה דרך FASP. יש לדחות אותה אם לא ביקשת את ההרשמה הזו מיוזמתך. אם זו בקשה מיוזמתך, יש להשוות בהקפדה אם השם וטביעת האצבע של המפתח הציבורי תואמים לפני אישור הרישום.
reject: דחיה
title: אישור הרשמת FASP
save: שמירה
select_capabilities: בחירת יכולות
sign_in: כניסה
status: מצב
title: ספקי משנה לפדיוורס
title: פרוטוקול FASP
follow_recommendations: follow_recommendations:
description_html: "<strong>עקבו אחר ההמלצות על מנת לעזור למשתמשים חדשים למצוא תוכן מעניין</strong>. במידה ומשתמש לא תקשר מספיק עם משתמשים אחרים כדי ליצור המלצות מעקב, חשבונות אלה יומלצו במקום. הם מחושבים מחדש על בסיסי יומיומי מתערובת של החשבונות הפעילים ביותר עם החשבונות הנעקבים ביותר עבור שפה נתונה." description_html: "<strong>עקבו אחר ההמלצות על מנת לעזור למשתמשים חדשים למצוא תוכן מעניין</strong>. במידה ומשתמש לא תקשר מספיק עם משתמשים אחרים כדי ליצור המלצות מעקב, חשבונות אלה יומלצו במקום. הם מחושבים מחדש על בסיסי יומיומי מתערובת של החשבונות הפעילים ביותר עם החשבונות הנעקבים ביותר עבור שפה נתונה."
language: עבור שפה language: עבור שפה

View file

@ -479,6 +479,36 @@ it:
new: new:
title: Importare i blocchi di dominio title: Importare i blocchi di dominio
no_file: Nessun file selezionato no_file: Nessun file selezionato
fasp:
debug:
callbacks:
created_at: Creato il
delete: Cancella
ip: Indirizzo IP
request_body: Request body
title: Debug Callbacks
providers:
active: Attivo
base_url: Url di base
callback: Callback
delete: Cancella
edit: Modifica Provider
finish_registration: Registrazione terminata
name: Nome
providers: Providers
public_key_fingerprint: Chiave pubblica fingerprint
registration_requested: Registrazione richiesta
registrations:
confirm: Conferma
description: Hai ricevuto una registrazione da un FASP. Rifiutala se non l'hai avviata tu. Se l'hai avviata tu, confronta attentamente nome e impronta della chiave prima di confermare la registrazione.
reject: Rifiuta
title: Conferma registrazione FASP
save: Salva
select_capabilities: Seleziona Capacità
sign_in: Connettiti
status: Stato
title: Fornitori di Servizi Ausiliari per il Fediverso
title: FASP
follow_recommendations: follow_recommendations:
description_html: "<strong>I consigli su chi seguire aiutano i nuovi utenti a trovare rapidamente dei contenuti interessanti</strong>. Quando un utente non ha interagito abbastanza con altri per avere dei consigli personalizzati, vengono consigliati questi account. Sono ricalcolati ogni giorno da un misto di account con le più alte interazioni recenti e con il maggior numero di seguaci locali per una data lingua." description_html: "<strong>I consigli su chi seguire aiutano i nuovi utenti a trovare rapidamente dei contenuti interessanti</strong>. Quando un utente non ha interagito abbastanza con altri per avere dei consigli personalizzati, vengono consigliati questi account. Sono ricalcolati ogni giorno da un misto di account con le più alte interazioni recenti e con il maggior numero di seguaci locali per una data lingua."
language: Per lingua language: Per lingua

View file

@ -268,6 +268,15 @@ kab:
no_file: Ula d yiwen ufaylu ma yettwafran no_file: Ula d yiwen ufaylu ma yettwafran
export_domain_blocks: export_domain_blocks:
no_file: Ulac afaylu yettwafernen no_file: Ulac afaylu yettwafernen
fasp:
debug:
callbacks:
delete: Kkes
ip: Tansa IP
providers:
delete: Kkes
save: Sekles
title: FASP
follow_recommendations: follow_recommendations:
language: I tutlayt language: I tutlayt
status: Addad status: Addad
@ -378,6 +387,7 @@ kab:
everyone: Tisirag timezwura everyone: Tisirag timezwura
privileges: privileges:
administrator: Anedbal administrator: Anedbal
view_dashboard: Timẓriwt n tfelwit
rules: rules:
add_new: Rnu alugen add_new: Rnu alugen
delete: Kkes delete: Kkes
@ -391,6 +401,7 @@ kab:
title: Udem title: Udem
discovery: discovery:
profile_directory: Akaram n imaɣnuten profile_directory: Akaram n imaɣnuten
title: Asnirem
trends: Ayen mucaɛen trends: Ayen mucaɛen
domain_blocks: domain_blocks:
all: I medden akk all: I medden akk
@ -431,6 +442,9 @@ kab:
software_version_patch_check: software_version_patch_check:
action: Wali ileqqman yellan action: Wali ileqqman yellan
tags: tags:
name: Isem
newest: Amaynut
oldest: Aqbur
search: Anadi search: Anadi
title: Ihacṭagen title: Ihacṭagen
terms_of_service: terms_of_service:
@ -705,6 +719,7 @@ kab:
units: units:
billion: AṬ billion: AṬ
million: A million: A
thousand: GM
trillion: Am trillion: Am
otp_authentication: otp_authentication:
enable: Rmed enable: Rmed
@ -864,6 +879,7 @@ kab:
warning: warning:
categories: categories:
spam: Aspam spam: Aspam
reason: 'Taɣẓint:'
title: title:
disable: Amiḍan i igersen disable: Amiḍan i igersen
none: Ɣur-wat none: Ɣur-wat

View file

@ -304,6 +304,7 @@ lv:
title: Audita žurnāls title: Audita žurnāls
unavailable_instance: "(domēna vārds nav pieejams)" unavailable_instance: "(domēna vārds nav pieejams)"
announcements: announcements:
back: Atgriezties pie paziņojumiem
destroyed_msg: Paziņojums sekmīgi izdzēsts. destroyed_msg: Paziņojums sekmīgi izdzēsts.
edit: edit:
title: Labot paziņojumu title: Labot paziņojumu
@ -312,6 +313,9 @@ lv:
new: new:
create: Izveidot paziņojumu create: Izveidot paziņojumu
title: Jauns paziņojums title: Jauns paziņojums
preview:
explanation_html: 'E-pasta ziņojums tiks nosūtīts <strong>%{display_count} lietotājiem</strong>. Šis teksts tiks iekļauts e-pasta ziņojumā:'
title: Priekšskatīt paziņojumu
publish: Publicēt publish: Publicēt
published_msg: Paziņojums sekmīgi publicēts. published_msg: Paziņojums sekmīgi publicēts.
scheduled_for: Plānots uz %{time} scheduled_for: Plānots uz %{time}
@ -455,7 +459,9 @@ lv:
create: Pievienot domēnu create: Pievienot domēnu
resolve: Atrisināt domēnu resolve: Atrisināt domēnu
title: Liegt jaunu e-pasta domēnu title: Liegt jaunu e-pasta domēnu
no_email_domain_block_selected: Neviens e-pasta domēna bloks netika mainīts, jo neviens netika atlasīts
not_permitted: Nav atļauta not_permitted: Nav atļauta
resolved_dns_records_hint_html: Domēna vārds saistās ar zemāk norādītajiem MX domēniem, kuri beigās ir atbildīgi par e-pasta pieņemšana. MX domēna liegšana liegs reģistrēšanos no jebkuras e-pasta adreses, kas izmanto to pašu MX domēnu, pat ja redzamais domēna vārds ir atšķirīgs. <strong>Jāuzmanās, lai neliegtu galvenos e-pasta pakalpojuma sniedzējus.</strong>
resolved_through_html: Atrisināts, izmantojot %{domain} resolved_through_html: Atrisināts, izmantojot %{domain}
title: Bloķētie e-pasta domēni title: Bloķētie e-pasta domēni
export_domain_allows: export_domain_allows:
@ -473,6 +479,13 @@ lv:
new: new:
title: Importēt bloķētos domēnus title: Importēt bloķētos domēnus
no_file: Nav atlasīts neviens fails no_file: Nav atlasīts neviens fails
fasp:
debug:
callbacks:
created_at: Izveidots
delete: Izdzēst
ip: IP adrese
request_body: Pieprasījuma saturs
follow_recommendations: follow_recommendations:
description_html: "<strong>Sekošanas ieteikumi palīdz jauniem lietotājiem ātri arast saistošu saturu</strong>. Kad lietotājs nav pietiekami mijiedarbojies ar citiem, lai veidotos pielāgoti sekošanas iteikumi, tiek ieteikti šie konti. Tie tiek pārskaitļoti ik dienas, izmantojot kontu, kuriem ir augstākās nesenās iesaistīšanās un lielākais vietējo sekotāju skaits norādītajā valodā." description_html: "<strong>Sekošanas ieteikumi palīdz jauniem lietotājiem ātri arast saistošu saturu</strong>. Kad lietotājs nav pietiekami mijiedarbojies ar citiem, lai veidotos pielāgoti sekošanas iteikumi, tiek ieteikti šie konti. Tie tiek pārskaitļoti ik dienas, izmantojot kontu, kuriem ir augstākās nesenās iesaistīšanās un lielākais vietējo sekotāju skaits norādītajā valodā."
language: Valodai language: Valodai
@ -934,6 +947,7 @@ lv:
chance_to_review_html: "<strong>Izveidotie pakalpojuma izmantošanas noteikumi netiks laisti klajā automātiski.</strong> Būs iespēja izskatīt iznākumu. Lūgums norādīt nepieciešamo informāciju, lai turpinātu." chance_to_review_html: "<strong>Izveidotie pakalpojuma izmantošanas noteikumi netiks laisti klajā automātiski.</strong> Būs iespēja izskatīt iznākumu. Lūgums norādīt nepieciešamo informāciju, lai turpinātu."
explanation_html: Pakalpojuma izmantošanas noteikumu sagatave tiek piedāvāta tikai izzināšanas nolūkam, un to nevajadzētu izmantot kā juridisku padomu jebkurā jautājumā. Lūgums sazināties ar savu juridisko padomdevēju par saviem apstākļiem un noteiktiem juridiskiem jautājumiem. explanation_html: Pakalpojuma izmantošanas noteikumu sagatave tiek piedāvāta tikai izzināšanas nolūkam, un to nevajadzētu izmantot kā juridisku padomu jebkurā jautājumā. Lūgums sazināties ar savu juridisko padomdevēju par saviem apstākļiem un noteiktiem juridiskiem jautājumiem.
title: Pakalpojuma izmantošānas noteikumu uzstādīšana title: Pakalpojuma izmantošānas noteikumu uzstādīšana
going_live_on_html: Darbībā, spēkā no %{date}
history: Vēsture history: Vēsture
live: Darbībā live: Darbībā
no_history: Nav ierakstu par pakalpojuma izmantošanas noteikumu izmaiņām. no_history: Nav ierakstu par pakalpojuma izmantošanas noteikumu izmaiņām.
@ -1060,6 +1074,7 @@ lv:
admin_mailer: admin_mailer:
auto_close_registrations: auto_close_registrations:
body: Nesenu satura pārraudzības darbību trūkuma dēļ reģistrācija %{instance} ir automātiski pārslēgta nepieciešamība pēc pašrocīgas izskatīšanas, lai novērstu %{instance} izmantošana kā platformu iespējami sliktiem dalībniekiem. Jebkurā brīdī var ieslēgt atpakaļ atvērtu reģistrēšanos. body: Nesenu satura pārraudzības darbību trūkuma dēļ reģistrācija %{instance} ir automātiski pārslēgta nepieciešamība pēc pašrocīgas izskatīšanas, lai novērstu %{instance} izmantošana kā platformu iespējami sliktiem dalībniekiem. Jebkurā brīdī var ieslēgt atpakaļ atvērtu reģistrēšanos.
subject: Reģistrēšanās %{instance} tika automātiski pārslēgta, lai pieprasītu apstiprināšanu
new_appeal: new_appeal:
actions: actions:
delete_statuses: lai izdzēstu viņu ierakstus delete_statuses: lai izdzēstu viņu ierakstus
@ -1186,6 +1201,7 @@ lv:
set_new_password: Iestatīt jaunu paroli set_new_password: Iestatīt jaunu paroli
setup: setup:
email_below_hint_html: Jāpārbauda sava surogātpasta mape vai jāpieprasa vēl vienu! Savu e-pasta adresi var labot, ja tā ir nepareiza. email_below_hint_html: Jāpārbauda sava surogātpasta mape vai jāpieprasa vēl vienu! Savu e-pasta adresi var labot, ja tā ir nepareiza.
email_settings_hint_html: Jāatver saite, kuru mēs nosūtījām uz %{email}, lai sāktu izmantot Mastodon. Mēs gaidīsim šeit pat.
link_not_received: Vai nesaņēmi sati? link_not_received: Vai nesaņēmi sati?
new_confirmation_instructions_sent: Pēc dažām minūtēm saņemsi jaunu e-pasta ziņojumu ar apstiprinājuma saiti. new_confirmation_instructions_sent: Pēc dažām minūtēm saņemsi jaunu e-pasta ziņojumu ar apstiprinājuma saiti.
title: Pārbaudi savu iesūtni title: Pārbaudi savu iesūtni
@ -1194,21 +1210,27 @@ lv:
title: Pieteikties %{domain} title: Pieteikties %{domain}
sign_up: sign_up:
manual_review: Reģistrāciju %{domain} pašrocīgi izskata mūsu satura pārraudzītāji. Lai palīdzētu mums apstrādāt Tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}! manual_review: Reģistrāciju %{domain} pašrocīgi izskata mūsu satura pārraudzītāji. Lai palīdzētu mums apstrādāt Tavu reģistrāciju, uzraksti mazliet par sevi un to, kāpēc vēlies kontu %{domain}!
preamble: Ar kontu šajā Mastodon serverī varēsi sekot jebkuram citam cilvēkam fediversā, neatkarīgi no tā, kur tiek mitināts viņu konts.
title: Atļauj tevi iestatīt %{domain}. title: Atļauj tevi iestatīt %{domain}.
status: status:
account_status: Konta statuss account_status: Konta statuss
confirming: Gaida e-pasta adreses apstiprināšanas pabeigšanu. confirming: Gaida e-pasta adreses apstiprināšanas pabeigšanu.
functional: Tavs konts ir pilnā darba kārtībā. functional: Tavs konts ir pilnā darba kārtībā.
pending: Tavs pieteikums ir rindā uz izskatīšanu, ko veic mūsu personāls. Tas var aizņemt kādu laiku. Tu saņemsi e-pasta ziņojumu, ja Tavs pieteikums tiks apstiprināts.
redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}. redirecting_to: Tavs konts ir neaktīvs, jo pašlaik tas tiek novirzīts uz %{acct}.
self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam. self_destruct: Tā kā %{domain} tiek slēgts, tu iegūsi tikai ierobežotu piekļuvi savam kontam.
view_strikes: Skati iepriekšējos brīdinājumus par savu kontu view_strikes: Skati iepriekšējos brīdinājumus par savu kontu
too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz. too_fast: Veidlapa ir iesniegta pārāk ātri, mēģini vēlreiz.
use_security_key: Lietot drošības atslēgu use_security_key: Lietot drošības atslēgu
user_agreement_html: Es esmu izlasījis un piekrītu <a href="%{terms_of_service_path}" target="_blank">pakalpojuma izmantošanas noteikumiem</a> un <a href="%{privacy_policy_path}" target="_blank">privātuma nosacījumiem</a> user_agreement_html: Es esmu izlasījis un piekrītu <a href="%{terms_of_service_path}" target="_blank">pakalpojuma izmantošanas noteikumiem</a> un <a href="%{privacy_policy_path}" target="_blank">privātuma nosacījumiem</a>
user_privacy_agreement_html: Es izlasīju un piekrītu <a href="%{privacy_policy_path}" target="_blank">privātuma pamatnostādnēm</a>
author_attribution: author_attribution:
example_title: Parauga teksts example_title: Parauga teksts
hint_html: Vai Tu Raksti ziņu vai emuāra rakstus ārpus Mastodon? Pārraugi apliecinājumus, kad raksti tiek kopīgoti Mastodon.
instructions: 'Jāpārliecinās, ka šis kods ir raksta HTML:'
more_from_html: Vairāk no %{name} more_from_html: Vairāk no %{name}
s_blog: "%{name} emuāri" s_blog: "%{name} emuāri"
then_instructions: Tad jāpievieno publicējuma domēna vārds zemāk esošajā laukā.
title: Autora attiecinājums title: Autora attiecinājums
challenge: challenge:
confirm: Turpināt confirm: Turpināt
@ -1413,6 +1435,48 @@ lv:
merge_long: Saglabāt esošos ierakstus un pievienot jaunus merge_long: Saglabāt esošos ierakstus un pievienot jaunus
overwrite: Pārrakstīt overwrite: Pārrakstīt
overwrite_long: Nomainīt pašreizējos ierakstus ar jauniem overwrite_long: Nomainīt pašreizējos ierakstus ar jauniem
overwrite_preambles:
blocking_html:
one: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>aizstāt savu lieguma sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
bookmarks_html:
one: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>aizstāt savas grāmatzīmes</strong> ar līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong>.
domain_blocking_html:
one: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēnam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>aizstāt savu liegto domēnu sarakstu</strong> ar līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
following_html:
one: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
other: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
zero: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong> un <strong>pārtrauksi sekot citiem</strong>.
lists_html:
one: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontam</strong> tiks pievienoti jaunajos sarakstos.
other: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontiem</strong> tiks pievienoti jaunajos sarakstos.
zero: Tu gatavojies <strong>aizstāt savus sarakstus</strong> ar <strong>%{filename}</strong> saturu. Līdz <strong>%{count} kontiem</strong> tiks pievienoti jaunajos sarakstos.
muting_html:
one: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>aizstāt savu apklusināto kontu sarakstu</strong> ar līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
preambles:
blocking_html:
one: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
bookmarks_html:
one: Tu gatavojies pievienot līdz <strong>%{count} ierakstam</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
other: Tu gatavojies pievienot līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
zero: Tu gatavojies pievienot līdz <strong>%{count} ierakstiem</strong> no <strong>%{filename}</strong> savām <strong>grāmatzīmēm</strong>.
domain_blocking_html:
one: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēnam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>liegt</strong> līdz <strong>%{count} domēniem</strong> no <strong>%{filename}</strong>.
following_html:
one: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontam</strong> no <strong>%{filename}</strong>.
other: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
zero: Tu gatavojies <strong>sekot</strong> līdz <strong>%{count} kontiem</strong> no <strong>%{filename}</strong>.
preface: Tu vari ievietot datus, kurus esi izguvis no cita servera, kā, piemēram, cilvēku sarakstu, kuriem Tu seko vai kurus bloķē. preface: Tu vari ievietot datus, kurus esi izguvis no cita servera, kā, piemēram, cilvēku sarakstu, kuriem Tu seko vai kurus bloķē.
recent_imports: Nesen importēts recent_imports: Nesen importēts
states: states:

View file

@ -84,7 +84,7 @@ de:
backups_retention_period: Nutzer*innen haben die Möglichkeit, Archive ihrer Beiträge zu erstellen, die sie später herunterladen können. Wenn ein positiver Wert gesetzt ist, werden diese Archive nach der festgelegten Anzahl von Tagen automatisch aus deinem Speicher gelöscht. backups_retention_period: Nutzer*innen haben die Möglichkeit, Archive ihrer Beiträge zu erstellen, die sie später herunterladen können. Wenn ein positiver Wert gesetzt ist, werden diese Archive nach der festgelegten Anzahl von Tagen automatisch aus deinem Speicher gelöscht.
bootstrap_timeline_accounts: Diese Konten werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet. bootstrap_timeline_accounts: Diese Konten werden bei den Follower-Empfehlungen für neu registrierte Nutzer*innen oben angeheftet.
closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind closed_registrations_message: Wird angezeigt, wenn Registrierungen deaktiviert sind
content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Das Verwenden dieser Option richtet sich ausschließlich an Server für spezielle Zwecke und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist. content_cache_retention_period: Sämtliche Beiträge von anderen Servern (einschließlich geteilte Beiträge und Antworten) werden, unabhängig von der Interaktion der lokalen Nutzer*innen mit diesen Beiträgen, nach der festgelegten Anzahl von Tagen gelöscht. Das betrifft auch Beiträge, die von lokalen Nutzer*innen favorisiert oder als Lesezeichen gespeichert wurden. Private Erwähnungen zwischen Nutzer*innen von verschiedenen Servern werden ebenfalls verloren gehen und können nicht wiederhergestellt werden. Diese Option richtet sich ausschließlich an Server mit speziellen Zwecken und wird die allgemeine Nutzungserfahrung beeinträchtigen, wenn sie für den allgemeinen Gebrauch aktiviert ist.
custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden. custom_css: Du kannst benutzerdefinierte Stile auf die Web-Version von Mastodon anwenden.
favicon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Symbol. favicon: WEBP, PNG, GIF oder JPG. Überschreibt das Standard-Mastodon-Favicon mit einem eigenen Symbol.
mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche. mascot: Überschreibt die Abbildung in der erweiterten Weboberfläche.

View file

@ -75,7 +75,7 @@ es-MX:
filters: filters:
action: Elegir qué acción realizar cuando una publicación coincide con el filtro action: Elegir qué acción realizar cuando una publicación coincide con el filtro
actions: actions:
blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el texto en sí blur: Ocultar contenido multimedia detrás de una advertencia, sin ocultar el propio texto
hide: Ocultar completamente el contenido filtrado, comportándose como si no existiera hide: Ocultar completamente el contenido filtrado, comportándose como si no existiera
warn: Ocultar el contenido filtrado detrás de una advertencia mencionando el título del filtro warn: Ocultar el contenido filtrado detrás de una advertencia mencionando el título del filtro
form_admin_settings: form_admin_settings:
@ -89,7 +89,7 @@ es-MX:
favicon: WEBP, PNG, GIF o JPG. Reemplaza el icono predeterminado de Mastodon con un icono personalizado. favicon: WEBP, PNG, GIF o JPG. Reemplaza el icono predeterminado de Mastodon con un icono personalizado.
mascot: Reemplaza la ilustración en la interfaz web avanzada. mascot: Reemplaza la ilustración en la interfaz web avanzada.
media_cache_retention_period: Los archivos multimedia de las publicaciones realizadas por usuarios remotos se almacenan en caché en su servidor. Si se establece en un valor positivo, los archivos multimedia se eliminarán tras el número de días especificado. Si los datos multimedia se solicitan después de haber sido eliminados, se volverán a descargar, si el contenido de origen sigue estando disponible. Debido a las restricciones sobre la frecuencia con la que las tarjetas de previsualización de enlaces sondean sitios de terceros, se recomienda establecer este valor en al menos 14 días, o las tarjetas de previsualización de enlaces no se actualizarán bajo demanda antes de ese tiempo. media_cache_retention_period: Los archivos multimedia de las publicaciones realizadas por usuarios remotos se almacenan en caché en su servidor. Si se establece en un valor positivo, los archivos multimedia se eliminarán tras el número de días especificado. Si los datos multimedia se solicitan después de haber sido eliminados, se volverán a descargar, si el contenido de origen sigue estando disponible. Debido a las restricciones sobre la frecuencia con la que las tarjetas de previsualización de enlaces sondean sitios de terceros, se recomienda establecer este valor en al menos 14 días, o las tarjetas de previsualización de enlaces no se actualizarán bajo demanda antes de ese tiempo.
min_age: Se pedirá a los usuarios que confirmen su fecha de nacimiento durante el registro min_age: Se pedirá a los usuarios que confirmen su fecha de nacimiento al registrarse
peers_api_enabled: Una lista de nombres de dominio que este servidor ha encontrado en el fediverso. Aquí no se incluye ningún dato sobre si usted federa con un servidor determinado, sólo que su servidor lo sabe. Esto es utilizado por los servicios que recopilan estadísticas sobre la federación en un sentido general. peers_api_enabled: Una lista de nombres de dominio que este servidor ha encontrado en el fediverso. Aquí no se incluye ningún dato sobre si usted federa con un servidor determinado, sólo que su servidor lo sabe. Esto es utilizado por los servicios que recopilan estadísticas sobre la federación en un sentido general.
profile_directory: El directorio de perfiles lista a todos los usuarios que han optado por que su cuenta pueda ser descubierta. profile_directory: El directorio de perfiles lista a todos los usuarios que han optado por que su cuenta pueda ser descubierta.
require_invite_text: Cuando los registros requieren aprobación manual, hace obligatoria la entrada de texto "¿Por qué quieres unirte?" en lugar de opcional require_invite_text: Cuando los registros requieren aprobación manual, hace obligatoria la entrada de texto "¿Por qué quieres unirte?" en lugar de opcional
@ -145,10 +145,10 @@ es-MX:
dmca_email: Puede ser el mismo correo electrónico utilizado para "Dirección de correo electrónico para avisos legales" de arriba. dmca_email: Puede ser el mismo correo electrónico utilizado para "Dirección de correo electrónico para avisos legales" de arriba.
domain: Identificación única del servicio en línea que presta. domain: Identificación única del servicio en línea que presta.
jurisdiction: Indique el país de residencia de quien paga las facturas. Si se trata de una empresa u otra entidad, indique el país en el que está constituida y la ciudad, región, territorio o estado, según proceda. jurisdiction: Indique el país de residencia de quien paga las facturas. Si se trata de una empresa u otra entidad, indique el país en el que está constituida y la ciudad, región, territorio o estado, según proceda.
min_age: No debería estar por debajo de la edad mínima requerida por las leyes de su jurisdicción. min_age: No debe ser menor de la edad mínima exigida por las leyes de su jurisdicción.
user: user:
chosen_languages: Cuando se marca, solo se mostrarán las publicaciones en los idiomas seleccionados en las líneas de tiempo públicas chosen_languages: Cuando se marca, solo se mostrarán las publicaciones en los idiomas seleccionados en las líneas de tiempo públicas
date_of_birth: Tenemos que asegurarnos de que al menos tienes %{age} años para usar Mastodon. No almacenaremos esta información. date_of_birth: Tenemos que asegurarnos de que tienes al menos %{age} para usar Mastodon. No almacenaremos esto.
role: El rol controla qué permisos tiene el usuario. role: El rol controla qué permisos tiene el usuario.
user_role: user_role:
color: Color que se usará para el rol en toda la interfaz de usuario, como RGB en formato hexadecimal color: Color que se usará para el rol en toda la interfaz de usuario, como RGB en formato hexadecimal

View file

@ -480,6 +480,34 @@ tr:
title: Domain bloklarını içe aktar title: Domain bloklarını içe aktar
no_file: Dosya seçilmedi no_file: Dosya seçilmedi
fasp: fasp:
debug:
callbacks:
created_at: Oluşturulma tarihi
delete: Sil
ip: IP adresi
request_body: İstek gövdesi
title: Hata ayıklama geri çağrıları
providers:
active: Etkin
base_url: Temel URL
callback: Geri çağırma
delete: Sil
edit: Sağlayıcıyı Düzenle
finish_registration: Kaydı tamamla
name: Ad
providers: Sağlayıcılar
public_key_fingerprint: ık anahtar parmak izi
registration_requested: Kayıt istendi
registrations:
confirm: Onayla
description: FASP'tan bir kayıt aldınız. Eğer bunu siz başlatmadıysanız reddedin. Eğer siz başlattıysanız, kaydı onaylamadan önce ad ve anahtar parmak izini dikkatlice karşılaştırın.
reject: Reddet
title: FASP Kaydını Onayla
save: Kaydet
select_capabilities: Yetenekleri Seç
sign_in: Oturum Aç
status: Durum
title: Fediverse Yardımcı Hizmet Sağlayıcıları (FASP)
title: FASP title: FASP
follow_recommendations: follow_recommendations:
description_html: "<strong>Takip önerileri yeni kullanıcıların hızlı bir şekilde ilginç içerik bulmalarını sağlar</strong>. Eğer bir kullanıcı, kişisel takip önerileri almaya yetecek kadar başkalarıyla etkileşime girmediğinde, onun yerine bu hesaplar önerilir. Bu öneriler, verili bir dil için en yüksek takipçi sayısına ve en yüksek güncel meşguliyete sahip hesapların bir karışımdan günlük olarak hesaplanıyorlar." description_html: "<strong>Takip önerileri yeni kullanıcıların hızlı bir şekilde ilginç içerik bulmalarını sağlar</strong>. Eğer bir kullanıcı, kişisel takip önerileri almaya yetecek kadar başkalarıyla etkileşime girmediğinde, onun yerine bu hesaplar önerilir. Bu öneriler, verili bir dil için en yüksek takipçi sayısına ve en yüksek güncel meşguliyete sahip hesapların bir karışımdan günlük olarak hesaplanıyorlar."

View file

@ -12,6 +12,7 @@ module Mastodon
class RateLimitExceededError < Error; end class RateLimitExceededError < Error; end
class SyntaxError < Error; end class SyntaxError < Error; end
class InvalidParameterError < Error; end class InvalidParameterError < Error; end
class SignatureVerificationError < Error; end
class UnexpectedResponseError < Error class UnexpectedResponseError < Error
attr_reader :response attr_reader :response

View file

@ -1,7 +1,7 @@
{ {
"name": "@mastodon/mastodon", "name": "@mastodon/mastodon",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"packageManager": "yarn@4.7.0", "packageManager": "yarn@4.8.1",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },
@ -151,7 +151,7 @@
"@testing-library/jest-dom": "^6.0.0", "@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^16.0.0", "@testing-library/react": "^16.0.0",
"@types/babel__core": "^7.20.1", "@types/babel__core": "^7.20.1",
"@types/emoji-mart": "^3.0.9", "@types/emoji-mart": "3.0.14",
"@types/escape-html": "^1.0.2", "@types/escape-html": "^1.0.2",
"@types/hoist-non-react-statics": "^3.3.1", "@types/hoist-non-react-statics": "^3.3.1",
"@types/http-link-header": "^1.0.3", "@types/http-link-header": "^1.0.3",
@ -197,7 +197,7 @@
"stylelint": "^16.11.0", "stylelint": "^16.11.0",
"stylelint-config-prettier-scss": "^1.0.0", "stylelint-config-prettier-scss": "^1.0.0",
"stylelint-config-standard-scss": "^14.0.0", "stylelint-config-standard-scss": "^14.0.0",
"typescript": "^5.0.4", "typescript": "~5.7.3",
"typescript-eslint": "^8.28.0", "typescript-eslint": "^8.28.0",
"webpack-dev-server": "^3.11.3" "webpack-dev-server": "^3.11.3"
}, },

View file

@ -1,52 +0,0 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe Settings::PicturesController do
render_views
let!(:user) { Fabricate(:user) }
before do
sign_in user, scope: :user
end
describe 'DELETE #destroy' do
context 'with invalid picture id' do
it 'returns http bad request' do
delete :destroy, params: { id: 'invalid' }
expect(response).to have_http_status(400)
end
end
context 'with valid picture id' do
context 'when account updates correctly' do
let(:service) { instance_double(UpdateAccountService, call: true) }
before do
allow(UpdateAccountService).to receive(:new).and_return(service)
end
it 'updates the account' do
delete :destroy, params: { id: 'avatar' }
expect(response).to redirect_to(settings_profile_path)
expect(response).to have_http_status(303)
expect(service).to have_received(:call).with(user.account, { 'avatar' => nil, 'avatar_remote_url' => '' })
end
end
context 'when account cannot update' do
let(:service) { instance_double(UpdateAccountService, call: false) }
before do
allow(UpdateAccountService).to receive(:new).and_return(service)
end
it 'redirects to profile' do
delete :destroy, params: { id: 'avatar' }
expect(response).to redirect_to(settings_profile_path)
end
end
end
end
end

View file

@ -28,6 +28,19 @@ RSpec.describe Admin::Trends::StatusesHelper do
end end
end end
context 'with a remote status that has excessive attributes' do
let(:attr_limit) { Nokogiri::Gumbo::DEFAULT_MAX_ATTRIBUTES * 2 }
let(:html) { "<html><body #{(1..attr_limit).map { |x| "attr-#{x}" }.join(' ')}><p>text</p></body></html>" }
let(:status) { Fabricate.build(:status, uri: 'https://host.example', text: html) }
it 'renders a correct preview text' do
result = helper.one_line_preview(status)
expect(result).to eq ''
end
end
context 'with a status that has empty text' do context 'with a status that has empty text' do
let(:status) { Fabricate.build(:status, text: '') } let(:status) { Fabricate.build(:status, text: '') }

View file

@ -187,6 +187,23 @@ RSpec.describe ActivityPub::TagManager do
end end
end end
describe '#uris_to_local_accounts' do
it 'returns the expected local accounts' do
account = Fabricate(:account)
expect(subject.uris_to_local_accounts([subject.uri_for(account), instance_actor_url])).to contain_exactly(account, Account.representative)
end
it 'does not return remote accounts' do
account = Fabricate(:account, uri: 'https://example.com/123', domain: 'example.com')
expect(subject.uris_to_local_accounts([subject.uri_for(account)])).to be_empty
end
it 'does not return an account for a local post' do
status = Fabricate(:status)
expect(subject.uris_to_local_accounts([subject.uri_for(status)])).to be_empty
end
end
describe '#uri_to_resource' do describe '#uri_to_resource' do
it 'returns the local account' do it 'returns the local account' do
account = Fabricate(:account) account = Fabricate(:account)

View file

@ -38,7 +38,7 @@ RSpec.describe Fasp::Request do
it 'raises an error' do it 'raises an error' do
expect do expect do
subject.send(method, '/test_path') subject.send(method, '/test_path')
end.to raise_error(SignatureVerification::SignatureVerificationError) end.to raise_error(Mastodon::SignatureVerificationError)
end end
end end
end end

View file

@ -0,0 +1,55 @@
# frozen_string_literal: true
require 'rails_helper'
RSpec.describe 'Settings Pictures' do
let!(:user) { Fabricate(:user) }
before { sign_in user }
describe 'DELETE /settings/profile/pictures/:id' do
context 'with invalid picture id' do
it 'returns http bad request' do
delete settings_profile_picture_path(id: 'invalid')
expect(response)
.to have_http_status(400)
end
end
context 'with valid picture id' do
before { stub_service }
context 'when account updates correctly' do
let(:service) { instance_double(UpdateAccountService, call: true) }
it 'updates the account' do
delete settings_profile_picture_path(id: 'avatar')
expect(response)
.to redirect_to(settings_profile_path)
.and have_http_status(303)
expect(service)
.to have_received(:call).with(user.account, { 'avatar' => nil, 'avatar_remote_url' => '' })
end
end
context 'when account cannot update' do
let(:service) { instance_double(UpdateAccountService, call: false) }
it 'redirects to profile' do
delete settings_profile_picture_path(id: 'avatar')
expect(response)
.to redirect_to(settings_profile_path)
end
end
def stub_service
allow(UpdateAccountService)
.to receive(:new)
.and_return(service)
end
end
end
end

View file

@ -1,7 +1,7 @@
{ {
"name": "@mastodon/streaming", "name": "@mastodon/streaming",
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"packageManager": "yarn@4.7.0", "packageManager": "yarn@4.8.1",
"engines": { "engines": {
"node": ">=18" "node": ">=18"
}, },
@ -39,7 +39,7 @@
"@types/ws": "^8.5.9", "@types/ws": "^8.5.9",
"globals": "^16.0.0", "globals": "^16.0.0",
"pino-pretty": "^13.0.0", "pino-pretty": "^13.0.0",
"typescript": "^5.0.4", "typescript": "~5.7.3",
"typescript-eslint": "^8.28.0" "typescript-eslint": "^8.28.0"
}, },
"optionalDependencies": { "optionalDependencies": {

147
yarn.lock
View file

@ -2190,14 +2190,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@eslint-community/regexpp@npm:^4.10.0": "@eslint-community/regexpp@npm:^4.10.0, @eslint-community/regexpp@npm:^4.12.1":
version: 4.10.0
resolution: "@eslint-community/regexpp@npm:4.10.0"
checksum: 10c0/c5f60ef1f1ea7649fa7af0e80a5a79f64b55a8a8fa5086de4727eb4c86c652aedee407a9c143b8995d2c0b2d75c1222bec9ba5d73dbfc1f314550554f0979ef4
languageName: node
linkType: hard
"@eslint-community/regexpp@npm:^4.12.1":
version: 4.12.1 version: 4.12.1
resolution: "@eslint-community/regexpp@npm:4.12.1" resolution: "@eslint-community/regexpp@npm:4.12.1"
checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6 checksum: 10c0/a03d98c246bcb9109aec2c08e4d10c8d010256538dcb3f56610191607214523d4fb1b00aa81df830b6dffb74c5fa0be03642513a289c567949d3e550ca11cdf6
@ -2848,7 +2841,7 @@ __metadata:
"@testing-library/jest-dom": "npm:^6.0.0" "@testing-library/jest-dom": "npm:^6.0.0"
"@testing-library/react": "npm:^16.0.0" "@testing-library/react": "npm:^16.0.0"
"@types/babel__core": "npm:^7.20.1" "@types/babel__core": "npm:^7.20.1"
"@types/emoji-mart": "npm:^3.0.9" "@types/emoji-mart": "npm:3.0.14"
"@types/escape-html": "npm:^1.0.2" "@types/escape-html": "npm:^1.0.2"
"@types/hoist-non-react-statics": "npm:^3.3.1" "@types/hoist-non-react-statics": "npm:^3.3.1"
"@types/http-link-header": "npm:^1.0.3" "@types/http-link-header": "npm:^1.0.3"
@ -2970,7 +2963,7 @@ __metadata:
tesseract.js: "npm:^6.0.0" tesseract.js: "npm:^6.0.0"
tiny-queue: "npm:^0.2.1" tiny-queue: "npm:^0.2.1"
twitter-text: "npm:3.1.0" twitter-text: "npm:3.1.0"
typescript: "npm:^5.0.4" typescript: "npm:~5.7.3"
typescript-eslint: "npm:^8.28.0" typescript-eslint: "npm:^8.28.0"
use-debounce: "npm:^10.0.0" use-debounce: "npm:^10.0.0"
webpack: "npm:^4.47.0" webpack: "npm:^4.47.0"
@ -3019,7 +3012,7 @@ __metadata:
pino-http: "npm:^10.0.0" pino-http: "npm:^10.0.0"
pino-pretty: "npm:^13.0.0" pino-pretty: "npm:^13.0.0"
prom-client: "npm:^15.0.0" prom-client: "npm:^15.0.0"
typescript: "npm:^5.0.4" typescript: "npm:~5.7.3"
typescript-eslint: "npm:^8.28.0" typescript-eslint: "npm:^8.28.0"
utf-8-validate: "npm:^6.0.3" utf-8-validate: "npm:^6.0.3"
uuid: "npm:^11.0.0" uuid: "npm:^11.0.0"
@ -3822,7 +3815,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/emoji-mart@npm:^3.0.9": "@types/emoji-mart@npm:3.0.14":
version: 3.0.14 version: 3.0.14
resolution: "@types/emoji-mart@npm:3.0.14" resolution: "@types/emoji-mart@npm:3.0.14"
dependencies: dependencies:
@ -3848,10 +3841,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/estree@npm:*, @types/estree@npm:^1.0.0": "@types/estree@npm:*, @types/estree@npm:^1.0.0, @types/estree@npm:^1.0.6":
version: 1.0.5 version: 1.0.7
resolution: "@types/estree@npm:1.0.5" resolution: "@types/estree@npm:1.0.7"
checksum: 10c0/b3b0e334288ddb407c7b3357ca67dbee75ee22db242ca7c56fe27db4e1a31989cb8af48a84dd401deb787fe10cc6b2ab1ee82dc4783be87ededbe3d53c79c70d checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c
languageName: node languageName: node
linkType: hard linkType: hard
@ -3862,13 +3855,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/estree@npm:^1.0.6":
version: 1.0.7
resolution: "@types/estree@npm:1.0.7"
checksum: 10c0/be815254316882f7c40847336cd484c3bc1c3e34f710d197160d455dc9d6d050ffbf4c3bc76585dba86f737f020ab20bdb137ebe0e9116b0c86c7c0342221b8c
languageName: node
linkType: hard
"@types/express-serve-static-core@npm:^4.17.33": "@types/express-serve-static-core@npm:^4.17.33":
version: 4.17.41 version: 4.17.41
resolution: "@types/express-serve-static-core@npm:4.17.41" resolution: "@types/express-serve-static-core@npm:4.17.41"
@ -4054,16 +4040,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@types/node@npm:*": "@types/node@npm:*, @types/node@npm:^22.0.0":
version: 22.8.6
resolution: "@types/node@npm:22.8.6"
dependencies:
undici-types: "npm:~6.19.8"
checksum: 10c0/d3a11f2549234a91a4c5d0ff35ab4bdcb7ba34db4d3f1d189be39b8bd41c19aac98d117150a95a9c5a9d45b1014135477ea240b2b8317c86ae3d3cf1c3b3f8f4
languageName: node
linkType: hard
"@types/node@npm:^22.0.0":
version: 22.13.14 version: 22.13.14
resolution: "@types/node@npm:22.13.14" resolution: "@types/node@npm:22.13.14"
dependencies: dependencies:
@ -4908,16 +4885,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.12.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2": "acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.14.0, acorn@npm:^8.8.1, acorn@npm:^8.8.2":
version: 8.12.1
resolution: "acorn@npm:8.12.1"
bin:
acorn: bin/acorn
checksum: 10c0/51fb26cd678f914e13287e886da2d7021f8c2bc0ccc95e03d3e0447ee278dd3b40b9c57dc222acd5881adcf26f3edc40901a4953403232129e3876793cd17386
languageName: node
linkType: hard
"acorn@npm:^8.14.0":
version: 8.14.1 version: 8.14.1
resolution: "acorn@npm:8.14.1" resolution: "acorn@npm:8.14.1"
bin: bin:
@ -6860,18 +6828,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3": "cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.3, cross-spawn@npm:^7.0.6":
version: 7.0.3
resolution: "cross-spawn@npm:7.0.3"
dependencies:
path-key: "npm:^3.1.0"
shebang-command: "npm:^2.0.0"
which: "npm:^2.0.1"
checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750
languageName: node
linkType: hard
"cross-spawn@npm:^7.0.6":
version: 7.0.6 version: 7.0.6
resolution: "cross-spawn@npm:7.0.6" resolution: "cross-spawn@npm:7.0.6"
dependencies: dependencies:
@ -8384,7 +8341,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"eslint-visitor-keys@npm:^4.0.0, eslint-visitor-keys@npm:^4.2.0": "eslint-visitor-keys@npm:^4.2.0":
version: 4.2.0 version: 4.2.0
resolution: "eslint-visitor-keys@npm:4.2.0" resolution: "eslint-visitor-keys@npm:4.2.0"
checksum: 10c0/2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269 checksum: 10c0/2ed81c663b147ca6f578312919483eb040295bbab759e5a371953456c636c5b49a559883e2677112453728d66293c0a4c90ab11cab3428cf02a0236d2e738269
@ -8441,7 +8398,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"espree@npm:^10.0.1, espree@npm:^10.3.0": "espree@npm:^10.0.1, espree@npm:^10.1.0, espree@npm:^10.3.0":
version: 10.3.0 version: 10.3.0
resolution: "espree@npm:10.3.0" resolution: "espree@npm:10.3.0"
dependencies: dependencies:
@ -8452,17 +8409,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"espree@npm:^10.1.0":
version: 10.1.0
resolution: "espree@npm:10.1.0"
dependencies:
acorn: "npm:^8.12.0"
acorn-jsx: "npm:^5.3.2"
eslint-visitor-keys: "npm:^4.0.0"
checksum: 10c0/52e6feaa77a31a6038f0c0e3fce93010a4625701925b0715cd54a2ae190b3275053a0717db698697b32653788ac04845e489d6773b508d6c2e8752f3c57470a0
languageName: node
linkType: hard
"esprima@npm:^4.0.0, esprima@npm:^4.0.1": "esprima@npm:^4.0.0, esprima@npm:^4.0.1":
version: 4.0.1 version: 4.0.1
resolution: "esprima@npm:4.0.1" resolution: "esprima@npm:4.0.1"
@ -15133,15 +15079,15 @@ __metadata:
linkType: hard linkType: hard
"react-textarea-autosize@npm:^8.4.1": "react-textarea-autosize@npm:^8.4.1":
version: 8.5.8 version: 8.5.9
resolution: "react-textarea-autosize@npm:8.5.8" resolution: "react-textarea-autosize@npm:8.5.9"
dependencies: dependencies:
"@babel/runtime": "npm:^7.20.13" "@babel/runtime": "npm:^7.20.13"
use-composed-ref: "npm:^1.3.0" use-composed-ref: "npm:^1.3.0"
use-latest: "npm:^1.2.1" use-latest: "npm:^1.2.1"
peerDependencies: peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
checksum: 10c0/3d7add9773fd3dc189a6668efb82c1d2d5238ee5b7e933204f5f7da9df8daef81df50b36ca573a57beaa31b2727c6176ea806422790ad23be6cf7f5a5f71bbb9 checksum: 10c0/3a924db59259a6e3b834dcddc12a8661b43dcdaa1b43c41c732e0548bb2761e9a53dbc6db4e0d9e237728b4869e42c25e5417408b0391aec290c90874733a09f
languageName: node languageName: node
linkType: hard linkType: hard
@ -15816,8 +15762,8 @@ __metadata:
linkType: hard linkType: hard
"sass@npm:^1.62.1": "sass@npm:^1.62.1":
version: 1.86.0 version: 1.86.3
resolution: "sass@npm:1.86.0" resolution: "sass@npm:1.86.3"
dependencies: dependencies:
"@parcel/watcher": "npm:^2.4.1" "@parcel/watcher": "npm:^2.4.1"
chokidar: "npm:^4.0.0" chokidar: "npm:^4.0.0"
@ -15828,7 +15774,7 @@ __metadata:
optional: true optional: true
bin: bin:
sass: sass.js sass: sass.js
checksum: 10c0/921caea1fd8a450d4a986e5570ce13c4ca7b2a57da390811add3d2087ad8f46f53b34652ddcb237d8bdaad49c560b8d6eee130c733c787d058bc5a71a914c139 checksum: 10c0/ba819a0828f732adf7a94cd8ca017bce92bc299ffb878836ed1da80a30612bfbbf56a5e42d6dff3ad80d919c2025afb42948fc7b54a7bc61a9a2d58e1e0c558a
languageName: node languageName: node
linkType: hard linkType: hard
@ -15941,16 +15887,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3": "semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4, semver@npm:^7.6.0, semver@npm:^7.6.3, semver@npm:^7.7.1":
version: 7.6.3
resolution: "semver@npm:7.6.3"
bin:
semver: bin/semver.js
checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf
languageName: node
linkType: hard
"semver@npm:^7.7.1":
version: 7.7.1 version: 7.7.1
resolution: "semver@npm:7.7.1" resolution: "semver@npm:7.7.1"
bin: bin:
@ -17604,14 +17541,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tslib@npm:^2.0.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": "tslib@npm:^2.0.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2, tslib@npm:^2.8.0":
version: 2.8.0
resolution: "tslib@npm:2.8.0"
checksum: 10c0/31e4d14dc1355e9b89e4d3c893a18abb7f90b6886b089c2da91224d0a7752c79f3ddc41bc1aa0a588ac895bd97bb99c5bc2bfdb2f86de849f31caeb3ba79bbe5
languageName: node
linkType: hard
"tslib@npm:^2.8.0":
version: 2.8.1 version: 2.8.1
resolution: "tslib@npm:2.8.1" resolution: "tslib@npm:2.8.1"
checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62 checksum: 10c0/9c4759110a19c53f992d9aae23aac5ced636e99887b51b9e61def52611732872ff7668757d4e4c61f19691e36f4da981cd9485e869b4a7408d689f6bf1f14e62
@ -17751,16 +17681,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typescript@npm:^5.0.4":
version: 5.7.3
resolution: "typescript@npm:5.7.3"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
languageName: node
linkType: hard
"typescript@npm:^5.6.0": "typescript@npm:^5.6.0":
version: 5.8.2 version: 5.8.2
resolution: "typescript@npm:5.8.2" resolution: "typescript@npm:5.8.2"
@ -17771,13 +17691,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typescript@patch:typescript@npm%3A^5.0.4#optional!builtin<compat/typescript>": "typescript@npm:~5.7.3":
version: 5.7.3 version: 5.7.3
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5" resolution: "typescript@npm:5.7.3"
bin: bin:
tsc: bin/tsc tsc: bin/tsc
tsserver: bin/tsserver tsserver: bin/tsserver
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4 checksum: 10c0/b7580d716cf1824736cc6e628ab4cd8b51877408ba2be0869d2866da35ef8366dd6ae9eb9d0851470a39be17cbd61df1126f9e211d8799d764ea7431d5435afa
languageName: node languageName: node
linkType: hard linkType: hard
@ -17791,6 +17711,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"typescript@patch:typescript@npm%3A~5.7.3#optional!builtin<compat/typescript>":
version: 5.7.3
resolution: "typescript@patch:typescript@npm%3A5.7.3#optional!builtin<compat/typescript>::version=5.7.3&hash=5786d5"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: 10c0/6fd7e0ed3bf23a81246878c613423730c40e8bdbfec4c6e4d7bf1b847cbb39076e56ad5f50aa9d7ebd89877999abaee216002d3f2818885e41c907caaa192cc4
languageName: node
linkType: hard
"unbox-primitive@npm:^1.1.0": "unbox-primitive@npm:^1.1.0":
version: 1.1.0 version: 1.1.0
resolution: "unbox-primitive@npm:1.1.0" resolution: "unbox-primitive@npm:1.1.0"
@ -17817,13 +17747,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"undici-types@npm:~6.19.8":
version: 6.19.8
resolution: "undici-types@npm:6.19.8"
checksum: 10c0/078afa5990fba110f6824823ace86073b4638f1d5112ee26e790155f481f2a868cc3e0615505b6f4282bdf74a3d8caad715fd809e870c2bb0704e3ea6082f344
languageName: node
linkType: hard
"undici-types@npm:~6.20.0": "undici-types@npm:~6.20.0":
version: 6.20.0 version: 6.20.0
resolution: "undici-types@npm:6.20.0" resolution: "undici-types@npm:6.20.0"