Conflicts: - `config/initializers/content_security_policy.rb`: Kept our version, it was not affected by upstream's bug.th-downstream
commit
ee1de4206a
@ -0,0 +1,114 @@
|
|||||||
|
{
|
||||||
|
$schema: 'https://docs.renovatebot.com/renovate-schema.json',
|
||||||
|
extends: [
|
||||||
|
'config:base',
|
||||||
|
':dependencyDashboard',
|
||||||
|
':labels(dependencies)',
|
||||||
|
':maintainLockFilesMonthly', // update non-direct dependencies monthly
|
||||||
|
':prConcurrentLimit10', // only 10 open PRs at the same time
|
||||||
|
],
|
||||||
|
stabilityDays: 3, // Wait 3 days after the package has been published before upgrading it
|
||||||
|
// packageRules order is important, they are applied from top to bottom and are merged,
|
||||||
|
// so for example grouping rules needs to be at the bottom
|
||||||
|
packageRules: [
|
||||||
|
{
|
||||||
|
// Ignore major version bumps for these node packages
|
||||||
|
matchManagers: ['npm'],
|
||||||
|
matchPackageNames: [
|
||||||
|
'@rails/ujs', // Needs to match the major Rails version
|
||||||
|
'tesseract.js', // Requires code changes
|
||||||
|
'react-hotkeys', // Requires code changes
|
||||||
|
|
||||||
|
// Requires Webpacker upgrade or replacement
|
||||||
|
'@types/webpack',
|
||||||
|
'babel-loader',
|
||||||
|
'compression-webpack-plugin',
|
||||||
|
'css-loader',
|
||||||
|
'imports-loader',
|
||||||
|
'mini-css-extract-plugin',
|
||||||
|
'postcss-loader',
|
||||||
|
'sass-loader',
|
||||||
|
'terser-webpack-plugin',
|
||||||
|
'webpack',
|
||||||
|
'webpack-assets-manifest',
|
||||||
|
'webpack-bundle-analyzer',
|
||||||
|
'webpack-dev-server',
|
||||||
|
'webpack-cli',
|
||||||
|
|
||||||
|
// react-router: Requires manual upgrade
|
||||||
|
'history',
|
||||||
|
'react-router-dom',
|
||||||
|
],
|
||||||
|
matchUpdateTypes: ['major'],
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Ignore major version bumps for these Ruby packages
|
||||||
|
matchManagers: ['bundler'],
|
||||||
|
matchPackageNames: [
|
||||||
|
'sprockets', // Requires manual upgrade https://github.com/rails/sprockets/blob/master/UPGRADING.md#guide-to-upgrading-from-sprockets-3x-to-4x
|
||||||
|
'strong_migrations', // Requires manual upgrade
|
||||||
|
'sidekiq', // Requires manual upgrade
|
||||||
|
'sidekiq-unique-jobs', // Requires manual upgrades and sync with Sidekiq version
|
||||||
|
'redis', // Requires manual upgrade and sync with Sidekiq version
|
||||||
|
'fog-openstack', // TODO: was ignored in https://github.com/mastodon/mastodon/pull/13964
|
||||||
|
|
||||||
|
// Needs major Rails version bump
|
||||||
|
'rack',
|
||||||
|
'rails',
|
||||||
|
'rails-i18n',
|
||||||
|
],
|
||||||
|
matchUpdateTypes: ['major'],
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Update Github Actions and Docker images weekly
|
||||||
|
matchManagers: ['github-actions', 'dockerfile', 'docker-compose'],
|
||||||
|
extends: ['schedule:weekly'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Ignore major & minor bumps for the ruby image, this needs to be synced with .ruby-version
|
||||||
|
matchManagers: ['dockerfile'],
|
||||||
|
matchPackageNames: ['moritzheiber/ruby-jemalloc'],
|
||||||
|
matchUpdateTypes: ['minor', 'major'],
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Ignore major bump for the node image, this needs to be synced with .nvmrc
|
||||||
|
matchManagers: ['dockerfile'],
|
||||||
|
matchPackageNames: ['node'],
|
||||||
|
matchUpdateTypes: ['major'],
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Ignore major postgres bumps in the docker-compose file, as those break dev environments
|
||||||
|
matchManagers: ['docker-compose'],
|
||||||
|
matchPackageNames: ['postgres'],
|
||||||
|
matchUpdateTypes: ['major'],
|
||||||
|
enabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Update devDependencies every week, with one grouped PR
|
||||||
|
matchDepTypes: 'devDependencies',
|
||||||
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
|
excludePackageNames: [
|
||||||
|
'typescript', // Typescript has many changes in minor versions, needs to be checked every time
|
||||||
|
],
|
||||||
|
groupName: 'devDependencies (non-major)',
|
||||||
|
extends: ['schedule:weekly'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Update @types/* packages every week, with one grouped PR
|
||||||
|
matchPackagePrefixes: '@types/',
|
||||||
|
matchUpdateTypes: ['patch', 'minor'],
|
||||||
|
groupName: 'DefinitelyTyped types (non-major)',
|
||||||
|
extends: ['schedule:weekly'],
|
||||||
|
addLabels: ['typescript'],
|
||||||
|
},
|
||||||
|
// Add labels depending on package manager
|
||||||
|
{ matchManagers: ['npm', 'nvm'], addLabels: ['javascript'] },
|
||||||
|
{ matchManagers: ['bundler', 'ruby-version'], addLabels: ['ruby'] },
|
||||||
|
{ matchManagers: ['docker-compose', 'dockerfile'], addLabels: ['docker'] },
|
||||||
|
{ matchManagers: ['github-actions'], addLabels: ['github_actions'] },
|
||||||
|
],
|
||||||
|
}
|
@ -1,28 +0,0 @@
|
|||||||
import PropTypes from 'prop-types';
|
|
||||||
import { PureComponent } from 'react';
|
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
export default class LoadMore extends PureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
onClick: PropTypes.func,
|
|
||||||
disabled: PropTypes.bool,
|
|
||||||
visible: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
visible: true,
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { disabled, visible } = this.props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button type='button' className='load-more' disabled={disabled || !visible} style={{ visibility: visible ? 'visible' : 'hidden' }} onClick={this.props.onClick}>
|
|
||||||
<FormattedMessage id='status.load_more' defaultMessage='Load more' />
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,24 @@
|
|||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
onClick: (event: React.MouseEvent) => void;
|
||||||
|
disabled?: boolean;
|
||||||
|
visible?: boolean;
|
||||||
|
}
|
||||||
|
export const LoadMore: React.FC<Props> = ({
|
||||||
|
onClick,
|
||||||
|
disabled,
|
||||||
|
visible = true,
|
||||||
|
}) => {
|
||||||
|
return (
|
||||||
|
<button
|
||||||
|
type='button'
|
||||||
|
className='load-more'
|
||||||
|
disabled={disabled || !visible}
|
||||||
|
style={{ visibility: visible ? 'visible' : 'hidden' }}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<FormattedMessage id='status.load_more' defaultMessage='Load more' />
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
};
|
@ -0,0 +1,25 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Admin::Metrics::Measure::QueryHelper
|
||||||
|
protected
|
||||||
|
|
||||||
|
def perform_data_query
|
||||||
|
measurement_data_rows.map { |row| { date: row['period'], value: row['value'].to_s } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def measurement_data_rows
|
||||||
|
ActiveRecord::Base.connection.select_all(sanitized_sql_string)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sanitized_sql_string
|
||||||
|
ActiveRecord::Base.sanitize_sql_array(sql_array)
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_domain_sql(include_subdomains)
|
||||||
|
if include_subdomains
|
||||||
|
"accounts.domain IN (SELECT domain FROM instances WHERE reverse('.' || domain) LIKE reverse('.' || :domain::text))"
|
||||||
|
else
|
||||||
|
'accounts.domain = :domain::text'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,67 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class Webhooks::PayloadRenderer
|
||||||
|
class DocumentTraverser
|
||||||
|
INT_REGEX = /[0-9]+/
|
||||||
|
|
||||||
|
def initialize(document)
|
||||||
|
@document = document.with_indifferent_access
|
||||||
|
end
|
||||||
|
|
||||||
|
def get(path)
|
||||||
|
value = @document.dig(*parse_path(path))
|
||||||
|
string = Oj.dump(value)
|
||||||
|
|
||||||
|
# We want to make sure people can use the variable inside
|
||||||
|
# other strings, so it can't be wrapped in quotes.
|
||||||
|
if value.is_a?(String)
|
||||||
|
string[1...-1]
|
||||||
|
else
|
||||||
|
string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def parse_path(path)
|
||||||
|
path.split('.').filter_map do |segment|
|
||||||
|
if segment.match(INT_REGEX)
|
||||||
|
segment.to_i
|
||||||
|
else
|
||||||
|
segment.presence
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class TemplateParser < Parslet::Parser
|
||||||
|
rule(:dot) { str('.') }
|
||||||
|
rule(:digit) { match('[0-9]') }
|
||||||
|
rule(:property_name) { match('[a-z_]').repeat(1) }
|
||||||
|
rule(:array_index) { digit.repeat(1) }
|
||||||
|
rule(:segment) { (property_name | array_index) }
|
||||||
|
rule(:path) { property_name >> (dot >> segment).repeat }
|
||||||
|
rule(:variable) { (str('}}').absent? >> path).repeat.as(:variable) }
|
||||||
|
rule(:expression) { str('{{') >> variable >> str('}}') }
|
||||||
|
rule(:text) { (str('{{').absent? >> any).repeat(1) }
|
||||||
|
rule(:text_with_expressions) { (text.as(:text) | expression).repeat.as(:text) }
|
||||||
|
root(:text_with_expressions)
|
||||||
|
end
|
||||||
|
|
||||||
|
EXPRESSION_REGEXP = /
|
||||||
|
\{\{
|
||||||
|
[a-z_]+
|
||||||
|
(\.
|
||||||
|
([a-z_]+|[0-9]+)
|
||||||
|
)*
|
||||||
|
\}\}
|
||||||
|
/iox
|
||||||
|
|
||||||
|
def initialize(json)
|
||||||
|
@document = DocumentTraverser.new(Oj.load(json))
|
||||||
|
end
|
||||||
|
|
||||||
|
def render(template)
|
||||||
|
template.gsub(EXPRESSION_REGEXP) { |match| @document.get(match[2...-2]) }
|
||||||
|
end
|
||||||
|
end
|
@ -1,3 +1,4 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
StrongMigrations.start_after = 2017_09_24_022025
|
StrongMigrations.start_after = 2017_09_24_022025
|
||||||
|
StrongMigrations.target_version = 10
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddTemplateToWebhooks < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
add_column :webhooks, :template, :text
|
||||||
|
end
|
||||||
|
end
|
@ -1,7 +1,17 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require Rails.root.join('lib', 'mastodon', 'migration_helpers')
|
||||||
|
|
||||||
class AddExclusiveToLists < ActiveRecord::Migration[6.1]
|
class AddExclusiveToLists < ActiveRecord::Migration[6.1]
|
||||||
def change
|
include Mastodon::MigrationHelpers
|
||||||
add_column :lists, :exclusive, :boolean, null: false, default: false
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
safety_assured { add_column_with_default :lists, :exclusive, :boolean, default: false, allow_null: false }
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_column :lists, :exclusive
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
inherit_from: ../../.rubocop.yml
|
||||||
|
|
||||||
|
# Anonymous controllers in specs cannot access described_class
|
||||||
|
# https://github.com/rubocop/rubocop-rspec/blob/master/lib/rubocop/cop/rspec/described_class.rb#L36-L39
|
||||||
|
RSpec/DescribedClass:
|
||||||
|
SkipBlocks: true
|
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Admin::Metrics::Measure::ActiveUsersMeasure do
|
||||||
|
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||||
|
|
||||||
|
let(:start_at) { 2.days.ago }
|
||||||
|
let(:end_at) { Time.now.utc }
|
||||||
|
let(:params) { ActionController::Parameters.new }
|
||||||
|
|
||||||
|
describe '#data' do
|
||||||
|
it 'runs data query without error' do
|
||||||
|
expect { measure.data }.to_not raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Admin::Metrics::Measure::InteractionsMeasure do
|
||||||
|
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||||
|
|
||||||
|
let(:start_at) { 2.days.ago }
|
||||||
|
let(:end_at) { Time.now.utc }
|
||||||
|
let(:params) { ActionController::Parameters.new }
|
||||||
|
|
||||||
|
describe '#data' do
|
||||||
|
it 'runs data query without error' do
|
||||||
|
expect { measure.data }.to_not raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
describe Admin::Metrics::Measure::NewUsersMeasure do
|
||||||
|
subject(:measure) { described_class.new(start_at, end_at, params) }
|
||||||
|
|
||||||
|
let(:start_at) { 2.days.ago }
|
||||||
|
let(:end_at) { Time.now.utc }
|
||||||
|
let(:params) { ActionController::Parameters.new }
|
||||||
|
|
||||||
|
describe '#data' do
|
||||||
|
it 'runs data query without error' do
|
||||||
|
expect { measure.data }.to_not raise_error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue