From 49b8433c564647b4f80e8d70dd838753ed87d835 Mon Sep 17 00:00:00 2001 From: Claire Date: Wed, 25 Oct 2023 23:33:44 +0200 Subject: [PATCH 001/834] Fix confusing screen when visiting a confirmation link for an already-confirmed email (#27368) --- .../auth/confirmations_controller.rb | 8 +++++- app/views/auth/confirmations/new.html.haml | 28 +++++++++++++++---- app/views/auth/shared/_progress.html.haml | 6 ++-- config/locales/en.yml | 8 ++++++ spec/features/captcha_spec.rb | 8 ++++++ 5 files changed, 49 insertions(+), 9 deletions(-) diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index 667e8eb063..05e4605f4e 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -39,6 +39,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController show end + def redirect_to_app? + truthy_param?(:redirect_to_app) + end + + helper_method :redirect_to_app? + private def require_captcha_if_needed! @@ -82,7 +88,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController end def after_confirmation_path_for(_resource_name, user) - if user.created_by_application && truthy_param?(:redirect_to_app) + if user.created_by_application && redirect_to_app? user.created_by_application.confirmation_redirect_uri elsif user_signed_in? web_url('start') diff --git a/app/views/auth/confirmations/new.html.haml b/app/views/auth/confirmations/new.html.haml index a98257873c..0cb82a1f86 100644 --- a/app/views/auth/confirmations/new.html.haml +++ b/app/views/auth/confirmations/new.html.haml @@ -1,13 +1,29 @@ - content_for :page_title do = t('auth.resend_confirmation') -= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| - = render 'shared/error_messages', object: resource +- if resource.errors.of_kind?(:email, :already_confirmed) + .simple_form + = render 'auth/shared/progress', stage: resource.approved? ? 'completed' : 'confirmed' - .fields-group - = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint') + - if resource.approved? + %h1.title= t('auth.confirmations.welcome_title', name: resource.account.username) + %p.lead= t('auth.confirmations.registration_complete', domain: site_hostname) + - if resource.created_by_application && redirect_to_app? + - app = resource.created_by_application + %p.lead= t('auth.confirmations.redirect_to_app_html', app_name: app.name, clicking_this_link: link_to(t('auth.confirmations.clicking_this_link'), app.confirmation_redirect_uri)) + - else + %p.lead= t('auth.confirmations.proceed_to_login_html', login_link: link_to_login(t('auth.confirmations.login_link'))) + - else + %h1.title= t('auth.confirmations.awaiting_review_title') + %p.lead= t('auth.confirmations.awaiting_review', domain: site_hostname) +- else + = simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| + = render 'shared/error_messages', object: resource - .actions - = f.button :button, t('auth.resend_confirmation'), type: :submit + .fields-group + = f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint') + + .actions + = f.button :button, t('auth.resend_confirmation'), type: :submit .form-footer= render 'auth/shared/links' diff --git a/app/views/auth/shared/_progress.html.haml b/app/views/auth/shared/_progress.html.haml index 578f62fa9c..8fb3385419 100644 --- a/app/views/auth/shared/_progress.html.haml +++ b/app/views/auth/shared/_progress.html.haml @@ -1,4 +1,4 @@ -- progress_index = { rules: 0, details: 1, confirm: 2 }[stage.to_sym] +- progress_index = { rules: 0, details: 1, confirm: 2, confirmed: 3, completed: 4 }[stage.to_sym] %ol.progress-tracker %li{ class: progress_index.positive? ? 'completed' : 'active' } @@ -20,6 +20,8 @@ .label= t('auth.progress.confirm') - if approved_registrations? %li.separator{ class: progress_index > 2 ? 'completed' : nil } - %li + %li{ class: [progress_index > 3 && 'completed', progress_index == 3 && 'active'] } .circle + - if progress_index > 3 + = check_icon .label= t('auth.progress.review') diff --git a/config/locales/en.yml b/config/locales/en.yml index e8e0f21e1c..c298c47d35 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1041,6 +1041,14 @@ en: hint_html: Just one more thing! We need to confirm you're a human (this is so we can keep the spam out!). Solve the CAPTCHA below and click "Continue". title: Security check confirmations: + awaiting_review: Your e-mail address is confirmed! The %{domain} staff is now reviewing your registration. You will receive an e-mail if they approve your account! + awaiting_review_title: Your registration is being reviewed + clicking_this_link: clicking this link + login_link: log in + proceed_to_login_html: You can now proceed to %{login_link}. + redirect_to_app_html: You should have been redirected to the %{app_name} app. If that did not happen, try %{clicking_this_link} or manually return to the app. + registration_complete: Your registration on %{domain} is now complete! + welcome_title: Welcome, %{name}! wrong_email_hint: If that e-mail address is not correct, you can change it in account settings. delete_account: Delete account delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. diff --git a/spec/features/captcha_spec.rb b/spec/features/captcha_spec.rb index 6ccf066208..a5c5a44aa6 100644 --- a/spec/features/captcha_spec.rb +++ b/spec/features/captcha_spec.rb @@ -30,6 +30,14 @@ describe 'email confirmation flow when captcha is enabled' do click_button I18n.t('challenge.confirm') expect(user.reload.confirmed?).to be true expect(page).to have_current_path(/\A#{client_app.confirmation_redirect_uri}/, url: true) + + # Browsers will generally reload the original page upon redirection + # to external handlers, so test this as well + visit "/auth/confirmation?confirmation_token=#{user.confirmation_token}&redirect_to_app=true" + + # It presents a page with a link to the app callback + expect(page).to have_content(I18n.t('auth.confirmations.registration_complete', domain: 'cb6e6126.ngrok.io')) + expect(page).to have_link(I18n.t('auth.confirmations.clicking_this_link'), href: client_app.confirmation_redirect_uri) end end end From 6e018f722850dddf61abe0c974050f10597380b0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:48:55 +0200 Subject: [PATCH 002/834] Update dependency sass to v1.69.5 (#27566) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index a984ce9e23..6af6770f39 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10945,9 +10945,9 @@ sass-loader@^10.2.0: semver "^7.3.2" sass@^1.62.1: - version "1.69.4" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.4.tgz#10c735f55e3ea0b7742c6efa940bce30e07fbca2" - integrity sha512-+qEreVhqAy8o++aQfCJwp0sklr2xyEzkm9Pp/Igu9wNPoe7EZEQ8X/MBvvXggI2ql607cxKg/RKOwDj6pp2XDA== + version "1.69.5" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.69.5.tgz#23e18d1c757a35f2e52cc81871060b9ad653dfde" + integrity sha512-qg2+UCJibLr2LCVOt3OlPhr/dqVHWOa9XtZf2OjbLs/T4VPSJ00udtgJxH3neXZm+QqX8B+3cU7RaLqp1iVfcQ== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From 400f5c917447eb0d044b0af063059e9023e22f02 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 12:49:39 +0200 Subject: [PATCH 003/834] Update dependency @material-symbols/svg-600 to v0.13.2 (#27565) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6af6770f39..44abf3f61d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1766,9 +1766,9 @@ "@jridgewell/sourcemap-codec" "^1.4.14" "@material-symbols/svg-600@^0.13.1": - version "0.13.1" - resolved "https://registry.yarnpkg.com/@material-symbols/svg-600/-/svg-600-0.13.1.tgz#9f1c2a1fa4439e6cc9ad5f7a7ef64ce7691b42c8" - integrity sha512-oI4De/ePwj1IBxtabmpqMy092Y4ius0byQo/BC3yvLY4WbtzQlIScxUY7bUx+Gqrwq03QZDYrgP/cU4a/TXqyA== + version "0.13.2" + resolved "https://registry.yarnpkg.com/@material-symbols/svg-600/-/svg-600-0.13.2.tgz#a98361ed5a100492780e3301c9d9e4d79aefe0f1" + integrity sha512-4n/bbh6444ZfJ72VHYrWc2f2E8PCsC6ue/ou4Q4QqQFvSRbQSZjcSXuTb0lA4xkaIf2cJf4grvF8ZsskIBLbHg== "@nodelib/fs.scandir@2.1.5": version "2.1.5" From 3ca974e101dd789c1e5540f4d1c5b197ab92083d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 26 Oct 2023 06:52:14 -0400 Subject: [PATCH 004/834] Use `next` keyword in field loop in admin/accounts/index view (#27559) --- .haml-lint_todo.yml | 1 - app/views/admin/accounts/index.html.haml | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index 7684ab63f7..ff66764e07 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -16,6 +16,5 @@ linters: exclude: - 'app/views/admin/accounts/_buttons.html.haml' - 'app/views/admin/accounts/_local_account.html.haml' - - 'app/views/admin/accounts/index.html.haml' - 'app/views/admin/roles/_form.html.haml' - 'app/views/layouts/application.html.haml' diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml index da11e4361c..9cec8d6325 100644 --- a/app/views/admin/accounts/index.html.haml +++ b/app/views/admin/accounts/index.html.haml @@ -22,9 +22,10 @@ .fields-group - %i(username by_domain display_name email ip).each do |key| - - unless key == :by_domain && params[:origin] != 'remote' - .input.string.optional - = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}") + - next if key == :by_domain && params[:origin] != 'remote' + + .input.string.optional + = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}") .actions %button.button= t('admin.accounts.search') From 537442853fca0e068757969e93747c1c98ed394c Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Thu, 26 Oct 2023 13:00:10 +0200 Subject: [PATCH 005/834] Use a context to propagate column-related Props, and remove `forceUpdate` usage (#27548) --- .../components/column_back_button.jsx | 65 ----------- .../components/column_back_button.tsx | 70 +++++++++++ .../components/column_back_button_slim.jsx | 20 ---- .../mastodon/components/column_header.jsx | 20 +--- app/javascript/mastodon/components/router.tsx | 19 +-- .../features/account_gallery/index.jsx | 4 +- .../features/account_timeline/index.jsx | 4 +- .../mastodon/features/blocks/index.jsx | 2 +- .../mastodon/features/domain_blocks/index.jsx | 2 +- .../features/follow_requests/index.jsx | 2 +- .../mastodon/features/followers/index.jsx | 4 +- .../mastodon/features/following/index.jsx | 4 +- .../mastodon/features/mutes/index.jsx | 2 +- .../mastodon/features/onboarding/follows.jsx | 7 +- .../mastodon/features/onboarding/index.jsx | 7 +- .../mastodon/features/onboarding/share.jsx | 7 +- .../features/pinned_statuses/index.jsx | 2 +- .../features/ui/components/columns_area.jsx | 16 ++- app/javascript/mastodon/features/ui/index.jsx | 110 +++++++++--------- .../features/ui/util/columns_context.tsx | 51 ++++++++ 20 files changed, 230 insertions(+), 188 deletions(-) delete mode 100644 app/javascript/mastodon/components/column_back_button.jsx create mode 100644 app/javascript/mastodon/components/column_back_button.tsx delete mode 100644 app/javascript/mastodon/components/column_back_button_slim.jsx create mode 100644 app/javascript/mastodon/features/ui/util/columns_context.tsx diff --git a/app/javascript/mastodon/components/column_back_button.jsx b/app/javascript/mastodon/components/column_back_button.jsx deleted file mode 100644 index 3e914ecadd..0000000000 --- a/app/javascript/mastodon/components/column_back_button.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import PropTypes from 'prop-types'; -import { PureComponent } from 'react'; -import { createPortal } from 'react-dom'; - -import { FormattedMessage } from 'react-intl'; - -import { withRouter } from 'react-router-dom'; - -import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg'; - -import { Icon } from 'mastodon/components/icon'; -import { WithRouterPropTypes } from 'mastodon/utils/react_router'; - -export class ColumnBackButton extends PureComponent { - - static propTypes = { - multiColumn: PropTypes.bool, - onClick: PropTypes.func, - ...WithRouterPropTypes, - }; - - handleClick = () => { - const { onClick, history } = this.props; - - if (onClick) { - onClick(); - } else if (history.location?.state?.fromMastodon) { - history.goBack(); - } else { - history.push('/'); - } - }; - - render () { - const { multiColumn } = this.props; - - const component = ( - - ); - - if (multiColumn) { - return component; - } else { - // The portal container and the component may be rendered to the DOM in - // the same React render pass, so the container might not be available at - // the time `render()` is called. - const container = document.getElementById('tabs-bar__portal'); - if (container === null) { - // The container wasn't available, force a re-render so that the - // component can eventually be inserted in the container and not scroll - // with the rest of the area. - this.forceUpdate(); - return component; - } else { - return createPortal(component, container); - } - } - } - -} - -export default withRouter(ColumnBackButton); diff --git a/app/javascript/mastodon/components/column_back_button.tsx b/app/javascript/mastodon/components/column_back_button.tsx new file mode 100644 index 0000000000..965edc8dcd --- /dev/null +++ b/app/javascript/mastodon/components/column_back_button.tsx @@ -0,0 +1,70 @@ +import { useCallback } from 'react'; + +import { FormattedMessage } from 'react-intl'; + +import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg'; + +import { Icon } from 'mastodon/components/icon'; +import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context'; + +import { useAppHistory } from './router'; + +type OnClickCallback = () => void; + +function useHandleClick(onClick?: OnClickCallback) { + const history = useAppHistory(); + + return useCallback(() => { + if (onClick) { + onClick(); + } else if (history.location.state?.fromMastodon) { + history.goBack(); + } else { + history.push('/'); + } + }, [history, onClick]); +} + +export const ColumnBackButton: React.FC<{ onClick: OnClickCallback }> = ({ + onClick, +}) => { + const handleClick = useHandleClick(onClick); + + const component = ( + + ); + + return {component}; +}; + +export const ColumnBackButtonSlim: React.FC<{ onClick: OnClickCallback }> = ({ + onClick, +}) => { + const handleClick = useHandleClick(onClick); + + return ( +
+ {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */} +
+ + +
+
+ ); +}; diff --git a/app/javascript/mastodon/components/column_back_button_slim.jsx b/app/javascript/mastodon/components/column_back_button_slim.jsx deleted file mode 100644 index 397e6c6a77..0000000000 --- a/app/javascript/mastodon/components/column_back_button_slim.jsx +++ /dev/null @@ -1,20 +0,0 @@ -import { FormattedMessage } from 'react-intl'; - -import { ReactComponent as ArrowBackIcon } from '@material-symbols/svg-600/outlined/arrow_back.svg'; - -import { Icon } from 'mastodon/components/icon'; - -import { ColumnBackButton } from './column_back_button'; - -export default class ColumnBackButtonSlim extends ColumnBackButton { - render () { - return ( -
-
- - -
-
- ); - } -} diff --git a/app/javascript/mastodon/components/column_header.jsx b/app/javascript/mastodon/components/column_header.jsx index f60b17d9b8..c3709f0b71 100644 --- a/app/javascript/mastodon/components/column_header.jsx +++ b/app/javascript/mastodon/components/column_header.jsx @@ -1,6 +1,5 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { createPortal } from 'react-dom'; import { FormattedMessage, injectIntl, defineMessages } from 'react-intl'; @@ -15,6 +14,7 @@ import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/ import { ReactComponent as TuneIcon } from '@material-symbols/svg-600/outlined/tune.svg'; import { Icon } from 'mastodon/components/icon'; +import { ButtonInTabsBar } from 'mastodon/features/ui/util/columns_context'; import { WithRouterPropTypes } from 'mastodon/utils/react_router'; const messages = defineMessages({ @@ -203,22 +203,12 @@ class ColumnHeader extends PureComponent { ); - if (multiColumn || placeholder) { + if (placeholder) { return component; } else { - // The portal container and the component may be rendered to the DOM in - // the same React render pass, so the container might not be available at - // the time `render()` is called. - const container = document.getElementById('tabs-bar__portal'); - if (container === null) { - // The container wasn't available, force a re-render so that the - // component can eventually be inserted in the container and not scroll - // with the rest of the area. - this.forceUpdate(); - return component; - } else { - return createPortal(component, container); - } + return ( + {component} + ); } } diff --git a/app/javascript/mastodon/components/router.tsx b/app/javascript/mastodon/components/router.tsx index e381571676..fe50fc2ba9 100644 --- a/app/javascript/mastodon/components/router.tsx +++ b/app/javascript/mastodon/components/router.tsx @@ -1,7 +1,7 @@ import type { PropsWithChildren } from 'react'; import React from 'react'; -import { Router as OriginalRouter } from 'react-router'; +import { Router as OriginalRouter, useHistory } from 'react-router'; import type { LocationDescriptor, @@ -16,18 +16,23 @@ interface MastodonLocationState { fromMastodon?: boolean; mastodonModalKey?: string; } -type HistoryPath = Path | LocationDescriptor; -const browserHistory = createBrowserHistory< - MastodonLocationState | undefined ->(); +type LocationState = MastodonLocationState | null | undefined; + +type HistoryPath = Path | LocationDescriptor; + +const browserHistory = createBrowserHistory(); const originalPush = browserHistory.push.bind(browserHistory); const originalReplace = browserHistory.replace.bind(browserHistory); +export function useAppHistory() { + return useHistory(); +} + function normalizePath( path: HistoryPath, - state?: MastodonLocationState, -): LocationDescriptorObject { + state?: LocationState, +): LocationDescriptorObject { const location = typeof path === 'string' ? { pathname: path } : { ...path }; if (location.state === undefined && state !== undefined) { diff --git a/app/javascript/mastodon/features/account_gallery/index.jsx b/app/javascript/mastodon/features/account_gallery/index.jsx index 19c10fa9f8..6a1d0b322f 100644 --- a/app/javascript/mastodon/features/account_gallery/index.jsx +++ b/app/javascript/mastodon/features/account_gallery/index.jsx @@ -8,7 +8,7 @@ import { connect } from 'react-redux'; import { lookupAccount, fetchAccount } from 'mastodon/actions/accounts'; import { openModal } from 'mastodon/actions/modal'; -import ColumnBackButton from 'mastodon/components/column_back_button'; +import { ColumnBackButton } from 'mastodon/components/column_back_button'; import { LoadMore } from 'mastodon/components/load_more'; import { LoadingIndicator } from 'mastodon/components/loading_indicator'; import ScrollContainer from 'mastodon/containers/scroll_container'; @@ -203,7 +203,7 @@ class AccountGallery extends ImmutablePureComponent { return ( - +
diff --git a/app/javascript/mastodon/features/account_timeline/index.jsx b/app/javascript/mastodon/features/account_timeline/index.jsx index 0f18c043b8..5dae66b463 100644 --- a/app/javascript/mastodon/features/account_timeline/index.jsx +++ b/app/javascript/mastodon/features/account_timeline/index.jsx @@ -16,7 +16,7 @@ import { getAccountHidden } from 'mastodon/selectors'; import { lookupAccount, fetchAccount } from '../../actions/accounts'; import { fetchFeaturedTags } from '../../actions/featured_tags'; import { expandAccountFeaturedTimeline, expandAccountTimeline, connectTimeline, disconnectTimeline } from '../../actions/timelines'; -import ColumnBackButton from '../../components/column_back_button'; +import { ColumnBackButton } from '../../components/column_back_button'; import { LoadingIndicator } from '../../components/loading_indicator'; import StatusList from '../../components/status_list'; import Column from '../ui/components/column'; @@ -184,7 +184,7 @@ class AccountTimeline extends ImmutablePureComponent { return ( - + } diff --git a/app/javascript/mastodon/features/blocks/index.jsx b/app/javascript/mastodon/features/blocks/index.jsx index 210260c811..21b7a263f1 100644 --- a/app/javascript/mastodon/features/blocks/index.jsx +++ b/app/javascript/mastodon/features/blocks/index.jsx @@ -10,7 +10,7 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/ import { debounce } from 'lodash'; import { fetchBlocks, expandBlocks } from '../../actions/blocks'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; +import { ColumnBackButtonSlim } from '../../components/column_back_button'; import { LoadingIndicator } from '../../components/loading_indicator'; import ScrollableList from '../../components/scrollable_list'; import AccountContainer from '../../containers/account_container'; diff --git a/app/javascript/mastodon/features/domain_blocks/index.jsx b/app/javascript/mastodon/features/domain_blocks/index.jsx index 5ac1d2a71e..958083d588 100644 --- a/app/javascript/mastodon/features/domain_blocks/index.jsx +++ b/app/javascript/mastodon/features/domain_blocks/index.jsx @@ -12,7 +12,7 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/ import { debounce } from 'lodash'; import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; +import { ColumnBackButtonSlim } from '../../components/column_back_button'; import { LoadingIndicator } from '../../components/loading_indicator'; import ScrollableList from '../../components/scrollable_list'; import DomainContainer from '../../containers/domain_container'; diff --git a/app/javascript/mastodon/features/follow_requests/index.jsx b/app/javascript/mastodon/features/follow_requests/index.jsx index 8e17607fd9..7d8785e052 100644 --- a/app/javascript/mastodon/features/follow_requests/index.jsx +++ b/app/javascript/mastodon/features/follow_requests/index.jsx @@ -12,7 +12,7 @@ import { ReactComponent as PersonAddIcon } from '@material-symbols/svg-600/outli import { debounce } from 'lodash'; import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; +import { ColumnBackButtonSlim } from '../../components/column_back_button'; import ScrollableList from '../../components/scrollable_list'; import { me } from '../../initial_state'; import Column from '../ui/components/column'; diff --git a/app/javascript/mastodon/features/followers/index.jsx b/app/javascript/mastodon/features/followers/index.jsx index ec39395518..fc0ce8ab30 100644 --- a/app/javascript/mastodon/features/followers/index.jsx +++ b/app/javascript/mastodon/features/followers/index.jsx @@ -19,7 +19,7 @@ import { fetchFollowers, expandFollowers, } from '../../actions/accounts'; -import ColumnBackButton from '../../components/column_back_button'; +import { ColumnBackButton } from '../../components/column_back_button'; import { LoadingIndicator } from '../../components/loading_indicator'; import ScrollableList from '../../components/scrollable_list'; import AccountContainer from '../../containers/account_container'; @@ -147,7 +147,7 @@ class Followers extends ImmutablePureComponent { return ( - + - + - +
diff --git a/app/javascript/mastodon/features/onboarding/index.jsx b/app/javascript/mastodon/features/onboarding/index.jsx index 0be1512ad8..7b8a41faa5 100644 --- a/app/javascript/mastodon/features/onboarding/index.jsx +++ b/app/javascript/mastodon/features/onboarding/index.jsx @@ -47,7 +47,6 @@ class Onboarding extends ImmutablePureComponent { static propTypes = { dispatch: PropTypes.func.isRequired, account: ImmutablePropTypes.map, - multiColumn: PropTypes.bool, ...WithRouterPropTypes, }; @@ -100,14 +99,14 @@ class Onboarding extends ImmutablePureComponent { } render () { - const { account, multiColumn } = this.props; + const { account } = this.props; const { step, shareClicked } = this.state; switch(step) { case 'follows': - return ; + return ; case 'share': - return ; + return ; } return ( diff --git a/app/javascript/mastodon/features/onboarding/share.jsx b/app/javascript/mastodon/features/onboarding/share.jsx index c9d58c4e65..8e01701eb3 100644 --- a/app/javascript/mastodon/features/onboarding/share.jsx +++ b/app/javascript/mastodon/features/onboarding/share.jsx @@ -14,7 +14,7 @@ import { ReactComponent as ContentCopyIcon } from '@material-symbols/svg-600/out import SwipeableViews from 'react-swipeable-views'; import Column from 'mastodon/components/column'; -import ColumnBackButton from 'mastodon/components/column_back_button'; +import { ColumnBackButton } from 'mastodon/components/column_back_button'; import { Icon } from 'mastodon/components/icon'; import { me, domain } from 'mastodon/initial_state'; @@ -146,18 +146,17 @@ class Share extends PureComponent { static propTypes = { onBack: PropTypes.func, account: ImmutablePropTypes.map, - multiColumn: PropTypes.bool, intl: PropTypes.object, }; render () { - const { onBack, account, multiColumn, intl } = this.props; + const { onBack, account, intl } = this.props; const url = (new URL(`/@${account.get('username')}`, document.baseURI)).href; return ( - +
diff --git a/app/javascript/mastodon/features/pinned_statuses/index.jsx b/app/javascript/mastodon/features/pinned_statuses/index.jsx index 57d9768bed..e8206d704c 100644 --- a/app/javascript/mastodon/features/pinned_statuses/index.jsx +++ b/app/javascript/mastodon/features/pinned_statuses/index.jsx @@ -13,7 +13,7 @@ import { ReactComponent as PushPinIcon } from '@material-symbols/svg-600/outline import { getStatusList } from 'mastodon/selectors'; import { fetchPinnedStatuses } from '../../actions/pin_statuses'; -import ColumnBackButtonSlim from '../../components/column_back_button_slim'; +import { ColumnBackButtonSlim } from '../../components/column_back_button'; import StatusList from '../../components/status_list'; import Column from '../ui/components/column'; diff --git a/app/javascript/mastodon/features/ui/components/columns_area.jsx b/app/javascript/mastodon/features/ui/components/columns_area.jsx index 9cf6136652..19c2f40ac6 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.jsx +++ b/app/javascript/mastodon/features/ui/components/columns_area.jsx @@ -1,5 +1,5 @@ import PropTypes from 'prop-types'; -import { Children, cloneElement } from 'react'; +import { Children, cloneElement, useCallback } from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; @@ -21,6 +21,7 @@ import { ListTimeline, Directory, } from '../util/async-components'; +import { useColumnsContext } from '../util/columns_context'; import BundleColumnError from './bundle_column_error'; import { ColumnLoading } from './column_loading'; @@ -43,6 +44,17 @@ const componentMap = { 'DIRECTORY': Directory, }; +const TabsBarPortal = () => { + const {setTabsBarElement} = useColumnsContext(); + + const setRef = useCallback((element) => { + if(element) + setTabsBarElement(element); + }, [setTabsBarElement]); + + return
; +}; + export default class ColumnsArea extends ImmutablePureComponent { static propTypes = { columns: ImmutablePropTypes.list.isRequired, @@ -146,7 +158,7 @@ export default class ColumnsArea extends ImmutablePureComponent {
-
+
{children}
diff --git a/app/javascript/mastodon/features/ui/index.jsx b/app/javascript/mastodon/features/ui/index.jsx index f836dace7f..02c69cbbaf 100644 --- a/app/javascript/mastodon/features/ui/index.jsx +++ b/app/javascript/mastodon/features/ui/index.jsx @@ -64,8 +64,8 @@ import { About, PrivacyPolicy, } from './util/async-components'; +import { ColumnsContextProvider } from './util/columns_context'; import { WrappedSwitch, WrappedRoute } from './util/react_router_helpers'; - // Dummy import, to make sure that ends up in the application bundle. // Without this it ends up in ~8 very commonly used bundles. import '../../components/status'; @@ -179,68 +179,70 @@ class SwitchingColumnsArea extends PureComponent { } return ( - - - {redirect} + + + + {redirect} - {singleColumn ? : null} - {singleColumn && pathName.startsWith('/deck/') ? : null} - {/* Redirect old bookmarks (without /deck) with home-like routes to the advanced interface */} - {!singleColumn && pathName === '/getting-started' ? : null} - {!singleColumn && pathName === '/home' ? : null} + {singleColumn ? : null} + {singleColumn && pathName.startsWith('/deck/') ? : null} + {/* Redirect old bookmarks (without /deck) with home-like routes to the advanced interface */} + {!singleColumn && pathName === '/getting-started' ? : null} + {!singleColumn && pathName === '/home' ? : null} - - - - + + + + - - - - - - - - - - - + + + + + + + + + + + - - + + - - - - + + + + - - - - - - - - - + + + + + + + + + - {/* Legacy routes, cannot be easily factored with other routes because they share a param name */} - - - - - + {/* Legacy routes, cannot be easily factored with other routes because they share a param name */} + + + + + - - - - - - + + + + + + - - - + + + + ); } diff --git a/app/javascript/mastodon/features/ui/util/columns_context.tsx b/app/javascript/mastodon/features/ui/util/columns_context.tsx new file mode 100644 index 0000000000..e02918deb0 --- /dev/null +++ b/app/javascript/mastodon/features/ui/util/columns_context.tsx @@ -0,0 +1,51 @@ +import type { ReactElement } from 'react'; +import { createContext, useContext, useMemo, useState } from 'react'; +import { createPortal } from 'react-dom'; + +export const ColumnsContext = createContext<{ + tabsBarElement: HTMLElement | null; + setTabsBarElement: (element: HTMLElement) => void; + multiColumn: boolean; +}>({ + tabsBarElement: null, + multiColumn: false, + setTabsBarElement: () => undefined, // no-op +}); + +export function useColumnsContext() { + return useContext(ColumnsContext); +} + +export const ButtonInTabsBar: React.FC<{ + children: ReactElement | string | undefined; +}> = ({ children }) => { + const { multiColumn, tabsBarElement } = useColumnsContext(); + + if (multiColumn) { + return children; + } else if (!tabsBarElement) { + return children; + } else { + return createPortal(children, tabsBarElement); + } +}; + +type ContextValue = React.ContextType; + +export const ColumnsContextProvider: React.FC< + React.PropsWithChildren<{ multiColumn: boolean }> +> = ({ multiColumn, children }) => { + const [tabsBarElement, setTabsBarElement] = + useState(null); + + const contextValue = useMemo( + () => ({ multiColumn, tabsBarElement, setTabsBarElement }), + [multiColumn, tabsBarElement], + ); + + return ( + + {children} + + ); +}; From 3427b51d63fde169fbd72163cc9c138335570e09 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Oct 2023 13:05:47 +0200 Subject: [PATCH 006/834] New Crowdin Translations (automated) (#27567) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/fi.json | 2 +- app/javascript/mastodon/locales/gl.json | 2 +- app/javascript/mastodon/locales/ko.json | 2 +- app/javascript/mastodon/locales/pl.json | 2 +- config/locales/cy.yml | 4 ++++ config/locales/da.yml | 8 ++++++++ config/locales/de.yml | 6 ++++++ config/locales/devise.sr-Latn.yml | 2 +- config/locales/devise.sr.yml | 2 +- config/locales/es-MX.yml | 8 ++++++++ config/locales/fi.yml | 14 +++++++++++--- config/locales/gl.yml | 8 ++++++++ config/locales/hu.yml | 8 ++++++++ config/locales/is.yml | 4 ++++ config/locales/ja.yml | 8 ++++++++ config/locales/ko.yml | 8 ++++++++ config/locales/sk.yml | 3 +++ config/locales/sr-Latn.yml | 12 ++++++++++-- config/locales/sr.yml | 12 ++++++++++-- config/locales/sv.yml | 4 ++++ config/locales/zh-CN.yml | 8 ++++++++ config/locales/zh-TW.yml | 8 ++++++++ 22 files changed, 122 insertions(+), 13 deletions(-) diff --git a/app/javascript/mastodon/locales/fi.json b/app/javascript/mastodon/locales/fi.json index aac4256ffd..c4dbbc5f03 100644 --- a/app/javascript/mastodon/locales/fi.json +++ b/app/javascript/mastodon/locales/fi.json @@ -1,5 +1,5 @@ { - "about.blocks": "Valvotut palvelimet", + "about.blocks": "Moderoidut palvelimet", "about.contact": "Ota yhteyttä:", "about.disclaimer": "Mastodon on vapaa avoimen lähdekoodin ohjelmisto ja Mastodon gGmbH:n tavaramerkki.", "about.domain_blocks.no_reason_available": "Syytä ei ole ilmoitettu", diff --git a/app/javascript/mastodon/locales/gl.json b/app/javascript/mastodon/locales/gl.json index b5d9e50f65..8431d12acc 100644 --- a/app/javascript/mastodon/locales/gl.json +++ b/app/javascript/mastodon/locales/gl.json @@ -20,7 +20,7 @@ "account.block_short": "Bloquear", "account.blocked": "Bloqueada", "account.browse_more_on_origin_server": "Busca máis no perfil orixinal", - "account.cancel_follow_request": "Retirar solicitude de seguimento", + "account.cancel_follow_request": "Cancelar a solicitude de seguimento", "account.direct": "Mencionar de xeito privado a @{name}", "account.disable_notifications": "Deixar de notificarme cando @{name} publica", "account.domain_blocked": "Dominio agochado", diff --git a/app/javascript/mastodon/locales/ko.json b/app/javascript/mastodon/locales/ko.json index ccd783e809..3a78a9cd79 100644 --- a/app/javascript/mastodon/locales/ko.json +++ b/app/javascript/mastodon/locales/ko.json @@ -590,7 +590,7 @@ "search.quick_action.open_url": "마스토돈에서 URL 열기", "search.quick_action.status_search": "{x}에 맞는 게시물", "search.search_or_paste": "검색하거나 URL 붙여넣기", - "search_popout.full_text_search_disabled_message": "{domain}에서는 사용할 수 없습니다.", + "search_popout.full_text_search_disabled_message": "{domain}에서는 이용할 수 없습니다.", "search_popout.language_code": "ISO 언어코드", "search_popout.options": "검색 옵션", "search_popout.quick_actions": "빠른 작업", diff --git a/app/javascript/mastodon/locales/pl.json b/app/javascript/mastodon/locales/pl.json index 814a14c156..84ea64bb98 100644 --- a/app/javascript/mastodon/locales/pl.json +++ b/app/javascript/mastodon/locales/pl.json @@ -81,7 +81,7 @@ "admin.impact_report.instance_follows": "Obserwujący, których straciliby ich użytkownicy", "admin.impact_report.title": "Podsumowanie wpływu", "alert.rate_limited.message": "Spróbuj ponownie po {retry_time, time, medium}.", - "alert.rate_limited.title": "Ograniczony czasowo", + "alert.rate_limited.title": "Ograniczenie liczby zapytań", "alert.unexpected.message": "Wystąpił nieoczekiwany błąd.", "alert.unexpected.title": "Ups!", "announcement.announcement": "Ogłoszenie", diff --git a/config/locales/cy.yml b/config/locales/cy.yml index 09e201f55a..baa6d31e35 100644 --- a/config/locales/cy.yml +++ b/config/locales/cy.yml @@ -1174,6 +1174,7 @@ cy: functional: Mae eich cyfrif nawr yn weithredol. pending: Mae'ch cais yn aros i gael ei adolygu gan ein staff. Gall hyn gymryd cryn amser. Byddwch yn derbyn e-bost os caiff eich cais ei gymeradwyo. redirecting_to: Mae eich cyfrif yn anweithredol oherwydd ei fod ar hyn o bryd yn ailgyfeirio i %{acct}. + self_destruct: Gab fod parth %{domain} yn cau, dim ond mynediad cyfyngedig fyddwch yn ei gael i'ch cyfrif. view_strikes: Gweld rybuddion y gorffennol yn erbyn eich cyfrif too_fast: Cafodd y ffurflen ei chyflwyno'n rhy gyflym, ceisiwch eto. use_security_key: Defnyddiwch allwedd diogelwch @@ -1675,6 +1676,9 @@ cy: over_daily_limit: Rydych wedi mynd dros y terfyn o %{limit} postiad a drefnwyd ar gyfer heddiw over_total_limit: Rydych wedi mynd dros y terfyn o %{limit} postiad a drefnwyd too_soon: Rhaid i'r dyddiad a drefnwyd fod yn y dyfodol + self_destruct: + lead_html: Yn anffodus mae %{domain} yn cau'n barhaol. Os oedd gennych gyfrif yno, ni fydd modd i chi barhau i'w ddefnyddio, ond mae dal modd gofyn i gael copi wrth gefn o'ch data. + title: Mae'r gweinydd hwn yn cau sessions: activity: Gweithgaredd ddiwethaf browser: Porwr diff --git a/config/locales/da.yml b/config/locales/da.yml index 9ffece04d7..c5d6391853 100644 --- a/config/locales/da.yml +++ b/config/locales/da.yml @@ -1041,6 +1041,14 @@ da: hint_html: Bare en ting mere! Vi er nødt til at bekræfte, at du er et menneske (dette er for at vi kan holde spam ude!). Løs CAPTCHA'en nedenfor og klik på "Fortsæt". title: Sikkerhedstjek confirmations: + awaiting_review: E-mailadressen er bekræftet! %{domain}-personalet gennemgår nu registreringen. En e-mail fremsendes, såfremt din konto godkendes! + awaiting_review_title: Registreringen er ved at blive gennemgået + clicking_this_link: klikke på dette link + login_link: log ind + proceed_to_login_html: Der kan nu fortsættes til %{login_link}. + redirect_to_app_html: En omdirigering til %{app_name}-appen burde være sket. Er det ikke tilfældet, prøv da %{clicking_this_link} eller returnér manuelt til appen. + registration_complete: Registreringen på %{domain} er nu fuldført! + welcome_title: Velkommen %{name}! wrong_email_hint: Er denne e-mailadresse ikke korrekt, kan den ændres i kontoindstillinger. delete_account: Slet konto delete_account_html: Ønsker du at slette din konto, kan du gøre dette hér. Du vil blive bedt om bekræftelse. diff --git a/config/locales/de.yml b/config/locales/de.yml index c6b3218ee9..21dfe4a7fb 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1041,6 +1041,12 @@ de: hint_html: Fast geschafft! Wir müssen uns vergewissern, dass du ein Mensch bist (damit wir Spam verhindern können!). Bitte löse das CAPTCHA und klicke auf „Weiter“. title: Sicherheitsüberprüfung confirmations: + awaiting_review: Deine E-Mail-Adresse wurde bestätigt und das Team von %{domain} überprüft nun deine Registrierung. Sobald es dein Konto genehmigt, wirst du eine E-Mail erhalten. + awaiting_review_title: Deine Registrierung wird überprüft + login_link: anmelden + proceed_to_login_html: Du kannst dich nun %{login_link}. + registration_complete: Deine Registrierung auf %{domain} ist nun abgeschlossen! + welcome_title: Willkommen, %{name}! wrong_email_hint: Sollte diese E-Mail-Adresse nicht korrekt sein, kannst du sie in den Kontoeinstellungen ändern. delete_account: Konto löschen delete_account_html: Falls du dein Konto endgültig löschen möchtest, kannst du das hier vornehmen. Du musst dies zusätzlich bestätigen. diff --git a/config/locales/devise.sr-Latn.yml b/config/locales/devise.sr-Latn.yml index 6b4a5801c6..40f3d51c30 100644 --- a/config/locales/devise.sr-Latn.yml +++ b/config/locales/devise.sr-Latn.yml @@ -88,7 +88,7 @@ sr-Latn: updated_not_active: Vaša lozinka nije uspešno promenjena. registrations: destroyed: Ćao! Vaš nalog je uspešno obrisan. Nadamo se da ćete se uskoro vratiti. - signed_up: Dobrodošli! Uspešno ste se registrovali. + signed_up: Dobro došli! Uspešno ste se registrovali. signed_up_but_inactive: Uspešno ste se registrovali. Nažalost ne možete se prijaviti zato što Vaš nalog još nije aktiviran. signed_up_but_locked: Uspešno ste se registrovali. Nažalost ne možete se prijaviti zato što je Vaš nalog zaključan. signed_up_but_pending: Na vaš imejl poslata je poruka sa vezom za potvrdu. Nakon što kliknete na vezu, pregledaćemo vašu prijavu. Bićete obavešteni ako bude odobreno. diff --git a/config/locales/devise.sr.yml b/config/locales/devise.sr.yml index d55cf7a268..f61431de60 100644 --- a/config/locales/devise.sr.yml +++ b/config/locales/devise.sr.yml @@ -88,7 +88,7 @@ sr: updated_not_active: Ваша лозинка није успешно промењена. registrations: destroyed: Ћао! Ваш налог је успешно обрисан. Надамо се да ћете се ускоро вратити. - signed_up: Добродошли! Успешно сте се регистровали. + signed_up: Добро дошли! Успешно сте се регистровали. signed_up_but_inactive: Успешно сте се регистровали. Нажалост не можете се пријавити зато што Ваш налог још није активиран. signed_up_but_locked: Успешно сте се регистровали. Нажалост не можете се пријавити зато што је Ваш налог закључан. signed_up_but_pending: На ваш имејл послата је порука са везом за потврду. Након што кликнете на везу, прегледаћемо вашу пријаву. Бићете обавештени ако буде одобрено. diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml index e055ff4c79..ad2fb184ea 100644 --- a/config/locales/es-MX.yml +++ b/config/locales/es-MX.yml @@ -1041,6 +1041,14 @@ es-MX: hint_html: ¡Una última cosita! Necesitamos confirmar que eres humano (¡así podemos evitar el spam!). Resuelve este CAPTCHA de debajo y pulsa en "Continuar". title: Comprobación de seguridad confirmations: + awaiting_review: "¡Tu dirección de correo electrónico ha sido confirmada! El personal de %{domain} está revisando tu registro. ¡Recibirás un correo electrónico si aprueban tu cuenta!" + awaiting_review_title: Su registro está siendo revisado + clicking_this_link: presionando este enlace + login_link: iniciar sesión + proceed_to_login_html: Ahora puedes proceder a %{login_link}. + redirect_to_app_html: Deberías haber sido redirigido a la aplicación %{app_name}. Si eso no sucedió, prueba %{clicking_this_link} o vuelve a la aplicación manualmente. + registration_complete: "¡Tu registro en %{domain} ha sido completado!" + welcome_title: "¡Bienvenido, %{name}!" wrong_email_hint: Si esa dirección de correo electrónico no es correcta, puedes cambiarla en la configuración de la cuenta. delete_account: Borrar cuenta delete_account_html: Si desea eliminar su cuenta, puede proceder aquí. Será pedido de una confirmación. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index c8c17b853a..4b4585f690 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -1041,6 +1041,14 @@ fi: hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka". title: Turvatarkastus confirmations: + awaiting_review: Sähköpostiosoitteesi on vahvistettu! Palvelun %{domain} ylläpito tarkistaa nyt rekisteröitymisesi. Saat sähköpostiviestin, jos tilisi hyväksytään! + awaiting_review_title: Rekisteröitymisesi on tarkistettavana + clicking_this_link: napsauttaa tätä linkkiä + login_link: kirjautumalla sisään + proceed_to_login_html: Voit nyt jatkaa %{login_link}. + redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen %{app_name}. Jos näin ei tapahtunut, kokeile %{clicking_this_link} tai palaa sovellukseen manuaalisesti. + registration_complete: Rekisteröitymisesi palveluun %{domain} on nyt valmis! + welcome_title: Tervetuloa, %{name}! wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista. delete_account: Poista tili delete_account_html: Jos haluat poistaa tilisi, voit edetä tästä. Sinua pyydetään vahvistamaan poisto. @@ -1100,7 +1108,7 @@ fi: account_status: Tilin tila confirming: Odotetaan sähköpostivahvistuksen valmistumista. functional: Tilisi on täysin toiminnassa. - pending: Hakemuksesi odottaa henkilökuntamme tarkastusta. Tämä voi kestää jonkin aikaa. Saat sähköpostiviestin, jos hakemuksesi hyväksytään. + pending: Hakemuksesi odottaa palvelimen ylläpidon tarkastusta. Tämä voi kestää jonkin aikaa. Saat sähköpostiviestin, jos hakemuksesi hyväksytään. redirecting_to: Tilisi ei ole aktiivinen, koska se ohjaa tällä hetkellä tilille %{acct}. self_destruct: Koska %{domain} sulkeutuu, voit käyttää tiliäsi vain rajoitetusti. view_strikes: Näytä tiliäsi koskevia aiempia varoituksia @@ -1163,7 +1171,7 @@ fi: approve_appeal: Hyväksy valitus associated_report: Liittyvä raportti created_at: Päivätty - description_html: Nämä ovat tiliäsi koskevia toimia ja varoituksia, jotka instanssin %{instance} henkilökunta on lähettänyt sinulle. + description_html: Nämä ovat tiliäsi koskevia toimia ja varoituksia, jotka instanssin %{instance} ylläpito on lähettänyt sinulle. recipient: Osoitettu reject_appeal: Hylkää valitus status: 'Julkaisu #%{id}' @@ -1786,7 +1794,7 @@ fi: title: Uusi kirjautuminen warning: appeal: Lähetä valitus - appeal_description: Jos uskot, että tämä on virhe, voit hakea muutosta instanssin %{instance} henkilökunnalta. + appeal_description: Jos uskot, että tämä on virhe, voit hakea muutosta instanssin %{instance} ylläpidolta. categories: spam: Roskaposti violation: Sisältö rikkoo seuraavia yhteisön sääntöjä diff --git a/config/locales/gl.yml b/config/locales/gl.yml index f76c4dda12..525532ed98 100644 --- a/config/locales/gl.yml +++ b/config/locales/gl.yml @@ -1041,6 +1041,14 @@ gl: hint_html: Unha cousa máis! Temos que confirmar que es un ser humano (para poder evitar contas de spam!). Resolve o CAPTCHA de aquí embaixo e preme en "Continuar". title: Comprobación de seguridade confirmations: + awaiting_review: O teu correo está verificado! A administración de %{domain} está revisando a túa solicitude. Recibirás outro correo se aproban a túa conta! + awaiting_review_title: Estamos revisando a solicitude de rexistro + clicking_this_link: premendo nesta ligazón + login_link: acceder + proceed_to_login_html: Xa podes %{login_link}. + redirect_to_app_html: Ímoste redirixir á app %{app_name}. Se iso non acontece, proba %{clicking_this_link} ou volve ti manualmente á app. + registration_complete: Completouse a creación da conta en %{domain}! + welcome_title: Benvida, %{name}! wrong_email_hint: Se o enderezo de email non é correcto, podes cambialo nos axustes da conta. delete_account: Eliminar conta delete_account_html: Se queres eliminar a túa conta, podes facelo aquí. Deberás confirmar a acción. diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 67f5b693ac..9d08786428 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1041,6 +1041,14 @@ hu: hint_html: Még egy dolog! Meg kell győződnünk róla, hogy tényleg valós személy vagy (így távol tarthatjuk a spam-et). Oldd meg az alábbi CAPTCHA-t és kattints a "Folytatás"-ra. title: Biztonsági ellenőrzés confirmations: + awaiting_review: Az email cím megerősítésre került. %{domain} stáb elenleg áttrkinti a regisztrációt. Ha jóváhagyásra kerül a fiók, egy email kerül kiküldésre! + awaiting_review_title: A regisztráció áttekintés alatt áll. + clicking_this_link: kattintás erre a hivatkozásra + login_link: bejelentkezés + proceed_to_login_html: 'Most továbbléphetünk: %{login_link}.' + redirect_to_app_html: Át kellett volna kerülni %{app_name} alkalmazáshoz. Ha ez nem történt meg, próbálkozzunk %{clicking_this_link} lehetőséggel vagy térjünk vissza manuálisan az alkalmazáshoz. + registration_complete: A regisztráció %{domain} domainen befejeződött! + welcome_title: Üdvözlet, %{name}! wrong_email_hint: Ha az emailcím nem helyes, a fiókbeállításokban megváltoztathatod. delete_account: Felhasználói fiók törlése delete_account_html: Felhasználói fiókod törléséhez kattints ide. A rendszer újbóli megerősítést fog kérni. diff --git a/config/locales/is.yml b/config/locales/is.yml index f5d89eca66..a229f0af02 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1045,6 +1045,10 @@ is: Leystu Turing skynprófið og smelltu á "Áfram". title: Öryggisathugun confirmations: + clicking_this_link: smella á þennan tengil + login_link: skrá þig inn + proceed_to_login_html: Þú getur núna farið í að %{login_link}. + welcome_title: Velkomin/n %{name}! wrong_email_hint: Ef það tölvupóstfang er ekki rétt geturðu breytt því í stillingum notandaaðgangsins. delete_account: Eyða notandaaðgangi delete_account_html: Ef þú vilt eyða notandaaðgangnum þínum, þá geturðu farið í það hér. Þú verður beðin/n um staðfestingu. diff --git a/config/locales/ja.yml b/config/locales/ja.yml index 9df32b09dd..0c805b9e56 100644 --- a/config/locales/ja.yml +++ b/config/locales/ja.yml @@ -1023,6 +1023,14 @@ ja: hint_html: もう一つだけ!あなたが人間であることを確認する必要があります(スパムを防ぐためです!)。 以下のCAPTCHAを解き、「続ける」をクリックします。 title: セキュリティチェック confirmations: + awaiting_review: メールアドレスは確認済みです。%{domain} のモデレーターによりアカウント登録の審査が完了すると、メールでお知らせします。 + awaiting_review_title: 登録の審査待ちです + clicking_this_link: こちらのリンク + login_link: こちらのリンク + proceed_to_login_html: "%{login_link}から早速ログインしてみましょう。" + redirect_to_app_html: "%{app_name}に戻ります。自動で移動しない場合は%{clicking_this_link}を押すか、手動でアプリを切り替えてください。" + registration_complete: "%{domain} へのアカウント登録が完了しました。" + welcome_title: Mastodonへようこそ、%{name}さん wrong_email_hint: メールアドレスが正しくない場合は、アカウント設定で変更できます。 delete_account: アカウントの削除 delete_account_html: アカウントを削除したい場合、こちらから手続きが行えます。削除する前に、確認画面があります。 diff --git a/config/locales/ko.yml b/config/locales/ko.yml index eecac963e0..1bcc8853e5 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1025,6 +1025,14 @@ ko: hint_html: 하나만 더! 당신이 사람인지 확인이 필요합니다 (스팸 계정을 거르기 위해서 필요한 과정입니다). 아래에 있는 CAPTCHA를 풀고 "계속"을 누르세요 title: 보안 체크 confirmations: + awaiting_review: 이메일 주소를 확인했어요! 이제 %{domain} 스태프가 가입을 검토해요. 계정이 승인되면 이메일을 보내드려요. + awaiting_review_title: 가입 검토 중 + clicking_this_link: 이 링크를 클릭 + login_link: 로그인 + proceed_to_login_html: "%{login_link} 할 수 있게 되었어요." + redirect_to_app_html: 곧 %{app_name}으로 리디렉션 되어요. 안 된다면, %{clicking_this_link}하거나 직접 앱으로 돌아가세요. + registration_complete: 지금 막 %{domain} 가입을 마쳤어요! + welcome_title: "%{name} 님 반가워요!" wrong_email_hint: 만약 이메일 주소가 올바르지 않다면, 계정 설정에서 수정할 수 있습니다. delete_account: 계정 삭제 delete_account_html: 계정을 삭제하고 싶은 경우, 여기서 삭제할 수 있습니다. 삭제 전 확인 화면이 표시됩니다. diff --git a/config/locales/sk.yml b/config/locales/sk.yml index 6e3fe0cd89..f16803fb29 100644 --- a/config/locales/sk.yml +++ b/config/locales/sk.yml @@ -125,6 +125,8 @@ sk: removed_header_msg: Úspešne odstránený obrázok hlavičky %{username} resend_confirmation: already_confirmed: Tento užívateľ je už potvrdený + send: Odošli potvrdzovací odkaz znovu + success: Potvrdzovací email úspešne odoslaný! reset: Resetuj reset_password: Obnov heslo resubscribe: Znovu odoberaj @@ -1040,6 +1042,7 @@ sk: confirm_remove_selected_followers: Si si istý/á, že chceš odstrániť vybraných sledovateľov? confirm_remove_selected_follows: Si si istý/á, že chceš odstrániť vybraných sledovaných? dormant: Spiace + follow_failure: Nemožno nasledovať niektoré z vybraných účtov. follow_selected_followers: Následuj označených sledovatelov followers: Následovatelia following: Následovaní diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml index 37166bc03b..cba4354f06 100644 --- a/config/locales/sr-Latn.yml +++ b/config/locales/sr-Latn.yml @@ -1059,6 +1059,14 @@ sr-Latn: hint_html: Samo još jedna stvar! Moramo da potvrdimo da ste ljudsko biće (ovo je da bismo sprečili neželjenu poštu!). Rešite CAPTCHA ispod i kliknite na „Nastavi”. title: Bezbedonosna provera confirmations: + awaiting_review: Vaša adresa e-pošte je potvrđena! Osoblje %{domain} sada pregleda vašu registraciju. Dobićete e-poštu ako odobre vaš nalog! + awaiting_review_title: Vaša registracija se pregleda + clicking_this_link: klikom na ovu vezu + login_link: prijavi se + proceed_to_login_html: Sada možete da pređete na %{login_link}. + redirect_to_app_html: Trebalo je da budete preusmereni na aplikaciju %{app_name}. Ako se to nije desilo, pokušajte sa %{clicking_this_link} ili se ručno vratite u aplikaciju. + registration_complete: Vaša registracija na %{domain} je sada kompletirana! + welcome_title: Dobro došli, %{name}! wrong_email_hint: Ako ta imejl adresa nije ispravna, možete je promeniti u podešavanjima naloga. delete_account: Brisanje naloga delete_account_html: Ako želite da izbrišete vaš nalog, možete nastaviti ovde. Od vas će se tražiti potvrda. @@ -1855,8 +1863,8 @@ sr-Latn: final_step: 'Počnite da objavljujete! Čak i bez pratilaca, Vaše javne objave su vidljive drugim ljudima, na primer na lokalnoj vremenskoj liniji ili u heš oznakama. Možda želite da se predstavite sa heš oznakom #introductions ili #predstavljanja.' full_handle: Vaš pun nadimak full_handle_hint: Ovo biste rekli svojim prijateljima kako bi vam oni poslali poruku, ili zapratili sa druge instance. - subject: Dobrodošli na Mastodon - title: Dobrodošli, %{name}! + subject: Dobro došli na Mastodon + title: Dobro došli, %{name}! users: follow_limit_reached: Ne možete pratiti više od %{limit} ljudi go_to_sso_account_settings: Idite na podešavanja naloga svog dobavljača identiteta diff --git a/config/locales/sr.yml b/config/locales/sr.yml index ba269488e4..902f13ad61 100644 --- a/config/locales/sr.yml +++ b/config/locales/sr.yml @@ -1059,6 +1059,14 @@ sr: hint_html: Само још једна ствар! Морамо да потврдимо да сте људско биће (ово је да бисмо спречили нежељену пошту!). Решите CAPTCHA испод и кликните на „Настави”. title: Безбедоносна провера confirmations: + awaiting_review: Ваша адреса е-поште је потврђена! Особље %{domain} сада прегледа вашу регистрацију. Добићете е-пошту ако одобре ваш налог! + awaiting_review_title: Ваша регистрација се прегледа + clicking_this_link: кликом на ову везу + login_link: пријави се + proceed_to_login_html: Сада можете да пређете на %{login_link}. + redirect_to_app_html: Требало је да будете преусмерени на апликацију %{app_name}. Ако се то није десило, покушајте са %{clicking_this_link} или се ручно вратите у апликацију. + registration_complete: Ваша регистрација на %{domain} је сада комплетирана! + welcome_title: Добро дошли, %{name}! wrong_email_hint: Ако та имејл адреса није исправна, можете је променити у подешавањима налога. delete_account: Брисање налога delete_account_html: Ако желите да избришете ваш налог, можете наставити овде. Од вас ће се тражити потврда. @@ -1855,8 +1863,8 @@ sr: final_step: 'Почните да објављујете! Чак и без пратилаца, Ваше јавне објаве су видљиве другим људима, на пример на локалној временској линији или у хеш ознакама. Можда желите да се представите са хеш ознаком #introductions или #представљања.' full_handle: Ваш пун надимак full_handle_hint: Ово бисте рекли својим пријатељима како би вам они послали поруку, или запратили са друге инстанце. - subject: Добродошли на Mastodon - title: Добродошли, %{name}! + subject: Добро дошли на Mastodon + title: Добро дошли, %{name}! users: follow_limit_reached: Не можете пратити више од %{limit} људи go_to_sso_account_settings: Идите на подешавања налога свог добављача идентитета diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 72c5295b35..1cccb301d1 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1041,6 +1041,10 @@ sv: hint_html: En sista sak till! Vi måste bekräfta att du är en människa (för att hålla borta skräpinlägg!). Lös CAPTCHA nedan och klicka på "Fortsätt". title: Säkerhetskontroll confirmations: + awaiting_review_title: Din registrering är under granskning + clicking_this_link: klicka på denna länk + registration_complete: Din registrering på %{domain} är nu slutförd! + welcome_title: Välkommen, %{name}! wrong_email_hint: Om e-postadressen inte är rätt, kan du ändra den i kontoinställningarna. delete_account: Radera konto delete_account_html: Om du vill radera ditt konto kan du fortsätta här. Du kommer att bli ombedd att bekräfta. diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml index 6d3beddbcf..7902cea4dd 100644 --- a/config/locales/zh-CN.yml +++ b/config/locales/zh-CN.yml @@ -1023,6 +1023,14 @@ zh-CN: hint_html: 只剩最后一件事了!我们需要确认您是一个人类(这样我们才能阻止恶意访问!)。请输入下面的验证码,然后点击“继续”。 title: 安全检查 confirmations: + awaiting_review: 您的电子邮件地址已确认!%{domain} 的工作人员正在审核您的注册信息。如果他们批准了您的账户,您将收到一封邮件通知! + awaiting_review_title: 您的注册申请正在审核中 + clicking_this_link: 点击此链接 + login_link: 登录 + proceed_to_login_html: 现在您可以继续前往 %{login_link} 。 + redirect_to_app_html: 您应该已被重定向到 %{app_name} 应用程序。如果没有,请尝试 %{clicking_this_link} 或手动返回应用程序。 + registration_complete: 您在 %{domain} 上的注册现已完成! + welcome_title: 欢迎您,%{name}! wrong_email_hint: 如果该电子邮件地址不正确,您可以在帐户设置中进行更改。 delete_account: 删除帐户 delete_account_html: 如果你想删除你的帐户,请点击这里继续。你需要确认你的操作。 diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 28507b076a..9d75f50a50 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1025,6 +1025,14 @@ zh-TW: hint_html: 僅再一步!我們必須確認您是位人類(這是防止垃圾訊息濫用)。請完成以下 CAPTCHA 挑戰並點擊「繼續」。 title: 安全性檢查 confirmations: + awaiting_review: 已驗證您的電子郵件!%{domain} 的管理員正在審核您的註冊申請。若您的帳號通過審核,您將收到電子郵件通知。 + awaiting_review_title: 我們正在審核您的註冊申請 + clicking_this_link: 點擊這個連結 + login_link: 登入 + proceed_to_login_html: 您現在可以前往 %{login_link}。 + redirect_to_app_html: 您應被重新導向至 %{app_name} 應用程式。如尚未重新導向,請嘗試 %{clicking_this_link} 或手動回到應用程式。 + registration_complete: 您於 %{domain} 之註冊申請已完成! + welcome_title: 歡迎,%{name}! wrong_email_hint: 若電子郵件地址不正確,您可以於帳號設定中更改。 delete_account: 刪除帳號 delete_account_html: 如果您欲刪除您的帳號,請點擊這裡繼續。您需要再三確認您的操作。 From 75255c01fccb68cd34b7503b798a8f72793f863f Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 26 Oct 2023 15:09:48 +0200 Subject: [PATCH 007/834] Fix error when trying to delete already-deleted file with OpenStack Swift (#27569) --- app/lib/attachment_batch.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/app/lib/attachment_batch.rb b/app/lib/attachment_batch.rb index 78bd593160..13a9da828f 100644 --- a/app/lib/attachment_batch.rb +++ b/app/lib/attachment_batch.rb @@ -75,7 +75,12 @@ class AttachmentBatch end when :fog logger.debug { "Deleting #{attachment.path(style)}" } - attachment.send(:directory).files.new(key: attachment.path(style)).destroy + + begin + attachment.send(:directory).files.new(key: attachment.path(style)).destroy + rescue Fog::Storage::OpenStack::NotFound + # Ignore failure to delete a file that has already been deleted + end when :azure logger.debug { "Deleting #{attachment.path(style)}" } attachment.destroy From ba8dcb50fe0bde2beecfe35a526cc31c50e67fa6 Mon Sep 17 00:00:00 2001 From: "Mark T. Tomczak" Date: Thu, 26 Oct 2023 10:08:25 -0400 Subject: [PATCH 008/834] Issue 26048: swap "muting" and "blocking" list options in settings -> Data Exports (#26088) --- app/views/settings/exports/show.html.haml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/settings/exports/show.html.haml b/app/views/settings/exports/show.html.haml index d7b59af270..320bb0c7ce 100644 --- a/app/views/settings/exports/show.html.haml +++ b/app/views/settings/exports/show.html.haml @@ -24,14 +24,14 @@ %th= t('admin.accounts.followers') %td= number_with_delimiter @export.total_followers %td - %tr - %th= t('exports.blocks') - %td= number_with_delimiter @export.total_blocks - %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv) %tr %th= t('exports.mutes') %td= number_with_delimiter @export.total_mutes %td= table_link_to 'download', t('exports.csv'), settings_exports_mutes_path(format: :csv) + %tr + %th= t('exports.blocks') + %td= number_with_delimiter @export.total_blocks + %td= table_link_to 'download', t('exports.csv'), settings_exports_blocks_path(format: :csv) %tr %th= t('exports.domain_blocks') %td= number_with_delimiter @export.total_domain_blocks From d2f52f7f641395200b372386adad748d7cad5d5b Mon Sep 17 00:00:00 2001 From: Claire Date: Thu, 26 Oct 2023 19:03:31 +0200 Subject: [PATCH 009/834] Fix report processing notice not mentioning the report number when performing a custom action (#27442) --- app/controllers/admin/account_actions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/account_actions_controller.rb b/app/controllers/admin/account_actions_controller.rb index e89404b609..e674bf55a0 100644 --- a/app/controllers/admin/account_actions_controller.rb +++ b/app/controllers/admin/account_actions_controller.rb @@ -21,7 +21,7 @@ module Admin account_action.save! if account_action.with_report? - redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: params[:report_id]) + redirect_to admin_reports_path, notice: I18n.t('admin.reports.processed_msg', id: resource_params[:report_id]) else redirect_to admin_account_path(@account.id) end From 2d8f759a342813c48e00412d17ec2517ed9ef761 Mon Sep 17 00:00:00 2001 From: Simon Rapilly <85184231+srapilly@users.noreply.github.com> Date: Thu, 26 Oct 2023 16:34:15 -0400 Subject: [PATCH 010/834] Add HTML lang attribute to preview card descriptions (#27503) --- app/javascript/mastodon/features/status/components/card.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index efd57c8716..684c599adb 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -143,7 +143,7 @@ export default class Card extends PureComponent { {card.get('title')} - {card.get('author_name').length > 0 ? {card.get('author_name')} }} /> : {card.get('description')}} + {card.get('author_name').length > 0 ? {card.get('author_name')} }} /> : {card.get('description')}}
); From 4aa05d45fc45b797e0a3b7d40885ef89c2161a73 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 26 Oct 2023 16:35:15 -0400 Subject: [PATCH 011/834] Capture minimum postgres version 12 (#27528) --- README.md | 2 +- config/initializers/strong_migrations.rb | 2 +- lib/mastodon/migration_helpers.rb | 63 ++---------------------- 3 files changed, 7 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index ce9b5cfbdc..62b04f0203 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Mastodon acts as an OAuth2 provider, so 3rd party apps can use the REST and Stre ### Requirements -- **PostgreSQL** 9.5+ +- **PostgreSQL** 12+ - **Redis** 4+ - **Ruby** 2.7+ - **Node.js** 16+ diff --git a/config/initializers/strong_migrations.rb b/config/initializers/strong_migrations.rb index 10b3805db2..4dcec1c2a2 100644 --- a/config/initializers/strong_migrations.rb +++ b/config/initializers/strong_migrations.rb @@ -1,4 +1,4 @@ # frozen_string_literal: true StrongMigrations.start_after = 2017_09_24_022025 -StrongMigrations.target_version = 10 +StrongMigrations.target_version = 12 diff --git a/lib/mastodon/migration_helpers.rb b/lib/mastodon/migration_helpers.rb index a92a8767ce..7bc1298838 100644 --- a/lib/mastodon/migration_helpers.rb +++ b/lib/mastodon/migration_helpers.rb @@ -158,10 +158,8 @@ module Mastodon 'in the body of your migration class' end - if supports_drop_index_concurrently? - options = options.merge({ algorithm: :concurrently }) - disable_statement_timeout - end + options = options.merge({ algorithm: :concurrently }) + disable_statement_timeout remove_index(table_name, **options.merge({ column: column_name })) end @@ -182,28 +180,12 @@ module Mastodon 'in the body of your migration class' end - if supports_drop_index_concurrently? - options = options.merge({ algorithm: :concurrently }) - disable_statement_timeout - end + options = options.merge({ algorithm: :concurrently }) + disable_statement_timeout remove_index(table_name, **options.merge({ name: index_name })) end - # Only available on Postgresql >= 9.2 - def supports_drop_index_concurrently? - version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i - - version >= 90_200 - end - - # Only available on Postgresql >= 11 - def supports_add_column_with_default? - version = select_one("SELECT current_setting('server_version_num') AS v")['v'].to_i - - version >= 110_000 - end - # Adds a foreign key with only minimal locking on the tables involved. # # This method only requires minimal locking when using PostgreSQL. When @@ -420,42 +402,7 @@ module Mastodon # This method can also take a block which is passed directly to the # `update_column_in_batches` method. def add_column_with_default(table, column, type, default:, limit: nil, allow_null: false, &block) - if supports_add_column_with_default? - add_column(table, column, type, default: default, limit: limit, null: allow_null) - return - end - - if transaction_open? - raise 'add_column_with_default can not be run inside a transaction, ' \ - 'you can disable transactions by calling disable_ddl_transaction! ' \ - 'in the body of your migration class' - end - - disable_statement_timeout - - transaction do - if limit - add_column(table, column, type, default: nil, limit: limit) - else - add_column(table, column, type, default: nil) - end - - # Changing the default before the update ensures any newly inserted - # rows already use the proper default value. - change_column_default(table, column, default) - end - - begin - update_column_in_batches(table, column, default, &block) - - change_column_null(table, column, false) unless allow_null - # We want to rescue _all_ exceptions here, even those that don't inherit - # from StandardError. - rescue Exception => error # rubocop: disable all - remove_column(table, column) - - raise error - end + add_column(table, column, type, default: default, limit: limit, null: allow_null) end # Renames a column without requiring downtime. From 12550a6a28939bf870c7ab1c8122028b122e6587 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Thu, 26 Oct 2023 17:20:41 -0400 Subject: [PATCH 012/834] Use `Rails.env.local?` shorthand method to check env (#27519) --- app/models/user.rb | 2 +- config/application.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index fa445af811..2ebf4a24bf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -488,7 +488,7 @@ class User < ApplicationRecord end def validate_email_dns? - email_changed? && !external? && !(Rails.env.test? || Rails.env.development?) + email_changed? && !external? && !Rails.env.local? # rubocop:disable Rails/UnknownEnv end def validate_role_elevation diff --git a/config/application.rb b/config/application.rb index 7f7f8b5d6c..ad931fd36b 100644 --- a/config/application.rb +++ b/config/application.rb @@ -206,7 +206,7 @@ module Mastodon # We use our own middleware for this config.public_file_server.enabled = false - config.middleware.use PublicFileServerMiddleware if Rails.env.development? || Rails.env.test? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true' + config.middleware.use PublicFileServerMiddleware if Rails.env.local? || ENV['RAILS_SERVE_STATIC_FILES'] == 'true' # rubocop:disable Rails/UnknownEnv config.middleware.use Rack::Attack config.middleware.use Mastodon::RackMiddleware From fa7e64df1de13b361551b0ff8f81335719c1a4a2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 27 Oct 2023 01:37:58 +0200 Subject: [PATCH 013/834] Fix various icon styles in web UI (#27579) --- .../features/account/components/header.jsx | 6 ++--- .../mastodon/features/audio/index.jsx | 6 ++--- .../features/status/components/card.jsx | 4 ++-- .../mastodon/features/video/index.jsx | 6 ++--- .../styles/mastodon/components.scss | 22 ++++++++++++++++++- 5 files changed, 32 insertions(+), 12 deletions(-) diff --git a/app/javascript/mastodon/features/account/components/header.jsx b/app/javascript/mastodon/features/account/components/header.jsx index 3ecfb8a2bb..76074225ad 100644 --- a/app/javascript/mastodon/features/account/components/header.jsx +++ b/app/javascript/mastodon/features/account/components/header.jsx @@ -12,8 +12,8 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { ReactComponent as CheckIcon } from '@material-symbols/svg-600/outlined/check.svg'; import { ReactComponent as LockIcon } from '@material-symbols/svg-600/outlined/lock.svg'; import { ReactComponent as MoreHorizIcon } from '@material-symbols/svg-600/outlined/more_horiz.svg'; -import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications-fill.svg'; -import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active.svg'; +import { ReactComponent as NotificationsIcon } from '@material-symbols/svg-600/outlined/notifications.svg'; +import { ReactComponent as NotificationsActiveIcon } from '@material-symbols/svg-600/outlined/notifications_active-fill.svg'; import { Avatar } from 'mastodon/components/avatar'; import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge'; @@ -264,7 +264,7 @@ class Header extends ImmutablePureComponent { } if (account.getIn(['relationship', 'requested']) || account.getIn(['relationship', 'following'])) { - bellBtn = ; + bellBtn = ; } if (me !== account.get('id')) { diff --git a/app/javascript/mastodon/features/audio/index.jsx b/app/javascript/mastodon/features/audio/index.jsx index 60d599b97a..7a7d0910fa 100644 --- a/app/javascript/mastodon/features/audio/index.jsx +++ b/app/javascript/mastodon/features/audio/index.jsx @@ -9,10 +9,10 @@ import { is } from 'immutable'; import { ReactComponent as DownloadIcon } from '@material-symbols/svg-600/outlined/download.svg'; import { ReactComponent as PauseIcon } from '@material-symbols/svg-600/outlined/pause.svg'; -import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow.svg'; +import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow-fill.svg'; import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg'; -import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outlined/volume_off.svg'; -import { ReactComponent as VolumeUpIcon } from '@material-symbols/svg-600/outlined/volume_up.svg'; +import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outlined/volume_off-fill.svg'; +import { ReactComponent as VolumeUpIcon } from '@material-symbols/svg-600/outlined/volume_up-fill.svg'; import { throttle, debounce } from 'lodash'; import { Icon } from 'mastodon/components/icon'; diff --git a/app/javascript/mastodon/features/status/components/card.jsx b/app/javascript/mastodon/features/status/components/card.jsx index 684c599adb..d7d688952d 100644 --- a/app/javascript/mastodon/features/status/components/card.jsx +++ b/app/javascript/mastodon/features/status/components/card.jsx @@ -10,9 +10,9 @@ import classNames from 'classnames'; import Immutable from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { ReactComponent as DescriptionIcon } from '@material-symbols/svg-600/outlined/description.svg'; +import { ReactComponent as DescriptionIcon } from '@material-symbols/svg-600/outlined/description-fill.svg'; import { ReactComponent as OpenInNewIcon } from '@material-symbols/svg-600/outlined/open_in_new.svg'; -import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow.svg'; +import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow-fill.svg'; import { Blurhash } from 'mastodon/components/blurhash'; import { Icon } from 'mastodon/components/icon'; diff --git a/app/javascript/mastodon/features/video/index.jsx b/app/javascript/mastodon/features/video/index.jsx index c04d9e3d4b..05b1316fd0 100644 --- a/app/javascript/mastodon/features/video/index.jsx +++ b/app/javascript/mastodon/features/video/index.jsx @@ -10,11 +10,11 @@ import { is } from 'immutable'; import { ReactComponent as FullscreenIcon } from '@material-symbols/svg-600/outlined/fullscreen.svg'; import { ReactComponent as FullscreenExitIcon } from '@material-symbols/svg-600/outlined/fullscreen_exit.svg'; import { ReactComponent as PauseIcon } from '@material-symbols/svg-600/outlined/pause.svg'; -import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow.svg'; +import { ReactComponent as PlayArrowIcon } from '@material-symbols/svg-600/outlined/play_arrow-fill.svg'; import { ReactComponent as RectangleIcon } from '@material-symbols/svg-600/outlined/rectangle.svg'; import { ReactComponent as VisibilityOffIcon } from '@material-symbols/svg-600/outlined/visibility_off.svg'; -import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outlined/volume_off.svg'; -import { ReactComponent as VolumeUpIcon } from '@material-symbols/svg-600/outlined/volume_up.svg'; +import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outlined/volume_off-fill.svg'; +import { ReactComponent as VolumeUpIcon } from '@material-symbols/svg-600/outlined/volume_up-fill.svg'; import { throttle } from 'lodash'; import { Blurhash } from 'mastodon/components/blurhash'; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 417f262a28..b8e6af0aaa 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -7434,7 +7434,12 @@ noscript { border: 1px solid lighten($ui-base-color, 12%); border-radius: 4px; box-sizing: content-box; - padding: 2px; + padding: 5px; + + .icon { + width: 24px; + height: 24px; + } } } @@ -7517,6 +7522,11 @@ noscript { color: lighten($ui-highlight-color, 8%); } + .icon { + width: 18px; + height: 18px; + } + .verified { border: 1px solid rgba($valid-value-color, 0.5); margin-top: -1px; @@ -7537,6 +7547,16 @@ noscript { color: $valid-value-color; } + dd { + display: flex; + align-items: center; + gap: 4px; + + span { + display: flex; + } + } + a { color: $valid-value-color; } From 8f998cd96a1512b545cf674edad012839cec5cb2 Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Fri, 27 Oct 2023 11:36:22 +0900 Subject: [PATCH 014/834] Handle featured collections without items (#27581) --- .../activitypub/fetch_featured_collection_service.rb | 2 ++ .../fetch_featured_collection_service_spec.rb | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/app/services/activitypub/fetch_featured_collection_service.rb b/app/services/activitypub/fetch_featured_collection_service.rb index e8a31dade9..d2bae08a0e 100644 --- a/app/services/activitypub/fetch_featured_collection_service.rb +++ b/app/services/activitypub/fetch_featured_collection_service.rb @@ -37,6 +37,8 @@ class ActivityPub::FetchFeaturedCollectionService < BaseService end def process_items(items) + return if items.nil? + process_note_items(items) if @options[:note] process_hashtag_items(items) if @options[:hashtag] end diff --git a/spec/services/activitypub/fetch_featured_collection_service_spec.rb b/spec/services/activitypub/fetch_featured_collection_service_spec.rb index 5975c81a10..466da891a8 100644 --- a/spec/services/activitypub/fetch_featured_collection_service_spec.rb +++ b/spec/services/activitypub/fetch_featured_collection_service_spec.rb @@ -42,12 +42,22 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do } end + let(:featured_with_null) do + { + '@context': 'https://www.w3.org/ns/activitystreams', + id: 'https://example.com/account/collections/featured', + totalItems: 0, + type: 'OrderedCollection', + } + end + let(:items) do [ 'https://example.com/account/pinned/known', # known status_json_pinned_unknown_inlined, # unknown inlined 'https://example.com/account/pinned/unknown-unreachable', # unknown unreachable 'https://example.com/account/pinned/unknown-reachable', # unknown reachable + 'https://example.com/account/collections/featured', # featured with null ] end @@ -66,6 +76,7 @@ RSpec.describe ActivityPub::FetchFeaturedCollectionService, type: :service do stub_request(:get, 'https://example.com/account/pinned/unknown-inlined').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_inlined)) stub_request(:get, 'https://example.com/account/pinned/unknown-unreachable').to_return(status: 404) stub_request(:get, 'https://example.com/account/pinned/unknown-reachable').to_return(status: 200, body: Oj.dump(status_json_pinned_unknown_unreachable)) + stub_request(:get, 'https://example.com/account/collections/featured').to_return(status: 200, body: Oj.dump(featured_with_null)) subject.call(actor, note: true, hashtag: false) end From bbf46cc41833d14d9bda7dcfd37dc188861987da Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 27 Oct 2023 10:35:21 +0200 Subject: [PATCH 015/834] Fix error and incorrect URLs in `/api/v1/accounts/:id/featured_tags` for remote accounts (#27459) --- .../rest/featured_tag_serializer.rb | 4 +- config/routes.rb | 2 +- .../accounts/featured_tags_controller_spec.rb | 23 --------- .../api/v1/accounts/featured_tags_spec.rb | 50 +++++++++++++++++++ 4 files changed, 54 insertions(+), 25 deletions(-) delete mode 100644 spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb create mode 100644 spec/requests/api/v1/accounts/featured_tags_spec.rb diff --git a/app/serializers/rest/featured_tag_serializer.rb b/app/serializers/rest/featured_tag_serializer.rb index c4b35ab03a..c1ff4602aa 100644 --- a/app/serializers/rest/featured_tag_serializer.rb +++ b/app/serializers/rest/featured_tag_serializer.rb @@ -10,7 +10,9 @@ class REST::FeaturedTagSerializer < ActiveModel::Serializer end def url - short_account_tag_url(object.account, object.tag) + # The path is hardcoded because we have to deal with both local and + # remote users, which are different routes + account_with_domain_url(object.account, "tagged/#{object.tag.to_param}") end def name diff --git a/config/routes.rb b/config/routes.rb index 89c147869a..ce3fd9596a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -134,7 +134,7 @@ Rails.application.routes.draw do get '/@:account_username/:id/embed', to: 'statuses#embed', as: :embed_short_account_status end - get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: %r{([^/])+?} }, format: false + get '/@:username_with_domain/(*any)', to: 'home#index', constraints: { username_with_domain: %r{([^/])+?} }, as: :account_with_domain, format: false get '/settings', to: redirect('/settings/profile') draw(:settings) diff --git a/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb b/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb deleted file mode 100644 index 53ac1e2a7a..0000000000 --- a/spec/controllers/api/v1/accounts/featured_tags_controller_spec.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true - -require 'rails_helper' - -describe Api::V1::Accounts::FeaturedTagsController do - render_views - - let(:user) { Fabricate(:user) } - let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: 'read:accounts') } - let(:account) { Fabricate(:account) } - - before do - allow(controller).to receive(:doorkeeper_token) { token } - end - - describe 'GET #index' do - it 'returns http success' do - get :index, params: { account_id: account.id, limit: 2 } - - expect(response).to have_http_status(200) - end - end -end diff --git a/spec/requests/api/v1/accounts/featured_tags_spec.rb b/spec/requests/api/v1/accounts/featured_tags_spec.rb new file mode 100644 index 0000000000..bae7d448b6 --- /dev/null +++ b/spec/requests/api/v1/accounts/featured_tags_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'account featured tags API' do + let(:user) { Fabricate(:user) } + let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) } + let(:scopes) { 'read:accounts' } + let(:headers) { { 'Authorization' => "Bearer #{token.token}" } } + let(:account) { Fabricate(:account) } + + describe 'GET /api/v1/accounts/:id/featured_tags' do + subject do + get "/api/v1/accounts/#{account.id}/featured_tags", headers: headers + end + + before do + account.featured_tags.create!(name: 'foo') + account.featured_tags.create!(name: 'bar') + end + + it 'returns the expected tags', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to contain_exactly(a_hash_including({ + name: 'bar', + url: "https://cb6e6126.ngrok.io/@#{account.username}/tagged/bar", + }), a_hash_including({ + name: 'foo', + url: "https://cb6e6126.ngrok.io/@#{account.username}/tagged/foo", + })) + end + + context 'when the account is remote' do + it 'returns the expected tags', :aggregate_failures do + subject + + expect(response).to have_http_status(200) + expect(body_as_json).to contain_exactly(a_hash_including({ + name: 'bar', + url: "https://cb6e6126.ngrok.io/@#{account.pretty_acct}/tagged/bar", + }), a_hash_including({ + name: 'foo', + url: "https://cb6e6126.ngrok.io/@#{account.pretty_acct}/tagged/foo", + })) + end + end + end +end From 8ca16f032e8347935ad6c03b5d97a8d7a3e367b7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 11:38:04 +0200 Subject: [PATCH 016/834] New Crowdin Translations (automated) (#27583) Co-authored-by: GitHub Actions --- config/locales/de.yml | 2 ++ config/locales/es-AR.yml | 8 ++++++++ config/locales/es.yml | 8 ++++++-- config/locales/fo.yml | 8 ++++++++ config/locales/fr-QC.yml | 8 ++++++++ config/locales/fr.yml | 8 ++++++++ config/locales/fy.yml | 8 ++++++++ config/locales/he.yml | 8 ++++++++ config/locales/hu.yml | 10 +++++----- config/locales/is.yml | 4 ++++ config/locales/it.yml | 8 ++++++++ config/locales/nl.yml | 8 ++++++++ config/locales/pt-BR.yml | 2 ++ config/locales/pt-PT.yml | 8 ++++++++ config/locales/ru.yml | 10 ++++++++++ config/locales/sv.yml | 3 ++- config/locales/th.yml | 8 ++++++++ config/locales/tr.yml | 8 ++++++++ config/locales/uk.yml | 8 ++++++++ 19 files changed, 127 insertions(+), 8 deletions(-) diff --git a/config/locales/de.yml b/config/locales/de.yml index 21dfe4a7fb..ca7659c4c9 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -1043,8 +1043,10 @@ de: confirmations: awaiting_review: Deine E-Mail-Adresse wurde bestätigt und das Team von %{domain} überprüft nun deine Registrierung. Sobald es dein Konto genehmigt, wirst du eine E-Mail erhalten. awaiting_review_title: Deine Registrierung wird überprüft + clicking_this_link: Klick auf diesen Link login_link: anmelden proceed_to_login_html: Du kannst dich nun %{login_link}. + redirect_to_app_html: Du hättest zur %{app_name}-App weitergeleitet werden sollen. Wenn das nicht geschehen ist, versuche es mit einem %{clicking_this_link} oder kehre manuell zur App zurück. registration_complete: Deine Registrierung auf %{domain} ist nun abgeschlossen! welcome_title: Willkommen, %{name}! wrong_email_hint: Sollte diese E-Mail-Adresse nicht korrekt sein, kannst du sie in den Kontoeinstellungen ändern. diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml index fcff946910..127f1262a3 100644 --- a/config/locales/es-AR.yml +++ b/config/locales/es-AR.yml @@ -1041,6 +1041,14 @@ es-AR: hint_html: ¡Sólo una cosa más! Necesitamos confirmar que sos humano (¡esto es para que podamos mantener el spam fuera!). Resuelvé la CAPTCHA abajo y hacé clic en "Continuar". title: Comprobación de seguridad confirmations: + awaiting_review: "¡Tu dirección de correo electrónico fue confirmada! El equipo de %{domain} está revisando tu registro. ¡Recibirás un correo electrónico si aprueban tu cuenta!" + awaiting_review_title: Tu registro está siendo revisado + clicking_this_link: haciendo clic en este enlace + login_link: iniciar sesión + proceed_to_login_html: Ahora podés %{login_link}. + redirect_to_app_html: Deberías haber sido redirigido a la aplicación %{app_name}. Si eso no sucedió, probá %{clicking_this_link} o volvé a la aplicación manualmente. + registration_complete: "¡Tu registro en %{domain} fue completado!" + welcome_title: "¡Te damos la bienvenida, %{name}!" wrong_email_hint: Si esa dirección de correo electrónico no es correcta, podés cambiarla en la configuración de la cuenta. delete_account: Eliminar cuenta delete_account_html: Si querés eliminar tu cuenta, podés seguir por acá. Se te va a pedir una confirmación. diff --git a/config/locales/es.yml b/config/locales/es.yml index 5dce6330d6..aab31747e7 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1041,6 +1041,10 @@ es: hint_html: ¡Una última cosita! Necesitamos confirmar que eres humano (¡así podemos evitar el spam!). Resuelve este CAPTCHA de debajo y pulsa en "Continuar". title: Comprobación de seguridad confirmations: + awaiting_review: "¡Tu dirección de correo electrónico ha sido confirmada! El personal de %{domain} está revisando tu registro. ¡Recibirás un correo electrónico cuando aprueben tu cuenta!" + awaiting_review_title: Estamos revisando tu registro + clicking_this_link: haciendo clic en este enlace + registration_complete: "¡Has completado tu registro en %{domain}!" wrong_email_hint: Si esa dirección de correo electrónico no es correcta, puedes cambiarla en la configuración de la cuenta. delete_account: Borrar cuenta delete_account_html: Si desea eliminar su cuenta, puede proceder aquí. Será pedido de una confirmación. @@ -1100,7 +1104,7 @@ es: account_status: Estado de la cuenta confirming: Esperando confirmación de correo electrónico. functional: Tu cuenta está completamente operativa. - pending: Su solicitud está pendiente de revisión por nuestros administradores. Eso puede tardar algún tiempo. Usted recibirá un correo electrónico si el solicitud sea aprobada. + pending: Tu solicitud está pendiente de revisión por nuestro personal. Eso puede tardar un tiempo. Recibirás un correo electrónico cuando tu solicitud sea aprobada. redirecting_to: Tu cuenta se encuentra inactiva porque está siendo redirigida a %{acct}. self_destruct: Como %{domain} está en proceso de cierre, solo tendrás acceso limitado a tu cuenta. view_strikes: Ver amonestaciones pasadas contra tu cuenta @@ -1786,7 +1790,7 @@ es: title: Un nuevo inicio de sesión warning: appeal: Enviar una apelación - appeal_description: Si crees que esto es un error, puedes enviar una apelación al equipo de %{instance}. + appeal_description: Si crees que esto es un error, puedes enviar una apelación al personal de %{instance}. categories: spam: Spam violation: El contenido viola las siguientes directrices de la comunidad diff --git a/config/locales/fo.yml b/config/locales/fo.yml index bd716fa384..8e98cc8649 100644 --- a/config/locales/fo.yml +++ b/config/locales/fo.yml @@ -1041,6 +1041,14 @@ fo: hint_html: Bara eitt afturat! Tað er neyðugt hjá okkum at vátta, at tú ert eitt menniskja (fyri at sleppa undan ruskposti!). Loys CAPTCHA niðanfyri og trýst á "Halt fram". title: Trygdarkanning confirmations: + awaiting_review: Teldupostadressan hjá góðkend! Nú kanna %{domain} ábyrgdarfólk skrásetingina hjá tær. Góðkenna tey kontu tína, so senda tey tær eitt teldubræv! + awaiting_review_title: Skrásetingin hjá tær verður viðgjørd + clicking_this_link: við at klikkja á hetta leinki + login_link: rita inn + proceed_to_login_html: Nú kanst tú fara víðari til %{login_link}. + redirect_to_app_html: Tú skuldi verið send/ur víðari til %{app_name} appina. Hendi tað ikki, so kanst tú royna %{clicking_this_link} ella fara manuelt aftur til appina. + registration_complete: Skráseting tín á %{domain} er nú avgreidd! + welcome_title: Vælkomin, %{name}! wrong_email_hint: Um hesin teldupoststaðurin ikki er rættur, so kanst tú broyta hann í kontustillingunum. delete_account: Strika kontu delete_account_html: Ynskir tú at strika kontuna, so kanst tú halda fram her. Tú verður spurd/ur um váttan. diff --git a/config/locales/fr-QC.yml b/config/locales/fr-QC.yml index 15e0fa6096..41b71f569d 100644 --- a/config/locales/fr-QC.yml +++ b/config/locales/fr-QC.yml @@ -1041,6 +1041,14 @@ fr-QC: hint_html: Juste une autre chose! Nous avons besoin de confirmer que vous êtes un humain (pour que nous puissions empêcher les spams!). Résolvez le CAPTCHA ci-dessous et cliquez sur "Continuer". title: Vérification de sécurité confirmations: + awaiting_review: Votre adresse e-mail est confirmée ! L’équipe de %{domain} vérifie désormais votre inscription. Vous recevrez un e-mail si votre compte est approuvé ! + awaiting_review_title: Votre inscription est en cours de validation + clicking_this_link: cliquer sur ce lien + login_link: vous connecter + proceed_to_login_html: Vous pouvez désormais %{login_link}. + redirect_to_app_html: Vous auriez dû être redirigé vers l’application %{app_name}. Si cela ne s’est pas produit, essayez de %{clicking_this_link} ou de revenir manuellement à l’application. + registration_complete: Votre inscription sur %{domain} est désormais terminée ! + welcome_title: Bienvenue, %{name} ! wrong_email_hint: Si cette adresse de courriel est incorrecte, vous pouvez la modifier dans vos paramètres de compte. delete_account: Supprimer le compte delete_account_html: Si vous désirez supprimer votre compte, vous pouvez cliquer ici. Il vous sera demandé de confirmer cette action. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 1616f76726..79d8b92c2a 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1041,6 +1041,14 @@ fr: hint_html: Encore une chose ! Nous avons besoin de confirmer que vous êtes un humain (c'est pour que nous puissions empêcher les spams !). Résolvez le CAPTCHA ci-dessous et cliquez sur "Continuer". title: Vérification de sécurité confirmations: + awaiting_review: Votre adresse e-mail est confirmée ! L’équipe de %{domain} vérifie désormais votre inscription. Vous recevrez un e-mail si votre compte est approuvé ! + awaiting_review_title: Votre inscription est en cours de validation + clicking_this_link: cliquer sur ce lien + login_link: vous connecter + proceed_to_login_html: Vous pouvez désormais %{login_link}. + redirect_to_app_html: Vous auriez dû être redirigé vers l’application %{app_name}. Si cela ne s’est pas produit, essayez de %{clicking_this_link} ou de revenir manuellement à l’application. + registration_complete: Votre inscription sur %{domain} est désormais terminée ! + welcome_title: Bienvenue, %{name} ! wrong_email_hint: Si cette adresse de courriel est incorrecte, vous pouvez la modifier dans vos paramètres de compte. delete_account: Supprimer le compte delete_account_html: Si vous désirez supprimer votre compte, vous pouvez cliquer ici. Il vous sera demandé de confirmer cette action. diff --git a/config/locales/fy.yml b/config/locales/fy.yml index a7ab89fc87..011899d15d 100644 --- a/config/locales/fy.yml +++ b/config/locales/fy.yml @@ -1041,6 +1041,14 @@ fy: hint_html: Noch ien ding! Jo moatte befêstigje dat jo in minske binne (dit is om de spam bûten de doar te hâlden!). Los de ûndersteande CAPTCHA op en klik op ‘Trochgean’. title: Befeiligingskontrôle confirmations: + awaiting_review: Jo e-mailadres is befêstige! De %{domain}-meiwurkers binne no dwaande mei it besjen fan jo registraasje. Jo ûntfange in e-mailberjocht as de jo account goedkarre! + awaiting_review_title: Jo registraasje wurdt beoardield + clicking_this_link: klik op dizze keppeling + login_link: oanmelde + proceed_to_login_html: Jo kinne no fierder gean nei %{login_link}. + redirect_to_app_html: Jo soene omlaad wêze moatte nei de %{app_name} app. As dat net bard is, probearje dan %{clicking_this_link} of kear hânmjittich werom nei de app. + registration_complete: Jo registraasje op %{domain} is no foltôge! + welcome_title: Wolkom, %{name}! wrong_email_hint: As it e-mailadres net korrekt is, kinne jo dat wizigje yn de accountynstellingen. delete_account: Account fuortsmite delete_account_html: Wannear’t jo jo account graach fuortsmite wolle, kinne jo dat hjir dwaan. Wy freegje jo dêr om in befêstiging. diff --git a/config/locales/he.yml b/config/locales/he.yml index 33f57155f2..d987931f1e 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1077,6 +1077,14 @@ he: hint_html: עוד דבר אחד, עלינו לאשרר שאת(ה) אנושיים (לצורך סינון ספאם). נא לפתור את הקאפצ'ה להלן וללחוץ "המשך". title: בדיקות אבטחה confirmations: + awaiting_review: כתובת הדואל שלך אושרה! צוות %{domain} עכשיו יבדוק את הרשמתך. תשלח אליך הודעת דואל אם הצוות יאשר את החשבון! + awaiting_review_title: הרשמתך עוברת בדיקה + clicking_this_link: לחיצה על קישור זה + login_link: כניסה + proceed_to_login_html: ניתן להמשיך עכשיו אל %{login_link}. + redirect_to_app_html: כאן אמורה היתה להיות הפניה אוטמטית ליישומון %{app_name}. אם זה לא קרה, ניתן לנסות שוב על ידי %{clicking_this_link} או חזרה ידנית אל היישומון. + registration_complete: הרשמתך לשרת %{domain} הושלמה כעת! + welcome_title: ברוך/ה הבא/ה, %{name}! wrong_email_hint: אם כתובת הדואל הזו איננה נכונה, ניתן לשנות אותה בעמוד ההגדרות. delete_account: מחיקת חשבון delete_account_html: אם ברצונך למחוק את החשבון, ניתן להמשיך כאן. תתבקש/י לספק אישור נוסף. diff --git a/config/locales/hu.yml b/config/locales/hu.yml index 9d08786428..c01f38a9a9 100644 --- a/config/locales/hu.yml +++ b/config/locales/hu.yml @@ -1041,13 +1041,13 @@ hu: hint_html: Még egy dolog! Meg kell győződnünk róla, hogy tényleg valós személy vagy (így távol tarthatjuk a spam-et). Oldd meg az alábbi CAPTCHA-t és kattints a "Folytatás"-ra. title: Biztonsági ellenőrzés confirmations: - awaiting_review: Az email cím megerősítésre került. %{domain} stáb elenleg áttrkinti a regisztrációt. Ha jóváhagyásra kerül a fiók, egy email kerül kiküldésre! - awaiting_review_title: A regisztráció áttekintés alatt áll. + awaiting_review: Az email címed megerősítésre került. %{domain} stábja jelenleg áttekinti a regisztrációdat. Ha jóváhagyásra került a fiókod, egy emailt küldenek majd! + awaiting_review_title: A regisztrációd áttekintés alatt áll clicking_this_link: kattintás erre a hivatkozásra login_link: bejelentkezés - proceed_to_login_html: 'Most továbbléphetünk: %{login_link}.' - redirect_to_app_html: Át kellett volna kerülni %{app_name} alkalmazáshoz. Ha ez nem történt meg, próbálkozzunk %{clicking_this_link} lehetőséggel vagy térjünk vissza manuálisan az alkalmazáshoz. - registration_complete: A regisztráció %{domain} domainen befejeződött! + proceed_to_login_html: 'Most továbbléphetsz: %{login_link}.' + redirect_to_app_html: Át kellett volna irányítsunk a %{app_name} alkalmazáshoz. Ha ez nem történt meg, próbálkozz a %{clicking_this_link} lehetőséggel vagy térj vissza manuálisan az alkalmazáshoz. + registration_complete: A regisztrációd %{domain} domainen befejeződött! welcome_title: Üdvözlet, %{name}! wrong_email_hint: Ha az emailcím nem helyes, a fiókbeállításokban megváltoztathatod. delete_account: Felhasználói fiók törlése diff --git a/config/locales/is.yml b/config/locales/is.yml index a229f0af02..e0eb955699 100644 --- a/config/locales/is.yml +++ b/config/locales/is.yml @@ -1045,9 +1045,13 @@ is: Leystu Turing skynprófið og smelltu á "Áfram". title: Öryggisathugun confirmations: + awaiting_review: Tölvupóstfangið þitt er staðfest. Umsjónarfólk %{domain} er núna að yfirfara skráninguna þína. Þú munt fá tölvupóst ef þau samþykkja skráninguna þína! + awaiting_review_title: Verið er að yfirfara skráninguna þína clicking_this_link: smella á þennan tengil login_link: skrá þig inn proceed_to_login_html: Þú getur núna farið í að %{login_link}. + redirect_to_app_html: Þér ætti að hafa verið endurbeint í %{app_name} forritið. Ef það gerðist ekki, skaltu prófa að %{clicking_this_link} eða fara aftur í forritið. + registration_complete: Skráning þín á %{domain} er núna tilbúin! welcome_title: Velkomin/n %{name}! wrong_email_hint: Ef það tölvupóstfang er ekki rétt geturðu breytt því í stillingum notandaaðgangsins. delete_account: Eyða notandaaðgangi diff --git a/config/locales/it.yml b/config/locales/it.yml index 6e41389bc5..e62ea620c9 100644 --- a/config/locales/it.yml +++ b/config/locales/it.yml @@ -1043,6 +1043,14 @@ it: hint_html: Solamente un'altra cosa! Dobbiamo confermare che tu sia un essere umano (così possiamo tenere fuori lo spam!). Risolvi il CAPTCHA sottostante e fai clic su "Continua". title: Controllo di sicurezza confirmations: + awaiting_review: Il tuo indirizzo e-mail è confermato! Lo staff di %{domain} sta esaminando la tua registrazione. Riceverai una e-mail se il tuo account sarà approvato! + awaiting_review_title: La tua registrazione è in corso di revisione + clicking_this_link: cliccando su questo link + login_link: accedi + proceed_to_login_html: Ora puoi procedere con il %{login_link}. + redirect_to_app_html: Avresti dovuto essere reindirizzato all'app %{app_name}. Se ciò non fosse avvenuto, prova %{clicking_this_link} o torna manualmente all'app. + registration_complete: La tua registrazione su %{domain} è ora completata! + welcome_title: Benvenutə, %{name}! wrong_email_hint: Se l'indirizzo e-mail non è corretto, puoi modificarlo nelle impostazioni dell'account. delete_account: Elimina account delete_account_html: Se desideri cancellare il tuo account, puoi farlo qui. Ti sarà chiesta conferma. diff --git a/config/locales/nl.yml b/config/locales/nl.yml index f107cbeca1..d8a1c88656 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1041,6 +1041,14 @@ nl: hint_html: Nog maar één ding! Je moet bevestigen dat je een mens bent (dit is om de spam buiten de deur te houden!). Los de onderstaande CAPTCHA op en klik op "Doorgaan". title: Veiligheidscontrole confirmations: + awaiting_review: Je e-mailadres is bevestigd! De %{domain}-medewerkers zijn nu bezig met het bekijken van jouw registratie. Je ontvangt een e-mailbericht als ze jouw account goedkeuren! + awaiting_review_title: Je registratie wordt beoordeeld + clicking_this_link: klik op deze koppeling + login_link: aanmelden + proceed_to_login_html: Je kunt nu verder gaan naar %{login_link}. + redirect_to_app_html: Je zou omgeleid moeten zijn naar de %{app_name} app. Als dat niet is gebeurd, probeer dan %{clicking_this_link} of keer handmatig terug naar de app. + registration_complete: Je registratie op %{domain} is nu voltooid! + welcome_title: Welkom, %{name}! wrong_email_hint: Als dat e-mailadres niet correct is, kun je het wijzigen in je accountinstellingen. delete_account: Account verwijderen delete_account_html: Wanneer je jouw account graag wilt verwijderen, kun je dat hier doen. We vragen jou daar om een bevestiging. diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index da79c7555c..4e64f9cfd9 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1040,6 +1040,8 @@ pt-BR: hint_html: Só mais uma coisa! Precisamos confirmar que você é um humano (isso é para que possamos evitar o spam!). Resolva o CAPTCHA abaixo e clique em "Continuar". title: Verificação de segurança confirmations: + registration_complete: Seu cadastro no %{domain} foi concluído! + welcome_title: Boas vindas, %{name}! wrong_email_hint: Se esse endereço de e-mail não estiver correto, você pode alterá-lo nas configurações da conta. delete_account: Excluir conta delete_account_html: Se você deseja excluir sua conta, você pode fazer isso aqui. Uma confirmação será solicitada. diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml index 62b497d70b..a40ac02f4c 100644 --- a/config/locales/pt-PT.yml +++ b/config/locales/pt-PT.yml @@ -1041,6 +1041,14 @@ pt-PT: hint_html: Só mais uma coisa! Precisamos confirmar que você é um humano (isto para que possamos evitar spam!). Resolva o CAPTCHA abaixo e clique em "Continuar". title: Verificação de segurança confirmations: + awaiting_review: O seu endereço de correio eletrónico foi confirmado! A equipa %{domain} está agora a rever a sua inscrição. Receberá uma mensagem de correio eletrónico se aprovarem a sua conta! + awaiting_review_title: A sua inscrição está a ser revista + clicking_this_link: clicar nesta hiperligação + login_link: iniciar sessão + proceed_to_login_html: Pode agora prosseguir para %{login_link}. + redirect_to_app_html: Devia ter sido reencaminhado para a aplicação %{app_name}. Se isso não aconteceu, tente %{clicking_this_link} ou volte manualmente para a aplicação. + registration_complete: O seu registo sem %{domain} está agora concluído! + welcome_title: Bem-vindo(a), %{name}! wrong_email_hint: Se esse endereço de e-mail não estiver correto, você pode alterá-lo nas configurações da conta. delete_account: Eliminar conta delete_account_html: Se deseja eliminar a sua conta, pode continuar aqui. Uma confirmação será solicitada. diff --git a/config/locales/ru.yml b/config/locales/ru.yml index f9e526c4e8..945b190435 100644 --- a/config/locales/ru.yml +++ b/config/locales/ru.yml @@ -556,6 +556,7 @@ ru: total_reported: Жалобы на них total_storage: Медиафайлы totals_time_period_hint_html: Итоги, показанные ниже, включают данные за всё время. + unknown_instance: На данный момент нет записей об этом домене на этом сервере. invites: deactivate_all: Отключить все filter: @@ -1076,6 +1077,12 @@ ru: hint_html: Еще одна вещь! Нам нужно подтвердить, что вы человек (так что мы можем держать спам!). Решите капчу ниже и нажмите кнопку «Продолжить». title: Проверка безопасности confirmations: + awaiting_review: Ваш адрес электронной почты подтвержден! Сотрудники %{domain} проверяют вашу регистрацию. Вы получите письмо, если они подтвердят вашу учетную запись! + awaiting_review_title: Ваша регистрация проверяется + login_link: войти + proceed_to_login_html: Теперь вы можете перейти к %{login_link}. + registration_complete: Ваша регистрация на %{domain} завершена! + welcome_title: Добро пожаловать, %{name}! wrong_email_hint: Если этот адрес электронной почты неверен, вы можете изменить его в настройках аккаунта. delete_account: Удалить учётную запись delete_account_html: Удалить свою учётную запись можно в два счёта здесь, но прежде у вас будет спрошено подтверждение. @@ -1137,6 +1144,7 @@ ru: functional: Ваша учётная запись в полном порядке. pending: Ваша заявка ожидает одобрения администраторами, это может занять немного времени. Вы получите письмо, как только заявку одобрят. redirecting_to: Ваша учётная запись деактивированна, потому что вы настроили перенаправление на %{acct}. + self_destruct: Поскольку %{domain} закрывается, вы получите ограниченный доступ к вашей учетной записи. view_strikes: Просмотр предыдущих замечаний в адрес вашей учетной записи too_fast: Форма отправлена слишком быстро, попробуйте еще раз. use_security_key: Использовать ключ безопасности @@ -1622,6 +1630,8 @@ ru: over_daily_limit: Вы превысили лимит в %{limit} запланированных постов на указанный день over_total_limit: Вы превысили лимит на %{limit} запланированных постов too_soon: Запланированная дата должна быть в будущем + self_destruct: + title: Этот сервер закрывается sessions: activity: Последняя активность browser: Браузер diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 1cccb301d1..1d84f8a6af 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1043,8 +1043,9 @@ sv: confirmations: awaiting_review_title: Din registrering är under granskning clicking_this_link: klicka på denna länk + login_link: logga in registration_complete: Din registrering på %{domain} är nu slutförd! - welcome_title: Välkommen, %{name}! + welcome_title: Välkommen %{name}! wrong_email_hint: Om e-postadressen inte är rätt, kan du ändra den i kontoinställningarna. delete_account: Radera konto delete_account_html: Om du vill radera ditt konto kan du fortsätta här. Du kommer att bli ombedd att bekräfta. diff --git a/config/locales/th.yml b/config/locales/th.yml index d8ab63730b..33d8a898ed 100644 --- a/config/locales/th.yml +++ b/config/locales/th.yml @@ -1023,6 +1023,14 @@ th: hint_html: อีกเพียงหนึ่งสิ่งเพิ่มเติม! เราจำเป็นต้องยืนยันว่าคุณเป็นมนุษย์ (นี่ก็เพื่อให้เราสามารถกันสแปมออกไป!) แก้ CAPTCHA ด้านล่างและคลิก "ดำเนินการต่อ" title: การตรวจสอบความปลอดภัย confirmations: + awaiting_review: ยืนยันที่อยู่อีเมลของคุณแล้ว! ตอนนี้พนักงานของ %{domain} กำลังตรวจทานการลงทะเบียนของคุณ คุณจะได้รับอีเมลหากพนักงานอนุมัติบัญชีของคุณ! + awaiting_review_title: กำลังตรวจทานการลงทะเบียนของคุณ + clicking_this_link: คลิกลิงก์นี้ + login_link: เข้าสู่ระบบ + proceed_to_login_html: ตอนนี้คุณสามารถดำเนินการต่อเพื่อ %{login_link} + redirect_to_app_html: คุณควรได้รับการเปลี่ยนเส้นทางไปยังแอป %{app_name} หากนั่นไม่เกิดขึ้น ลอง %{clicking_this_link} หรือกลับไปยังแอปด้วยตนเอง + registration_complete: ตอนนี้การลงทะเบียนของคุณใน %{domain} เสร็จสมบูรณ์แล้ว! + welcome_title: ยินดีต้อนรับ %{name}! wrong_email_hint: หากที่อยู่อีเมลนั้นไม่ถูกต้อง คุณสามารถเปลี่ยนที่อยู่อีเมลได้ในการตั้งค่าบัญชี delete_account: ลบบัญชี delete_account_html: หากคุณต้องการลบบัญชีของคุณ คุณสามารถ ดำเนินการต่อที่นี่ คุณจะได้รับการถามเพื่อการยืนยัน diff --git a/config/locales/tr.yml b/config/locales/tr.yml index 86d153528b..c9adfd9132 100644 --- a/config/locales/tr.yml +++ b/config/locales/tr.yml @@ -1041,6 +1041,14 @@ tr: hint_html: Sadece bir şey daha! Sizin bir insan olduğunuzu doğrulamamız gerekiyor (bu, spam'i dışarıda tutabilmemiz içindir!). Aşağıdaki CAPTCHA'yı çözün ve "Devam Et" düğmesini tıklayın. title: Güvenlik denetimi confirmations: + awaiting_review: E-posta adresiniz doğrulandı! %{domain} çalışanları şimdi kaydınızı inceliyorlar. Hesabınızı onayladıklarında bir e-posta alacaksınız! + awaiting_review_title: Kaydınız inceleniyor + clicking_this_link: bu bağlantıyı tıklamayı + login_link: oturum aç + proceed_to_login_html: Şimdi %{login_link} devam edebilirsiniz. + redirect_to_app_html: "%{app_name} uygulamasına yönlendirileceksiniz. Eğer yönlendirme olmazsa, %{clicking_this_link} veya uygulamaya geri dönmeyi deneyin." + registration_complete: "%{domain} sunucusunda kaydınız şimdi tamamlandı!" + welcome_title: Hoşgeldin %{name}! wrong_email_hint: Eğer bu e-posta adresi doğru değilse, hesap ayarlarında değiştirebilirsiniz. delete_account: Hesabı sil delete_account_html: Hesabını silmek istersen, buradan devam edebilirsin. Onay istenir. diff --git a/config/locales/uk.yml b/config/locales/uk.yml index afa85ae67b..8069c76c6d 100644 --- a/config/locales/uk.yml +++ b/config/locales/uk.yml @@ -1077,6 +1077,14 @@ uk: hint_html: Ще одне! Ми повинні пересвідчитись, що ви людина (щоб ми могли уникнути спаму!). Розв'яжіть CAPTCHA внизу і натисніть кнопку "Продовжити". title: Перевірка безпеки confirmations: + awaiting_review: Ваша електронна адреса підтверджена! Співробітники %{domain} тепер переглядають вашу реєстрацію. Ви отримаєте електронного листа, якщо вони затвердять ваш обліковий запис! + awaiting_review_title: Ваша реєстрація розглядається + clicking_this_link: натисніть це посилання + login_link: увійти + proceed_to_login_html: Тепер ви можете перейти до %{login_link}. + redirect_to_app_html: Ви мали бути перенаправлені до програми %{app_name}. Якщо цього не сталося, спробуйте %{clicking_this_link} або вручну поверніться до програми. + registration_complete: Ваша реєстрація на %{domain} завершена! + welcome_title: Ласкаво просимо, %{name}! wrong_email_hint: Якщо ця адреса електронної пошти неправильна, можна змінити її в налаштуваннях облікового запису. delete_account: Видалити обліковий запис delete_account_html: Якщо ви хочете видалити свій обліковий запис, ви можете перейти сюди. Вас попросять підтвердити дію. From 37929b9707a8421a43da15d5629811688b29b4fc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 11:56:45 +0200 Subject: [PATCH 017/834] Update libretranslate/libretranslate Docker tag to v1.4.0 (#27504) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index 0369521963..f1945f8a64 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -70,7 +70,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.3.12 + image: libretranslate/libretranslate:v1.4.0 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local From 1f5187e2e28828c02c6c1ee1c00d6629836f8969 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 27 Oct 2023 05:57:16 -0400 Subject: [PATCH 018/834] Misc spec/refactor to user mailer and user mailer spec (#27486) --- .../admin/disputes/appeals_controller.rb | 2 +- app/mailers/user_mailer.rb | 62 +++++++++---------- config/i18n-tasks.yml | 1 + spec/mailers/user_mailer_spec.rb | 51 ++++++++++----- 4 files changed, 65 insertions(+), 51 deletions(-) diff --git a/app/controllers/admin/disputes/appeals_controller.rb b/app/controllers/admin/disputes/appeals_controller.rb index 32e5e2f6fd..5e342409b0 100644 --- a/app/controllers/admin/disputes/appeals_controller.rb +++ b/app/controllers/admin/disputes/appeals_controller.rb @@ -20,7 +20,7 @@ class Admin::Disputes::AppealsController < Admin::BaseController authorize @appeal, :approve? log_action :reject, @appeal @appeal.reject!(current_account) - UserMailer.appeal_rejected(@appeal.account.user, @appeal) + UserMailer.appeal_rejected(@appeal.account.user, @appeal).deliver_later redirect_to disputes_strike_path(@appeal.strike) end diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index 2889d13b53..2af2a3a41d 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -8,13 +8,15 @@ class UserMailer < Devise::Mailer helper :instance helper :statuses helper :formatting + helper :routing - helper RoutingHelper + before_action :set_instance + + default to: -> { @resource.email } def confirmation_instructions(user, token, *, **) @resource = user @token = token - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? @@ -28,185 +30,177 @@ class UserMailer < Devise::Mailer def reset_password_instructions(user, token, *, **) @resource = user @token = token - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.reset_password_instructions.subject') + mail subject: default_devise_subject end end def password_change(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.password_change.subject') + mail subject: default_devise_subject end end def email_changed(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.email_changed.subject') + mail subject: default_devise_subject end end def two_factor_enabled(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_enabled.subject') + mail subject: default_devise_subject end end def two_factor_disabled(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_disabled.subject') + mail subject: default_devise_subject end end def two_factor_recovery_codes_changed(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.two_factor_recovery_codes_changed.subject') + mail subject: default_devise_subject end end def webauthn_enabled(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_enabled.subject') + mail subject: default_devise_subject end end def webauthn_disabled(user, *, **) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_disabled.subject') + mail subject: default_devise_subject end end def webauthn_credential_added(user, webauthn_credential) @resource = user - @instance = Rails.configuration.x.local_domain @webauthn_credential = webauthn_credential return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.added.subject') + mail subject: I18n.t('devise.mailer.webauthn_credential.added.subject') end end def webauthn_credential_deleted(user, webauthn_credential) @resource = user - @instance = Rails.configuration.x.local_domain @webauthn_credential = webauthn_credential return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('devise.mailer.webauthn_credential.deleted.subject') + mail subject: I18n.t('devise.mailer.webauthn_credential.deleted.subject') end end def welcome(user) @resource = user - @instance = Rails.configuration.x.local_domain return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.welcome.subject') + mail subject: default_i18n_subject end end def backup_ready(user, backup) @resource = user - @instance = Rails.configuration.x.local_domain @backup = backup return unless @resource.active_for_authentication? I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.backup_ready.subject') + mail subject: default_i18n_subject end end def warning(user, warning) @resource = user @warning = warning - @instance = Rails.configuration.x.local_domain @statuses = @warning.statuses.includes(:account, :preloadable_poll, :media_attachments, active_mentions: [:account]) I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}") + mail subject: I18n.t("user_mailer.warning.subject.#{@warning.action}", acct: "@#{user.account.local_username_and_domain}") end end def appeal_approved(user, appeal) @resource = user - @instance = Rails.configuration.x.local_domain @appeal = appeal I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.appeal_approved.subject', date: l(@appeal.created_at)) + mail subject: default_i18n_subject(date: l(@appeal.created_at)) end end def appeal_rejected(user, appeal) @resource = user - @instance = Rails.configuration.x.local_domain @appeal = appeal I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.appeal_rejected.subject', date: l(@appeal.created_at)) + mail subject: default_i18n_subject(date: l(@appeal.created_at)) end end def suspicious_sign_in(user, remote_ip, user_agent, timestamp) @resource = user - @instance = Rails.configuration.x.local_domain @remote_ip = remote_ip @user_agent = user_agent @detection = Browser.new(user_agent) @timestamp = timestamp.to_time.utc I18n.with_locale(locale) do - mail to: @resource.email, subject: I18n.t('user_mailer.suspicious_sign_in.subject') + mail subject: default_i18n_subject end end private + def default_devise_subject + I18n.t(:subject, scope: ['devise.mailer', action_name]) + end + + def set_instance + @instance = Rails.configuration.x.local_domain + end + def locale @resource.locale.presence || I18n.default_locale end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml index 2d4487ce56..e2ea4153c9 100644 --- a/config/i18n-tasks.yml +++ b/config/i18n-tasks.yml @@ -64,6 +64,7 @@ ignore_unused: - 'statuses.attached.*' - 'move_handler.carry_{mutes,blocks}_over_text' - 'admin_mailer.*.subject' + - 'user_mailer.*.subject' - 'notification_mailer.*' - 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' - 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html' diff --git a/spec/mailers/user_mailer_spec.rb b/spec/mailers/user_mailer_spec.rb index 5affa66e07..c661f5bbda 100644 --- a/spec/mailers/user_mailer_spec.rb +++ b/spec/mailers/user_mailer_spec.rb @@ -5,7 +5,7 @@ require 'rails_helper' describe UserMailer do let(:receiver) { Fabricate(:user) } - describe 'confirmation_instructions' do + describe '#confirmation_instructions' do let(:mail) { described_class.confirmation_instructions(receiver, 'spec') } it 'renders confirmation instructions' do @@ -20,7 +20,7 @@ describe UserMailer do instance: Rails.configuration.x.local_domain end - describe 'reconfirmation_instructions' do + describe '#reconfirmation_instructions' do let(:mail) { described_class.confirmation_instructions(receiver, 'spec') } it 'renders reconfirmation instructions' do @@ -34,7 +34,7 @@ describe UserMailer do end end - describe 'reset_password_instructions' do + describe '#reset_password_instructions' do let(:mail) { described_class.reset_password_instructions(receiver, 'spec') } it 'renders reset password instructions' do @@ -47,7 +47,7 @@ describe UserMailer do 'devise.mailer.reset_password_instructions.subject' end - describe 'password_change' do + describe '#password_change' do let(:mail) { described_class.password_change(receiver) } it 'renders password change notification' do @@ -59,7 +59,7 @@ describe UserMailer do 'devise.mailer.password_change.subject' end - describe 'email_changed' do + describe '#email_changed' do let(:mail) { described_class.email_changed(receiver) } it 'renders email change notification' do @@ -71,7 +71,7 @@ describe UserMailer do 'devise.mailer.email_changed.subject' end - describe 'warning' do + describe '#warning' do let(:strike) { Fabricate(:account_warning, target_account: receiver.account, text: 'dont worry its just the testsuite', action: 'suspend') } let(:mail) { described_class.warning(receiver, strike) } @@ -82,7 +82,7 @@ describe UserMailer do end end - describe 'webauthn_credential_deleted' do + describe '#webauthn_credential_deleted' do let(:credential) { Fabricate(:webauthn_credential, user_id: receiver.id) } let(:mail) { described_class.webauthn_credential_deleted(receiver, credential) } @@ -95,7 +95,7 @@ describe UserMailer do 'devise.mailer.webauthn_credential.deleted.subject' end - describe 'suspicious_sign_in' do + describe '#suspicious_sign_in' do let(:ip) { '192.168.0.1' } let(:agent) { 'NCSA_Mosaic/2.0 (Windows 3.1)' } let(:timestamp) { Time.now.utc } @@ -110,7 +110,7 @@ describe UserMailer do 'user_mailer.suspicious_sign_in.subject' end - describe 'appeal_approved' do + describe '#appeal_approved' do let(:appeal) { Fabricate(:appeal, account: receiver.account, approved_at: Time.now.utc) } let(:mail) { described_class.appeal_approved(receiver, appeal) } @@ -120,7 +120,7 @@ describe UserMailer do end end - describe 'appeal_rejected' do + describe '#appeal_rejected' do let(:appeal) { Fabricate(:appeal, account: receiver.account, rejected_at: Time.now.utc) } let(:mail) { described_class.appeal_rejected(receiver, appeal) } @@ -130,7 +130,7 @@ describe UserMailer do end end - describe 'two_factor_enabled' do + describe '#two_factor_enabled' do let(:mail) { described_class.two_factor_enabled(receiver) } it 'renders two_factor_enabled mail' do @@ -139,7 +139,7 @@ describe UserMailer do end end - describe 'two_factor_disabled' do + describe '#two_factor_disabled' do let(:mail) { described_class.two_factor_disabled(receiver) } it 'renders two_factor_disabled mail' do @@ -148,7 +148,7 @@ describe UserMailer do end end - describe 'webauthn_enabled' do + describe '#webauthn_enabled' do let(:mail) { described_class.webauthn_enabled(receiver) } it 'renders webauthn_enabled mail' do @@ -157,7 +157,7 @@ describe UserMailer do end end - describe 'webauthn_disabled' do + describe '#webauthn_disabled' do let(:mail) { described_class.webauthn_disabled(receiver) } it 'renders webauthn_disabled mail' do @@ -166,7 +166,7 @@ describe UserMailer do end end - describe 'two_factor_recovery_codes_changed' do + describe '#two_factor_recovery_codes_changed' do let(:mail) { described_class.two_factor_recovery_codes_changed(receiver) } it 'renders two_factor_recovery_codes_changed mail' do @@ -175,7 +175,7 @@ describe UserMailer do end end - describe 'webauthn_credential_added' do + describe '#webauthn_credential_added' do let(:credential) { Fabricate.build(:webauthn_credential) } let(:mail) { described_class.webauthn_credential_added(receiver, credential) } @@ -184,4 +184,23 @@ describe UserMailer do expect(mail.body.encoded).to include I18n.t('devise.mailer.webauthn_credential.added.explanation') end end + + describe '#welcome' do + let(:mail) { described_class.welcome(receiver) } + + it 'renders welcome mail' do + expect(mail.subject).to eq I18n.t('user_mailer.welcome.subject') + expect(mail.body.encoded).to include I18n.t('user_mailer.welcome.explanation') + end + end + + describe '#backup_ready' do + let(:backup) { Fabricate(:backup) } + let(:mail) { described_class.backup_ready(receiver, backup) } + + it 'renders backup_ready mail' do + expect(mail.subject).to eq I18n.t('user_mailer.backup_ready.subject') + expect(mail.body.encoded).to include I18n.t('user_mailer.backup_ready.explanation') + end + end end From 13d310e64df9aee293d434eb68d541b9002ec2e9 Mon Sep 17 00:00:00 2001 From: Renaud Chaput Date: Fri, 27 Oct 2023 15:21:07 +0200 Subject: [PATCH 019/834] Simplify column headers (#27557) --- .../components/__tests__/button-test.jsx | 3 +- .../components/column_back_button.tsx | 25 -------- .../mastodon/components/column_header.jsx | 55 +++++++++------- .../mastodon/features/blocks/index.jsx | 4 +- .../mastodon/features/domain_blocks/index.jsx | 5 +- .../features/follow_requests/index.jsx | 4 +- .../mastodon/features/mutes/index.jsx | 4 +- .../features/pinned_statuses/index.jsx | 4 +- .../ui/components/__tests__/column-test.jsx | 8 ++- .../features/ui/components/column.jsx | 9 +-- .../features/ui/components/column_header.jsx | 41 ------------ app/javascript/mastodon/test_helpers.tsx | 62 +++++++++++++++++++ .../styles/mastodon/components.scss | 14 ----- 13 files changed, 113 insertions(+), 125 deletions(-) delete mode 100644 app/javascript/mastodon/features/ui/components/column_header.jsx create mode 100644 app/javascript/mastodon/test_helpers.tsx diff --git a/app/javascript/mastodon/components/__tests__/button-test.jsx b/app/javascript/mastodon/components/__tests__/button-test.jsx index ad7a0c49ca..f38ff6a7dd 100644 --- a/app/javascript/mastodon/components/__tests__/button-test.jsx +++ b/app/javascript/mastodon/components/__tests__/button-test.jsx @@ -1,6 +1,7 @@ -import { render, fireEvent, screen } from '@testing-library/react'; import renderer from 'react-test-renderer'; +import { render, fireEvent, screen } from 'mastodon/test_helpers'; + import { Button } from '../button'; describe('); + +}; + +BackButton.propTypes = { + pinned: PropTypes.bool, + show: PropTypes.bool, +}; + class ColumnHeader extends PureComponent { static contextTypes = { @@ -72,16 +102,6 @@ class ColumnHeader extends PureComponent { this.props.onMove(1); }; - handleBackClick = () => { - const { history } = this.props; - - if (history.location?.state?.fromMastodon) { - history.goBack(); - } else { - history.push('/'); - } - }; - handleTransitionEnd = () => { this.setState({ animating: false }); }; @@ -95,7 +115,7 @@ class ColumnHeader extends PureComponent { }; render () { - const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues, history } = this.props; + const { title, icon, iconComponent, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props; const { collapsed, animating } = this.state; const wrapperClassName = classNames('column-header__wrapper', { @@ -138,14 +158,7 @@ class ColumnHeader extends PureComponent { pinButton = ; } - if (!pinned && ((multiColumn && history.location?.state?.fromMastodon) || showBackButton)) { - backButton = ( - - ); - } + backButton = ; const collapsedContent = [ extraContent, diff --git a/app/javascript/mastodon/features/blocks/index.jsx b/app/javascript/mastodon/features/blocks/index.jsx index 21b7a263f1..615e4c8be2 100644 --- a/app/javascript/mastodon/features/blocks/index.jsx +++ b/app/javascript/mastodon/features/blocks/index.jsx @@ -10,7 +10,6 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/ import { debounce } from 'lodash'; import { fetchBlocks, expandBlocks } from '../../actions/blocks'; -import { ColumnBackButtonSlim } from '../../components/column_back_button'; import { LoadingIndicator } from '../../components/loading_indicator'; import ScrollableList from '../../components/scrollable_list'; import AccountContainer from '../../containers/account_container'; @@ -60,8 +59,7 @@ class Blocks extends ImmutablePureComponent { const emptyMessage = ; return ( - - + ; return ( - - - + - + ; return ( - - + - + ; + describe('', () => { describe(' click handler', () => { it('runs the scroll animation if the column contains scrollable content', () => { const scrollToMock = jest.fn(); const { container } = render( - +
, ); @@ -17,7 +19,7 @@ describe('', () => { }); it('does not try to scroll if there is no scrollable content', () => { - render(); + render(); fireEvent.click(screen.getByText('notifications')); }); }); diff --git a/app/javascript/mastodon/features/ui/components/column.jsx b/app/javascript/mastodon/features/ui/components/column.jsx index d667f42d99..b6c09b62cd 100644 --- a/app/javascript/mastodon/features/ui/components/column.jsx +++ b/app/javascript/mastodon/features/ui/components/column.jsx @@ -3,15 +3,15 @@ import { PureComponent } from 'react'; import { debounce } from 'lodash'; +import ColumnHeader from '../../../components/column_header'; import { isMobile } from '../../../is_mobile'; import { scrollTop } from '../../../scroll'; -import ColumnHeader from './column_header'; - export default class Column extends PureComponent { static propTypes = { heading: PropTypes.string, + alwaysShowBackButton: PropTypes.bool, icon: PropTypes.string, iconComponent: PropTypes.func, children: PropTypes.node, @@ -51,13 +51,14 @@ export default class Column extends PureComponent { }; render () { - const { heading, icon, iconComponent, children, active, hideHeadingOnMobile } = this.props; + const { heading, icon, iconComponent, children, active, hideHeadingOnMobile, alwaysShowBackButton } = this.props; const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth))); const columnHeaderId = showHeading && heading.replace(/ /g, '-'); + const header = showHeading && ( - + ); return (
{ - this.props.onClick(); - }; - - render () { - const { icon, iconComponent, type, active, columnHeaderId } = this.props; - let iconElement = ''; - - if (icon) { - iconElement = ; - } - - return ( -

- -

- ); - } - -} diff --git a/app/javascript/mastodon/test_helpers.tsx b/app/javascript/mastodon/test_helpers.tsx new file mode 100644 index 0000000000..6895895569 --- /dev/null +++ b/app/javascript/mastodon/test_helpers.tsx @@ -0,0 +1,62 @@ +import PropTypes from 'prop-types'; +import type { PropsWithChildren } from 'react'; +import { Component } from 'react'; + +import { IntlProvider } from 'react-intl'; + +import { MemoryRouter } from 'react-router'; + +// eslint-disable-next-line import/no-extraneous-dependencies +import { render as rtlRender } from '@testing-library/react'; + +class FakeIdentityWrapper extends Component< + PropsWithChildren<{ signedIn: boolean }> +> { + static childContextTypes = { + identity: PropTypes.shape({ + signedIn: PropTypes.bool.isRequired, + accountId: PropTypes.string, + disabledAccountId: PropTypes.string, + accessToken: PropTypes.string, + }).isRequired, + }; + + getChildContext() { + return { + identity: { + signedIn: this.props.signedIn, + accountId: '123', + accessToken: 'test-access-token', + }, + }; + } + + render() { + return this.props.children; + } +} + +function render( + ui: React.ReactElement, + { locale = 'en', signedIn = true, ...renderOptions } = {}, +) { + const Wrapper = (props: { children: React.ReactElement }) => { + return ( + + + + {props.children} + + + + ); + }; + return rtlRender(ui, { wrapper: Wrapper, ...renderOptions }); +} + +// re-export everything +// eslint-disable-next-line import/no-extraneous-dependencies +export * from '@testing-library/react'; + +// override render method +export { render }; diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index b8e6af0aaa..1e341680e0 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3137,20 +3137,6 @@ $ui-header-height: 55px; margin-inline-end: 5px; } -.column-back-button--slim { - position: relative; -} - -.column-back-button--slim-button { - cursor: pointer; - flex: 0 0 auto; - font-size: 16px; - padding: 15px; - position: absolute; - inset-inline-end: 0; - top: -50px; -} - .react-toggle { display: inline-block; position: relative; From 15ef654e9a9f81e6d2fc39b2f60397df5c9020ce Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 27 Oct 2023 15:43:00 +0200 Subject: [PATCH 020/834] Update dependency pundit to v2.3.1 (#27585) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 33e355a06b..5021800eba 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -532,7 +532,7 @@ GEM public_suffix (5.0.3) puma (6.4.0) nio4r (~> 2.0) - pundit (2.3.0) + pundit (2.3.1) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.7.1) From 08bdd5751e706080077041f89cfdc031434fa0c3 Mon Sep 17 00:00:00 2001 From: SouthFox <58982705+SouthFox-D@users.noreply.github.com> Date: Fri, 27 Oct 2023 22:03:21 +0800 Subject: [PATCH 021/834] Fix account click on detailed status (#27587) --- .../mastodon/features/status/components/detailed_status.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/status/components/detailed_status.jsx b/app/javascript/mastodon/features/status/components/detailed_status.jsx index baddc67310..d8d9559127 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.jsx +++ b/app/javascript/mastodon/features/status/components/detailed_status.jsx @@ -58,7 +58,7 @@ class DetailedStatus extends ImmutablePureComponent { handleAccountClick = (e) => { if (e.button === 0 && !(e.ctrlKey || e.metaKey) && this.props.history) { e.preventDefault(); - this.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); + this.props.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`); } e.stopPropagation(); From 93e4cdc31b69bb1f248e3e6b6811d93fe2522d4b Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 27 Oct 2023 16:04:51 +0200 Subject: [PATCH 022/834] Fix hashtag matching pattern matching some URLs (#27584) --- app/models/tag.rb | 2 +- spec/models/tag_spec.rb | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/app/models/tag.rb b/app/models/tag.rb index 413f6f5004..8fab98fb5c 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -35,7 +35,7 @@ class Tag < ApplicationRecord HASHTAG_LAST_SEQUENCE = '([[:word:]_]*[[:alpha:]][[:word:]_]*)' HASHTAG_NAME_PAT = "#{HASHTAG_FIRST_SEQUENCE}|#{HASHTAG_LAST_SEQUENCE}" - HASHTAG_RE = %r{(? Date: Fri, 27 Oct 2023 16:55:00 +0200 Subject: [PATCH 023/834] Have `Follow` activities bypass availability (#27586) Co-authored-by: Claire --- app/services/follow_service.rb | 2 +- app/workers/activitypub/delivery_worker.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/services/follow_service.rb b/app/services/follow_service.rb index feea40e3c0..1aa0241fe6 100644 --- a/app/services/follow_service.rb +++ b/app/services/follow_service.rb @@ -71,7 +71,7 @@ class FollowService < BaseService if @target_account.local? LocalNotificationWorker.perform_async(@target_account.id, follow_request.id, follow_request.class.name, 'follow_request') elsif @target_account.activitypub? - ActivityPub::DeliveryWorker.perform_async(build_json(follow_request), @source_account.id, @target_account.inbox_url) + ActivityPub::DeliveryWorker.perform_async(build_json(follow_request), @source_account.id, @target_account.inbox_url, { 'bypass_availability' => true }) end follow_request diff --git a/app/workers/activitypub/delivery_worker.rb b/app/workers/activitypub/delivery_worker.rb index 7c1c14766b..376c237a98 100644 --- a/app/workers/activitypub/delivery_worker.rb +++ b/app/workers/activitypub/delivery_worker.rb @@ -23,9 +23,10 @@ class ActivityPub::DeliveryWorker HEADERS = { 'Content-Type' => 'application/activity+json' }.freeze def perform(json, source_account_id, inbox_url, options = {}) - return unless DeliveryFailureTracker.available?(inbox_url) - @options = options.with_indifferent_access + + return unless @options[:bypass_availability] || DeliveryFailureTracker.available?(inbox_url) + @json = json @source_account = Account.find(source_account_id) @inbox_url = inbox_url From 2e6bf60f1549e5c1f1cfea2d614f978bea17b8a2 Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 27 Oct 2023 11:33:52 -0400 Subject: [PATCH 024/834] Use `deliveries.size` in mailer-related examples in controller specs (#27589) --- .../admin/disputes/appeals_controller_spec.rb | 12 ++++++------ spec/controllers/auth/sessions_controller_spec.rb | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/spec/controllers/admin/disputes/appeals_controller_spec.rb b/spec/controllers/admin/disputes/appeals_controller_spec.rb index 3f4175a281..4581d00d6f 100644 --- a/spec/controllers/admin/disputes/appeals_controller_spec.rb +++ b/spec/controllers/admin/disputes/appeals_controller_spec.rb @@ -33,8 +33,6 @@ RSpec.describe Admin::Disputes::AppealsController do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do - allow(UserMailer).to receive(:appeal_approved) - .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later: nil)) post :approve, params: { id: appeal.id } end @@ -47,7 +45,9 @@ RSpec.describe Admin::Disputes::AppealsController do end it 'notifies target account about approved appeal' do - expect(UserMailer).to have_received(:appeal_approved).with(target_account.user, appeal) + expect(UserMailer.deliveries.size).to eq(1) + expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) + expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_approved.subject', date: I18n.l(appeal.created_at))) end end @@ -55,8 +55,6 @@ RSpec.describe Admin::Disputes::AppealsController do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } before do - allow(UserMailer).to receive(:appeal_rejected) - .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later: nil)) post :reject, params: { id: appeal.id } end @@ -65,7 +63,9 @@ RSpec.describe Admin::Disputes::AppealsController do end it 'notifies target account about rejected appeal' do - expect(UserMailer).to have_received(:appeal_rejected).with(target_account.user, appeal) + expect(UserMailer.deliveries.size).to eq(1) + expect(UserMailer.deliveries.first.to.first).to eq(target_account.user.email) + expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.appeal_rejected.subject', date: I18n.l(appeal.created_at))) end end end diff --git a/spec/controllers/auth/sessions_controller_spec.rb b/spec/controllers/auth/sessions_controller_spec.rb index c727a76333..3ff9b15007 100644 --- a/spec/controllers/auth/sessions_controller_spec.rb +++ b/spec/controllers/auth/sessions_controller_spec.rb @@ -127,8 +127,6 @@ RSpec.describe Auth::SessionsController do before do allow_any_instance_of(ActionDispatch::Request).to receive(:remote_ip).and_return(current_ip) - allow(UserMailer).to receive(:suspicious_sign_in) - .and_return(instance_double(ActionMailer::MessageDelivery, deliver_later!: nil)) user.update(current_sign_in_at: 1.month.ago) post :create, params: { user: { email: user.email, password: user.password } } end @@ -142,7 +140,9 @@ RSpec.describe Auth::SessionsController do end it 'sends a suspicious sign-in mail' do - expect(UserMailer).to have_received(:suspicious_sign_in).with(user, current_ip, anything, anything) + expect(UserMailer.deliveries.size).to eq(1) + expect(UserMailer.deliveries.first.to.first).to eq(user.email) + expect(UserMailer.deliveries.first.subject).to eq(I18n.t('user_mailer.suspicious_sign_in.subject')) end end From eae5c7334ae61c463edd2e3cd03115b897f6e92b Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Fri, 27 Oct 2023 12:20:40 -0400 Subject: [PATCH 025/834] Extract class from CSP configuration/initialization (#26905) --- app/lib/content_security_policy.rb | 59 ++++++++ .../initializers/content_security_policy.rb | 21 +-- spec/lib/content_security_policy_spec.rb | 129 ++++++++++++++++++ 3 files changed, 192 insertions(+), 17 deletions(-) create mode 100644 app/lib/content_security_policy.rb create mode 100644 spec/lib/content_security_policy_spec.rb diff --git a/app/lib/content_security_policy.rb b/app/lib/content_security_policy.rb new file mode 100644 index 0000000000..e8fcf76a65 --- /dev/null +++ b/app/lib/content_security_policy.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class ContentSecurityPolicy + def base_host + Rails.configuration.x.web_domain + end + + def assets_host + url_from_configured_asset_host || url_from_base_host + end + + def media_host + cdn_host_value || assets_host + end + + private + + def url_from_configured_asset_host + Rails.configuration.action_controller.asset_host + end + + def cdn_host_value + s3_alias_host || s3_cloudfront_host || azure_alias_host || s3_hostname_host + end + + def url_from_base_host + host_to_url(base_host) + end + + def host_to_url(host_string) + uri_from_configuration_and_string(host_string) if host_string.present? + end + + def s3_alias_host + host_to_url ENV.fetch('S3_ALIAS_HOST', nil) + end + + def s3_cloudfront_host + host_to_url ENV.fetch('S3_CLOUDFRONT_HOST', nil) + end + + def azure_alias_host + host_to_url ENV.fetch('AZURE_ALIAS_HOST', nil) + end + + def s3_hostname_host + host_to_url ENV.fetch('S3_HOSTNAME', nil) + end + + def uri_from_configuration_and_string(host_string) + Addressable::URI.parse("#{host_protocol}://#{host_string}").tap do |uri| + uri.path += '/' unless uri.path.blank? || uri.path.end_with?('/') + end.to_s + end + + def host_protocol + Rails.configuration.x.use_https ? 'https' : 'http' + end +end diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index e5e672f2c7..8f8ea58028 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -6,24 +6,11 @@ # See the Securing Rails Applications Guide for more information: # https://guides.rubyonrails.org/security.html#content-security-policy-header -def host_to_url(str) - return if str.blank? +require_relative '../../app/lib/content_security_policy' - uri = Addressable::URI.parse("http#{Rails.configuration.x.use_https ? 's' : ''}://#{str}") - uri.path += '/' unless uri.path.blank? || uri.path.end_with?('/') - uri.to_s -end - -base_host = Rails.configuration.x.web_domain - -assets_host = Rails.configuration.action_controller.asset_host -assets_host ||= host_to_url(base_host) - -media_host = host_to_url(ENV['S3_ALIAS_HOST']) -media_host ||= host_to_url(ENV['S3_CLOUDFRONT_HOST']) -media_host ||= host_to_url(ENV['AZURE_ALIAS_HOST']) -media_host ||= host_to_url(ENV['S3_HOSTNAME']) if ENV['S3_ENABLED'] == 'true' -media_host ||= assets_host +policy = ContentSecurityPolicy.new +assets_host = policy.assets_host +media_host = policy.media_host def sso_host return unless ENV['ONE_CLICK_SSO_LOGIN'] == 'true' diff --git a/spec/lib/content_security_policy_spec.rb b/spec/lib/content_security_policy_spec.rb new file mode 100644 index 0000000000..2e92f815ac --- /dev/null +++ b/spec/lib/content_security_policy_spec.rb @@ -0,0 +1,129 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe ContentSecurityPolicy do + subject { described_class.new } + + around do |example| + original_asset_host = Rails.configuration.action_controller.asset_host + original_web_domain = Rails.configuration.x.web_domain + original_use_https = Rails.configuration.x.use_https + example.run + Rails.configuration.action_controller.asset_host = original_asset_host + Rails.configuration.x.web_domain = original_web_domain + Rails.configuration.x.use_https = original_use_https + end + + describe '#base_host' do + before { Rails.configuration.x.web_domain = 'host.example' } + + it 'returns the configured value for the web domain' do + expect(subject.base_host).to eq 'host.example' + end + end + + describe '#assets_host' do + context 'when asset_host is not configured' do + before { Rails.configuration.action_controller.asset_host = nil } + + context 'with a configured web domain' do + before { Rails.configuration.x.web_domain = 'host.example' } + + context 'when use_https is enabled' do + before { Rails.configuration.x.use_https = true } + + it 'returns value from base host with https protocol' do + expect(subject.assets_host).to eq 'https://host.example' + end + end + + context 'when use_https is disabled' do + before { Rails.configuration.x.use_https = false } + + it 'returns value from base host with http protocol' do + expect(subject.assets_host).to eq 'http://host.example' + end + end + end + end + + context 'when asset_host is configured' do + before do + Rails.configuration.action_controller.asset_host = 'https://assets.host.example' + end + + it 'returns full value from configured host' do + expect(subject.assets_host).to eq 'https://assets.host.example' + end + end + end + + describe '#media_host' do + context 'when there is no configured CDN' do + it 'defaults to using the assets_host value' do + expect(subject.media_host).to eq(subject.assets_host) + end + end + + context 'when an S3 alias host is configured' do + around do |example| + ClimateControl.modify S3_ALIAS_HOST: 'asset-host.s3-alias.example' do + example.run + end + end + + it 'uses the s3 alias host value' do + expect(subject.media_host).to eq 'https://asset-host.s3-alias.example' + end + end + + context 'when an S3 alias host with a trailing path is configured' do + around do |example| + ClimateControl.modify S3_ALIAS_HOST: 'asset-host.s3-alias.example/pathname' do + example.run + end + end + + it 'uses the s3 alias host value and preserves the path' do + expect(subject.media_host).to eq 'https://asset-host.s3-alias.example/pathname/' + end + end + + context 'when an S3 cloudfront host is configured' do + around do |example| + ClimateControl.modify S3_CLOUDFRONT_HOST: 'asset-host.s3-cloudfront.example' do + example.run + end + end + + it 'uses the s3 cloudfront host value' do + expect(subject.media_host).to eq 'https://asset-host.s3-cloudfront.example' + end + end + + context 'when an azure alias host is configured' do + around do |example| + ClimateControl.modify AZURE_ALIAS_HOST: 'asset-host.azure-alias.example' do + example.run + end + end + + it 'uses the azure alias host value' do + expect(subject.media_host).to eq 'https://asset-host.azure-alias.example' + end + end + + context 'when s3_enabled is configured' do + around do |example| + ClimateControl.modify S3_ENABLED: 'true', S3_HOSTNAME: 'asset-host.s3.example' do + example.run + end + end + + it 'uses the s3 hostname host value' do + expect(subject.media_host).to eq 'https://asset-host.s3.example' + end + end + end +end From 33f8c1c5eb075424eaba1263846efb09adfa89f5 Mon Sep 17 00:00:00 2001 From: Ricardo Trindade Date: Mon, 30 Oct 2023 15:04:12 +0100 Subject: [PATCH 026/834] Remove version check from update cache_concern.rb (#27592) --- app/controllers/concerns/cache_concern.rb | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/app/controllers/concerns/cache_concern.rb b/app/controllers/concerns/cache_concern.rb index 55ebe1bd64..2dfe5e263a 100644 --- a/app/controllers/concerns/cache_concern.rb +++ b/app/controllers/concerns/cache_concern.rb @@ -92,18 +92,10 @@ module CacheConcern arguments end - if Rails.gem_version >= Gem::Version.new('7.0') - def attributes_for_database(record) - attributes = record.attributes_for_database - attributes.transform_values! { |attr| attr.is_a?(::ActiveModel::Type::Binary::Data) ? attr.to_s : attr } - attributes - end - else - def attributes_for_database(record) - attributes = record.instance_variable_get(:@attributes).send(:attributes).transform_values(&:value_for_database) - attributes.transform_values! { |attr| attr.is_a?(::ActiveModel::Type::Binary::Data) ? attr.to_s : attr } - attributes - end + def attributes_for_database(record) + attributes = record.attributes_for_database + attributes.transform_values! { |attr| attr.is_a?(::ActiveModel::Type::Binary::Data) ? attr.to_s : attr } + attributes end def deserialize_record(class_name, attributes_from_database, new_record = false) # rubocop:disable Style/OptionalBooleanParameter From bf1d4529786d04527ae22055e22f7fe76a2b198a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:19:20 +0100 Subject: [PATCH 027/834] Update libretranslate/libretranslate Docker tag to v1.4.1 (#27616) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .devcontainer/docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml index f1945f8a64..137bebc599 100644 --- a/.devcontainer/docker-compose.yml +++ b/.devcontainer/docker-compose.yml @@ -70,7 +70,7 @@ services: hard: -1 libretranslate: - image: libretranslate/libretranslate:v1.4.0 + image: libretranslate/libretranslate:v1.4.1 restart: unless-stopped volumes: - lt-data:/home/libretranslate/.local From a918208ec61836f911bd9775d2f2dd6db72ac1a5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 15:19:25 +0100 Subject: [PATCH 028/834] New Crowdin Translations (automated) (#27596) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/he.json | 8 +-- config/locales/activerecord.he.yml | 2 +- config/locales/devise.he.yml | 24 ++++----- config/locales/es.yml | 4 ++ config/locales/fi.yml | 10 ++-- config/locales/he.yml | 2 +- config/locales/ko.yml | 12 ++--- config/locales/nl.yml | 12 ++--- config/locales/pl.yml | 8 +++ config/locales/simple_form.he.yml | 8 +-- config/locales/sl.yml | 70 +++++++++++++++++++++++++ config/locales/sq.yml | 8 +++ config/locales/sv.yml | 2 + config/locales/vi.yml | 8 +++ config/locales/zh-TW.yml | 2 +- 15 files changed, 140 insertions(+), 40 deletions(-) diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index 59cdb69a6c..c868655e15 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -202,7 +202,7 @@ "dismissable_banner.community_timeline": "אלו הם החצרוצים הציבוריים האחרונים מהמשתמשים על שרת {domain}.", "dismissable_banner.dismiss": "בטל", "dismissable_banner.explore_links": "אלו הקישורים האחרונים ששותפו על ידי משתמשים ששרת זה רואה ברשת המבוזרת כרגע.", - "dismissable_banner.explore_statuses": "ההודעות האלו, משרת זה ואחרים ברשת המבוזרת, צוברים חשיפה היום. הודעות חדשות יותר עם יותר הדהודים וחיבובים מדורגים יותר לגובה.", + "dismissable_banner.explore_statuses": "ההודעות האלו, משרת זה ואחרים ברשת המבוזרת, צוברים חשיפה היום. הודעות חדשות יותר עם יותר הדהודים וחיבובים מדורגים גבוה יותר.", "dismissable_banner.explore_tags": "התגיות האלו, משרת זה ואחרים ברשת המבוזרת, צוברות חשיפה כעת.", "dismissable_banner.public_timeline": "אלו ההודעות האחרונות שהתקבלו מהמשתמשים שנעקבים על ידי משתמשים מ־{domain}.", "embed.instructions": "ניתן להטמיע את ההודעה הזו באתרך ע\"י העתקת הקוד שלהלן.", @@ -315,7 +315,7 @@ "home.pending_critical_update.title": "יצא עדכון אבטחה חשוב!", "home.show_announcements": "הצג הכרזות", "interaction_modal.description.favourite": "עם חשבון מסטודון, ניתן לחבב את ההודעה כדי לומר למחבר/ת שהערכת את תוכנו או כדי לשמור אותו לקריאה בעתיד.", - "interaction_modal.description.follow": "עם חשבון מסטודון, ניתן לעקוב אחרי {name} כדי לקבל את הםוסטים שלו/ה בפיד הבית.", + "interaction_modal.description.follow": "עם חשבון מסטודון, ניתן לעקוב אחרי {name} כדי לקבל את הפוסטים שלו/ה בפיד הבית.", "interaction_modal.description.reblog": "עם חשבון מסטודון, ניתן להדהד את החצרוץ ולשתף עם עוקבים.", "interaction_modal.description.reply": "עם חשבון מסטודון, ניתן לענות לחצרוץ.", "interaction_modal.login.action": "קח אותי לדף הבית", @@ -493,7 +493,7 @@ "onboarding.steps.setup_profile.title": "התאמה אישית של הפרופיל", "onboarding.steps.share_profile.body": "ספרו לחברים איך למצוא אתכם במסטודון!", "onboarding.steps.share_profile.title": "לשתף פרופיל", - "onboarding.tips.2fa": "הידעת? ניתן לאבטח את החשבון ע\"י הקמת אימות בשני צעדים במסך מאפייני החשבון. השיטה תעבוד עם כל יישומון תואם TOTP על המגשיר שלך, אין צורך לתת לנו את מספר הטלפון!", + "onboarding.tips.2fa": "הידעת? ניתן לאבטח את החשבון ע\"י הקמת אימות דו-שלבי במסך מאפייני החשבון. השיטה תעבוד עם כל יישומון תואם TOTP על המכשיר שלך, ללא צורך במספר טלפון!", "onboarding.tips.accounts_from_other_servers": "הידעת? כיוון שמסטודון פועל ברשת מבוזרת, חלק מהפרופילים שתתקלו בהם פועלים משרתים אחרים משרת הבית שלכם. ניתן להיות איתם בקשר בצורה זהה לכל חשבון אחר! שם השרת שלהם הוא החלק השני של שם המשתמש שלהם!", "onboarding.tips.migration": "הידעת? אם תחליטו כי {domain} איננו שרת שמתאים לכם בעתיד, ניתן לעבור לשרת אחר מבלי לאבד עוקבים. תוכלו אפילו להקים שרת משלכן!", "onboarding.tips.verification": "הידעת? ניתן לאשרר את החשבון ע\"י קישור הפרופיל אל האתר שלכם ומהאתר חזרה לפרופיל. לא נדרשים תשלומים ומסמכים!", @@ -575,7 +575,7 @@ "report.thanks.title": "לא מעוניין/ת לראות את זה?", "report.thanks.title_actionable": "תודה על הדיווח, נבדוק את העניין.", "report.unfollow": "הפסיקו לעקוב אחרי @{name}", - "report.unfollow_explanation": "אתם עוקבים אחרי החשבון הזה. כדי להפסיק לראות את הפרסומים שלו בפיד הבית שלכם, הפסיקו לעקוב אחריהם.", + "report.unfollow_explanation": "אתם עוקבים אחרי החשבון הזה. כדי להפסיק לראות את הפרסומים שלו בפיד הבית שלכם, הפסיקו לעקוב אחריו.", "report_notification.attached_statuses": "{count, plural, one {הודעה מצורפת} two {הודעותיים מצורפות} many {{count} הודעות מצורפות} other {{count} הודעות מצורפות}}", "report_notification.categories.legal": "חוקי", "report_notification.categories.other": "שונות", diff --git a/config/locales/activerecord.he.yml b/config/locales/activerecord.he.yml index 54d0b0a1cc..211d984863 100644 --- a/config/locales/activerecord.he.yml +++ b/config/locales/activerecord.he.yml @@ -9,7 +9,7 @@ he: agreement: הסכם שירות email: כתובת דוא"ל locale: הגדרות אזוריות - password: סיסמא + password: סיסמה user/account: username: שם משתמש/ת user/invite_request: diff --git a/config/locales/devise.he.yml b/config/locales/devise.he.yml index 0f389bd383..e45f62b031 100644 --- a/config/locales/devise.he.yml +++ b/config/locales/devise.he.yml @@ -8,10 +8,10 @@ he: failure: already_authenticated: חשבון זה כבר מחובר. inactive: חשבון זה טרם הופעל. - invalid: "%{authentication_keys} או סיסמא לא נכונים." + invalid: "%{authentication_keys} או סיסמה לא נכונים." last_attempt: יש לך עוד ניסיון אחד לפני נעילת החשבון. locked: חשבון זה נעול. - not_found_in_database: "%{authentication_keys} או סיסמא לא נכונים." + not_found_in_database: "%{authentication_keys} או סיסמה לא נכונים." pending: חשבונך נמצא עדיין בבדיקה. timeout: פג תוקף השהיה בחשבון. נא להכנס מחדש על מנת להמשיך. unauthenticated: יש להרשם או להכנס לחשבון על מנת להמשיך. @@ -27,24 +27,24 @@ he: title: אימות כתובת דוא״ל email_changed: explanation: 'כתובת הדוא"ל של חשבונך שונתה ל:' - extra: אם לא שינית את כתובת הדוא"ל שלך, יכול להיות שמישהו השתלט על חשבונך. נא לשנות את הסיסמא מיידית או ליצור קשר עם מנהלי השרת אם ננעלת מחוץ לחשבון. + extra: אם לא שינית את כתובת הדוא"ל שלך, יכול להיות שמישהו השתלט על חשבונך. נא לשנות את הסיסמה שלך מיידית או ליצור קשר עם מנהלי השרת אם ננעלת מחוץ לחשבונך. subject: 'מסטודון: כתובת הדוא"ל שונתה' title: כתובת דוא״ל חדשה password_change: - explanation: הסיסמא לחשבונך שונתה. - extra: אם לא שינית את סיסמתך, יכול להיות שמישהו השתלט על חשבונך. נא לשנות את הסיסמא מיידית או ליצור קשר עם מנהלי השרת אם ננעלת מחוץ לחשבון. - subject: 'מסטודון: הסיסמא שונתה' - title: הסיסמא שונתה + explanation: הסיסמה לחשבונך שונתה. + extra: אם לא שינית את סיסמתך, יכול להיות שמישהו השתלט על חשבונך. נא לשנות את הסיסמה שלך מיידית או ליצור קשר עם מנהלי השרת אם ננעלת מחוץ לחשבונך. + subject: 'מסטודון: הסיסמה שונתה' + title: הסיסמה שונתה reconfirmation_instructions: explanation: נא לאמת את הכתובת הדוא"ל החדשה על מנת לשנותה. extra: אם שינוי זה לא בוצע על ידך, נא להתעלם מדוא"ל זה. כתובת הדוא"ל של חשבון המסטודון שלך לא תשונה אלא אם תלחץ הקישורית לעיל. subject: 'מסטודון: נא לאשר כתובת דוא"ל עבור %{instance}' title: אימות כתובת דוא״ל reset_password_instructions: - action: שינוי סיסמא - explanation: ביקשת סיסמא חדשה לחשבון. - extra: אם לא ביקשת את זה, נא להתעלם מדוא"ל זה. סיסמתך לא תשתנה עוד שתלחץ הקישורית לעיל ותיוצר סיסמא חדשה. - subject: 'מסטודון: הוראות לאיפוס סיסמא' + action: שינוי סיסמה + explanation: ביקשת סיסמה חדשה לחשבון שלך. + extra: אם לא ביקשת זאת, נא להתעלם מדוא"ל זה. סיסמתך לא תשתנה עוד שתלחץ הקישורית לעיל ותיוצר סיסמה חדשה. + subject: 'מסטודון: הוראות לאיפוס סיסמה' title: איפוס סיסמה two_factor_disabled: explanation: האימות הדו-גורמי לחשבונך בוטל. ניתן עתה להכנס לחשבון עם כתובת דוא"ל וסיסמא בלבד. @@ -81,7 +81,7 @@ he: failure: 'לא ניתן לאמת את חשבונך מ־%{kind} מהסיבה: "%{reason}".' success: נכשל אימות מחשבון %{kind}. passwords: - no_token: לא ניתן לגשת לעמוד זה, אלא מדוא"ל איפוס סיסמא. אם לא הגעת מדוא"ל איפוס סיסמא, יש לוודא שכתובת הקישורית הוקלדה בשלמותה. + no_token: לא ניתן לגשת לעמוד זה, אלא מדוא"ל איפוס סיסמה. אם הגעת מדוא"ל איפוס סיסמה, יש לוודא שכתובת הקישורית הוקלדה בשלמותה. send_instructions: בדקות הקרובות יתקבל דוא"ל עם הוראות לאיפוס סיסמתך. יש לבדוק את תיבת הספאם ליתר בטחון אם ההודעה לא הגיעה תוך דקות ספורות. send_paranoid_instructions: אם כתובת הדוא"ל שלך קיימת במסד הנתונים, יתקבל בדקות הקרובות דוא"ל עם הוראות לאחזור סיסמא. יש לבדוק את תיבת הספאם ליתר בטחון אם ההודעה לא הגיעה תוך דקות ספורות. updated: סיסמתך שונתה בהצלחה. הינך כעת במצב מחובר. diff --git a/config/locales/es.yml b/config/locales/es.yml index aab31747e7..d071e19a12 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -1044,7 +1044,11 @@ es: awaiting_review: "¡Tu dirección de correo electrónico ha sido confirmada! El personal de %{domain} está revisando tu registro. ¡Recibirás un correo electrónico cuando aprueben tu cuenta!" awaiting_review_title: Estamos revisando tu registro clicking_this_link: haciendo clic en este enlace + login_link: iniciar sesión + proceed_to_login_html: Ahora puedes proceder a %{login_link}. + redirect_to_app_html: Serás redirigido a la aplicación %{app_name}. Si esto no sucede, prueba %{clicking_this_link} o regresa manualmente a la aplicación. registration_complete: "¡Has completado tu registro en %{domain}!" + welcome_title: "¡Bienvenido, %{name}!" wrong_email_hint: Si esa dirección de correo electrónico no es correcta, puedes cambiarla en la configuración de la cuenta. delete_account: Borrar cuenta delete_account_html: Si desea eliminar su cuenta, puede proceder aquí. Será pedido de una confirmación. diff --git a/config/locales/fi.yml b/config/locales/fi.yml index 4b4585f690..0f670847f4 100644 --- a/config/locales/fi.yml +++ b/config/locales/fi.yml @@ -534,7 +534,7 @@ fi: total_reported: Niitä koskevat raportit total_storage: Medialiitteet totals_time_period_hint_html: Alla näkyvät yhteenlasketut tiedot sisältävät koko ajan. - unknown_instance: Tällä palvelimella ei ole tällä hetkellä tähän verkkotunnukseen liittyviä tietueita. + unknown_instance: Tällä palvelimella ei tällä hetkellä ole tähän verkkotunnukseen liittyviä tietueita. invites: deactivate_all: Poista kaikki käytöstä filter: @@ -1041,13 +1041,13 @@ fi: hint_html: Vielä yksi juttu! Meidän on vahvistettava, että olet ihminen (tämän avulla pidämme roskapostin poissa!). Ratkaise alla oleva CAPTCHA-vahvistus ja paina "Jatka". title: Turvatarkastus confirmations: - awaiting_review: Sähköpostiosoitteesi on vahvistettu! Palvelun %{domain} ylläpito tarkistaa nyt rekisteröitymisesi. Saat sähköpostiviestin, jos tilisi hyväksytään! + awaiting_review: Sähköpostiosoitteesi on vahvistettu! Seuraavaksi palvelimen %{domain} ylläpito tarkistaa rekisteröitymisesi ja saat lopuksi ilmoituksen sähköpostitse, jos tilisi hyväksytään! awaiting_review_title: Rekisteröitymisesi on tarkistettavana - clicking_this_link: napsauttaa tätä linkkiä + clicking_this_link: tästä linkistä login_link: kirjautumalla sisään proceed_to_login_html: Voit nyt jatkaa %{login_link}. - redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen %{app_name}. Jos näin ei tapahtunut, kokeile %{clicking_this_link} tai palaa sovellukseen manuaalisesti. - registration_complete: Rekisteröitymisesi palveluun %{domain} on nyt valmis! + redirect_to_app_html: Sinun olisi pitänyt ohjautua sovellukseen %{app_name}. Jos näin ei tapahtunut, yritä avata se %{clicking_this_link} tai palaa sovellukseen manuaalisesti. + registration_complete: Rekisteröitymisesi palvelimelle %{domain} on suoritettu! welcome_title: Tervetuloa, %{name}! wrong_email_hint: Jos sähköpostiosoite ei ole oikein, voit muuttaa sen tilin asetuksista. delete_account: Poista tili diff --git a/config/locales/he.yml b/config/locales/he.yml index d987931f1e..2bd9f89c71 100644 --- a/config/locales/he.yml +++ b/config/locales/he.yml @@ -1134,7 +1134,7 @@ he: new_confirmation_instructions_sent: אתם עומדים לקבל הודעת דואל חדשה עם קיש/ור אימות בדקות הקרובות! title: בדוק/בדקי את תיבת הדואר הנכנס שלך sign_in: - preamble_html: הכנס.י עם שם וסיסמא מאתר %{domain}. אם חשבונך מתארח בשרת אחר, לא ניתן להתחבר איתו פה. + preamble_html: הכנס.י עם שם וסיסמה מאתר %{domain}. אם חשבונך מתארח בשרת אחר, לא ניתן להתחבר איתו פה. title: התחבר אל %{domain} sign_up: manual_review: פתיחת חשבון אצל %{domain} עוברת בדיקה ידנית על ידי הצוות שלנו. כדי לסייע בתהליך הרישום שלכןם, כתבו לנו על עצמכןם ולמה אתןם רוצותים חשבון בשרת %{domain}. diff --git a/config/locales/ko.yml b/config/locales/ko.yml index 1bcc8853e5..dc1b0d1f49 100644 --- a/config/locales/ko.yml +++ b/config/locales/ko.yml @@ -1025,14 +1025,14 @@ ko: hint_html: 하나만 더! 당신이 사람인지 확인이 필요합니다 (스팸 계정을 거르기 위해서 필요한 과정입니다). 아래에 있는 CAPTCHA를 풀고 "계속"을 누르세요 title: 보안 체크 confirmations: - awaiting_review: 이메일 주소를 확인했어요! 이제 %{domain} 스태프가 가입을 검토해요. 계정이 승인되면 이메일을 보내드려요. - awaiting_review_title: 가입 검토 중 + awaiting_review: 이메일 주소가 확인되었습니다! 이제 %{domain} 스태프가 가입을 검토할 것입니다. 계정이 승인되면 이메일을 받게 됩니다! + awaiting_review_title: 가입 신청을 검토 중입니다 clicking_this_link: 이 링크를 클릭 login_link: 로그인 - proceed_to_login_html: "%{login_link} 할 수 있게 되었어요." - redirect_to_app_html: 곧 %{app_name}으로 리디렉션 되어요. 안 된다면, %{clicking_this_link}하거나 직접 앱으로 돌아가세요. - registration_complete: 지금 막 %{domain} 가입을 마쳤어요! - welcome_title: "%{name} 님 반가워요!" + proceed_to_login_html: 이제 %{login_link} 할 수 있습니다. + redirect_to_app_html: 곧 %{app_name}으로 리디렉션 됩니다. 안 된다면, %{clicking_this_link}하거나 직접 앱으로 돌아가세요. + registration_complete: 지금 막 %{domain} 가입이 완료되었습니다! + welcome_title: "%{name} 님 반갑습니다!" wrong_email_hint: 만약 이메일 주소가 올바르지 않다면, 계정 설정에서 수정할 수 있습니다. delete_account: 계정 삭제 delete_account_html: 계정을 삭제하고 싶은 경우, 여기서 삭제할 수 있습니다. 삭제 전 확인 화면이 표시됩니다. diff --git a/config/locales/nl.yml b/config/locales/nl.yml index d8a1c88656..2a8a59d764 100644 --- a/config/locales/nl.yml +++ b/config/locales/nl.yml @@ -1041,14 +1041,14 @@ nl: hint_html: Nog maar één ding! Je moet bevestigen dat je een mens bent (dit is om de spam buiten de deur te houden!). Los de onderstaande CAPTCHA op en klik op "Doorgaan". title: Veiligheidscontrole confirmations: - awaiting_review: Je e-mailadres is bevestigd! De %{domain}-medewerkers zijn nu bezig met het bekijken van jouw registratie. Je ontvangt een e-mailbericht als ze jouw account goedkeuren! + awaiting_review: Je e-mailadres is bevestigd! De medewerkers van %{domain} zijn nu bezig met het beoordelen van jouw registratie. Je ontvangt een e-mailbericht wanneer ze jouw account goedkeuren! awaiting_review_title: Je registratie wordt beoordeeld - clicking_this_link: klik op deze koppeling - login_link: aanmelden + clicking_this_link: op deze link te klikken + login_link: inloggen proceed_to_login_html: Je kunt nu verder gaan naar %{login_link}. redirect_to_app_html: Je zou omgeleid moeten zijn naar de %{app_name} app. Als dat niet is gebeurd, probeer dan %{clicking_this_link} of keer handmatig terug naar de app. registration_complete: Je registratie op %{domain} is nu voltooid! - welcome_title: Welkom, %{name}! + welcome_title: Welkom %{name}! wrong_email_hint: Als dat e-mailadres niet correct is, kun je het wijzigen in je accountinstellingen. delete_account: Account verwijderen delete_account_html: Wanneer je jouw account graag wilt verwijderen, kun je dat hier doen. We vragen jou daar om een bevestiging. @@ -1581,8 +1581,8 @@ nl: over_total_limit: Je hebt de limiet van %{limit} in te plannen berichten overschreden too_soon: De datum voor het ingeplande bericht moet in de toekomst liggen self_destruct: - lead_html: Helaas gaat %{domain} permanent afsluiten. Als u daar een account had, kunt u deze niet meer gebruiken, maar u kunt nog steeds een back-up van uw gegevens opvragen. - title: Deze server gaat afsluiten + lead_html: Helaas gaat %{domain} permanent sluiten. Als je daar een account had, kun je deze niet meer gebruiken, maar je kunt nog steeds een back-up van je gegevens opvragen. + title: Deze server gaat sluiten sessions: activity: Laatst actief browser: Webbrowser diff --git a/config/locales/pl.yml b/config/locales/pl.yml index 08df6e7fc9..e02cad0395 100644 --- a/config/locales/pl.yml +++ b/config/locales/pl.yml @@ -1077,6 +1077,14 @@ pl: hint_html: Jeszcze jedno! Potrzebujemy potwierdzić twoje człowieczeństwo, żeby ograniczyć spam. Rozwiąż poniższą CAPTCHA-ę i naciśnij "Kontynuuj". title: Kontrola bezpieczeństwa confirmations: + awaiting_review: Twój adres e-mail został potwierdzony! Administracja %{domain} sprawdza Twoją rejestrację. Otrzymasz e-mail w momencie, gdy zaakceptują Twoje konto! + awaiting_review_title: Twoja rejestracja jest obecnie sprawdzana + clicking_this_link: kliknąć ten link + login_link: zaloguj się + proceed_to_login_html: Teraz możesz przejść do %{login_link}. + redirect_to_app_html: Powinieneś zostać przekierowany do aplikacji %{app_name}. Jeśli tak się nie stało, spróbuj %{clicking_this_link} lub ręcznie wróć do aplikacji. + registration_complete: Twoja rejestracja na %{domain} została zakończona! + welcome_title: Witaj, %{name}! wrong_email_hint: Jeśli ten adres e-mail nie jest poprawny, możesz go zmienić w ustawieniach konta. delete_account: Usunięcie konta delete_account_html: Jeżeli chcesz usunąć konto, przejdź tutaj. Otrzymasz prośbę o potwierdzenie. diff --git a/config/locales/simple_form.he.yml b/config/locales/simple_form.he.yml index d8d47fee61..581a66807f 100644 --- a/config/locales/simple_form.he.yml +++ b/config/locales/simple_form.he.yml @@ -180,9 +180,9 @@ he: bot: זהו חשבון מסוג בוט chosen_languages: סינון שפות confirm_new_password: אישור סיסמא חדשה - confirm_password: אישור סיסמא + confirm_password: אישור סיסמה context: סינון לפי הקשר - current_password: סיסמא נוכחית + current_password: סיסמה נוכחית data: מידע display_name: שם להצגה email: כתובת דוא"ל @@ -194,10 +194,10 @@ he: irreversible: הסרה במקום הסתרה locale: שפה max_uses: מספר מרבי של שימושים - new_password: סיסמא חדשה + new_password: סיסמה חדשה note: אודות otp_attempt: קוד אימות דו-שלבי - password: סיסמא + password: סיסמה phrase: מילת מפתח או ביטוי setting_advanced_layout: אפשר ממשק ווב מתקדם setting_aggregate_reblogs: קבץ הדהודים זהים diff --git a/config/locales/sl.yml b/config/locales/sl.yml index 00c696f6fd..77ddfd6e2b 100644 --- a/config/locales/sl.yml +++ b/config/locales/sl.yml @@ -401,9 +401,11 @@ sl: cancel: Prekliči confirm: Suspendiraj permanent_action: Z razveljavitvijo suzpenza ne boste obnovili nobenih podatkov ali razmerij. + preamble_html: Suspendirali boste %{domain} in njene poddomene. remove_all_data: S tem boste odstranili celotno vsebino, medijske vsebine ter podatke iz profila za rčune te domene na vašem strežniku. stop_communication: Vaš strežnik bo prenehal komunicirati s temi strežniki. title: Potrdi domenski blok za %{domain} + undo_relationships: To bo prekinilo vse odnose sledenja med računi na teh strežnikih in na vašem strežniku. created_msg: Domenski blok se sedaj obdeluje destroyed_msg: Domenski blok je bil razveljavljen domain: Domena @@ -554,6 +556,7 @@ sl: total_reported: Prijave o njih total_storage: Predstavnostne priloge totals_time_period_hint_html: Spodaj prikazani seštevki vključujejo podatke za celotno obdobje. + unknown_instance: Trenutno ne obstaja zapis te domene na tem strežniku. invites: deactivate_all: Onemogoči vse filter: @@ -767,6 +770,9 @@ sl: branding: preamble: Blagovna znamka vašega strežnika ga loči od drugih strežnikov v omrežju. Podatki se lahko prikžejo prek številnih okolij, kot so spletni vmesnik Mastodona, domorodni programi, predogledi povezav na drugih spletiščih, aplikacije za sporočanje itn. Zatorej je najbolje, da te podatke ohranite jasne, kratke in pomenljive. title: Blagovne znamke + captcha_enabled: + desc_html: To se zanaša na zunanje skripte hCaptcha in lahko predstavlja tveganje za varnost in zasebnost. Poleg tega to lahko nekaterim ljudem (posebno invalidom) občutno oteži dostopnost registracijskega postopka. Zato svetujemo, da razmislite o drugih ukrepih, kot je na primer registracija na podlagi odobritve ali povabila. + title: Od novih uporabnikov zahtevaj reševanje CAPTCHA za potrditev računov content_retention: preamble: Nazdor nad hrambo vsebine uporabnikov v Mastodonu. title: Hramba vsebin @@ -795,13 +801,17 @@ sl: none: Nihče se ne more prijaviti open: Vsakdo se lahko prijavi security: + authorized_fetch: Od drugih strežnikov v federaciji zahtevaj overitev pristnosti + authorized_fetch_hint: Zahtevanje overitve pristnosti od drugih strežnikov v federaciji omogoči strožje uveljavljanje uporabniških in strežniških blokad. Vendar je cena za to počasnejše delovanje, zmanjšanje dosega vaših odgovorov in morebitne težave z združljivostjo z nekaterimi storitvami v federaciji. Poleg tega to odločenim akterjem ne bo preprečilo pridobivanja vaših javnih objav in računov. authorized_fetch_overridden_hint: Trenutno ne morete spremeniti te nastavitve, ker jo preglasi okoljska spremenljivka. + federation_authentication: Izvršba overitve pristnosti v federaciji title: Nastavitve strežnika site_uploads: delete: Izbriši naloženo datoteko destroyed_msg: Prenos na strežnik uspešno izbrisan! software_updates: critical_update: Kritično — čim prej posodobite + description: Vašo namestitev Mastodona je priporočeno vedno imeti posodobljeno in tako koristiti najnovejše popravke ter zmožnosti. Poleg tega je včasih nujno čim prej posodobiti Mastodon in se s tem izogniti varnostnim težavam. Zato Mastodon vsakih 30 minut preverja razpoložljivost posodobitev in vas o njih obvešča glede na vaše nastavitve obveščanja po e-pošti. documentation_link: Več o tem release_notes: Opombe ob izdaji title: Razpoložljive posodobitve @@ -851,10 +861,20 @@ sl: system_checks: database_schema_check: message_html: Na čakanju so migracije zbirke podatkov. Prosimo, izvedite jih, da zagotovite, da se program vede pričakovano + elasticsearch_health_red: + message_html: Z gručo Elasticsearch ni vse v redu (rdeče stanje), zmožnosti iskanja niso na voljo + elasticsearch_health_yellow: + message_html: Z gručo Elasticsearch ni vse v redu (rumeno stanje), priporočeno je ugotoviti razlog + elasticsearch_index_mismatch: + message_html: Preslikave kazala Elasticsearch so zastarele. Poženite tootctl search deploy --only=%{value} elasticsearch_preset: action: Glejte dokumentacijo + message_html: Vaša gruča Elasticsearch vsebuje več kot eno vozlišče, vendar Mastodon ni nastavljen, da bi jih uporabljal. elasticsearch_preset_single_node: action: Glejte dokumentacijo + message_html: Vaša gruča Elasticsearch vsebuje samo eno vozlišče, ES_PRESET bi moralo biti nastavljeno na single_node_cluster. + elasticsearch_reset_chewy: + message_html: Sistemsko kazalo Elasticsearch je zastarelo zaradi spremembe nastavitve. Za posodobitev poženite tootctl search deploy --reset-chewy. elasticsearch_running_check: message_html: Povezava z Elasticsearch ni uspela. Preverite, da deluje, ali onemogočite iskanje po vsem besedilu elasticsearch_version_check: @@ -867,6 +887,7 @@ sl: message_html: Noben proces Sidekiq ne poteka za %{value} vrst. Preglejte svojo prilagoditev Sidekiq software_version_critical_check: action: Glejte razpoložljive posodobitve + message_html: Na voljo je kritična posodobitev Mastodona. Posodobite čim prej. software_version_patch_check: action: Glejte razpoložljive posodobitve message_html: Na voljo je posodobitev Mastodona s popravki hroščev. @@ -991,6 +1012,9 @@ sl: body: "%{target} se pritožuje na moderatorsko odločitev %{action_taken_by} z dne %{date}, ki je bila %{type}. Zapisal/a je:" next_steps: Pritožbi lahko ugodite in s tem razveljavite moderatorsko odločitev ali pa jo prezrete. subject: "%{username} se je pritožil na moderatorsko odločitev na %{instance}" + new_critical_software_updates: + body: Izdane so bile nove kritične različice Mastodona. Priporočena je čimprejšnja posodobitev. + subject: Za %{instance} so na voljo kritične posodobitve Mastodona! new_pending_account: body: Podrobnosti o novem računu so navedene spodaj. To aplikacijo lahko odobrite ali zavrnete. subject: Nov račun za pregled na %{instance} (%{username}) @@ -998,6 +1022,9 @@ sl: body: "%{reporter} je prijavil %{target}" body_remote: Nekdo iz %{domain} je prijavil %{target} subject: Nove prijave za %{instance} (#%{id}) + new_software_updates: + body: Izdane so bile nove različice Mastodona. Priporočena je posodobitev. + subject: Za %{instance} so na voljo nove različice Mastodona. new_trends: body: 'Naslednji elementi potrebujejo pregled, preden jih je možno javno prikazati:' new_trending_links: @@ -1046,8 +1073,18 @@ sl: auth: apply_for_account: Zaprosite za račun captcha_confirmation: + help_html: Če imate težave pri reševanju CAPTCHA, lahko prek %{email} stopite v stik z nami in pomagali vam bomo. + hint_html: Samo še nekaj. Moramo se prepričati, da ste človek (to nam pomaga pri preprečevanju neželenih vsebin). Rešite spodnji CAPTCHA in kliknite »Nadaljuj«. title: Varnostno preverjanje confirmations: + awaiting_review: Vaš e-poštni naslov je potrjen. Skrbniki %{domain} bodo pregledali vašo prijavo. Če odobrijo vaš račun, boste o tem prejeli e-pošto. + awaiting_review_title: Vaša prijava se pregleduje + clicking_this_link: s klikom na to povezavo + login_link: prijavo + proceed_to_login_html: Sedaj lahko nadaljujete na %{login_link}. + redirect_to_app_html: Morali bi biti preusmerjeni na aplikacijo %{app_name}. Če se to ni zgodilo, poskusite %{clicking_this_link} ali pa se ročno vrnite na aplikacijo. + registration_complete: Vaša prijava na %{domain} je sedaj zaključena. + welcome_title: Pozdravljeni, %{name}! wrong_email_hint: Če ta e-poštni naslov ni pravilen, ga lahko spremenite v nastavitvah računa. delete_account: Izbriši račun delete_account_html: Če želite izbrisati svoj račun, lahko nadaljujete tukaj. Prosili vas bomo za potrditev. @@ -1083,7 +1120,9 @@ sl: rules: accept: Sprejmi back: Nazaj + invited_by: "%{domain} se lahko pridružite zahvaljujoč povabilu, ki ste ga prejeli od:" preamble: Slednje določajo in njihovo spoštovanje zagotavljajo moderatorji %{domain}. + preamble_invited: Preden nadaljujete, si preberite osnovna pravila, ki so jih postavili moderatorji na %{domain}. title: Nekaj osnovnih pravil. title_invited: Ste povabljeni. security: Varnost @@ -1107,6 +1146,7 @@ sl: functional: Vaš račun je polno opravilen. pending: Naše osebje preverja vašo prijavo. To lahko traja nekaj časa. Če bo vaša prijava odobrena, boste prejeli e-pošto. redirecting_to: Vaš račun ni dejaven, ker trenutno preusmerja na račun %{acct}. + self_destruct: Ker se %{domain} zapira, boste imeli omejen dostop da svojega računa. view_strikes: Pokaži pretekle ukrepe proti mojemu računu too_fast: Obrazec oddan prehitro, poskusite znova. use_security_key: Uporabi varnostni ključ @@ -1188,6 +1228,7 @@ sl: invalid_domain: ni veljavno ime domene edit_profile: basic_information: Osnovni podatki + hint_html: "Prilagodite, kaj ljudje vidijo na vašem javnem profilu in poleg vaših objav. Drugi vam bodo raje sledili nazaj in z vami klepetali, če boste imeli izpolnjen profil in nastavljeno profilno sliko." other: Drugo errors: '400': Zahteva, ki ste jo oddali, je neveljavna ali nepravilno oblikovana. @@ -1322,6 +1363,20 @@ sl: merge_long: Ohrani obstoječe zapise in dodaj nove overwrite: Prepiši overwrite_long: Zamenjaj trenutne zapise z novimi + overwrite_preambles: + blocking_html: Svoj seznam blokiranih računov boste nadomestili z največ %{total_items} računi iz %{filename}. + bookmarks_html: Svoje zaznamke boste nadomestili z največ %{total_items} objavami iz %{filename}. + domain_blocking_html: Svoj seznam blokiranih domen boste nadomestili z največ %{total_items} domenami iz %{filename}. + following_html: "Začeli boste slediti največ %{total_items} računom iz %{filename} in prenehali slediti vsem ostalim." + lists_html: Svoje sezname boste nadomestili z vsebino datoteke %{filename}. Največ %{total_items} računov bo dodanih na nove sezname. + muting_html: Svoj seznam utišanih računov boste nadomestili z največ %{total_items} računi iz %{filename}. + preambles: + blocking_html: "Blokirali boste največ %{total_items} računov iz %{filename}." + bookmarks_html: "Med zaznamke boste dodali boste največ %{total_items} objav iz %{filename}." + domain_blocking_html: "Blokirali boste največ %{total_items} domen iz %{filename}." + following_html: "Začeli boste slediti največ %{total_items} računom iz %{filename}." + lists_html: Dodali boste največ %{total_items} računov iz %{filename} na svoje sezname. Po potrebi bodo ustvarjeni novi seznami. + muting_html: "Utišali boste največ %{total_items} računov iz %{filename}." preface: Podatke, ki ste jih izvozili iz drugega strežnika, lahko uvozite. Na primer seznam oseb, ki jih spremljate ali blokirate. recent_imports: Nedavni uvozi states: @@ -1393,6 +1448,7 @@ sl: unsubscribe: action: Da, odjavi me complete: Odjavljeni + confirmation_html: Ali se res želite odjaviti od prejemanja %{type} za Mastodon na %{domain} na svojo e-pošto %{email}? Kadarkoli se lahko znova prijavite iz svojih nastavitev e-poštnih obvestil. emails: notification_emails: favourite: e-sporočil z obvestili o priljubljenosti @@ -1400,6 +1456,7 @@ sl: follow_request: e-sporočil o zahtevah za sledenje mention: e-sporočil z obvestili o omembah reblog: e-sporočil z obvestili o izpostavljanju + resubscribe_html: Če ste se odjavili po pomoti, se lahko znova prijavite iz svojih nastavitev e-poštnih obvestil. success_html: Nič več ne boste prejemali %{type} za Mastodon na %{domain} na svoj e-naslov %{email}. title: Odjavi od naročnine media_attachments: @@ -1526,9 +1583,13 @@ sl: posting_defaults: Privzete nastavitev objavljanja public_timelines: Javne časovnice privacy: + hint_html: "Prilagodite, kako lahko drugi najdejo vaš profil in vaše objave. V Mastodonu obstaja več zmožnosti, ki vam pomagajo doseči širše občinstvo, če so omogočene. Vzemite si čas in preverite, ali te nastavitve ustrezajo vašemu namenu uporabe." privacy: Zasebnost + privacy_hint_html: Nadzorujte, koliko informacij želite razkriti drugim. Ljudje lahko zanimive profile in aplikacije odkrijejo z brskanjem po seznamih sledenih in ko vidijo katere programe drugi uporabljajo za objavljanje. Morda pa bi to želeli skriti in varovati zasebnost. reach: Dosegljivost + reach_hint_html: Nadzorujte, ali želite, da vas drugi ljudje najdejo in vam pričnejo slediti. Ali želite, da se vaše objave prikažejo na strani Razišči? Ali želite, da vas drugi ljudje vidijo med predlogi za sledenje? Ali želite nove sledilce odobriti samodejno, ali vsakega posebej odobriti ročno? search: Iskanje + search_hint_html: Nadzorujte, kako želite, da vas najdejo. Ali želite, da vas ljudje najdejo po javnih objavah? Ali želite, da ljudje, ki niso na Mastodonu, lahko najdejo vaš profil med iskanjem po spletu? Vedite, da javnih objav in podatkov ni mogoče povsem izvzeti iz podatkovnih zbirk vseh spletnih iskalnikov. title: Zasebnost in dosegljivost privacy_policy: title: Pravilnik o zasebnosti @@ -1571,6 +1632,9 @@ sl: over_daily_limit: Za ta dan ste presegli omejitev %{limit} načrtovanih objav over_total_limit: Presegli ste omejitev %{limit} načrtovanih objav too_soon: Načrtovani datum mora biti v prihodnosti + self_destruct: + lead_html: Na žalost se %{domain} za vedno zapira. Če ste tu imeli svoj račun, ga v prihodnje ne boste mogli več uporabljati. Zahtevate lahko kopijo svojih podatkov. + title: Ta strežnik se zapira sessions: activity: Zadnja dejavnost browser: Brskalnik @@ -1752,6 +1816,10 @@ sl: month: "%b %Y" time: "%H:%M" with_time_zone: "%d. %b. %Y %H:%M %Z" + translation: + errors: + quota_exceeded: Kvota uporabe prevajalne storitve za ta strežnik je bila presežena. + too_many_requests: V zadnjem času je prevajalna storitev prejela preveč zahtevkov. two_factor_authentication: add: Dodaj disable: Onemogoči @@ -1837,7 +1905,9 @@ sl: seamless_external_login: Prijavljeni ste prek zunanje storitve, tako da nastavitve gesla in e-pošte niso na voljo. signed_in_as: 'Vpisani kot:' verification: + extra_instructions_html: Nasvet: Povezava na vaši spletni strani je lahko nevidna. Pomembni del je atribut rel="me", ki preprečuje lažno predstavljanje na spletnih straneh z uporabniško ustvarjeno vsebino. Namesto oznake a lahko uporabite tudi oznako link znotraj glave (head) spletne strani, vendar mora biti HTML dosegljiv brez izvajanja skript JavaScript. here_is_how: Kako to poteka + hint_html: "Vsakdo lahko potrdi svojo istovetnost na Mastodonu. To temelji na odprtih spletnih standardih in je sedaj in za vedno brezplačno. Potrebujete le osebno spletno stran, po kateri vas ljudje prepoznajo. Ko na svoj profil dodate povezavo na to osebno spletno stran, bo Mastodon preveril, ali na njej obstaja povezava nazaj na profil. Če ta obstaja, bo to vidno na profiu." instructions_html: Spodnjo kodo kopirajte in prilepite v HTML svojega spletnega mesta. Nato dodajte naslov svoje spletne strani v eno od dodatnih polj v svojem profilu v zavihku »Uredi profil« in shranite spremembe. verification: Potrditev verified_links: Vaše preverjene povezave diff --git a/config/locales/sq.yml b/config/locales/sq.yml index 74810b147a..e4fb811ce3 100644 --- a/config/locales/sq.yml +++ b/config/locales/sq.yml @@ -1035,6 +1035,14 @@ sq: hint_html: Edhe një gjë tjetër! Na duhet të ripohoni se jeni qenie njerëzore (që të mbajmë larg mesazhe të padëshiruar!). Zgjidhni CAPTCHA-n më poshtë dhe klikoni mbi “Vazhdo”. title: Kontroll sigurie confirmations: + awaiting_review: Adresa juaj email u ripohua! Ekipi i %{domain} stani po bën regjistrimin tuaj. Nëse e miratojnë llogarinë tuaj, do të merrni një email! + awaiting_review_title: Regjistrimi juaj po merret në shqyrtim + clicking_this_link: duke klikuar këtë lidhje + login_link: hyni + proceed_to_login_html: Tani mund të vazhdoni të %{login_link}. + redirect_to_app_html: Duhet të ishit ridrejtuar te aplikacioni %{app_name}. Nëse s’ndodhi, provoni %{clicking_this_link}, ose të ktheheni dorazi te aplikacioni. + registration_complete: Tanimë është plotësuar regjistrimi juaj në %{domain}! + welcome_title: Mirë se vini, %{name}! wrong_email_hint: Nëse ajo adresë email s’është e saktë, mund ta ndryshoni te rregullimet e llogarisë. delete_account: Fshije llogarinë delete_account_html: Nëse dëshironi të fshihni llogarinë tuaj, mund ta bëni që këtu. Do t’ju kërkohet ta ripohoni. diff --git a/config/locales/sv.yml b/config/locales/sv.yml index 1d84f8a6af..a6ee12ba27 100644 --- a/config/locales/sv.yml +++ b/config/locales/sv.yml @@ -1044,6 +1044,8 @@ sv: awaiting_review_title: Din registrering är under granskning clicking_this_link: klicka på denna länk login_link: logga in + proceed_to_login_html: Du kan nu fortsätta med att %{login_link}. + redirect_to_app_html: Du borde ha omdirigerats till appen %{app_name}. Om det inte hände, försök att %{clicking_this_link} eller återgå manuellt till appen. registration_complete: Din registrering på %{domain} är nu slutförd! welcome_title: Välkommen %{name}! wrong_email_hint: Om e-postadressen inte är rätt, kan du ändra den i kontoinställningarna. diff --git a/config/locales/vi.yml b/config/locales/vi.yml index 79ec13571d..ec8f6c1395 100644 --- a/config/locales/vi.yml +++ b/config/locales/vi.yml @@ -1023,6 +1023,14 @@ vi: hint_html: Còn một xíu nữa! Chúng tôi cần xác minh bạn là con người (để chúng tôi có thể ngăn chặn thư rác!). Nhập CAPTCHA bên dưới và nhấn "Tiếp tục". title: Kiểm tra an toàn confirmations: + awaiting_review: Đã xác minh email của bạn! Kiểm duyệt viên %{domain} đang xem xét đăng ký của bạn. Bạn sẽ nhận được một email nếu tài khoản của bạn được duyệt! + awaiting_review_title: Đăng ký của bạn đang chờ duyệt + clicking_this_link: nhấn vào link này + login_link: đăng nhập + proceed_to_login_html: Bạn có thể tiếp tục %{login_link}. + redirect_to_app_html: Bạn đã có thể chuyển tiếp tới %{app_name}. Nếu không có gì xảy ra, thử %{clicking_this_link} hoặc tự quay lại app. + registration_complete: Hoàn tất đăng ký trên %{domain}! + welcome_title: Chào mừng, %{name}! wrong_email_hint: Nếu địa chỉ email đó không chính xác, bạn có thể thay đổi nó trong cài đặt tài khoản. delete_account: Xóa tài khoản delete_account_html: Nếu bạn muốn xóa tài khoản của mình, hãy yêu cầu tại đây. Bạn sẽ được yêu cầu xác nhận. diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml index 9d75f50a50..7bcc133964 100644 --- a/config/locales/zh-TW.yml +++ b/config/locales/zh-TW.yml @@ -1027,7 +1027,7 @@ zh-TW: confirmations: awaiting_review: 已驗證您的電子郵件!%{domain} 的管理員正在審核您的註冊申請。若您的帳號通過審核,您將收到電子郵件通知。 awaiting_review_title: 我們正在審核您的註冊申請 - clicking_this_link: 點擊這個連結 + clicking_this_link: 點擊此連結 login_link: 登入 proceed_to_login_html: 您現在可以前往 %{login_link}。 redirect_to_app_html: 您應被重新導向至 %{app_name} 應用程式。如尚未重新導向,請嘗試 %{clicking_this_link} 或手動回到應用程式。 From c2cc1df5efd174677ab4ecd4002735c315d6dadc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:30:02 +0100 Subject: [PATCH 029/834] Update dependency @types/react to v18.2.33 (#27615) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 44abf3f61d..9bf6fba3d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2512,9 +2512,9 @@ "@types/react" "*" "@types/react@*", "@types/react@16 || 17 || 18", "@types/react@>=16.9.11", "@types/react@^18.0.26", "@types/react@^18.2.7": - version "18.2.31" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.31.tgz#74ae2630e4aa9af599584157abd3b95d96fb9b40" - integrity sha512-c2UnPv548q+5DFh03y8lEDeMfDwBn9G3dRwfkrxQMo/dOtRHUUO57k6pHvBIfH/VF4Nh+98mZ5aaSe+2echD5g== + version "18.2.33" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.33.tgz#055356243dc4350a9ee6c6a2c07c5cae12e38877" + integrity sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" From 547d3c1b9bf569f83d43faa4ac2c908b09bae5d3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:30:26 +0100 Subject: [PATCH 030/834] Update dependency core-js to v3.33.2 (#27624) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9bf6fba3d4..c398aef27e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4411,9 +4411,9 @@ core-js@^2.5.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.30.2: - version "3.33.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.1.tgz#ef3766cfa382482d0a2c2bc5cb52c6d88805da52" - integrity sha512-qVSq3s+d4+GsqN0teRCJtM6tdEEXyWxjzbhVrCHmBS5ZTM0FS2MOS0D13dUXAWDUN6a+lHI/N1hF9Ytz6iLl9Q== + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" + integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== core-util-is@~1.0.0: version "1.0.3" From 372494e553a841ad6753eac066b171f32e087e30 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:31:22 +0100 Subject: [PATCH 031/834] Update dependency punycode to v2.3.1 (#27625) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index c398aef27e..dfd1991147 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10075,9 +10075,9 @@ punycode@1.4.1, punycode@^1.2.4, punycode@^1.4.1: integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== pure-rand@^6.0.0: version "6.0.2" From b8adb08f92fde81d22fa70860bc5704d0272c4ec Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 30 Oct 2023 23:31:32 +0100 Subject: [PATCH 032/834] Update dependency axios to v1.6.0 (#27580) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index dfd1991147..7ca344e6dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3410,9 +3410,9 @@ axe-core@^4.6.2: integrity sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g== axios@^1.4.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.5.1.tgz#11fbaa11fc35f431193a9564109c88c1f27b585f" - integrity sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A== + version "1.6.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" + integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" From 6c52f8286b335248162035acf86635c63cfc9222 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 30 Oct 2023 23:32:25 +0100 Subject: [PATCH 033/834] Fix posts from force-sensitized accounts being able to trend (#27620) --- app/models/trends/statuses.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/trends/statuses.rb b/app/models/trends/statuses.rb index 427fa8e797..c47fb8427b 100644 --- a/app/models/trends/statuses.rb +++ b/app/models/trends/statuses.rb @@ -106,7 +106,7 @@ class Trends::Statuses < Trends::Base private def eligible?(status) - status.public_visibility? && status.account.discoverable? && !status.account.silenced? && status.spoiler_text.blank? && !status.sensitive? && !status.reply? && valid_locale?(status.language) + status.public_visibility? && status.account.discoverable? && !status.account.silenced? && !status.account.sensitized? && status.spoiler_text.blank? && !status.sensitive? && !status.reply? && valid_locale?(status.language) end def calculate_scores(statuses, at_time) From beee9ea9915f8ef93e35ace45b9fcc34e9dc5f4d Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 31 Oct 2023 04:22:19 -0400 Subject: [PATCH 034/834] Fix `RSpec/LetSetup` cop in spec/controllers/admin area (#27619) --- .rubocop_todo.yml | 5 ----- .../admin/accounts_controller_spec.rb | 5 ++++- .../admin/action_logs_controller_spec.rb | 4 ++-- .../admin/instances_controller_spec.rb | 4 ++-- .../admin/reports/actions_controller_spec.rb | 18 ++++++++++++------ .../admin/statuses_controller_spec.rb | 7 ++++--- 6 files changed, 24 insertions(+), 19 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 9609923434..6409181601 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -130,11 +130,6 @@ RSpec/InstanceVariable: RSpec/LetSetup: Exclude: - - 'spec/controllers/admin/accounts_controller_spec.rb' - - 'spec/controllers/admin/action_logs_controller_spec.rb' - - 'spec/controllers/admin/instances_controller_spec.rb' - - 'spec/controllers/admin/reports/actions_controller_spec.rb' - - 'spec/controllers/admin/statuses_controller_spec.rb' - 'spec/controllers/api/v1/accounts/statuses_controller_spec.rb' - 'spec/controllers/api/v1/filters_controller_spec.rb' - 'spec/controllers/api/v2/admin/accounts_controller_spec.rb' diff --git a/spec/controllers/admin/accounts_controller_spec.rb b/spec/controllers/admin/accounts_controller_spec.rb index 782e460a42..b57ec67141 100644 --- a/spec/controllers/admin/accounts_controller_spec.rb +++ b/spec/controllers/admin/accounts_controller_spec.rb @@ -285,7 +285,10 @@ RSpec.describe Admin::AccountsController do let(:current_user) { Fabricate(:user, role: role) } let(:account) { Fabricate(:account, suspended: true) } - let!(:email_block) { Fabricate(:canonical_email_block, reference_account: account) } + + before do + _email_block = Fabricate(:canonical_email_block, reference_account: account) + end context 'when user is admin' do let(:role) { UserRole.find_by(name: 'Admin') } diff --git a/spec/controllers/admin/action_logs_controller_spec.rb b/spec/controllers/admin/action_logs_controller_spec.rb index 044ddf2c42..b7854469dd 100644 --- a/spec/controllers/admin/action_logs_controller_spec.rb +++ b/spec/controllers/admin/action_logs_controller_spec.rb @@ -8,8 +8,8 @@ describe Admin::ActionLogsController do # Action logs typically cause issues when their targets are not in the database let!(:account) { Fabricate(:account) } - let!(:orphaned_logs) do - %w( + before do + _orphaned_logs = %w( Account User UserRole Report DomainBlock DomainAllow EmailDomainBlock UnavailableDomain Status AccountWarning Announcement IpBlock Instance CustomEmoji CanonicalEmailBlock Appeal diff --git a/spec/controllers/admin/instances_controller_spec.rb b/spec/controllers/admin/instances_controller_spec.rb index 5fed5d98d2..74d69d1aaa 100644 --- a/spec/controllers/admin/instances_controller_spec.rb +++ b/spec/controllers/admin/instances_controller_spec.rb @@ -8,10 +8,10 @@ RSpec.describe Admin::InstancesController do let(:current_user) { Fabricate(:user, role: UserRole.find_by(name: 'Admin')) } let!(:account_popular_main) { Fabricate(:account, domain: 'popular') } - let!(:account_popular_other) { Fabricate(:account, domain: 'popular') } - let!(:account_less_popular) { Fabricate(:account, domain: 'less.popular') } before do + _account_less_popular = Fabricate(:account, domain: 'less.popular') + _account_popular_other = Fabricate(:account, domain: 'popular') sign_in current_user, scope: :user end diff --git a/spec/controllers/admin/reports/actions_controller_spec.rb b/spec/controllers/admin/reports/actions_controller_spec.rb index 1f3951516d..06d4b31f54 100644 --- a/spec/controllers/admin/reports/actions_controller_spec.rb +++ b/spec/controllers/admin/reports/actions_controller_spec.rb @@ -54,13 +54,16 @@ describe Admin::Reports::ActionsController do describe 'POST #create' do let(:target_account) { Fabricate(:account) } let(:statuses) { [Fabricate(:status, account: target_account), Fabricate(:status, account: target_account)] } - let!(:media) { Fabricate(:media_attachment, account: target_account, status: statuses[0]) } let(:report) { Fabricate(:report, target_account: target_account, status_ids: statuses.map(&:id)) } let(:text) { 'hello' } let(:common_params) do { report_id: report.id, text: text } end + before do + _media = Fabricate(:media_attachment, account: target_account, status: statuses[0]) + end + shared_examples 'common behavior' do it 'closes the report and redirects' do expect { subject }.to mark_report_action_taken.and create_target_account_strike @@ -122,14 +125,17 @@ describe Admin::Reports::ActionsController do let(:action) { 'mark_as_sensitive' } let(:statuses) { [media_attached_status, media_attached_deleted_status] } - let!(:status) { Fabricate(:status, account: target_account) } let(:media_attached_status) { Fabricate(:status, account: target_account) } - let!(:media_attachment) { Fabricate(:media_attachment, account: target_account, status: media_attached_status) } let(:media_attached_deleted_status) { Fabricate(:status, account: target_account, deleted_at: 1.day.ago) } - let!(:media_attachment2) { Fabricate(:media_attachment, account: target_account, status: media_attached_deleted_status) } let(:last_media_attached_status) { Fabricate(:status, account: target_account) } - let!(:last_media_attachment) { Fabricate(:media_attachment, account: target_account, status: last_media_attached_status) } - let!(:last_status) { Fabricate(:status, account: target_account) } + + before do + _last_media_attachment = Fabricate(:media_attachment, account: target_account, status: last_media_attached_status) + _last_status = Fabricate(:status, account: target_account) + _media_attachment = Fabricate(:media_attachment, account: target_account, status: media_attached_status) + _media_attachment2 = Fabricate(:media_attachment, account: target_account, status: media_attached_deleted_status) + _status = Fabricate(:status, account: target_account) + end it_behaves_like 'common behavior' diff --git a/spec/controllers/admin/statuses_controller_spec.rb b/spec/controllers/admin/statuses_controller_spec.rb index 9befdf978f..dc5e28e972 100644 --- a/spec/controllers/admin/statuses_controller_spec.rb +++ b/spec/controllers/admin/statuses_controller_spec.rb @@ -9,13 +9,14 @@ describe Admin::StatusesController do let(:account) { Fabricate(:account) } let!(:status) { Fabricate(:status, account: account) } let(:media_attached_status) { Fabricate(:status, account: account, sensitive: !sensitive) } - let!(:media_attachment) { Fabricate(:media_attachment, account: account, status: media_attached_status) } let(:last_media_attached_status) { Fabricate(:status, account: account, sensitive: !sensitive) } - let!(:last_media_attachment) { Fabricate(:media_attachment, account: account, status: last_media_attached_status) } - let!(:last_status) { Fabricate(:status, account: account) } let(:sensitive) { true } before do + _last_media_attachment = Fabricate(:media_attachment, account: account, status: last_media_attached_status) + _last_status = Fabricate(:status, account: account) + _media_attachment = Fabricate(:media_attachment, account: account, status: media_attached_status) + sign_in user, scope: :user end From 204c00b5c63c088e8a673ec9cf703097d549fbd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 08:24:04 +0000 Subject: [PATCH 035/834] Update dependency bootsnap to '~> 1.17.0' (#27617) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index c935b5410f..b8fcbaa886 100644 --- a/Gemfile +++ b/Gemfile @@ -23,7 +23,7 @@ gem 'blurhash', '~> 0.1' gem 'active_model_serializers', '~> 0.10' gem 'addressable', '~> 2.8' -gem 'bootsnap', '~> 1.16.0', require: false +gem 'bootsnap', '~> 1.17.0', require: false gem 'browser' gem 'charlock_holmes', '~> 0.7.7' gem 'chewy', '~> 7.3' diff --git a/Gemfile.lock b/Gemfile.lock index 5021800eba..1a64667d20 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -171,7 +171,7 @@ GEM binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) blurhash (0.1.7) - bootsnap (1.16.0) + bootsnap (1.17.0) msgpack (~> 1.2) brakeman (6.0.1) browser (5.3.1) @@ -455,7 +455,7 @@ GEM mini_mime (1.1.5) mini_portile2 (2.8.4) minitest (5.20.0) - msgpack (1.7.1) + msgpack (1.7.2) multi_json (1.15.0) multipart-post (2.3.0) mutex_m (0.1.2) @@ -833,7 +833,7 @@ DEPENDENCIES better_errors (~> 2.9) binding_of_caller (~> 1.0) blurhash (~> 0.1) - bootsnap (~> 1.16.0) + bootsnap (~> 1.17.0) brakeman (~> 6.0) browser bundler-audit (~> 0.9) From 147417a6d02dcd4396ad2c4d62953711bb36af2e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 09:26:21 +0100 Subject: [PATCH 036/834] Update dependency rspec-sidekiq to v4.1.0 (#27593) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 1a64667d20..6ca89599c5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -631,7 +631,7 @@ GEM rspec-support (~> 3.12.0) rspec-github (2.4.0) rspec-core (~> 3.0) - rspec-mocks (3.12.5) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) rspec-rails (6.0.3) @@ -642,7 +642,7 @@ GEM rspec-expectations (~> 3.12) rspec-mocks (~> 3.12) rspec-support (~> 3.12) - rspec-sidekiq (4.0.1) + rspec-sidekiq (4.1.0) rspec-core (~> 3.0) rspec-expectations (~> 3.0) rspec-mocks (~> 3.0) From e5b7ae95765eb99c1c9536bbed43425c63c68108 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 31 Oct 2023 09:43:17 +0100 Subject: [PATCH 037/834] New Crowdin Translations (automated) (#27630) Co-authored-by: GitHub Actions --- app/javascript/mastodon/locales/he.json | 6 ++-- app/javascript/mastodon/locales/ms.json | 7 +++- config/locales/bg.yml | 13 ++++++++ config/locales/ms.yml | 43 ++++++++++++++++++++++--- config/locales/oc.yml | 3 ++ config/locales/simple_form.ms.yml | 15 ++++++--- 6 files changed, 75 insertions(+), 12 deletions(-) diff --git a/app/javascript/mastodon/locales/he.json b/app/javascript/mastodon/locales/he.json index c868655e15..01618118a3 100644 --- a/app/javascript/mastodon/locales/he.json +++ b/app/javascript/mastodon/locales/he.json @@ -202,7 +202,7 @@ "dismissable_banner.community_timeline": "אלו הם החצרוצים הציבוריים האחרונים מהמשתמשים על שרת {domain}.", "dismissable_banner.dismiss": "בטל", "dismissable_banner.explore_links": "אלו הקישורים האחרונים ששותפו על ידי משתמשים ששרת זה רואה ברשת המבוזרת כרגע.", - "dismissable_banner.explore_statuses": "ההודעות האלו, משרת זה ואחרים ברשת המבוזרת, צוברים חשיפה היום. הודעות חדשות יותר עם יותר הדהודים וחיבובים מדורגים גבוה יותר.", + "dismissable_banner.explore_statuses": "ההודעות האלו, משרת זה ואחרים ברשת המבוזרת, צוברים חשיפה היום. הודעות חדשות יותר עם יותר הדהודים וחיבובים מדורגות גבוה יותר.", "dismissable_banner.explore_tags": "התגיות האלו, משרת זה ואחרים ברשת המבוזרת, צוברות חשיפה כעת.", "dismissable_banner.public_timeline": "אלו ההודעות האחרונות שהתקבלו מהמשתמשים שנעקבים על ידי משתמשים מ־{domain}.", "embed.instructions": "ניתן להטמיע את ההודעה הזו באתרך ע\"י העתקת הקוד שלהלן.", @@ -349,7 +349,7 @@ "keyboard_shortcuts.hotkey": "מקש קיצור", "keyboard_shortcuts.legend": "הצגת מקרא", "keyboard_shortcuts.local": "פתיחת ציר זמן קהילתי", - "keyboard_shortcuts.mention": "לאזכר את המחבר(ת)", + "keyboard_shortcuts.mention": "לאזכר את המחבר.ת", "keyboard_shortcuts.muted": "פתיחת רשימת משתמשים מושתקים", "keyboard_shortcuts.my_profile": "פתיחת הפרופיל שלך", "keyboard_shortcuts.notifications": "פתיחת טור התראות", @@ -707,7 +707,7 @@ "upload_modal.apply": "החל", "upload_modal.applying": "מחיל…", "upload_modal.choose_image": "בחר/י תמונה", - "upload_modal.description_placeholder": "דג סקרן שט בים מאוכזב ולפתע מצא חברה", + "upload_modal.description_placeholder": "עטלף אבק נס דרך מזגן שהתפוצץ כי חם", "upload_modal.detect_text": "זהה טקסט מתמונה", "upload_modal.edit_media": "עריכת מדיה", "upload_modal.hint": "הקליקי או גררי את המעגל על גבי התצוגה המקדימה על מנת לבחור בנקודת המוקד שתראה תמיד בכל התמונות הממוזערות.", diff --git a/app/javascript/mastodon/locales/ms.json b/app/javascript/mastodon/locales/ms.json index 3814e69151..a3bbd0067d 100644 --- a/app/javascript/mastodon/locales/ms.json +++ b/app/javascript/mastodon/locales/ms.json @@ -137,7 +137,7 @@ "compose.language.search": "Cari bahasa...", "compose.published.body": "Pos telah diterbitkan.", "compose.published.open": "Buka", - "compose.saved.body": "Pos disimpan.", + "compose.saved.body": "Kiriman disimpan.", "compose_form.direct_message_warning_learn_more": "Ketahui lebih lanjut", "compose_form.encryption_warning": "Hantaran pada Mastodon tidak disulitkan hujung ke hujung. Jangan berkongsi sebarang maklumat sensitif melalui Mastodon.", "compose_form.hashtag_warning": "Hantaran ini tidak akan disenaraikan di bawah mana-mana tanda pagar kerana ia tidak tersenarai. Hanya hantaran awam sahaja boleh dicari menggunakan tanda pagar.", @@ -307,6 +307,9 @@ "home.explore_prompt.body": "Suapan rumah anda akan mempunyai gabungan pos daripada hashtag yang telah anda pilih untuk diikuti, orang yang telah anda pilih untuk diikuti dan pos yang mereka tingkatkan. Jika itu terasa terlalu senyap, anda mungkin mahu:", "home.explore_prompt.title": "Ini adalah pusat operasi anda dalam Mastodon.", "home.hide_announcements": "Sembunyikan pengumuman", + "home.pending_critical_update.body": "Sila kemas kini pelayan Mastodon anda secepat yang mungkin!", + "home.pending_critical_update.link": "Lihat pengemaskinian", + "home.pending_critical_update.title": "Kemas kini keselamatan kritikal tersedia!", "home.show_announcements": "Tunjukkan pengumuman", "interaction_modal.description.favourite": "Dengan akaun di Mastodon, anda boleh menggemari pos ini untuk memberitahu pengarang anda menghargainya dan menyimpannya untuk kemudian.", "interaction_modal.description.follow": "Dengan akaun pada Mastodon, anda boleh mengikut {name} untuk menerima hantaran mereka di suapan rumah anda.", @@ -408,6 +411,7 @@ "navigation_bar.lists": "Senarai", "navigation_bar.logout": "Log keluar", "navigation_bar.mutes": "Pengguna yang dibisukan", + "navigation_bar.opened_in_classic_interface": "Kiriman, akaun dan halaman tertentu yang lain dibuka secara lalai di antara muka web klasik.", "navigation_bar.personal": "Peribadi", "navigation_bar.pins": "Hantaran disemat", "navigation_bar.preferences": "Keutamaan", @@ -583,6 +587,7 @@ "search.quick_action.open_url": "Buka URL dalam Mastadon", "search.quick_action.status_search": "Pos sepadan {x}", "search.search_or_paste": "Cari atau tampal URL", + "search_popout.full_text_search_disabled_message": "Tidak tersedia di {domain}.", "search_popout.language_code": "Kod bahasa ISO", "search_popout.options": "Pilihan carian", "search_popout.quick_actions": "Tindakan pantas", diff --git a/config/locales/bg.yml b/config/locales/bg.yml index b1d91875b3..04b4d438bb 100644 --- a/config/locales/bg.yml +++ b/config/locales/bg.yml @@ -534,6 +534,7 @@ bg: total_reported: Доклади за тях total_storage: Прикачена мултимедия totals_time_period_hint_html: Общите стойности, показани по-долу, включват данни за всички времена. + unknown_instance: В момента няма запис на този домейн на този сървър. invites: deactivate_all: Деактивиране на всички filter: @@ -1040,6 +1041,14 @@ bg: hint_html: Просто още едно нещо! Трябва да потвърдим, че сте човек (това е с цел предпазване на нежелани съобщения!). Разгадайте капчата долу и щракнете на "Продължаване". title: Проверка за сигурност confirmations: + awaiting_review: Вашият адрес на е-поща е потвърден! Служителите на %{domain} сега преглеждат регистрацията ви. Ще получите е-писмо, ако одобрят акаунта ви! + awaiting_review_title: Вашата регистрация се преглежда + clicking_this_link: щракване на тази връзка + login_link: влизане + proceed_to_login_html: Сега може да пристъпите към %{login_link}. + redirect_to_app_html: Трябва да сте пренасочени към приложението %{app_name}. Ако не се случи това, то опитайте %{clicking_this_link} или ръчно се върнете към приложението. + registration_complete: Вашата регистрация на %{domain} вече завърши! + welcome_title: Добре дошли, %{name}! wrong_email_hint: Ако този адрес на е-поща не е правилен, то може да го промените в настройки на акаунта. delete_account: Изтриване на акаунта delete_account_html: Ако желаете да изтриете акаунта си, може да сторите това тук. Ще ви се поиска потвърждение. @@ -1101,6 +1110,7 @@ bg: functional: Вашият акаунт е в изправност. pending: Вашето приложение чака преглед от нашия екип. Това може да отнеме време. Ще получите имейл, ако приложението е одобрено. redirecting_to: Вашият акаунт е бездеен, защото сега се пренасочва към %{acct}. + self_destruct: Затваряйки %{domain}, ще получите само ограничен достъп до акаунта си. view_strikes: Преглед на предишните предупреждения против акаунта ви too_fast: Образецът подаден пребързо, опитайте пак. use_security_key: Употреба на ключ за сигурност @@ -1570,6 +1580,9 @@ bg: over_daily_limit: Завишили сте ограничението от %{limit} планирани публикации за днес over_total_limit: Завишили сте ограничението от %{limit} планирани публикации too_soon: Заплануваната дата трябва да е в бъдеще + self_destruct: + lead_html: За жалост, %{domain} е трайно затворен. Ако сте имали там акаунт, то няма да може да продължите да го употребявате, но още може да заявите резервно копие на данните си. + title: Този сървър се затваря sessions: activity: Последна активност browser: Браузър diff --git a/config/locales/ms.yml b/config/locales/ms.yml index 6d1ededbc4..951b04194e 100644 --- a/config/locales/ms.yml +++ b/config/locales/ms.yml @@ -306,6 +306,7 @@ ms: unpublish: Nyahterbit unpublished_msg: Pengumuman berjaya dinyahterbitkan! updated_msg: Pengumuman berjaya dikemaskini! + critical_update_pending: Kemas kini kritikal belum selesai custom_emojis: assign_category: Menugaskan kategori by_domain: Domain @@ -522,6 +523,7 @@ ms: total_reported: Laporan tentang mereka total_storage: Lampiran media totals_time_period_hint_html: Jumlah yang dipaparkan di bawah termasuk data untuk sepanjang masa. + unknown_instance: Pada masa ini tiada rekod domain ini pada pelayan ini. invites: deactivate_all: Nyahaktifkan semua filter: @@ -756,10 +758,26 @@ ms: approved: Kelulusan diperlukan untuk pendaftaran none: Tiada siapa boleh mendaftar open: Sesiapapun boleh mendaftar + security: + authorized_fetch: Memerlukan pengesahan daripada pelayan bersekutu + authorized_fetch_overridden_hint: Pada masa ini anda tidak dapat menukar tetapan ini kerana ia ditindih oleh pemboleh ubah persekitaran. + federation_authentication: Penguatkuasaan pengesahan persekutuan title: Tetapan server site_uploads: delete: Hapuskan fail yang dimuat naik destroyed_msg: Muat naik tapak berjaya dihapuskan! + software_updates: + critical_update: Penting — sila kemas kini dengan segera + description: Disarankan untuk memastikan pemasangan Mastodon anda dikemas kini bagi mendapat manfaat daripada pembaikan dan ciri terkini. Selain itu, kadangkala penting untuk mengemas kini Mastodon tepat pada masanya untuk mengelakkan isu keselamatan. Atas sebab ini, Mastodon menyemak kemas kini setiap 30 minit dan akan memberitahu anda mengikut keutamaan pemberitahuan e-mel anda. + documentation_link: Ketahui lebih lanjut + release_notes: Catatan keluaran + title: Kemas kini tersedia + type: Jenis + types: + major: Keluaran utama + minor: Keluaran kecil + patch: Keluaran tampung — pembetulan pepijat dan perubahan yang mudah diterapkan + version: Versi statuses: account: Penulis application: Aplikasi @@ -807,10 +825,10 @@ ms: elasticsearch_index_mismatch: message_html: Pemetaan indeks Elasticsearch sudah lapuk. Sila jalankan tootctl search deploy --only=%{value} elasticsearch_preset: - action: Lihat dokumentasi - message_html: Kelompok Elasticsearch anda mempunyai lebih daripada satu nod, tetapi Mastodon tidak dikonfigurasikan untuk menggunakannya. + action: Lihat pendokumenan + message_html: Kelompok Elasticsearch anda mempunyai lebih daripada satu nod, tetapi Mastodon tidak ditatarajah untuk menggunakannya. elasticsearch_preset_single_node: - action: Lihat dokumentasi + action: Lihat pendokumenan message_html: Kelompok Elasticsearch anda hanya mempunyai satu nod, ES_PRESET hendaklah ditetapkan kepada single_node_cluster. elasticsearch_reset_chewy: message_html: Indeks sistem Elasticsearch anda sudah lapuk kerana perubahan tetapan. Sila jalankan tootctl search deploy --reset-chewy untuk mengemas kininya. @@ -824,6 +842,12 @@ ms: message_html: Anda belum menentukan sebarang peraturan server. sidekiq_process_check: message_html: Tiada proses Sidekiq berjalan untuk baris gilir %{value}. Sila semak konfigurasi Sidekiq anda + software_version_critical_check: + action: Lihat kemas kini yang tersedia + message_html: Kemas kini kritikal Mastodon telah tersedia, sila kemas kini secepat yang mungkin. + software_version_patch_check: + action: Lihat kemas kini yang tersedia + message_html: Kemas kini pembetulan pepijat Mastodon telah tersedia. upload_check_privacy_error: action: Semak di sini untuk maklumat lanjut message_html: "Server web anda salah konfigurasi. Privasi pengguna anda berisiko" @@ -933,6 +957,9 @@ ms: body: "%{target} sedang merayu keputusan penyederhanaan sebanyak %{action_taken_by} dari %{date}, iaitu %{type}. Mereka tulis:" next_steps: Anda boleh meluluskan rayuan untuk membuat asal keputusan penyederhanaan atau mengabaikannya. subject: "%{username} sedang merayu keputusan penyederhanaan pada %{instance}" + new_critical_software_updates: + body: Versi kritikal baharu Mastodon telah dikeluarkan, anda mungkin ingin mengemas kini secepat yang mungkin! + subject: Kemas kini kritikal Mastodon telah tersedia untuk %{instance}! new_pending_account: body: Butiran akaun baharu ada di bawah. Anda boleh meluluskan atau menolak aplikasi ini. subject: Akaun baharu disediakan untuk semakan pada %{instance} (%{username}) @@ -940,6 +967,9 @@ ms: body: "%{reporter} telah melaporkan %{target}" body_remote: Seseorang daripada %{domain} telah melaporkan %{target} subject: Laporan baharu untuk %{instance} (#%{id}) + new_software_updates: + body: Versi baharu Mastodon telah dikeluarkan, anda mungkin mahu mengemas kini! + subject: Versi baharu Mastodon telah tersedia untuk %{instance}! new_trends: body: 'Item berikut memerlukan semakan sebelum boleh dipaparkan secara terbuka:' new_trending_links: @@ -1053,6 +1083,7 @@ ms: functional: Akaun anda beroperasi sepenuhnya. pending: Permohonan anda sedang menunggu semakan oleh kakitangan kami. Ini mungkin mengambil sedikit masa. Anda akan menerima e-mel sekiranya permohonan anda diluluskan. redirecting_to: Akaun anda tidak aktif kerana ia sedang mengubah hala ke %{acct}. + self_destruct: Memandangkan %{domain} akan ditutup, anda hanya akan mendapat capaian terhad kepada akaun anda. view_strikes: Lihat pelanggaran yang lepas terhadap akaun anda too_fast: Borang diserahkan terlalu cepat, cuba lagi. use_security_key: Gunakan kunci keselamatan @@ -1504,6 +1535,9 @@ ms: over_daily_limit: Anda telah melebihi had %{limit} pos berjadual untuk hari ini over_total_limit: Anda telah melebihi had %{limit} pos berjadual too_soon: Tarikh yang dijadualkan mestilah pada masa hadapan + self_destruct: + lead_html: Malangnya, %{domain} akan ditutup secara kekal. Jika anda mempunyai akaun di situ, anda tidak akan dapat terus menggunakannya, tetapi anda masih boleh meminta sandaran data anda. + title: Pelayan ini akan ditutup sessions: activity: Aktiviti terakhir browser: Pelayar @@ -1666,9 +1700,10 @@ ms: default: "%b %d, %Y, %H:%M" month: "%b %Y" time: "%H:%M" + with_time_zone: "%d %b %Y, %H:%M %Z" translation: errors: - quota_exceeded: Kuota penggunaan seluruh server untuk perkhidmatan terjemahan telah melebihi. + quota_exceeded: Kuota penggunaan seluruh pelayan untuk perkhidmatan terjemahan telah berlebihan. too_many_requests: Terdapat terlalu banyak permintaan kepada perkhidmatan terjemahan baru-baru ini. two_factor_authentication: add: Tambah diff --git a/config/locales/oc.yml b/config/locales/oc.yml index 8145002e56..83c2638b51 100644 --- a/config/locales/oc.yml +++ b/config/locales/oc.yml @@ -474,6 +474,9 @@ oc: warning: Mèfi ! Agachatz de partejar aquela donada amb degun ! your_token: Vòstre geton d’accès auth: + confirmations: + clicking_this_link: en clicant aqueste ligam + welcome_title: La benvenguda %{name} ! delete_account: Suprimir lo compte delete_account_html: Se volètz suprimir vòstre compte, podètz o far aquí. Vos demandarem que confirmetz. description: diff --git a/config/locales/simple_form.ms.yml b/config/locales/simple_form.ms.yml index c0d47ace0a..79929cec5d 100644 --- a/config/locales/simple_form.ms.yml +++ b/config/locales/simple_form.ms.yml @@ -6,10 +6,10 @@ ms: discoverable: Siaran awam dan profil anda mungkin dipaparkan atau disyorkan dalam pelbagai kawasan Mastodon dan profil anda mungkin dicadangkan kepada pengguna lain. display_name: Nama penuh anda atau nama anda yang menyeronokkan. fields: Halaman utama anda, kata ganti nama, umur, apa sahaja yang anda mahukan. - indexable: Pos awam anda mungkin muncul dalam hasil carian di Mastodon. Orang yang telah berinteraksi dengan pos anda mungkin boleh mencarinya tanpa mengira. + indexable: Kiriman awam anda mungkin muncul dalam hasil carian di Mastodon. Orang yang telah berinteraksi dengan kiriman anda mungkin boleh mencarinya. note: 'Anda boleh @menyebut orang lain atau #hashtags.' - show_collections: Orang akan dapat menyemak imbas mengikut dan pengikut anda. Orang yang anda ikuti akan melihat bahawa anda mengikuti mereka tanpa mengira. - unlocked: Orang akan dapat mengikuti anda tanpa meminta kelulusan. Nyahtanda jika anda ingin menyemak permintaan ikuti dan pilih sama ada untuk menerima atau menolak pengikut baharu. + show_collections: Orang akan dapat menyemak imbas ikutan dan pengikut anda. Orang yang anda ikuti akan melihat bahawa anda tetap mengikuti mereka. + unlocked: Orang akan dapat mengikuti anda tanpa meminta kelulusan. Nyahtanda jika anda ingin menyemak permintaan ikutan dan pilih sama ada untuk menerima atau menolak pengikut baharu. account_alias: acct: Tentukan namapengguna@domain akaun yang ingin anda alihkan daripada account_migration: @@ -144,7 +144,7 @@ ms: fields: name: Label value: Kandungan - indexable: Sertakan pos awam dalam hasil carian + indexable: Termasuk kiriman awam dalam hasil carian show_collections: Tunjukkan ikutan dan pengikut pada profil unlocked: Terima pengikut baharu secara automatik account_alias: @@ -291,6 +291,12 @@ ms: pending_account: Akaun baru memerlukan semakan reblog: Seorang menggalakan hantaran anda report: Laporan baru telah dihantar + software_updates: + all: Beritahu mengenai semua kemas kini + critical: Beritahu mengenai kemas kini kritikal sahaja + label: Versi baharu Mastodon kini tersedia + none: Tidak pernah memberitahu mengenai kemas kini (tidak disarankan) + patch: Beritahu mengenai kemas kini pembetulan pepijat trending_tag: Trend baru memerlukan semakan rule: text: Peraturan @@ -317,6 +323,7 @@ ms: url: URL titik akhir 'no': Tidak not_recommended: Tidak disyorkan + overridden: Ditindih recommended: Disyorkan required: mark: "*" From d649bbf28f9bbf7cddc7d471121129a4788298b2 Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 31 Oct 2023 10:40:30 +0100 Subject: [PATCH 038/834] Add some more tests and clean up domain block controller (#27469) --- .../admin/domain_blocks_controller.rb | 2 +- spec/features/admin/domain_blocks_spec.rb | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/app/controllers/admin/domain_blocks_controller.rb b/app/controllers/admin/domain_blocks_controller.rb index 96c31a38fd..325b33df80 100644 --- a/app/controllers/admin/domain_blocks_controller.rb +++ b/app/controllers/admin/domain_blocks_controller.rb @@ -33,7 +33,7 @@ module Admin # Disallow accidentally downgrading a domain block if existing_domain_block.present? && !@domain_block.stricter_than?(existing_domain_block) - @domain_block.save + @domain_block.validate flash.now[:alert] = I18n.t('admin.domain_blocks.existing_domain_block_html', name: existing_domain_block.domain, unblock_url: admin_domain_block_path(existing_domain_block)).html_safe @domain_block.errors.delete(:domain) return render :new diff --git a/spec/features/admin/domain_blocks_spec.rb b/spec/features/admin/domain_blocks_spec.rb index 0d7b90c21c..4379ac91db 100644 --- a/spec/features/admin/domain_blocks_spec.rb +++ b/spec/features/admin/domain_blocks_spec.rb @@ -4,6 +4,7 @@ require 'rails_helper' describe 'blocking domains through the moderation interface' do before do + allow(DomainBlockWorker).to receive(:perform_async).and_return(true) sign_in Fabricate(:user, role: UserRole.find_by(name: 'Admin')), scope: :user end @@ -16,6 +17,7 @@ describe 'blocking domains through the moderation interface' do click_button I18n.t('admin.domain_blocks.new.create') expect(DomainBlock.exists?(domain: 'example.com', severity: 'silence')).to be true + expect(DomainBlockWorker).to have_received(:perform_async) end end @@ -27,13 +29,15 @@ describe 'blocking domains through the moderation interface' do select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' click_button I18n.t('admin.domain_blocks.new.create') - # It presents a confirmation screen + # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming creates a block click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(DomainBlock.exists?(domain: 'example.com', severity: 'suspend')).to be true + expect(DomainBlockWorker).to have_received(:perform_async) end end @@ -47,13 +51,15 @@ describe 'blocking domains through the moderation interface' do select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' click_button I18n.t('admin.domain_blocks.new.create') - # It presents a confirmation screen + # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming updates the block click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(domain_block.reload.severity).to eq 'suspend' + expect(DomainBlockWorker).to have_received(:perform_async) end end @@ -67,13 +73,15 @@ describe 'blocking domains through the moderation interface' do select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' click_button I18n.t('admin.domain_blocks.new.create') - # It presents a confirmation screen + # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'subdomain.example.com')) + expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming creates the block click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') expect(DomainBlock.where(domain: 'subdomain.example.com', severity: 'suspend')).to exist + expect(DomainBlockWorker).to have_received(:perform_async) # And leaves the previous block alone expect(domain_block.reload.severity).to eq 'silence' @@ -90,11 +98,13 @@ describe 'blocking domains through the moderation interface' do select I18n.t('admin.domain_blocks.new.severity.suspend'), from: 'domain_block_severity' click_button I18n.t('generic.save_changes') - # It presents a confirmation screen + # It doesn't immediately block but presents a confirmation screen expect(page).to have_title(I18n.t('admin.domain_blocks.confirm_suspension.title', domain: 'example.com')) + expect(DomainBlockWorker).to_not have_received(:perform_async) # Confirming updates the block click_button I18n.t('admin.domain_blocks.confirm_suspension.confirm') + expect(DomainBlockWorker).to have_received(:perform_async) expect(domain_block.reload.severity).to eq 'suspend' end From a916251d8a8fffcaeb6be80eacf50138a53650dc Mon Sep 17 00:00:00 2001 From: Matt Jankowski Date: Tue, 31 Oct 2023 05:47:16 -0400 Subject: [PATCH 039/834] Update haml-lint line length configuration to match rubocop value (#27570) --- .haml-lint.yml | 2 ++ .haml-lint_todo.yml | 22 ++++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/.haml-lint.yml b/.haml-lint.yml index d1ed30b260..8cfcaec8d9 100644 --- a/.haml-lint.yml +++ b/.haml-lint.yml @@ -12,3 +12,5 @@ linters: enabled: true MiddleDot: enabled: true + LineLength: + max: 320 diff --git a/.haml-lint_todo.yml b/.haml-lint_todo.yml index ff66764e07..9686c177bd 100644 --- a/.haml-lint_todo.yml +++ b/.haml-lint_todo.yml @@ -1,17 +1,31 @@ # This configuration was generated by # `haml-lint --auto-gen-config` -# on 2023-10-25 08:29:48 -0400 using Haml-Lint version 0.51.0. +# on 2023-10-26 09:32:34 -0400 using Haml-Lint version 0.51.0. # The point is for the user to remove these configuration records # one by one as the lints are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of Haml-Lint, may require this file to be generated again. linters: - # Offense count: 945 + # Offense count: 16 LineLength: - enabled: false + exclude: + - 'app/views/admin/account_actions/new.html.haml' + - 'app/views/admin/accounts/index.html.haml' + - 'app/views/admin/ip_blocks/new.html.haml' + - 'app/views/admin/roles/_form.html.haml' + - 'app/views/admin/settings/discovery/show.html.haml' + - 'app/views/auth/registrations/edit.html.haml' + - 'app/views/auth/registrations/new.html.haml' + - 'app/views/filters/_filter_fields.html.haml' + - 'app/views/media/player.html.haml' + - 'app/views/settings/applications/_fields.html.haml' + - 'app/views/settings/imports/index.html.haml' + - 'app/views/settings/preferences/appearance/show.html.haml' + - 'app/views/settings/preferences/notifications/show.html.haml' + - 'app/views/settings/preferences/other/show.html.haml' - # Offense count: 10 + # Offense count: 9 RuboCop: exclude: - 'app/views/admin/accounts/_buttons.html.haml' From 9c8891b39a2d04898880f4bd0754a52739ada30a Mon Sep 17 00:00:00 2001 From: Claire Date: Tue, 31 Oct 2023 11:17:37 +0100 Subject: [PATCH 040/834] Rewrite `AutosuggestTextarea` as Functional Component (#27618) --- .../components/autosuggest_textarea.jsx | 231 +++++++++--------- .../compose/components/compose_form.jsx | 26 +- 2 files changed, 130 insertions(+), 127 deletions(-) diff --git a/app/javascript/mastodon/components/autosuggest_textarea.jsx b/app/javascript/mastodon/components/autosuggest_textarea.jsx index 230e4f6572..4d173af59d 100644 --- a/app/javascript/mastodon/components/autosuggest_textarea.jsx +++ b/app/javascript/mastodon/components/autosuggest_textarea.jsx @@ -1,9 +1,9 @@ import PropTypes from 'prop-types'; +import { useCallback, useRef, useState, useEffect, forwardRef } from 'react'; import classNames from 'classnames'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; import Textarea from 'react-textarea-autosize'; @@ -37,54 +37,46 @@ const textAtCursorMatchesToken = (str, caretPosition) => { } }; -export default class AutosuggestTextarea extends ImmutablePureComponent { +const AutosuggestTextarea = forwardRef(({ + value, + suggestions, + disabled, + placeholder, + onSuggestionSelected, + onSuggestionsClearRequested, + onSuggestionsFetchRequested, + onChange, + onKeyUp, + onKeyDown, + onPaste, + onFocus, + autoFocus = true, + lang, + children, +}, textareaRef) => { - static propTypes = { - value: PropTypes.string, - suggestions: ImmutablePropTypes.list, - disabled: PropTypes.bool, - placeholder: PropTypes.string, - onSuggestionSelected: PropTypes.func.isRequired, - onSuggestionsClearRequested: PropTypes.func.isRequired, - onSuggestionsFetchRequested: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onKeyUp: PropTypes.func, - onKeyDown: PropTypes.func, - onPaste: PropTypes.func.isRequired, - autoFocus: PropTypes.bool, - lang: PropTypes.string, - }; + const [suggestionsHidden, setSuggestionsHidden] = useState(true); + const [selectedSuggestion, setSelectedSuggestion] = useState(0); + const lastTokenRef = useRef(null); + const tokenStartRef = useRef(0); - static defaultProps = { - autoFocus: true, - }; - - state = { - suggestionsHidden: true, - focused: false, - selectedSuggestion: 0, - lastToken: null, - tokenStart: 0, - }; - - onChange = (e) => { + const handleChange = useCallback((e) => { const [ tokenStart, token ] = textAtCursorMatchesToken(e.target.value, e.target.selectionStart); - if (token !== null && this.state.lastToken !== token) { - this.setState({ lastToken: token, selectedSuggestion: 0, tokenStart }); - this.props.onSuggestionsFetchRequested(token); + if (token !== null && lastTokenRef.current !== token) { + tokenStartRef.current = tokenStart; + lastTokenRef.current = token; + setSelectedSuggestion(0); + onSuggestionsFetchRequested(token); } else if (token === null) { - this.setState({ lastToken: null }); - this.props.onSuggestionsClearRequested(); + lastTokenRef.current = null; + onSuggestionsClearRequested(); } - this.props.onChange(e); - }; - - onKeyDown = (e) => { - const { suggestions, disabled } = this.props; - const { selectedSuggestion, suggestionsHidden } = this.state; + onChange(e); + }, [onSuggestionsFetchRequested, onSuggestionsClearRequested, onChange, setSelectedSuggestion]); + const handleKeyDown = useCallback((e) => { if (disabled) { e.preventDefault(); return; @@ -102,80 +94,75 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { document.querySelector('.ui').parentElement.focus(); } else { e.preventDefault(); - this.setState({ suggestionsHidden: true }); + setSuggestionsHidden(true); } break; case 'ArrowDown': if (suggestions.size > 0 && !suggestionsHidden) { e.preventDefault(); - this.setState({ selectedSuggestion: Math.min(selectedSuggestion + 1, suggestions.size - 1) }); + setSelectedSuggestion(Math.min(selectedSuggestion + 1, suggestions.size - 1)); } break; case 'ArrowUp': if (suggestions.size > 0 && !suggestionsHidden) { e.preventDefault(); - this.setState({ selectedSuggestion: Math.max(selectedSuggestion - 1, 0) }); + setSelectedSuggestion(Math.max(selectedSuggestion - 1, 0)); } break; case 'Enter': case 'Tab': // Select suggestion - if (this.state.lastToken !== null && suggestions.size > 0 && !suggestionsHidden) { + if (lastTokenRef.current !== null && suggestions.size > 0 && !suggestionsHidden) { e.preventDefault(); e.stopPropagation(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestions.get(selectedSuggestion)); + onSuggestionSelected(tokenStartRef.current, lastTokenRef.current, suggestions.get(selectedSuggestion)); } break; } - if (e.defaultPrevented || !this.props.onKeyDown) { + if (e.defaultPrevented || !onKeyDown) { return; } - this.props.onKeyDown(e); - }; + onKeyDown(e); + }, [disabled, suggestions, suggestionsHidden, selectedSuggestion, setSelectedSuggestion, setSuggestionsHidden, onSuggestionSelected, onKeyDown]); - onBlur = () => { - this.setState({ suggestionsHidden: true, focused: false }); - }; + const handleBlur = useCallback(() => { + setSuggestionsHidden(true); + }, [setSuggestionsHidden]); - onFocus = (e) => { - this.setState({ focused: true }); - if (this.props.onFocus) { - this.props.onFocus(e); + const handleFocus = useCallback((e) => { + if (onFocus) { + onFocus(e); } - }; + }, [onFocus]); - onSuggestionClick = (e) => { - const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index')); + const handleSuggestionClick = useCallback((e) => { + const suggestion = suggestions.get(e.currentTarget.getAttribute('data-index')); e.preventDefault(); - this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion); - this.textarea.focus(); - }; + onSuggestionSelected(tokenStartRef.current, lastTokenRef.current, suggestion); + textareaRef.current?.focus(); + }, [suggestions, onSuggestionSelected, textareaRef]); - UNSAFE_componentWillReceiveProps (nextProps) { - if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) { - this.setState({ suggestionsHidden: false }); - } - } - - setTextarea = (c) => { - this.textarea = c; - }; - - onPaste = (e) => { + const handlePaste = useCallback((e) => { if (e.clipboardData && e.clipboardData.files.length === 1) { - this.props.onPaste(e.clipboardData.files); + onPaste(e.clipboardData.files); e.preventDefault(); } - }; + }, [onPaste]); - renderSuggestion = (suggestion, i) => { - const { selectedSuggestion } = this.state; + // Show the suggestions again whenever they change and the textarea is focused + useEffect(() => { + if (suggestions.size > 0 && textareaRef.current === document.activeElement) { + setSuggestionsHidden(false); + } + }, [suggestions, textareaRef, setSuggestionsHidden]); + + const renderSuggestion = (suggestion, i) => { let inner, key; if (suggestion.type === 'emoji') { @@ -190,50 +177,64 @@ export default class AutosuggestTextarea extends ImmutablePureComponent { } return ( -
+
{inner}
); }; - render () { - const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, lang, children } = this.props; - const { suggestionsHidden } = this.state; + return [ +
+
+