Compare commits
1 commit
kb_develop
...
kbtopic-85
Author | SHA1 | Date | |
---|---|---|---|
|
bbab545a3b |
1753 changed files with 26898 additions and 46941 deletions
|
@ -1,6 +1,10 @@
|
|||
[production]
|
||||
defaults
|
||||
> 0.2%
|
||||
firefox >= 78
|
||||
ios >= 15.6
|
||||
not dead
|
||||
not OperaMini all
|
||||
|
||||
[development]
|
||||
supports es6-module
|
||||
|
|
|
@ -10,7 +10,6 @@ services:
|
|||
RAILS_ENV: development
|
||||
NODE_ENV: development
|
||||
BIND: 0.0.0.0
|
||||
BOOTSNAP_CACHE_DIR: /tmp
|
||||
REDIS_HOST: redis
|
||||
REDIS_PORT: '6379'
|
||||
DB_HOST: db
|
||||
|
@ -21,13 +20,12 @@ services:
|
|||
ES_HOST: es
|
||||
ES_PORT: '9200'
|
||||
LIBRE_TRANSLATE_ENDPOINT: http://libretranslate:5000
|
||||
LOCAL_DOMAIN: ${LOCAL_DOMAIN:-localhost:3000}
|
||||
# Overrides default command so things don't shut down after the process ends.
|
||||
command: sleep infinity
|
||||
ports:
|
||||
- '3000:3000'
|
||||
- '3035:3035'
|
||||
- '4000:4000'
|
||||
- '127.0.0.1:3000:3000'
|
||||
- '127.0.0.1:3035:3035'
|
||||
- '127.0.0.1:4000:4000'
|
||||
networks:
|
||||
- external_network
|
||||
- internal_network
|
||||
|
|
|
@ -20,9 +20,3 @@ postgres14
|
|||
redis
|
||||
elasticsearch
|
||||
chart
|
||||
.yarn/
|
||||
!.yarn/patches
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/sdks
|
||||
!.yarn/versions
|
||||
|
|
|
@ -50,7 +50,7 @@ OTP_SECRET=
|
|||
# Must be available (and set to same values) for all server processes
|
||||
# These are private/secret values, do not share outside hosting environment
|
||||
# Use `bin/rails db:encryption:init` to generate fresh secrets
|
||||
# Do NOT change these secrets once in use, as this would cause data loss and other issues
|
||||
# Do not change these secrets once in use, as this would cause data loss and other issues
|
||||
# ------------------
|
||||
# ACTIVE_RECORD_ENCRYPTION_DETERMINISTIC_KEY=
|
||||
# ACTIVE_RECORD_ENCRYPTION_KEY_DERIVATION_SALT=
|
||||
|
@ -79,9 +79,6 @@ AWS_ACCESS_KEY_ID=
|
|||
AWS_SECRET_ACCESS_KEY=
|
||||
S3_ALIAS_HOST=files.example.com
|
||||
|
||||
# Optional list of hosts that are allowed to serve media for your instance
|
||||
# EXTRA_MEDIA_HOSTS=https://data.example1.com,https://data.example2.com
|
||||
|
||||
# IP and session retention
|
||||
# -----------------------
|
||||
# Make sure to modify the scheduling of ip_cleanup_scheduler in config/sidekiq.yml
|
||||
|
@ -89,27 +86,3 @@ S3_ALIAS_HOST=files.example.com
|
|||
# -----------------------
|
||||
IP_RETENTION_PERIOD=31556952
|
||||
SESSION_RETENTION_PERIOD=31556952
|
||||
|
||||
# Fetch All Replies Behavior
|
||||
# --------------------------
|
||||
# When a user expands a post (DetailedStatus view), fetch all of its replies
|
||||
# (default: false)
|
||||
FETCH_REPLIES_ENABLED=false
|
||||
|
||||
# Period to wait between fetching replies (in minutes)
|
||||
FETCH_REPLIES_COOLDOWN_MINUTES=15
|
||||
|
||||
# Period to wait after a post is first created before fetching its replies (in minutes)
|
||||
FETCH_REPLIES_INITIAL_WAIT_MINUTES=5
|
||||
|
||||
# Max number of replies to fetch - total, recursively through a whole reply tree
|
||||
FETCH_REPLIES_MAX_GLOBAL=1000
|
||||
|
||||
# Max number of replies to fetch - for a single post
|
||||
FETCH_REPLIES_MAX_SINGLE=500
|
||||
|
||||
# Max number of replies Collection pages to fetch - total
|
||||
FETCH_REPLIES_MAX_PAGES=500
|
||||
|
||||
# Maximum allowed character count
|
||||
MAX_CHARS=5555
|
||||
|
|
13
.eslintignore
Normal file
13
.eslintignore
Normal file
|
@ -0,0 +1,13 @@
|
|||
/build/**
|
||||
/coverage/**
|
||||
/db/**
|
||||
/lib/**
|
||||
/log/**
|
||||
/node_modules/**
|
||||
/nonobox/**
|
||||
/public/**
|
||||
!/public/embed.js
|
||||
/spec/**
|
||||
/tmp/**
|
||||
/vendor/**
|
||||
!.eslintrc.js
|
367
.eslintrc.js
Normal file
367
.eslintrc.js
Normal file
|
@ -0,0 +1,367 @@
|
|||
// @ts-check
|
||||
const { defineConfig } = require('eslint-define-config');
|
||||
|
||||
module.exports = defineConfig({
|
||||
root: true,
|
||||
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended',
|
||||
],
|
||||
|
||||
env: {
|
||||
browser: true,
|
||||
node: true,
|
||||
es6: true,
|
||||
},
|
||||
|
||||
parser: '@typescript-eslint/parser',
|
||||
|
||||
plugins: [
|
||||
'react',
|
||||
'jsx-a11y',
|
||||
'import',
|
||||
'promise',
|
||||
'@typescript-eslint',
|
||||
'formatjs',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
ecmaVersion: 2021,
|
||||
requireConfigFile: false,
|
||||
babelOptions: {
|
||||
configFile: false,
|
||||
presets: ['@babel/react', '@babel/env'],
|
||||
},
|
||||
},
|
||||
|
||||
settings: {
|
||||
react: {
|
||||
version: 'detect',
|
||||
},
|
||||
'import/ignore': [
|
||||
'node_modules',
|
||||
'\\.(css|scss|json)$',
|
||||
],
|
||||
'import/resolver': {
|
||||
typescript: {},
|
||||
},
|
||||
},
|
||||
|
||||
rules: {
|
||||
'consistent-return': 'error',
|
||||
'dot-notation': 'error',
|
||||
eqeqeq: ['error', 'always', { 'null': 'ignore' }],
|
||||
'indent': ['error', 2],
|
||||
'jsx-quotes': ['error', 'prefer-single'],
|
||||
'semi': ['error', 'always'],
|
||||
'no-catch-shadow': 'error',
|
||||
'no-console': [
|
||||
'warn',
|
||||
{
|
||||
allow: [
|
||||
'error',
|
||||
'warn',
|
||||
],
|
||||
},
|
||||
],
|
||||
'no-empty': ['error', { "allowEmptyCatch": true }],
|
||||
'no-restricted-properties': [
|
||||
'error',
|
||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
||||
{ property: 'substr', message: 'Use .slice instead of .substr.' },
|
||||
],
|
||||
'no-restricted-syntax': [
|
||||
'error',
|
||||
{
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
selector: 'Literal[value=/•/], JSXText[value=/•/]',
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
||||
},
|
||||
],
|
||||
'no-unused-expressions': 'error',
|
||||
'no-unused-vars': 'off',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
vars: 'all',
|
||||
args: 'after-used',
|
||||
destructuredArrayIgnorePattern: '^_',
|
||||
ignoreRestSiblings: true,
|
||||
},
|
||||
],
|
||||
'valid-typeof': 'error',
|
||||
|
||||
'react/jsx-filename-extension': ['error', { extensions: ['.jsx', 'tsx'] }],
|
||||
'react/jsx-boolean-value': 'error',
|
||||
'react/display-name': 'off',
|
||||
'react/jsx-fragments': ['error', 'syntax'],
|
||||
'react/jsx-equals-spacing': 'error',
|
||||
'react/jsx-no-bind': 'error',
|
||||
'react/jsx-no-useless-fragment': 'error',
|
||||
'react/jsx-no-target-blank': 'off',
|
||||
'react/jsx-tag-spacing': 'error',
|
||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
||||
'react/jsx-wrap-multilines': 'error',
|
||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
||||
'react/self-closing-comp': 'error',
|
||||
|
||||
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
||||
'jsx-a11y/click-events-have-key-events': 'off',
|
||||
'jsx-a11y/label-has-associated-control': 'off',
|
||||
'jsx-a11y/media-has-caption': 'off',
|
||||
'jsx-a11y/no-autofocus': 'off',
|
||||
// recommended rule is:
|
||||
// 'jsx-a11y/no-interactive-element-to-noninteractive-role': [
|
||||
// 'error',
|
||||
// {
|
||||
// tr: ['none', 'presentation'],
|
||||
// canvas: ['img'],
|
||||
// },
|
||||
// ],
|
||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
||||
// recommended rule is:
|
||||
// 'jsx-a11y/no-noninteractive-tabindex': [
|
||||
// 'error',
|
||||
// {
|
||||
// tags: [],
|
||||
// roles: ['tabpanel'],
|
||||
// allowExpressionValues: true,
|
||||
// },
|
||||
// ],
|
||||
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
||||
// recommended is full 'error'
|
||||
'jsx-a11y/no-static-element-interactions': [
|
||||
'warn',
|
||||
{
|
||||
handlers: [
|
||||
'onClick',
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
// See https://github.com/import-js/eslint-plugin-import/blob/v2.29.1/config/recommended.js
|
||||
'import/extensions': [
|
||||
'error',
|
||||
'always',
|
||||
{
|
||||
js: 'never',
|
||||
jsx: 'never',
|
||||
mjs: 'never',
|
||||
ts: 'never',
|
||||
tsx: 'never',
|
||||
},
|
||||
],
|
||||
'import/first': 'error',
|
||||
'import/newline-after-import': 'error',
|
||||
'import/no-anonymous-default-export': 'error',
|
||||
'import/no-extraneous-dependencies': [
|
||||
'error',
|
||||
{
|
||||
devDependencies: [
|
||||
'.eslintrc.js',
|
||||
'config/webpack/**',
|
||||
'app/javascript/mastodon/performance.js',
|
||||
'app/javascript/mastodon/test_setup.js',
|
||||
'app/javascript/**/__tests__/**',
|
||||
],
|
||||
},
|
||||
],
|
||||
'import/no-amd': 'error',
|
||||
'import/no-commonjs': 'error',
|
||||
'import/no-import-module-exports': 'error',
|
||||
'import/no-relative-packages': 'error',
|
||||
'import/no-self-import': 'error',
|
||||
'import/no-useless-path-segments': 'error',
|
||||
'import/no-webpack-loader-syntax': 'error',
|
||||
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
alphabetize: { order: 'asc' },
|
||||
'newlines-between': 'always',
|
||||
groups: [
|
||||
'builtin',
|
||||
'external',
|
||||
'internal',
|
||||
'parent',
|
||||
['index', 'sibling'],
|
||||
'object',
|
||||
],
|
||||
pathGroups: [
|
||||
// React core packages
|
||||
{
|
||||
pattern: '{react,react-dom,react-dom/client,prop-types}',
|
||||
group: 'builtin',
|
||||
position: 'after',
|
||||
},
|
||||
// I18n
|
||||
{
|
||||
pattern: '{react-intl,intl-messageformat}',
|
||||
group: 'builtin',
|
||||
position: 'after',
|
||||
},
|
||||
// Common React utilities
|
||||
{
|
||||
pattern: '{classnames,react-helmet,react-router,react-router-dom}',
|
||||
group: 'external',
|
||||
position: 'before',
|
||||
},
|
||||
// Immutable / Redux / data store
|
||||
{
|
||||
pattern: '{immutable,@reduxjs/toolkit,react-redux,react-immutable-proptypes,react-immutable-pure-component}',
|
||||
group: 'external',
|
||||
position: 'before',
|
||||
},
|
||||
// Internal packages
|
||||
{
|
||||
pattern: '{mastodon/**}',
|
||||
group: 'internal',
|
||||
position: 'after',
|
||||
},
|
||||
],
|
||||
pathGroupsExcludedImportTypes: [],
|
||||
},
|
||||
],
|
||||
|
||||
'promise/always-return': 'off',
|
||||
'promise/catch-or-return': [
|
||||
'error',
|
||||
{
|
||||
allowFinally: true,
|
||||
},
|
||||
],
|
||||
'promise/no-callback-in-promise': 'off',
|
||||
'promise/no-nesting': 'off',
|
||||
'promise/no-promise-in-callback': 'off',
|
||||
|
||||
'formatjs/blocklist-elements': 'error',
|
||||
'formatjs/enforce-default-message': ['error', 'literal'],
|
||||
'formatjs/enforce-description': 'off', // description values not currently used
|
||||
'formatjs/enforce-id': 'off', // Explicit IDs are used in the project
|
||||
'formatjs/enforce-placeholders': 'off', // Issues in short_number.jsx
|
||||
'formatjs/enforce-plural-rules': 'error',
|
||||
'formatjs/no-camel-case': 'off', // disabledAccount is only non-conforming
|
||||
'formatjs/no-complex-selectors': 'error',
|
||||
'formatjs/no-emoji': 'error',
|
||||
'formatjs/no-id': 'off', // IDs are used for translation keys
|
||||
'formatjs/no-invalid-icu': 'error',
|
||||
'formatjs/no-literal-string-in-jsx': 'off', // Should be looked at, but mainly flagging punctuation outside of strings
|
||||
'formatjs/no-multiple-whitespaces': 'error',
|
||||
'formatjs/no-offset': 'error',
|
||||
'formatjs/no-useless-message': 'error',
|
||||
'formatjs/prefer-formatted-message': 'error',
|
||||
'formatjs/prefer-pound-in-plural': 'error',
|
||||
|
||||
'jsdoc/check-types': 'off',
|
||||
'jsdoc/no-undefined-types': 'off',
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
'jsdoc/require-param-description': 'off',
|
||||
'jsdoc/require-property-description': 'off',
|
||||
'jsdoc/require-returns-description': 'off',
|
||||
'jsdoc/require-returns': 'off',
|
||||
},
|
||||
|
||||
overrides: [
|
||||
{
|
||||
files: [
|
||||
'.eslintrc.js',
|
||||
'*.config.js',
|
||||
'.*rc.js',
|
||||
'ide-helper.js',
|
||||
'config/webpack/**/*',
|
||||
'config/formatjs-formatter.js',
|
||||
],
|
||||
|
||||
env: {
|
||||
commonjs: true,
|
||||
},
|
||||
|
||||
parserOptions: {
|
||||
sourceType: 'script',
|
||||
},
|
||||
|
||||
rules: {
|
||||
'import/no-commonjs': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/*.ts',
|
||||
'**/*.tsx',
|
||||
],
|
||||
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/strict-type-checked',
|
||||
'plugin:@typescript-eslint/stylistic-type-checked',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react-hooks/recommended',
|
||||
'plugin:jsx-a11y/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'plugin:promise/recommended',
|
||||
'plugin:jsdoc/recommended-typescript',
|
||||
],
|
||||
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
|
||||
rules: {
|
||||
// Disable formatting rules that have been enabled in the base config
|
||||
'indent': 'off',
|
||||
|
||||
// This is not needed as we use noImplicitReturns, which handles this in addition to understanding types
|
||||
'consistent-return': 'off',
|
||||
|
||||
'import/consistent-type-specifier-style': ['error', 'prefer-top-level'],
|
||||
|
||||
'@typescript-eslint/consistent-type-definitions': ['warn', 'interface'],
|
||||
'@typescript-eslint/consistent-type-exports': 'error',
|
||||
'@typescript-eslint/consistent-type-imports': 'error',
|
||||
"@typescript-eslint/prefer-nullish-coalescing": ['error', { ignorePrimitives: { boolean: true } }],
|
||||
"@typescript-eslint/no-restricted-imports": [
|
||||
"warn",
|
||||
{
|
||||
"name": "react-redux",
|
||||
"importNames": ["useSelector", "useDispatch"],
|
||||
"message": "Use typed hooks `useAppDispatch` and `useAppSelector` instead."
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/restrict-template-expressions": ['warn', { allowNumber: true }],
|
||||
'jsdoc/require-jsdoc': 'off',
|
||||
|
||||
// Those rules set stricter rules for TS files
|
||||
// to enforce better practices when converting from JS
|
||||
'import/no-default-export': 'warn',
|
||||
'react/prefer-stateless-function': 'warn',
|
||||
'react/function-component-definition': ['error', { namedComponents: 'arrow-function' }],
|
||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
||||
'react/prop-types': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/__tests__/*.js',
|
||||
'**/__tests__/*.jsx',
|
||||
],
|
||||
|
||||
env: {
|
||||
jest: true,
|
||||
},
|
||||
}
|
||||
],
|
||||
});
|
2
.github/ISSUE_TEMPLATE/3.troubleshooting.yml
vendored
2
.github/ISSUE_TEMPLATE/3.troubleshooting.yml
vendored
|
@ -61,7 +61,7 @@ body:
|
|||
value: |
|
||||
Please at least include those informations:
|
||||
- Operating system: (eg. Ubuntu 22.04)
|
||||
- Ruby version: (from `ruby --version`, eg. v3.4.1)
|
||||
- Ruby version: (from `ruby --version`, eg. v3.3.5)
|
||||
- Node.js version: (from `node --version`, eg. v20.18.0)
|
||||
validations:
|
||||
required: false
|
||||
|
|
10
.github/renovate.json5
vendored
10
.github/renovate.json5
vendored
|
@ -15,8 +15,6 @@
|
|||
// to `null` after any other rule set it to something.
|
||||
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
|
||||
postUpdateOptions: ['yarnDedupeHighest'],
|
||||
// The types are now included in recent versions,we ignore them here until we upgrade and remove the dependency
|
||||
ignoreDeps: ['@types/emoji-mart'],
|
||||
packageRules: [
|
||||
{
|
||||
// Require Dependency Dashboard Approval for major version bumps of these node packages
|
||||
|
@ -99,13 +97,7 @@
|
|||
{
|
||||
// Group all eslint-related packages with `eslint` in the same PR
|
||||
matchManagers: ['npm'],
|
||||
matchPackageNames: [
|
||||
'eslint',
|
||||
'eslint-*',
|
||||
'typescript-eslint',
|
||||
'@eslint/*',
|
||||
'globals',
|
||||
],
|
||||
matchPackageNames: ['eslint', 'eslint-*', '@typescript-eslint/*'],
|
||||
matchUpdateTypes: ['patch', 'minor'],
|
||||
groupName: 'eslint (non-major)',
|
||||
},
|
||||
|
|
4
.github/workflows/build-security.yml
vendored
4
.github/workflows/build-security.yml
vendored
|
@ -24,6 +24,8 @@ jobs:
|
|||
uses: ./.github/workflows/build-container-image.yml
|
||||
with:
|
||||
file_to_build: Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
use_native_arm64_builder: true
|
||||
cache: false
|
||||
push_to_images: |
|
||||
tootsuite/mastodon
|
||||
|
@ -44,6 +46,8 @@ jobs:
|
|||
uses: ./.github/workflows/build-container-image.yml
|
||||
with:
|
||||
file_to_build: streaming/Dockerfile
|
||||
platforms: linux/amd64,linux/arm64
|
||||
use_native_arm64_builder: true
|
||||
cache: false
|
||||
push_to_images: |
|
||||
tootsuite/mastodon-streaming
|
||||
|
|
2
.github/workflows/check-i18n.yml
vendored
2
.github/workflows/check-i18n.yml
vendored
|
@ -24,7 +24,7 @@ permissions:
|
|||
|
||||
jobs:
|
||||
check-i18n:
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
|
|
@ -50,7 +50,7 @@ jobs:
|
|||
|
||||
# Create or update the pull request
|
||||
- name: Create Pull Request
|
||||
uses: peter-evans/create-pull-request@v7.0.6
|
||||
uses: peter-evans/create-pull-request@v7.0.5
|
||||
with:
|
||||
commit-message: 'New Crowdin translations'
|
||||
title: 'New Crowdin Translations for ${{ github.base_ref || github.ref_name }} (automated)'
|
||||
|
|
2
.github/workflows/lint-css.yml
vendored
2
.github/workflows/lint-css.yml
vendored
|
@ -43,4 +43,4 @@ jobs:
|
|||
uses: ./.github/actions/setup-javascript
|
||||
|
||||
- name: Stylelint
|
||||
run: yarn lint:css --custom-formatter @csstools/stylelint-formatter-github
|
||||
run: yarn lint:css -f github
|
||||
|
|
6
.github/workflows/lint-js.yml
vendored
6
.github/workflows/lint-js.yml
vendored
|
@ -14,7 +14,7 @@ on:
|
|||
- 'tsconfig.json'
|
||||
- '.nvmrc'
|
||||
- '.prettier*'
|
||||
- 'eslint.config.mjs'
|
||||
- '.eslint*'
|
||||
- '**/*.js'
|
||||
- '**/*.jsx'
|
||||
- '**/*.ts'
|
||||
|
@ -28,7 +28,7 @@ on:
|
|||
- 'tsconfig.json'
|
||||
- '.nvmrc'
|
||||
- '.prettier*'
|
||||
- 'eslint.config.mjs'
|
||||
- '.eslint*'
|
||||
- '**/*.js'
|
||||
- '**/*.jsx'
|
||||
- '**/*.ts'
|
||||
|
@ -47,7 +47,7 @@ jobs:
|
|||
uses: ./.github/actions/setup-javascript
|
||||
|
||||
- name: ESLint
|
||||
run: yarn workspaces foreach --all --parallel run lint:js --max-warnings 0
|
||||
run: yarn lint:js --max-warnings 0
|
||||
|
||||
- name: Typecheck
|
||||
run: yarn typecheck
|
||||
|
|
2
.github/workflows/lint-ruby.yml
vendored
2
.github/workflows/lint-ruby.yml
vendored
|
@ -12,7 +12,6 @@ on:
|
|||
- 'Gemfile*'
|
||||
- '.rubocop*.yml'
|
||||
- '.ruby-version'
|
||||
- 'bin/rubocop'
|
||||
- 'config/brakeman.ignore'
|
||||
- '**/*.rb'
|
||||
- '**/*.rake'
|
||||
|
@ -23,7 +22,6 @@ on:
|
|||
- 'Gemfile*'
|
||||
- '.rubocop*.yml'
|
||||
- '.ruby-version'
|
||||
- 'bin/rubocop'
|
||||
- 'config/brakeman.ignore'
|
||||
- '**/*.rb'
|
||||
- '**/*.rake'
|
||||
|
|
13
.github/workflows/test-migrations.yml
vendored
13
.github/workflows/test-migrations.yml
vendored
|
@ -67,6 +67,7 @@ jobs:
|
|||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
DISABLE_SIMPLECOV: true
|
||||
RAILS_ENV: test
|
||||
BUNDLE_CLEAN: true
|
||||
BUNDLE_FROZEN: true
|
||||
|
@ -80,18 +81,6 @@ jobs:
|
|||
- name: Set up Ruby environment
|
||||
uses: ./.github/actions/setup-ruby
|
||||
|
||||
- name: Ensure no errors with `db:prepare`
|
||||
run: |
|
||||
bin/rails db:drop
|
||||
bin/rails db:prepare
|
||||
bin/rails db:migrate
|
||||
|
||||
- name: Ensure no errors with `db:prepare` and SKIP_POST_DEPLOYMENT_MIGRATIONS
|
||||
run: |
|
||||
bin/rails db:drop
|
||||
SKIP_POST_DEPLOYMENT_MIGRATIONS=true bin/rails db:prepare
|
||||
bin/rails db:migrate
|
||||
|
||||
- name: Test "one step migration" flow
|
||||
run: |
|
||||
bin/rails db:drop
|
||||
|
|
16
.github/workflows/test-ruby.yml
vendored
16
.github/workflows/test-ruby.yml
vendored
|
@ -110,7 +110,7 @@ jobs:
|
|||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
COVERAGE: ${{ matrix.ruby-version == '.ruby-version' }}
|
||||
DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }}
|
||||
RAILS_ENV: test
|
||||
ALLOW_NOPAM: true
|
||||
PAM_ENABLED: true
|
||||
|
@ -129,7 +129,6 @@ jobs:
|
|||
matrix:
|
||||
ruby-version:
|
||||
- '3.2'
|
||||
- '3.3'
|
||||
- '.ruby-version'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -171,7 +170,7 @@ jobs:
|
|||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: matrix.ruby-version == '.ruby-version'
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: coverage/lcov/*.lcov
|
||||
env:
|
||||
|
@ -179,7 +178,7 @@ jobs:
|
|||
|
||||
test-libvips:
|
||||
name: Libvips tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
needs:
|
||||
- build
|
||||
|
@ -212,7 +211,7 @@ jobs:
|
|||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
COVERAGE: ${{ matrix.ruby-version == '.ruby-version' }}
|
||||
DISABLE_SIMPLECOV: ${{ matrix.ruby-version != '.ruby-version' }}
|
||||
RAILS_ENV: test
|
||||
ALLOW_NOPAM: true
|
||||
PAM_ENABLED: true
|
||||
|
@ -231,7 +230,6 @@ jobs:
|
|||
matrix:
|
||||
ruby-version:
|
||||
- '3.2'
|
||||
- '3.3'
|
||||
- '.ruby-version'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
@ -258,7 +256,7 @@ jobs:
|
|||
|
||||
- name: Upload coverage reports to Codecov
|
||||
if: matrix.ruby-version == '.ruby-version'
|
||||
uses: codecov/codecov-action@v5
|
||||
uses: codecov/codecov-action@v4
|
||||
with:
|
||||
files: coverage/lcov/mastodon.lcov
|
||||
env:
|
||||
|
@ -299,6 +297,7 @@ jobs:
|
|||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
DISABLE_SIMPLECOV: true
|
||||
RAILS_ENV: test
|
||||
BUNDLE_WITH: test
|
||||
ES_ENABLED: false
|
||||
|
@ -310,7 +309,6 @@ jobs:
|
|||
matrix:
|
||||
ruby-version:
|
||||
- '3.2'
|
||||
- '3.3'
|
||||
- '.ruby-version'
|
||||
|
||||
steps:
|
||||
|
@ -415,6 +413,7 @@ jobs:
|
|||
DB_HOST: localhost
|
||||
DB_USER: postgres
|
||||
DB_PASS: postgres
|
||||
DISABLE_SIMPLECOV: true
|
||||
RAILS_ENV: test
|
||||
BUNDLE_WITH: test
|
||||
ES_ENABLED: true
|
||||
|
@ -426,7 +425,6 @@ jobs:
|
|||
matrix:
|
||||
ruby-version:
|
||||
- '3.2'
|
||||
- '3.3'
|
||||
- '.ruby-version'
|
||||
search-image:
|
||||
- docker.elastic.co/elasticsearch/elasticsearch:7.17.13
|
||||
|
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
|||
22.14
|
||||
22.12
|
||||
|
|
|
@ -63,7 +63,6 @@ docker-compose.override.yml
|
|||
|
||||
# Ignore emoji map file
|
||||
/app/javascript/mastodon/features/emoji/emoji_map.json
|
||||
/app/javascript/mastodon/features/emoji/emoji_sheet.json
|
||||
|
||||
# Ignore locale files
|
||||
/app/javascript/mastodon/locales/*.json
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
module.exports = {
|
||||
singleQuote: true,
|
||||
jsxSingleQuote: true
|
||||
};
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ inherit_from:
|
|||
- .rubocop/rspec_rails.yml
|
||||
- .rubocop/rspec.yml
|
||||
- .rubocop/style.yml
|
||||
- .rubocop/i18n.yml
|
||||
- .rubocop/custom.yml
|
||||
- .rubocop_todo.yml
|
||||
- .rubocop/strict.yml
|
||||
|
@ -27,10 +26,10 @@ inherit_mode:
|
|||
merge:
|
||||
- Exclude
|
||||
|
||||
plugins:
|
||||
- rubocop-capybara
|
||||
- rubocop-i18n
|
||||
- rubocop-performance
|
||||
require:
|
||||
- rubocop-rails
|
||||
- rubocop-rspec
|
||||
- rubocop-rspec_rails
|
||||
- rubocop-performance
|
||||
- rubocop-capybara
|
||||
- ./lib/linter/rubocop_middle_dot
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
I18n/RailsI18n:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'config/**/*'
|
||||
- 'db/**/*'
|
||||
- 'lib/**/*'
|
||||
- 'spec/**/*'
|
||||
I18n/GetText:
|
||||
Enabled: false
|
||||
|
||||
I18n/RailsI18n/DecorateStringFormattingUsingInterpolation:
|
||||
Enabled: false
|
|
@ -2,9 +2,6 @@
|
|||
Rails/BulkChangeTable:
|
||||
Enabled: false # Conflicts with strong_migrations features
|
||||
|
||||
Rails/Delegate:
|
||||
Enabled: false
|
||||
|
||||
Rails/FilePath:
|
||||
EnforcedStyle: arguments
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
---
|
||||
Style/ArrayIntersect:
|
||||
Enabled: false
|
||||
|
||||
Style/ClassAndModuleChildren:
|
||||
Enabled: false
|
||||
|
||||
|
@ -22,13 +19,6 @@ Style/HashSyntax:
|
|||
EnforcedShorthandSyntax: either
|
||||
EnforcedStyle: ruby19_no_mixed_keys
|
||||
|
||||
Style/IfUnlessModifier:
|
||||
Exclude:
|
||||
- '**/*.haml'
|
||||
|
||||
Style/KeywordArgumentsMerging:
|
||||
Enabled: false
|
||||
|
||||
Style/NumericLiterals:
|
||||
AllowedPatterns:
|
||||
- \d{4}_\d{2}_\d{2}_\d{6}
|
||||
|
@ -47,9 +37,6 @@ Style/RedundantFetchBlock:
|
|||
Style/RescueStandardError:
|
||||
EnforcedStyle: implicit
|
||||
|
||||
Style/SafeNavigationChainLength:
|
||||
Enabled: false
|
||||
|
||||
Style/SymbolArray:
|
||||
Enabled: false
|
||||
|
||||
|
@ -58,6 +45,3 @@ Style/TrailingCommaInArrayLiteral:
|
|||
|
||||
Style/TrailingCommaInHashLiteral:
|
||||
EnforcedStyleForMultiline: comma
|
||||
|
||||
Style/WordArray:
|
||||
MinSize: 3 # Override default of 2
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# This configuration was generated by
|
||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||
# using RuboCop version 1.75.2.
|
||||
# using RuboCop version 1.66.1.
|
||||
# The point is for the user to remove these configuration records
|
||||
# one by one as the offenses are removed from the code base.
|
||||
# Note that changes in the inspected code, or installation of new
|
||||
|
@ -8,7 +8,7 @@
|
|||
|
||||
Lint/NonLocalExitFromIterator:
|
||||
Exclude:
|
||||
- 'app/helpers/json_ld_helper.rb'
|
||||
- 'app/helpers/jsonld_helper.rb'
|
||||
|
||||
# Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
|
||||
Metrics/AbcSize:
|
||||
|
@ -39,6 +39,7 @@ Rails/OutputSafety:
|
|||
# Configuration parameters: AllowedVars.
|
||||
Style/FetchEnvVar:
|
||||
Exclude:
|
||||
- 'app/lib/translation_service.rb'
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/2_limited_federation_mode.rb'
|
||||
- 'config/initializers/3_omniauth.rb'
|
||||
|
@ -49,7 +50,7 @@ Style/FetchEnvVar:
|
|||
- 'lib/tasks/repo.rake'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, Mode, AllowedMethods, AllowedPatterns.
|
||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
||||
# SupportedStyles: annotated, template, unannotated
|
||||
# AllowedMethods: redirect
|
||||
Style/FormatStringToken:
|
||||
|
@ -62,10 +63,31 @@ Style/FormatStringToken:
|
|||
Style/GuardClause:
|
||||
Enabled: false
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/HashTransformValues:
|
||||
Exclude:
|
||||
- 'app/serializers/rest/web_push_subscription_serializer.rb'
|
||||
- 'app/services/import_service.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
Style/MapToHash:
|
||||
Exclude:
|
||||
- 'app/models/status.rb'
|
||||
|
||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||
# Configuration parameters: EnforcedStyle.
|
||||
# SupportedStyles: literals, strict
|
||||
Style/MutableConstant:
|
||||
Exclude:
|
||||
- 'app/models/tag.rb'
|
||||
- 'app/services/delete_account_service.rb'
|
||||
- 'lib/mastodon/migration_warning.rb'
|
||||
|
||||
# Configuration parameters: AllowedMethods.
|
||||
# AllowedMethods: respond_to_missing?
|
||||
Style/OptionalBooleanParameter:
|
||||
Exclude:
|
||||
- 'app/helpers/jsonld_helper.rb'
|
||||
- 'app/lib/admin/system_check/message.rb'
|
||||
- 'app/lib/request.rb'
|
||||
- 'app/lib/webfinger.rb'
|
||||
|
@ -86,3 +108,10 @@ Style/RedundantConstantBase:
|
|||
Exclude:
|
||||
- 'config/environments/production.rb'
|
||||
- 'config/initializers/sidekiq.rb'
|
||||
|
||||
# This cop supports safe autocorrection (--autocorrect).
|
||||
# Configuration parameters: WordRegex.
|
||||
# SupportedStyles: percent, brackets
|
||||
Style/WordArray:
|
||||
EnforcedStyle: percent
|
||||
MinSize: 3
|
||||
|
|
|
@ -1 +1 @@
|
|||
3.4.3
|
||||
3.3.6
|
||||
|
|
144
CHANGELOG.md
144
CHANGELOG.md
|
@ -2,148 +2,6 @@
|
|||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [4.3.7] - 2025-04-02
|
||||
|
||||
### Add
|
||||
|
||||
- Add delay to profile updates to debounce them (#34137 by @ClearlyClaire)
|
||||
- Add support for paginating partial collections in `SynchronizeFollowersService` (#34272 and #34277 by @ClearlyClaire)
|
||||
|
||||
### Changed
|
||||
|
||||
- Change account suspensions to be federated to recently-followed accounts as well (#34294 by @ClearlyClaire)
|
||||
- Change `AccountReachFinder` to consider statuses based on suspension date (#32805 and #34291 by @ClearlyClaire and @mjankowski)
|
||||
- Change user archive signed URL TTL from 10 seconds to 1 hour (#34254 by @ClearlyClaire)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix static version of animated PNG emojis not being properly extracted (#34337 by @ClearlyClaire)
|
||||
- Fix filters not applying in detailed view, favourites and bookmarks (#34259 and #34260 by @ClearlyClaire)
|
||||
- Fix handling of malformed/unusual HTML (#34201 by @ClearlyClaire)
|
||||
- Fix `CacheBuster` being queued for missing media attachments (#34253 by @ClearlyClaire)
|
||||
- Fix incorrect URL being used when cache busting (#34189 by @ClearlyClaire)
|
||||
- Fix streaming server refusing unix socket path in `DATABASE_URL` (#34091 by @ClearlyClaire)
|
||||
- Fix “x” hotkey not working on boosted filtered posts (#33758 by @ClearlyClaire)
|
||||
|
||||
## [4.3.6] - 2025-03-13
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependency `omniauth-saml`
|
||||
- Update dependency `rack`
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix Stoplight errors when using `REDIS_NAMESPACE` (#34126 by @ClearlyClaire)
|
||||
|
||||
## [4.3.5] - 2025-03-10
|
||||
|
||||
### Changed
|
||||
|
||||
- Change hashtag suggestion to prefer personal history capitalization (#34070 by @ClearlyClaire)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix processing errors for some HEIF images from iOS 18 (#34086 by @renchap)
|
||||
- Fix streaming server not filtering unknown-language posts from public timelines (#33774 by @ClearlyClaire)
|
||||
- Fix preview cards under Content Warnings not being shown in detailed statuses (#34068 by @ClearlyClaire)
|
||||
- Fix username and display name being hidden on narrow screens in moderation interface (#33064 by @ClearlyClaire)
|
||||
|
||||
## [4.3.4] - 2025-02-27
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependencies
|
||||
- Change HTML sanitization to remove unusable and unused `embed` tag (#34021 by @ClearlyClaire, [GHSA-mq2m-hr29-8gqf](https://github.com/mastodon/mastodon/security/advisories/GHSA-mq2m-hr29-8gqf))
|
||||
- Fix rate-limit on sign-up email verification ([GHSA-v39f-c9jj-8w7h](https://github.com/mastodon/mastodon/security/advisories/GHSA-v39f-c9jj-8w7h))
|
||||
- Fix improper disclosure of domain blocks to unverified users ([GHSA-94h4-fj37-c825](https://github.com/mastodon/mastodon/security/advisories/GHSA-94h4-fj37-c825))
|
||||
|
||||
### Changed
|
||||
|
||||
- Change preview cards to be shown when Content Warnings are expanded (#33827 by @ClearlyClaire)
|
||||
- Change warnings against changing encryption secrets to be even more noticeable (#33631 by @ClearlyClaire)
|
||||
- Change `mastodon:setup` to prevent overwriting already-configured servers (#33603, #33616, and #33684 by @ClearlyClaire and @mjankowski)
|
||||
- Change notifications from moderators to not be filtered (#32974 and #33654 by @ClearlyClaire and @mjankowski)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `GET /api/v2/notifications/:id` and `POST /api/v2/notifications/:id/dismiss` for ungrouped notifications (#33990 by @ClearlyClaire)
|
||||
- Fix issue with some versions of libvips on some systems (#33853 by @kleisauke)
|
||||
- Fix handling of duplicate mentions in incoming status `Update` (#33911 by @ClearlyClaire)
|
||||
- Fix inefficiencies in timeline generation (#33839 and #33842 by @ClearlyClaire)
|
||||
- Fix emoji rewrite adding unnecessary curft to the DOM for most emoji (#33818 by @ClearlyClaire)
|
||||
- Fix `tootctl feeds build` not building list timelines (#33783 by @ClearlyClaire)
|
||||
- Fix flaky test in `/api/v2/notifications` tests (#33773 by @ClearlyClaire)
|
||||
- Fix incorrect signature after HTTP redirect (#33757 and #33769 by @ClearlyClaire)
|
||||
- Fix polls not being validated on edition (#33755 by @ClearlyClaire)
|
||||
- Fix media preview height in compose form when 3 or more images are attached (#33571 by @ClearlyClaire)
|
||||
- Fix preview card sizing in “Author attribution” in profile settings (#33482 by @ClearlyClaire)
|
||||
- Fix processing of incoming notifications for unfilterable types (#33429 by @ClearlyClaire)
|
||||
- Fix featured tags for remote accounts not being kept up to date (#33372, #33406, and #33425 by @ClearlyClaire and @mjankowski)
|
||||
- Fix notification polling showing a loading bar in web UI (#32960 by @Gargron)
|
||||
- Fix accounts table long display name (#29316 by @WebCoder49)
|
||||
- Fix exclusive lists interfering with notifications (#28162 by @ShadowJonathan)
|
||||
|
||||
## [4.3.3] - 2025-01-16
|
||||
|
||||
### Security
|
||||
|
||||
- Fix insufficient validation of account URIs ([GHSA-5wxh-3p65-r4g6](https://github.com/mastodon/mastodon/security/advisories/GHSA-5wxh-3p65-r4g6))
|
||||
- Update dependencies
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix `libyaml` missing from `Dockerfile` build stage (#33591 by @vmstan)
|
||||
- Fix incorrect notification settings migration for non-followers (#33348 by @ClearlyClaire)
|
||||
- Fix down clause for notification policy v2 migrations (#33340 by @jesseplusplus)
|
||||
- Fix error decrementing status count when `FeaturedTags#last_status_at` is `nil` (#33320 by @ClearlyClaire)
|
||||
- Fix last paginated notification group only including data on a single notification (#33271 by @ClearlyClaire)
|
||||
- Fix processing of mentions for post edits with an existing corresponding silent mention (#33227 by @ClearlyClaire)
|
||||
- Fix deletion of unconfirmed users with Webauthn set (#33186 by @ClearlyClaire)
|
||||
- Fix empty authors preview card serialization (#33151, #33466 by @mjankowski and @ClearlyClaire)
|
||||
|
||||
## [4.3.2] - 2024-12-03
|
||||
|
||||
### Added
|
||||
|
||||
- Add `tootctl feeds vacuum` (#33065 by @ClearlyClaire)
|
||||
- Add error message when user tries to follow their own account (#31910 by @lenikadali)
|
||||
- Add client_secret_expires_at to OAuth Applications (#30317 by @ThisIsMissEm)
|
||||
|
||||
### Changed
|
||||
|
||||
- Change design of Content Warnings and filters (#32543 by @ClearlyClaire)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fix processing incoming post edits with mentions to unresolvable accounts (#33129 by @ClearlyClaire)
|
||||
- Fix error when including multiple instances of `embed.js` (#33107 by @YKWeyer)
|
||||
- Fix inactive users' timelines being backfilled on follow and unsuspend (#33094 by @ClearlyClaire)
|
||||
- Fix direct inbox delivery pushing posts into inactive followers' timelines (#33067 by @ClearlyClaire)
|
||||
- Fix `TagFollow` records not being correctly handled in account operations (#33063 by @ClearlyClaire)
|
||||
- Fix pushing hashtag-followed posts to feeds of inactive users (#33018 by @Gargron)
|
||||
- Fix duplicate notifications in notification groups when using slow mode (#33014 by @ClearlyClaire)
|
||||
- Fix posts made in the future being allowed to trend (#32996 by @ClearlyClaire)
|
||||
- Fix uploading higher-than-wide GIF profile picture with libvips enabled (#32911 by @ClearlyClaire)
|
||||
- Fix domain attribution field having autocorrect and autocapitalize enabled (#32903 by @ClearlyClaire)
|
||||
- Fix titles being escaped twice (#32889 by @ClearlyClaire)
|
||||
- Fix list creation limit check (#32869 by @ClearlyClaire)
|
||||
- Fix error in `tootctl email_domain_blocks` when supplying `--with-dns-records` (#32863 by @mjankowski)
|
||||
- Fix `min_id` and `max_id` causing error in search API (#32857 by @Gargron)
|
||||
- Fix inefficiencies when processing removal of posts that use featured tags (#32787 by @ClearlyClaire)
|
||||
- Fix alt-text pop-in not using the translated description (#32766 by @ClearlyClaire)
|
||||
- Fix preview cards with long titles erroneously causing layout changes (#32678 by @ClearlyClaire)
|
||||
- Fix embed modal layout on mobile (#32641 by @DismalShadowX)
|
||||
- Fix and improve batch attachment deletion handling when using OpenStack Swift (#32637 by @hugogameiro)
|
||||
- Fix blocks not being applied on link timeline (#32625 by @tribela)
|
||||
- Fix follow counters being incorrectly changed (#32622 by @oneiros)
|
||||
- Fix 'unknown' media attachment type rendering (#32613 and #32713 by @ThisIsMissEm and @renatolond)
|
||||
- Fix tl language native name (#32606 by @seav)
|
||||
|
||||
### Security
|
||||
|
||||
- Update dependencies
|
||||
|
||||
## [4.3.1] - 2024-10-21
|
||||
|
||||
### Added
|
||||
|
@ -235,7 +93,7 @@ The following changelog entries focus on changes visible to users, administrator
|
|||
- **Add notifications of severed relationships** (#27511, #29665, #29668, #29670, #29700, #29714, #29712, and #29731 by @ClearlyClaire and @Gargron)\
|
||||
Notify local users when they lose relationships as a result of a local moderator blocking a remote account or server, allowing the affected user to retrieve the list of broken relationships.\
|
||||
Note that this does not notify remote users.\
|
||||
This adds the `severed_relationships` notification type to the REST API and streaming, with a new [`event` attribute](https://docs.joinmastodon.org/entities/Notification/#relationship_severance_event).
|
||||
This adds the `severed_relationships` notification type to the REST API and streaming, with a new [`relationship_severance_event` attribute](https://docs.joinmastodon.org/entities/Notification/#relationship_severance_event).
|
||||
- **Add hover cards in web UI** (#30754, #30864, #30850, #30879, #30928, #30949, #30948, #30931, and #31300 by @ClearlyClaire, @Gargron, and @renchap)\
|
||||
Hovering over an avatar or username will now display a hover card with the first two lines of the user's description and their first two profile fields.\
|
||||
This can be disabled in the “Animations and accessibility” section of the preferences.
|
||||
|
|
81
Dockerfile
81
Dockerfile
|
@ -1,7 +1,7 @@
|
|||
# syntax=docker/dockerfile:1.12
|
||||
|
||||
# This file is designed for production server deployment, not local development work
|
||||
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/docs/DEVELOPMENT.md#docker
|
||||
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
||||
|
||||
# Please see https://docs.docker.com/engine/reference/builder for information about
|
||||
# the extended buildx capabilities used in this file.
|
||||
|
@ -9,20 +9,19 @@
|
|||
# See: https://docs.docker.com/build/building/multi-platform/
|
||||
ARG TARGETPLATFORM=${TARGETPLATFORM}
|
||||
ARG BUILDPLATFORM=${BUILDPLATFORM}
|
||||
ARG BASE_REGISTRY="docker.io"
|
||||
|
||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.4.x"]
|
||||
# Ruby image to use for base image, change with [--build-arg RUBY_VERSION="3.3.x"]
|
||||
# renovate: datasource=docker depName=docker.io/ruby
|
||||
ARG RUBY_VERSION="3.4.2"
|
||||
# # Node.js version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||
ARG RUBY_VERSION="3.3.6"
|
||||
# # Node version to use in base image, change with [--build-arg NODE_MAJOR_VERSION="20"]
|
||||
# renovate: datasource=node-version depName=node
|
||||
ARG NODE_MAJOR_VERSION="22"
|
||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||
ARG DEBIAN_VERSION="bookworm"
|
||||
# Node.js image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||
FROM ${BASE_REGISTRY}/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS node
|
||||
# Ruby image to use for base image based on combined variables (ex: 3.4.x-slim-bookworm)
|
||||
FROM ${BASE_REGISTRY}/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
|
||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS node
|
||||
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
||||
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
|
||||
|
||||
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
||||
# Example: v4.3.0-nightly.2023.11.09+pr-123456
|
||||
|
@ -61,7 +60,7 @@ ENV \
|
|||
ENV \
|
||||
# Configure the IP to bind Mastodon to when serving traffic
|
||||
BIND="0.0.0.0" \
|
||||
# Use production settings for Yarn, Node.js and related tools
|
||||
# Use production settings for Yarn, Node and related nodejs based tools
|
||||
NODE_ENV="production" \
|
||||
# Use production settings for Ruby on Rails
|
||||
RAILS_ENV="production" \
|
||||
|
@ -96,9 +95,6 @@ RUN \
|
|||
# Set /opt/mastodon as working directory
|
||||
WORKDIR /opt/mastodon
|
||||
|
||||
# Add backport repository for some specific packages where we need the latest version
|
||||
RUN echo 'deb http://deb.debian.org/debian bookworm-backports main' >> /etc/apt/sources.list
|
||||
|
||||
# hadolint ignore=DL3008,DL3005
|
||||
RUN \
|
||||
# Mount Apt cache and lib directories from Docker buildx caches
|
||||
|
@ -128,6 +124,13 @@ RUN \
|
|||
# Create temporary build layer from base image
|
||||
FROM ruby AS build
|
||||
|
||||
# Copy Node package configuration files into working directory
|
||||
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||
COPY .yarn /opt/mastodon/.yarn
|
||||
|
||||
COPY --from=node /usr/local/bin /usr/local/bin
|
||||
COPY --from=node /usr/local/lib /usr/local/lib
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
# hadolint ignore=DL3008
|
||||
|
@ -150,7 +153,6 @@ RUN \
|
|||
libpq-dev \
|
||||
libssl-dev \
|
||||
libtool \
|
||||
libyaml-dev \
|
||||
meson \
|
||||
nasm \
|
||||
pkg-config \
|
||||
|
@ -161,7 +163,7 @@ RUN \
|
|||
libexif-dev \
|
||||
libexpat1-dev \
|
||||
libgirepository1.0-dev \
|
||||
libheif-dev/bookworm-backports \
|
||||
libheif-dev \
|
||||
libimagequant-dev \
|
||||
libjpeg62-turbo-dev \
|
||||
liblcms2-dev \
|
||||
|
@ -181,12 +183,18 @@ RUN \
|
|||
libx265-dev \
|
||||
;
|
||||
|
||||
RUN \
|
||||
# Configure Corepack
|
||||
rm /usr/local/bin/yarn*; \
|
||||
corepack enable; \
|
||||
corepack prepare --activate;
|
||||
|
||||
# Create temporary libvips specific build layer from build layer
|
||||
FROM build AS libvips
|
||||
|
||||
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
|
||||
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
|
||||
ARG VIPS_VERSION=8.16.1
|
||||
ARG VIPS_VERSION=8.16.0
|
||||
# libvips download URL, change with [--build-arg VIPS_URL="https://github.com/libvips/libvips/releases/download"]
|
||||
ARG VIPS_URL=https://github.com/libvips/libvips/releases/download
|
||||
|
||||
|
@ -271,37 +279,38 @@ RUN \
|
|||
# Download and install required Gems
|
||||
bundle install -j"$(nproc)";
|
||||
|
||||
# Create temporary assets build layer from build layer
|
||||
FROM build AS precompiler
|
||||
# Create temporary node specific build layer from build layer
|
||||
FROM build AS yarn
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
# Copy Mastodon sources into layer
|
||||
COPY . /opt/mastodon/
|
||||
|
||||
# Copy Node.js binaries/libraries into layer
|
||||
COPY --from=node /usr/local/bin /usr/local/bin
|
||||
COPY --from=node /usr/local/lib /usr/local/lib
|
||||
|
||||
RUN \
|
||||
# Configure Corepack
|
||||
rm /usr/local/bin/yarn*; \
|
||||
corepack enable; \
|
||||
corepack prepare --activate;
|
||||
# Copy Node package configuration files into working directory
|
||||
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||
COPY streaming/package.json /opt/mastodon/streaming/
|
||||
COPY .yarn /opt/mastodon/.yarn
|
||||
|
||||
# hadolint ignore=DL3008
|
||||
RUN \
|
||||
--mount=type=cache,id=corepack-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/corepack,sharing=locked \
|
||||
--mount=type=cache,id=yarn-cache-${TARGETPLATFORM},target=/usr/local/share/.cache/yarn,sharing=locked \
|
||||
# Install Node.js packages
|
||||
# Install Node packages
|
||||
yarn workspaces focus --production @mastodon/mastodon;
|
||||
|
||||
# Copy libvips components into layer for precompiler
|
||||
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||
# Copy bundler packages into layer for precompiler
|
||||
# Create temporary assets build layer from build layer
|
||||
FROM build AS precompiler
|
||||
|
||||
# Copy Mastodon sources into precompiler layer
|
||||
COPY . /opt/mastodon/
|
||||
|
||||
# Copy bundler and node packages from build layer to container
|
||||
COPY --from=yarn /opt/mastodon /opt/mastodon/
|
||||
COPY --from=bundler /opt/mastodon /opt/mastodon/
|
||||
COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||
# Copy libvips components to layer for precompiler
|
||||
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
|
||||
RUN \
|
||||
ldconfig; \
|
||||
|
@ -337,7 +346,7 @@ RUN \
|
|||
# libvips components
|
||||
libcgif0 \
|
||||
libexif12 \
|
||||
libheif1/bookworm-backports \
|
||||
libheif1 \
|
||||
libimagequant0 \
|
||||
libjpeg62-turbo \
|
||||
liblcms2-2 \
|
||||
|
|
64
Gemfile
64
Gemfile
|
@ -1,12 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby '>= 3.2.0', '< 3.5.0'
|
||||
ruby '>= 3.2.0'
|
||||
|
||||
gem 'propshaft'
|
||||
gem 'puma', '~> 6.3'
|
||||
gem 'rack', '~> 2.2.7'
|
||||
gem 'rails', '~> 8.0'
|
||||
gem 'rails', '~> 7.2.0'
|
||||
gem 'thor', '~> 1.2'
|
||||
|
||||
gem 'dotenv'
|
||||
|
@ -14,7 +14,6 @@ gem 'haml-rails', '~>2.0'
|
|||
gem 'pg', '~> 1.5'
|
||||
gem 'pghero'
|
||||
|
||||
gem 'aws-sdk-core', '< 3.216.0', require: false # TODO: https://github.com/mastodon/mastodon/pull/34173#issuecomment-2733378873
|
||||
gem 'aws-sdk-s3', '~> 1.123', require: false
|
||||
gem 'blurhash', '~> 0.1'
|
||||
gem 'fog-core', '<= 2.6.0'
|
||||
|
@ -40,7 +39,7 @@ gem 'net-ldap', '~> 0.18'
|
|||
|
||||
gem 'omniauth', '~> 2.0'
|
||||
gem 'omniauth-cas', '~> 3.0.0.beta.1'
|
||||
gem 'omniauth_openid_connect', '~> 0.8.0'
|
||||
gem 'omniauth_openid_connect', '~> 0.6.1'
|
||||
gem 'omniauth-rails_csrf_protection', '~> 1.0'
|
||||
gem 'omniauth-saml', '~> 2.0'
|
||||
|
||||
|
@ -62,7 +61,6 @@ gem 'inline_svg'
|
|||
gem 'irb', '~> 1.8'
|
||||
gem 'kaminari', '~> 1.2'
|
||||
gem 'link_header', '~> 0.0'
|
||||
gem 'linzer', '~> 0.6.1'
|
||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||
gem 'mime-types', '~> 3.6.0', require: 'mime/types/columnar'
|
||||
gem 'mutex_m'
|
||||
|
@ -75,13 +73,13 @@ gem 'public_suffix', '~> 6.0'
|
|||
gem 'pundit', '~> 2.3'
|
||||
gem 'rack-attack', '~> 6.6'
|
||||
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
||||
gem 'rails-i18n', '~> 8.0'
|
||||
gem 'rails-i18n', '~> 7.0'
|
||||
gem 'redcarpet', '~> 3.6'
|
||||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
||||
gem 'redis-namespace', '~> 1.10'
|
||||
gem 'rqrcode', '~> 2.2'
|
||||
gem 'ruby-progressbar', '~> 1.13'
|
||||
gem 'sanitize', '~> 7.0'
|
||||
gem 'sanitize', '~> 6.0'
|
||||
gem 'scenic', '~> 1.7'
|
||||
gem 'sidekiq', '~> 6.5'
|
||||
gem 'sidekiq-bulk', '~> 0.2.0'
|
||||
|
@ -96,31 +94,29 @@ gem 'twitter-text', '~> 3.1.0'
|
|||
gem 'tzinfo-data', '~> 1.2023'
|
||||
gem 'webauthn', '~> 3.0'
|
||||
gem 'webpacker', '~> 5.4'
|
||||
gem 'webpush', github: 'mastodon/webpush', ref: '9631ac63045cfabddacc69fc06e919b4c13eb913'
|
||||
gem 'webpush', github: 'ClearlyClaire/webpush', ref: 'f14a4d52e201128b1b00245d11b6de80d6cfdcd9'
|
||||
|
||||
gem 'json-ld'
|
||||
gem 'json-ld-preloaded', '~> 3.2'
|
||||
gem 'rdf-normalize', '~> 0.5'
|
||||
|
||||
gem 'prometheus_exporter', '~> 2.2', require: false
|
||||
|
||||
gem 'opentelemetry-api', '~> 1.5.0'
|
||||
gem 'opentelemetry-api', '~> 1.4.0'
|
||||
|
||||
group :opentelemetry do
|
||||
gem 'opentelemetry-exporter-otlp', '~> 0.30.0', require: false
|
||||
gem 'opentelemetry-instrumentation-active_job', '~> 0.8.0', require: false
|
||||
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.22.0', require: false
|
||||
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.22.0', require: false
|
||||
gem 'opentelemetry-instrumentation-excon', '~> 0.23.0', require: false
|
||||
gem 'opentelemetry-instrumentation-faraday', '~> 0.26.0', require: false
|
||||
gem 'opentelemetry-instrumentation-http', '~> 0.24.0', require: false
|
||||
gem 'opentelemetry-instrumentation-http_client', '~> 0.23.0', require: false
|
||||
gem 'opentelemetry-instrumentation-net_http', '~> 0.23.0', require: false
|
||||
gem 'opentelemetry-instrumentation-pg', '~> 0.30.0', require: false
|
||||
gem 'opentelemetry-instrumentation-rack', '~> 0.26.0', require: false
|
||||
gem 'opentelemetry-instrumentation-rails', '~> 0.36.0', require: false
|
||||
gem 'opentelemetry-instrumentation-redis', '~> 0.26.0', require: false
|
||||
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.26.0', require: false
|
||||
gem 'opentelemetry-exporter-otlp', '~> 0.29.0', require: false
|
||||
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
||||
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
||||
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
||||
gem 'opentelemetry-instrumentation-excon', '~> 0.22.0', require: false
|
||||
gem 'opentelemetry-instrumentation-faraday', '~> 0.24.1', require: false
|
||||
gem 'opentelemetry-instrumentation-http', '~> 0.23.2', require: false
|
||||
gem 'opentelemetry-instrumentation-http_client', '~> 0.22.3', require: false
|
||||
gem 'opentelemetry-instrumentation-net_http', '~> 0.22.4', require: false
|
||||
gem 'opentelemetry-instrumentation-pg', '~> 0.29.0', require: false
|
||||
gem 'opentelemetry-instrumentation-rack', '~> 0.25.0', require: false
|
||||
gem 'opentelemetry-instrumentation-rails', '~> 0.33.0', require: false
|
||||
gem 'opentelemetry-instrumentation-redis', '~> 0.25.3', require: false
|
||||
gem 'opentelemetry-instrumentation-sidekiq', '~> 0.25.2', require: false
|
||||
gem 'opentelemetry-sdk', '~> 1.4', require: false
|
||||
end
|
||||
|
||||
|
@ -129,7 +125,7 @@ group :test do
|
|||
gem 'flatware-rspec'
|
||||
|
||||
# Adds RSpec Error/Warning annotations to GitHub PRs on the Files tab
|
||||
gem 'rspec-github', '~> 3.0', require: false
|
||||
gem 'rspec-github', '~> 2.4', require: false
|
||||
|
||||
# RSpec helpers for email specs
|
||||
gem 'email_spec'
|
||||
|
@ -147,6 +143,9 @@ group :test do
|
|||
# Used to mock environment variables
|
||||
gem 'climate_control'
|
||||
|
||||
# Add back helpers functions removed in Rails 5.1
|
||||
gem 'rails-controller-testing', '~> 1.0'
|
||||
|
||||
# Validate schemas in specs
|
||||
gem 'json-schema', '~> 5.0'
|
||||
|
||||
|
@ -155,7 +154,7 @@ group :test do
|
|||
|
||||
gem 'shoulda-matchers'
|
||||
|
||||
# Coverage formatter for RSpec
|
||||
# Coverage formatter for RSpec test if DISABLE_SIMPLECOV is false
|
||||
gem 'simplecov', '~> 0.22', require: false
|
||||
gem 'simplecov-lcov', '~> 0.8', require: false
|
||||
|
||||
|
@ -167,14 +166,13 @@ group :development do
|
|||
# Code linting CLI and plugins
|
||||
gem 'rubocop', require: false
|
||||
gem 'rubocop-capybara', require: false
|
||||
gem 'rubocop-i18n', require: false
|
||||
gem 'rubocop-performance', require: false
|
||||
gem 'rubocop-rails', require: false
|
||||
gem 'rubocop-rspec', require: false
|
||||
gem 'rubocop-rspec_rails', require: false
|
||||
|
||||
# Annotates modules with schema
|
||||
gem 'annotaterb', '~> 4.13', require: false
|
||||
gem 'annotaterb', '~> 4.13'
|
||||
|
||||
# Enhanced error message pages for development
|
||||
gem 'better_errors', '~> 2.9'
|
||||
|
@ -185,7 +183,7 @@ group :development do
|
|||
gem 'letter_opener_web', '~> 3.0'
|
||||
|
||||
# Security analysis CLI tools
|
||||
gem 'brakeman', '~> 7.0', require: false
|
||||
gem 'brakeman', '~> 6.0', require: false
|
||||
gem 'bundler-audit', '~> 0.9', require: false
|
||||
|
||||
# Linter CLI for HAML files
|
||||
|
@ -197,7 +195,7 @@ end
|
|||
|
||||
group :development, :test do
|
||||
# Interactive Debugging tools
|
||||
gem 'debug', '~> 1.8', require: false
|
||||
gem 'debug', '~> 1.8'
|
||||
|
||||
# Generate fake data values
|
||||
gem 'faker', '~> 3.2'
|
||||
|
@ -209,7 +207,7 @@ group :development, :test do
|
|||
gem 'memory_profiler', require: false
|
||||
gem 'ruby-prof', require: false
|
||||
gem 'stackprof', require: false
|
||||
gem 'test-prof', require: false
|
||||
gem 'test-prof'
|
||||
|
||||
# RSpec runner for rails
|
||||
gem 'rspec-rails', '~> 7.0'
|
||||
|
@ -224,7 +222,7 @@ gem 'concurrent-ruby', require: false
|
|||
gem 'connection_pool', require: false
|
||||
gem 'xorcist', '~> 1.1'
|
||||
|
||||
gem 'net-http', '~> 0.6.0'
|
||||
gem 'net-http', '~> 0.5.0'
|
||||
gem 'rubyzip', '~> 2.3'
|
||||
|
||||
gem 'hcaptcha', '~> 7.1'
|
||||
|
|
658
Gemfile.lock
658
Gemfile.lock
File diff suppressed because it is too large
Load diff
124
README.md
124
README.md
|
@ -1,27 +1,123 @@
|
|||
NAS is an KMY & Mastodon Fork
|
||||
#  kmyblue
|
||||
|
||||
The following are just a few of the most common features. There are many other minor changes to the specifications.
|
||||
[](https://github.com/kmycode/mastodon/actions/workflows/test-ruby.yml)
|
||||
|
||||
Emoji reactions
|
||||
! FOR ENGLISH USER ! We do not provide English documentation for kmyblue; we assume that you will use automatic translation software, such as Google, to translate the site.
|
||||
|
||||
Local Public (Does not appear on the federated timeline of remote servers, but does appear on followers' home timelines. This is different from local only)
|
||||
kmyblueは、ActivityPubに接続するSNSの1つである[Mastodon](https://github.com/mastodon/mastodon)のフォークです。創作作家のためのMastodonを目指して開発しました。
|
||||
|
||||
Bookmark classification
|
||||
kmyblueはフォーク名であり、同時に[サーバー名](https://kmy.blue)でもあります。以下は特に記述がない限り、フォークとしてのkmyblueをさします。
|
||||
|
||||
Set who can search your posts for each post (Searchability)
|
||||
kmyblueは AGPL ライセンスで公開されているため、どなたでも自由にフォークし、このソースコードを元に自分でサーバーを立てて公開することができます。確かにサーバーkmyblueは創作作家向けの利用規約が設定されていますが、フォークとしてのkmyblueのルールは全くの別物です。いかなるコミュニティにも平等にお使いいただけます。
|
||||
kmyblueは、閉鎖的なコミュニティ、あまり目立ちたくないコミュニティには特に強力な機能を提供します。kmyblueはプライバシーを考慮したうえで強力な独自機能を提供するため、汎用サーバーとして利用するにもある程度十分な機能が揃っています。
|
||||
|
||||
Quote posts, modest quotes (references)
|
||||
テストコード、Lint どちらも動いています。
|
||||
|
||||
Record posts that meet certain conditions such as domains, accounts, and keywords (Subscriptions/Antennas)
|
||||
### アジェンダ
|
||||
|
||||
Send posts to a designated set of followers (Circles) (different from direct messages)
|
||||
- 利用方法
|
||||
- kmyblueの開発方針
|
||||
- kmyblueは何でないか
|
||||
- kmyblueの独自機能
|
||||
- 英語のサポートについて
|
||||
|
||||
Notification of new posts on lists
|
||||
## 利用方法
|
||||
|
||||
Exclude posts from people you follow when filtering posts
|
||||
### インストール方法
|
||||
|
||||
Hide number of followers and followings
|
||||
[Wiki](https://github.com/kmycode/mastodon/wiki/Installation)を参照してください。
|
||||
|
||||
Automatically delete posts after a specified time has passed
|
||||
### 開発への参加方法
|
||||
|
||||
Expanding moderation functions
|
||||
CONTRIBUTING.mdを参照してください。
|
||||
|
||||
### テスト
|
||||
|
||||
```
|
||||
# デバッグ実行(以下のいずれか)
|
||||
foreman start
|
||||
DB_USER=postgres DB_PASS=password foreman start
|
||||
|
||||
# 一部を除く全てのテストを行う
|
||||
RAILS_ENV=test bundle exec rspec spec
|
||||
|
||||
# ElasticSearch連携テストを行う
|
||||
新
|
||||
RAILS_ENV=test ES_ENABLED=true bundle exec rspec --tag search
|
||||
旧
|
||||
RAILS_ENV=test ES_ENABLED=true RUN_SEARCH_SPECS=true bundle exec rspec spec/search
|
||||
```
|
||||
|
||||
## kmyblueの開発方針
|
||||
|
||||
### 本家Mastodonへの積極的追従
|
||||
|
||||
kmyblueは、追加機能を控えめにする代わりに本家Mastodonに積極的に追従を行います。kmyblueの追加機能そのままに、Mastodonの新機能も利用できるよう調整を行います。
|
||||
|
||||
### ゆるやかな内輪での運用
|
||||
|
||||
kmyblueは同人向けサーバーとして出発したため、同人作家に需要のある「内輪ノリを外部にできるだけもらさない」という部分に特化しています。
|
||||
|
||||
「ローカル公開」は、投稿を見せたくない人に見つかりにくくする効果があります。「サークル」は、フォロワーの中でも特に見せたい人だけに見せる効果があります。
|
||||
「検索許可」という独自の検索オプションを利用することで、公開投稿の一部だけを検索されにくくするだけでなく、非収載投稿が誰でも自由に検索できるようになります。
|
||||
|
||||
内輪とは自分のサーバーに限ったものではありません。内輪同士で複数のサーバーを運営するとき、お互いが深く繋がれる「フレンドサーバー」というシステムも用意しています。
|
||||
|
||||
### 少人数サーバーでの運用
|
||||
|
||||
kmyblueは、人の少ないサーバーでの運用を考慮して設計しています。そのため、Fedibirdにあるような、人の多いサーバー向けの機能はあまり作っていません。
|
||||
|
||||
サーバーの負荷については一部度外視している部分があります。たとえば絵文字リアクション機能はサーバーへ著しい負荷をかける場合があります。ただしkmyblueでは、絵文字リアクション機能そのものを無効にしたり、負荷の高いストリーミング処理を無効にする管理者オプションも存在します。
|
||||
|
||||
もちろん人の多いサーバーでの運用が不便になるような修正は行っていません。人数にかかわらず、そのままお使いいただけます。
|
||||
|
||||
### 比較的高い防御力
|
||||
|
||||
kmyblueでは、「Fediverseは将来的に荒むのではないか」「Fediverseは将来的にスパムに溢れるのではないか」を念頭に設計している部分があります。投稿だけでなく絵文字リアクションも対象にした防衛策があります。
|
||||
|
||||
管理者は「NGワード」「NGルール」機能の利用が可能です。設定を変更することで、一部のモデレーターもこの機能を利用できます。
|
||||
利用者は、独自拡張されたフィルター機能、絵文字リアクションのブロックなどを利用できます。
|
||||
|
||||
ただし防御力の高さは自由を犠牲にします。例えばNGワードが多すぎると、他のサーバーからの投稿が制限され、かつそれに気づきにくくなります。
|
||||
|
||||
## kmyblueは何でないか
|
||||
|
||||
kmyblueは、企業・政府機関向けに開発されたものではありません。開発者はセキュリティに関する専門知識を有しておらず、高度なセキュリティを求められる機関向けのソフトウェアを制作する能力はありません。また、kmyblueのメンテナは現在1人のみであり、そのメンテナが飽きたら開発がストップするリスクも高いです。Mastodonのような高い信頼性・安全性を保証することはできないので、導入の際はご自身で安全を十分に確認してからお使いになることを強くおすすめします。
|
||||
個人サーバーであっても、安定性を強く求める方にはおすすめできません。glitch-socがよりよい選択肢になるでしょう。
|
||||
|
||||
kmyblueは、Misskeyではありません。Misskeyは「楽しむ」をコンセプトにしていますが、kmyblueはMastodonの思想を受け継ぎ、炎上や喧騒を避けることのできる落ち着いた場所を目指しています。そのため、思想に合わない機能は実装しないか、大幅に弱体化しています。
|
||||
|
||||
kmyblueは、Fedibirdではありません。Fedibirdは大規模サーバー向けに設定していると思われる機能があり、例えば購読機能がその代表例です。Fedibirdの購読は擬似的なフォロー体験を与えるものですが、本物のフォローではないため、購読対象の投稿が配送されることを確約したものではありません。小規模サーバーだとかえって不便になる機能を、kmyblueは避けています。
|
||||
|
||||
## kmyblueの独自機能
|
||||
|
||||
以下に列挙したものはあくまで代表的なものです。これ以外にも、細かい仕様変更などが多数含まれます。
|
||||
|
||||
- 絵文字リアクション
|
||||
- ローカル公開(Local Public)(リモートサーバーの連合タイムラインには流れませんが、フォロワーのホームタイムラインには流れます。**ローカル限定とは異なります**)
|
||||
- ブックマークの分類
|
||||
- 自分の投稿を検索できる人を投稿ごとに設定(検索許可・Searchability)
|
||||
- 投稿の引用、ひかえめな引用(参照)
|
||||
- ドメイン・アカウント・キーワードなど特定条件を満たした投稿を記録する機能(購読・アンテナ)
|
||||
- フォロワーの一部を指名して投稿を送る機能(サークル)(ダイレクトメッセージとは異なります)
|
||||
- リスト新着投稿の通知
|
||||
- 投稿のフィルタリングにおいて、自分がフォローしている相手の投稿を除外
|
||||
- フォロー・フォロワー数を隠す機能
|
||||
- 指定した時間が経過したあとに投稿を自動削除する機能
|
||||
- モデレーション機能の拡張
|
||||
|
||||
## 英語のサポートについて
|
||||
|
||||
kmyblueのメイン開発者である[雪あすか](https://kmy.blue/@askyq)は、英語の読み書きがほとんどできません。そのため、ドキュメントの英語化、海外向け公式アカウントの新設などを行う予定はありません。
|
||||
|
||||
要望やバグ報告はIssueに書いて構いませんが、Issue画面内の説明やテンプレートはすべて日本語になっています。投稿が難しければ、Discussionに投稿してください。こちらで必要と判断したものは、改めてIssueとして起票します。
|
||||
|
||||
そのほか開発者へ質問があれば、[@askyq@kmy.blue](https://kmy.blue/@askyq)へ英語のまま送ってください。
|
||||
|
||||
ただしkmyblueのドキュメント、[@askyq@kmy.blue](https://kmy.blue/@askyq)内のkmyblueフォークに関係する投稿を、許可なく翻訳して公開することは問題ありません。
|
||||
|
||||
## 開発者のアカウントについて
|
||||
|
||||
kmyblueのメイン開発者である[雪あすか](https://kmy.blue/@askyq)は、用途別にアカウントを分けるようなことはせず、すべての発言を1つのアカウントで行っています。そのため、kmyblueの開発だけでなく、成人向け同人作品の話も混ざっています。
|
||||
|
||||
このうち、公開範囲「公開」「ローカル公開」「非収載」であるkmyblueフォークの開発に関係する投稿に限り抽出し、翻訳の有無に関係なく公開することを許可します。これはkmyblueフォークの利用者にとって公共性の高いコンテンツであると思われます。これは、日本と欧米では一般的に考えられている児童ポルノの基準が異なり、欧米のサーバーの中にはこのアカウントをフォローしづらいものもあるという懸念を考慮したものです。
|
||||
|
|
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
@ -174,7 +174,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
if config.vm.networks.any? { |type, options| type == :private_network }
|
||||
config.vm.synced_folder ".", "/vagrant", type: "nfs", mount_options: ['rw', 'actimeo=1']
|
||||
else
|
||||
config.vm.synced_folder ".", "/vagrant", type: "rsync", create: true, rsync__args: ["--verbose", "--archive", "--delete", "-z"]
|
||||
config.vm.synced_folder ".", "/vagrant"
|
||||
end
|
||||
|
||||
# Otherwise, you can access the site at http://localhost:3000 and http://localhost:4000 , http://localhost:8080
|
||||
|
|
|
@ -49,7 +49,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
|
|||
|
||||
def collection_presenter
|
||||
ActivityPub::CollectionPresenter.new(
|
||||
id: ActivityPub::TagManager.instance.collection_uri_for(@account, params[:id]),
|
||||
id: account_collection_url(@account, params[:id]),
|
||||
type: @type,
|
||||
size: @size,
|
||||
items: @items
|
||||
|
|
|
@ -41,8 +41,12 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
|
|||
end
|
||||
end
|
||||
|
||||
def outbox_url(...)
|
||||
ActivityPub::TagManager.instance.outbox_uri_for(@account, ...)
|
||||
def outbox_url(**)
|
||||
if params[:account_username].present?
|
||||
account_outbox_url(@account, **)
|
||||
else
|
||||
instance_actor_outbox_url(**)
|
||||
end
|
||||
end
|
||||
|
||||
def next_page
|
||||
|
|
|
@ -34,8 +34,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(admin_account_action: [:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses])
|
||||
params.require(:admin_account_action).permit(:type, :report_id, :warning_preset_id, :text, :send_email_notification, :include_statuses)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -29,8 +29,10 @@ module Admin
|
|||
private
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(account_moderation_note: [:content, :target_account_id])
|
||||
params.require(:account_moderation_note).permit(
|
||||
:content,
|
||||
:target_account_id
|
||||
)
|
||||
end
|
||||
|
||||
def set_account_moderation_note
|
||||
|
|
|
@ -172,8 +172,7 @@ module Admin
|
|||
end
|
||||
|
||||
def form_account_batch_params
|
||||
params
|
||||
.expect(form_account_batch: [:action, account_ids: []])
|
||||
params.require(:form_account_batch).permit(:action, account_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Announcements::DistributionsController < Admin::BaseController
|
||||
before_action :set_announcement
|
||||
|
||||
def create
|
||||
authorize @announcement, :distribute?
|
||||
@announcement.touch(:notification_sent_at)
|
||||
Admin::DistributeAnnouncementNotificationWorker.perform_async(@announcement.id)
|
||||
redirect_to admin_announcements_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_announcement
|
||||
@announcement = Announcement.find(params[:announcement_id])
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Announcements::PreviewsController < Admin::BaseController
|
||||
before_action :set_announcement
|
||||
|
||||
def show
|
||||
authorize @announcement, :distribute?
|
||||
@user_count = @announcement.scope_for_notification.count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_announcement
|
||||
@announcement = Announcement.find(params[:announcement_id])
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Announcements::TestsController < Admin::BaseController
|
||||
before_action :set_announcement
|
||||
|
||||
def create
|
||||
authorize @announcement, :distribute?
|
||||
UserMailer.announcement_published(current_user, @announcement).deliver_later!
|
||||
redirect_to admin_announcements_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_announcement
|
||||
@announcement = Announcement.find(params[:announcement_id])
|
||||
end
|
||||
end
|
|
@ -84,7 +84,6 @@ class Admin::AnnouncementsController < Admin::BaseController
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(announcement: [:text, :scheduled_at, :starts_at, :ends_at, :all_day])
|
||||
params.require(:announcement).permit(:text, :scheduled_at, :starts_at, :ends_at, :all_day)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,14 +7,14 @@ module Admin
|
|||
|
||||
layout 'admin'
|
||||
|
||||
before_action :set_referrer_policy_header
|
||||
before_action :set_cache_headers
|
||||
|
||||
after_action :verify_authorized
|
||||
|
||||
private
|
||||
|
||||
def set_referrer_policy_header
|
||||
response.headers['Referrer-Policy'] = 'same-origin'
|
||||
def set_cache_headers
|
||||
response.cache_control.replace(private: true, no_store: true)
|
||||
end
|
||||
|
||||
def set_user
|
||||
|
|
|
@ -41,8 +41,9 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(user: [:unconfirmed_email])
|
||||
params.require(:user).permit(
|
||||
:unconfirmed_email
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -67,13 +67,11 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(custom_emoji: [:shortcode, :image, :category_id, :visible_in_picker, :aliases_raw, :license])
|
||||
params.require(:custom_emoji).permit(:shortcode, :image, :category_id, :visible_in_picker, :aliases_raw, :license)
|
||||
end
|
||||
|
||||
def update_params
|
||||
params
|
||||
.expect(custom_emoji: [:category_id, :visible_in_picker, :aliases_raw, :license])
|
||||
params.require(:custom_emoji).permit(:category_id, :visible_in_picker, :aliases_raw, :license)
|
||||
end
|
||||
|
||||
def filtered_custom_emojis
|
||||
|
@ -103,8 +101,7 @@ module Admin
|
|||
end
|
||||
|
||||
def form_custom_emoji_batch_params
|
||||
params
|
||||
.expect(form_custom_emoji_batch: [:action, :category_id, :category_name, custom_emoji_ids: []])
|
||||
params.require(:form_custom_emoji_batch).permit(:action, :category_id, :category_name, custom_emoji_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,6 @@ class Admin::DomainAllowsController < Admin::BaseController
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(domain_allow: [:domain])
|
||||
params.require(:domain_allow).permit(:domain)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,9 +35,7 @@ module Admin
|
|||
rescue Mastodon::NotPermittedError
|
||||
flash[:alert] = I18n.t('admin.domain_blocks.not_permitted')
|
||||
else
|
||||
flash[:notice] = I18n.t('admin.domain_blocks.created_msg')
|
||||
ensure
|
||||
redirect_to admin_instances_path(limited: '1')
|
||||
redirect_to admin_instances_path(limited: '1'), notice: I18n.t('admin.domain_blocks.created_msg')
|
||||
end
|
||||
|
||||
def new
|
||||
|
@ -126,14 +124,9 @@ module Admin
|
|||
end
|
||||
|
||||
def form_domain_block_batch_params
|
||||
params
|
||||
.expect(
|
||||
form_domain_block_batch: [
|
||||
domain_blocks_attributes: [[:enabled, :domain, :severity, :reject_media, :reject_reports, :private_comment, :public_comment, :obfuscate,
|
||||
:reject_favourite, :reject_reply_exclude_followers, :reject_send_sensitive, :reject_hashtag,
|
||||
:reject_straight_follow, :reject_new_follow, :reject_friend, :block_trends, :detect_invalid_subscription, :hidden]],
|
||||
]
|
||||
)
|
||||
params.require(:form_domain_block_batch).permit(domain_blocks_attributes: [:enabled, :domain, :severity, :reject_media, :reject_favourite, :reject_reply_exclude_followers,
|
||||
:reject_send_sensitive, :reject_hashtag, :reject_straight_follow, :reject_new_follow, :reject_friend, :block_trends, :detect_invalid_subscription,
|
||||
:reject_reports, :private_comment, :public_comment, :obfuscate, :hidden])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -62,13 +62,11 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(email_domain_block: [:domain, :allow_with_approval, other_domains: []])
|
||||
params.require(:email_domain_block).permit(:domain, :allow_with_approval, other_domains: [])
|
||||
end
|
||||
|
||||
def form_email_domain_block_batch_params
|
||||
params
|
||||
.expect(form_email_domain_block_batch: [email_domain_block_ids: []])
|
||||
params.require(:form_email_domain_block_batch).permit(email_domain_block_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Fasp::Debug::CallbacksController < Admin::BaseController
|
||||
def index
|
||||
authorize [:admin, :fasp, :provider], :update?
|
||||
|
||||
@callbacks = Fasp::DebugCallback
|
||||
.includes(:fasp_provider)
|
||||
.order(created_at: :desc)
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize [:admin, :fasp, :provider], :update?
|
||||
|
||||
callback = Fasp::DebugCallback.find(params[:id])
|
||||
callback.destroy
|
||||
|
||||
redirect_to admin_fasp_debug_callbacks_path
|
||||
end
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Fasp::DebugCallsController < Admin::BaseController
|
||||
before_action :set_provider
|
||||
|
||||
def create
|
||||
authorize [:admin, @provider], :update?
|
||||
|
||||
@provider.perform_debug_call
|
||||
|
||||
redirect_to admin_fasp_providers_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_provider
|
||||
@provider = Fasp::Provider.find(params[:provider_id])
|
||||
end
|
||||
end
|
|
@ -1,47 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Fasp::ProvidersController < Admin::BaseController
|
||||
before_action :set_provider, only: [:show, :edit, :update, :destroy]
|
||||
|
||||
def index
|
||||
authorize [:admin, :fasp, :provider], :index?
|
||||
|
||||
@providers = Fasp::Provider.order(confirmed: :asc, created_at: :desc)
|
||||
end
|
||||
|
||||
def show
|
||||
authorize [:admin, @provider], :show?
|
||||
end
|
||||
|
||||
def edit
|
||||
authorize [:admin, @provider], :update?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize [:admin, @provider], :update?
|
||||
|
||||
if @provider.update(provider_params)
|
||||
redirect_to admin_fasp_providers_path
|
||||
else
|
||||
render :edit
|
||||
end
|
||||
end
|
||||
|
||||
def destroy
|
||||
authorize [:admin, @provider], :destroy?
|
||||
|
||||
@provider.destroy
|
||||
|
||||
redirect_to admin_fasp_providers_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def provider_params
|
||||
params.expect(fasp_provider: [capabilities_attributes: {}])
|
||||
end
|
||||
|
||||
def set_provider
|
||||
@provider = Fasp::Provider.find(params[:id])
|
||||
end
|
||||
end
|
|
@ -1,23 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::Fasp::RegistrationsController < Admin::BaseController
|
||||
before_action :set_provider
|
||||
|
||||
def new
|
||||
authorize [:admin, @provider], :create?
|
||||
end
|
||||
|
||||
def create
|
||||
authorize [:admin, @provider], :create?
|
||||
|
||||
@provider.update_info!(confirm: true)
|
||||
|
||||
redirect_to edit_admin_fasp_provider_path(@provider)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_provider
|
||||
@provider = Fasp::Provider.find(params[:provider_id])
|
||||
end
|
||||
end
|
|
@ -37,8 +37,7 @@ module Admin
|
|||
end
|
||||
|
||||
def form_account_batch_params
|
||||
params
|
||||
.expect(form_account_batch: [:action, account_ids: []])
|
||||
params.require(:form_account_batch).permit(:action, account_ids: [])
|
||||
end
|
||||
|
||||
def filter_params
|
||||
|
|
|
@ -79,11 +79,11 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params.expect(friend_domain: [:domain, :inbox_url, :available, :pseudo_relay, :delivery_local, :unlocked, :allow_all_posts])
|
||||
params.require(:friend_domain).permit(:domain, :inbox_url, :available, :pseudo_relay, :delivery_local, :unlocked, :allow_all_posts)
|
||||
end
|
||||
|
||||
def update_resource_params
|
||||
params.expect(friend_domain: [:inbox_url, :available, :pseudo_relay, :delivery_local, :unlocked, :allow_all_posts])
|
||||
params.require(:friend_domain).permit(:inbox_url, :available, :pseudo_relay, :delivery_local, :unlocked, :allow_all_posts)
|
||||
end
|
||||
|
||||
def warn_signatures_not_enabled!
|
||||
|
|
|
@ -39,8 +39,7 @@ module Admin
|
|||
private
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(invite: [:max_uses, :expires_in])
|
||||
params.require(:invite).permit(:max_uses, :expires_in)
|
||||
end
|
||||
|
||||
def filtered_invites
|
||||
|
|
|
@ -44,8 +44,7 @@ module Admin
|
|||
private
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(ip_block: [:ip, :severity, :comment, :expires_in])
|
||||
params.require(:ip_block).permit(:ip, :severity, :comment, :expires_in)
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
@ -53,8 +52,7 @@ module Admin
|
|||
end
|
||||
|
||||
def form_ip_block_batch_params
|
||||
params
|
||||
.expect(form_ip_block_batch: [ip_block_ids: []])
|
||||
params.require(:form_ip_block_batch).permit(ip_block_ids: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -82,16 +82,16 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params.expect(ng_rule: [:title, :expires_in, :available, :account_domain, :account_username, :account_display_name,
|
||||
:account_note, :account_field_name, :account_field_value, :account_avatar_state,
|
||||
:account_header_state, :account_include_local, :status_spoiler_text, :status_text, :status_tag,
|
||||
:status_sensitive_state, :status_cw_state, :status_media_state, :status_poll_state,
|
||||
:status_mention_state, :status_reference_state,
|
||||
:status_quote_state, :status_reply_state, :status_media_threshold, :status_poll_threshold,
|
||||
:status_mention_threshold, :status_allow_follower_mention,
|
||||
:reaction_allow_follower, :emoji_reaction_name, :emoji_reaction_origin_domain,
|
||||
:status_reference_threshold, :account_allow_followed_by_local, :record_history_also_local,
|
||||
status_visibility: [], status_searchability: [], reaction_type: []])
|
||||
params.require(:ng_rule).permit(:title, :expires_in, :available, :account_domain, :account_username, :account_display_name,
|
||||
:account_note, :account_field_name, :account_field_value, :account_avatar_state,
|
||||
:account_header_state, :account_include_local, :status_spoiler_text, :status_text, :status_tag,
|
||||
:status_sensitive_state, :status_cw_state, :status_media_state, :status_poll_state,
|
||||
:status_mention_state, :status_reference_state,
|
||||
:status_quote_state, :status_reply_state, :status_media_threshold, :status_poll_threshold,
|
||||
:status_mention_threshold, :status_allow_follower_mention,
|
||||
:reaction_allow_follower, :emoji_reaction_name, :emoji_reaction_origin_domain,
|
||||
:status_reference_threshold, :account_allow_followed_by_local, :record_history_also_local,
|
||||
status_visibility: [], status_searchability: [], reaction_type: [])
|
||||
end
|
||||
|
||||
def test_words!
|
||||
|
|
|
@ -21,10 +21,6 @@ module Admin
|
|||
false
|
||||
end
|
||||
|
||||
def avoid_save?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def after_update_redirect_path
|
||||
|
|
|
@ -13,12 +13,6 @@ module Admin
|
|||
|
||||
return unless validate
|
||||
|
||||
if avoid_save?
|
||||
flash[:notice] = I18n.t('generic.changes_saved_msg')
|
||||
redirect_to after_update_redirect_path
|
||||
return
|
||||
end
|
||||
|
||||
@admin_settings = Form::AdminSettings.new(settings_params)
|
||||
|
||||
if @admin_settings.save
|
||||
|
@ -39,18 +33,14 @@ module Admin
|
|||
admin_ng_words_path
|
||||
end
|
||||
|
||||
def avoid_save?
|
||||
false
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def settings_params
|
||||
params.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
|
||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||
end
|
||||
|
||||
def settings_params_test
|
||||
params.expect(form_admin_settings: [ng_words_test: [keywords: [], regexps: [], strangers: [], temporary_ids: []]])['ng_words_test']
|
||||
params.require(:form_admin_settings)[:ng_words_test]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -57,8 +57,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(relay: [:inbox_url])
|
||||
params.require(:relay).permit(:inbox_url)
|
||||
end
|
||||
|
||||
def warn_signatures_not_enabled!
|
||||
|
|
|
@ -47,8 +47,10 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(report_note: [:content, :report_id])
|
||||
params.require(:report_note).permit(
|
||||
:content,
|
||||
:report_id
|
||||
)
|
||||
end
|
||||
|
||||
def set_report_note
|
||||
|
|
|
@ -61,8 +61,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(user_role: [:name, :color, :highlighted, :position, permissions_as_keys: []])
|
||||
params.require(:user_role).permit(:name, :color, :highlighted, :position, permissions_as_keys: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,8 +53,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(rule: [:text, :hint, :priority])
|
||||
params.require(:rule).permit(:text, :hint, :priority)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ module Admin
|
|||
end
|
||||
|
||||
def settings_params
|
||||
params.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
|
||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||
end
|
||||
|
||||
def settings_params_test
|
||||
|
|
|
@ -28,8 +28,7 @@ module Admin
|
|||
end
|
||||
|
||||
def settings_params
|
||||
params
|
||||
.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
|
||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,7 +6,7 @@ module Admin
|
|||
|
||||
def index
|
||||
authorize :software_update, :index?
|
||||
@software_updates = SoftwareUpdate.by_version.filter(&:pending?)
|
||||
@software_updates = SoftwareUpdate.all.sort_by(&:gem_version)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -28,7 +28,7 @@ module Admin
|
|||
end
|
||||
|
||||
def settings_params
|
||||
params.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
|
||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,7 +28,7 @@ module Admin
|
|||
end
|
||||
|
||||
def settings_params
|
||||
params.expect(form_admin_settings: [*Form::AdminSettings::KEYS])
|
||||
params.require(:form_admin_settings).permit(*Form::AdminSettings::KEYS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -98,8 +98,7 @@ module Admin
|
|||
helper_method :batched_ordered_status_edits
|
||||
|
||||
def admin_status_batch_action_params
|
||||
params
|
||||
.expect(admin_status_batch_action: [status_ids: []])
|
||||
params.require(:admin_status_batch_action).permit(status_ids: [])
|
||||
end
|
||||
|
||||
def after_create_redirect_path
|
||||
|
|
|
@ -37,8 +37,7 @@ module Admin
|
|||
end
|
||||
|
||||
def tag_params
|
||||
params
|
||||
.expect(tag: [:name, :display_name, :trendable, :usable, :listable])
|
||||
params.require(:tag).permit(:name, :display_name, :trendable, :usable, :listable)
|
||||
end
|
||||
|
||||
def filtered_tags
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::DistributionsController < Admin::BaseController
|
||||
before_action :set_terms_of_service
|
||||
|
||||
def create
|
||||
authorize @terms_of_service, :distribute?
|
||||
@terms_of_service.touch(:notification_sent_at)
|
||||
Admin::DistributeTermsOfServiceNotificationWorker.perform_async(@terms_of_service.id)
|
||||
redirect_to admin_terms_of_service_index_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_terms_of_service
|
||||
@terms_of_service = TermsOfService.find(params[:terms_of_service_id])
|
||||
end
|
||||
end
|
|
@ -1,37 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::DraftsController < Admin::BaseController
|
||||
before_action :set_terms_of_service
|
||||
|
||||
def show
|
||||
authorize :terms_of_service, :create?
|
||||
end
|
||||
|
||||
def update
|
||||
authorize @terms_of_service, :update?
|
||||
|
||||
@terms_of_service.published_at = Time.now.utc if params[:action_type] == 'publish'
|
||||
|
||||
if @terms_of_service.update(resource_params)
|
||||
log_action(:publish, @terms_of_service) if @terms_of_service.published?
|
||||
redirect_to @terms_of_service.published? ? admin_terms_of_service_index_path : admin_terms_of_service_draft_path
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_terms_of_service
|
||||
@terms_of_service = TermsOfService.draft.first || TermsOfService.new(text: current_terms_of_service&.text, effective_date: 10.days.from_now)
|
||||
end
|
||||
|
||||
def current_terms_of_service
|
||||
TermsOfService.live.first
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(terms_of_service: [:text, :changelog, :effective_date])
|
||||
end
|
||||
end
|
|
@ -1,38 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::GeneratesController < Admin::BaseController
|
||||
before_action :set_instance_presenter
|
||||
|
||||
def show
|
||||
authorize :terms_of_service, :create?
|
||||
|
||||
@generator = TermsOfService::Generator.new(
|
||||
domain: @instance_presenter.domain,
|
||||
admin_email: @instance_presenter.contact.email
|
||||
)
|
||||
end
|
||||
|
||||
def create
|
||||
authorize :terms_of_service, :create?
|
||||
|
||||
@generator = TermsOfService::Generator.new(resource_params)
|
||||
|
||||
if @generator.valid?
|
||||
TermsOfService.create!(text: @generator.render)
|
||||
redirect_to admin_terms_of_service_draft_path
|
||||
else
|
||||
render :show
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_instance_presenter
|
||||
@instance_presenter = InstancePresenter.new
|
||||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(terms_of_service_generator: [*TermsOfService::Generator::VARIABLES])
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::HistoriesController < Admin::BaseController
|
||||
def show
|
||||
authorize :terms_of_service, :index?
|
||||
@terms_of_service = TermsOfService.published.all
|
||||
end
|
||||
end
|
|
@ -1,16 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::PreviewsController < Admin::BaseController
|
||||
before_action :set_terms_of_service
|
||||
|
||||
def show
|
||||
authorize @terms_of_service, :distribute?
|
||||
@user_count = @terms_of_service.scope_for_notification.count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_terms_of_service
|
||||
@terms_of_service = TermsOfService.find(params[:terms_of_service_id])
|
||||
end
|
||||
end
|
|
@ -1,17 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfService::TestsController < Admin::BaseController
|
||||
before_action :set_terms_of_service
|
||||
|
||||
def create
|
||||
authorize @terms_of_service, :distribute?
|
||||
UserMailer.terms_of_service_changed(current_user, @terms_of_service).deliver_later!
|
||||
redirect_to admin_terms_of_service_preview_path(@terms_of_service)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_terms_of_service
|
||||
@terms_of_service = TermsOfService.find(params[:terms_of_service_id])
|
||||
end
|
||||
end
|
|
@ -1,8 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Admin::TermsOfServiceController < Admin::BaseController
|
||||
def index
|
||||
authorize :terms_of_service, :index?
|
||||
@terms_of_service = TermsOfService.published.first
|
||||
end
|
||||
end
|
|
@ -31,8 +31,7 @@ class Admin::Trends::Links::PreviewCardProvidersController < Admin::BaseControll
|
|||
end
|
||||
|
||||
def trends_preview_card_provider_batch_params
|
||||
params
|
||||
.expect(trends_preview_card_provider_batch: [:action, preview_card_provider_ids: []])
|
||||
params.require(:trends_preview_card_provider_batch).permit(:action, preview_card_provider_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -31,8 +31,7 @@ class Admin::Trends::LinksController < Admin::BaseController
|
|||
end
|
||||
|
||||
def trends_preview_card_batch_params
|
||||
params
|
||||
.expect(trends_preview_card_batch: [:action, preview_card_ids: []])
|
||||
params.require(:trends_preview_card_batch).permit(:action, preview_card_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -31,8 +31,7 @@ class Admin::Trends::StatusesController < Admin::BaseController
|
|||
end
|
||||
|
||||
def trends_status_batch_params
|
||||
params
|
||||
.expect(trends_status_batch: [:action, status_ids: []])
|
||||
params.require(:trends_status_batch).permit(:action, status_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -31,8 +31,7 @@ class Admin::Trends::TagsController < Admin::BaseController
|
|||
end
|
||||
|
||||
def trends_tag_batch_params
|
||||
params
|
||||
.expect(trends_tag_batch: [:action, tag_ids: []])
|
||||
params.require(:trends_tag_batch).permit(:action, tag_ids: [])
|
||||
end
|
||||
|
||||
def action_from_button
|
||||
|
|
|
@ -28,8 +28,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(user: [:role_id])
|
||||
params.require(:user).permit(:role_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -52,8 +52,7 @@ module Admin
|
|||
end
|
||||
|
||||
def warning_preset_params
|
||||
params
|
||||
.expect(account_warning_preset: [:title, :text])
|
||||
params.require(:account_warning_preset).permit(:title, :text)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -74,8 +74,7 @@ module Admin
|
|||
end
|
||||
|
||||
def resource_params
|
||||
params
|
||||
.expect(webhook: [:url, :template, events: []])
|
||||
params.require(:webhook).permit(:url, :template, events: [])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,81 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::Fasp::BaseController < ApplicationController
|
||||
class Error < ::StandardError; end
|
||||
|
||||
DIGEST_PATTERN = /sha-256=:(.*?):/
|
||||
KEYID_PATTERN = /keyid="(.*?)"/
|
||||
|
||||
attr_reader :current_provider
|
||||
|
||||
skip_forgery_protection
|
||||
|
||||
before_action :check_fasp_enabled
|
||||
before_action :require_authentication
|
||||
after_action :sign_response
|
||||
|
||||
private
|
||||
|
||||
def require_authentication
|
||||
validate_content_digest!
|
||||
validate_signature!
|
||||
rescue Error, Linzer::Error, ActiveRecord::RecordNotFound => e
|
||||
logger.debug("FASP Authentication error: #{e}")
|
||||
authentication_error
|
||||
end
|
||||
|
||||
def authentication_error
|
||||
respond_to do |format|
|
||||
format.json { head 401 }
|
||||
end
|
||||
end
|
||||
|
||||
def validate_content_digest!
|
||||
content_digest_header = request.headers['content-digest']
|
||||
raise Error, 'content-digest missing' if content_digest_header.blank?
|
||||
|
||||
digest_received = content_digest_header.match(DIGEST_PATTERN)[1]
|
||||
|
||||
digest_computed = OpenSSL::Digest.base64digest('sha256', request.body&.string || '')
|
||||
|
||||
raise Error, 'content-digest does not match' if digest_received != digest_computed
|
||||
end
|
||||
|
||||
def validate_signature!
|
||||
signature_input = request.headers['signature-input']&.encode('UTF-8')
|
||||
raise Error, 'signature-input is missing' if signature_input.blank?
|
||||
|
||||
keyid = signature_input.match(KEYID_PATTERN)[1]
|
||||
provider = Fasp::Provider.find(keyid)
|
||||
linzer_request = Linzer.new_request(
|
||||
request.method,
|
||||
request.original_url,
|
||||
{},
|
||||
{
|
||||
'content-digest' => request.headers['content-digest'],
|
||||
'signature-input' => signature_input,
|
||||
'signature' => request.headers['signature'],
|
||||
}
|
||||
)
|
||||
message = Linzer::Message.new(linzer_request)
|
||||
key = Linzer.new_ed25519_public_key(provider.provider_public_key_pem, keyid)
|
||||
signature = Linzer::Signature.build(message.headers)
|
||||
Linzer.verify(key, message, signature)
|
||||
@current_provider = provider
|
||||
end
|
||||
|
||||
def sign_response
|
||||
response.headers['content-digest'] = "sha-256=:#{OpenSSL::Digest.base64digest('sha256', response.body || '')}:"
|
||||
|
||||
linzer_response = Linzer.new_response(response.body, response.status, { 'content-digest' => response.headers['content-digest'] })
|
||||
message = Linzer::Message.new(linzer_response)
|
||||
key = Linzer.new_ed25519_key(current_provider.server_private_key_pem)
|
||||
signature = Linzer.sign(key, message, %w(@status content-digest))
|
||||
|
||||
response.headers.merge!(signature.to_h)
|
||||
end
|
||||
|
||||
def check_fasp_enabled
|
||||
raise ActionController::RoutingError unless Mastodon::Feature.fasp_enabled?
|
||||
end
|
||||
end
|
|
@ -1,15 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::Fasp::Debug::V0::Callback::ResponsesController < Api::Fasp::BaseController
|
||||
def create
|
||||
Fasp::DebugCallback.create(
|
||||
fasp_provider: current_provider,
|
||||
ip: request.remote_ip,
|
||||
request_body: request.raw_post
|
||||
)
|
||||
|
||||
respond_to do |format|
|
||||
format.json { head 201 }
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,26 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::Fasp::RegistrationsController < Api::Fasp::BaseController
|
||||
skip_before_action :require_authentication
|
||||
|
||||
def create
|
||||
@current_provider = Fasp::Provider.create!(
|
||||
name: params[:name],
|
||||
base_url: params[:baseUrl],
|
||||
remote_identifier: params[:serverId],
|
||||
provider_public_key_base64: params[:publicKey]
|
||||
)
|
||||
|
||||
render json: registration_confirmation
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def registration_confirmation
|
||||
{
|
||||
faspId: current_provider.id.to_s,
|
||||
publicKey: current_provider.server_public_key_base64,
|
||||
registrationCompletionUri: new_admin_fasp_provider_registration_url(current_provider),
|
||||
}
|
||||
end
|
||||
end
|
|
@ -14,7 +14,7 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||
@account = current_account
|
||||
UpdateAccountService.new.call(@account, account_params, raise_error: true)
|
||||
current_user.update(user_params) if user_params
|
||||
ActivityPub::UpdateDistributionWorker.perform_in(ActivityPub::UpdateDistributionWorker::DEBOUNCE_DELAY, @account.id)
|
||||
ActivityPub::UpdateDistributionWorker.perform_async(@account.id)
|
||||
render json: @account, serializer: REST::CredentialAccountSerializer
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
render json: ValidationErrorFormatter.new(e).as_json, status: 422
|
||||
|
@ -34,7 +34,6 @@ class Api::V1::Accounts::CredentialsController < Api::BaseController
|
|||
:searchability,
|
||||
:hide_collections,
|
||||
:indexable,
|
||||
attribution_domains: [],
|
||||
fields_attributes: [:name, :value]
|
||||
)
|
||||
end
|
||||
|
|
|
@ -1,66 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::EndorsementsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { authorize_if_got_token! :read, :'read:accounts' }, only: :index
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }, except: :index
|
||||
before_action :require_user!, except: :index
|
||||
before_action :set_account
|
||||
before_action :set_endorsed_accounts, only: :index
|
||||
after_action :insert_pagination_headers, only: :index
|
||||
|
||||
def index
|
||||
cache_if_unauthenticated!
|
||||
render json: @endorsed_accounts, each_serializer: REST::AccountSerializer
|
||||
end
|
||||
|
||||
def create
|
||||
AccountPin.find_or_create_by!(account: current_account, target_account: @account)
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
||||
end
|
||||
|
||||
def destroy
|
||||
pin = AccountPin.find_by(account: current_account, target_account: @account)
|
||||
pin&.destroy!
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = Account.find(params[:account_id])
|
||||
end
|
||||
|
||||
def set_endorsed_accounts
|
||||
@endorsed_accounts = @account.unavailable? ? [] : paginated_endorsed_accounts
|
||||
end
|
||||
|
||||
def paginated_endorsed_accounts
|
||||
@account.endorsed_accounts.without_suspended.includes(:account_stat, :user).paginate_by_max_id(
|
||||
limit_param(DEFAULT_ACCOUNTS_LIMIT),
|
||||
params[:max_id],
|
||||
params[:since_id]
|
||||
)
|
||||
end
|
||||
|
||||
def relationships_presenter
|
||||
AccountRelationshipsPresenter.new([@account], current_user.account_id)
|
||||
end
|
||||
|
||||
def next_path
|
||||
api_v1_account_endorsements_url pagination_params(max_id: pagination_max_id) if records_continue?
|
||||
end
|
||||
|
||||
def prev_path
|
||||
api_v1_account_endorsements_url pagination_params(since_id: pagination_since_id) unless @endorsed_accounts.empty?
|
||||
end
|
||||
|
||||
def pagination_collection
|
||||
@endorsed_accounts
|
||||
end
|
||||
|
||||
def records_continue?
|
||||
@endorsed_accounts.size == limit_param(DEFAULT_ACCOUNTS_LIMIT)
|
||||
end
|
||||
end
|
|
@ -17,6 +17,6 @@ class Api::V1::Accounts::FeaturedTagsController < Api::BaseController
|
|||
end
|
||||
|
||||
def set_featured_tags
|
||||
@featured_tags = @account.unavailable? ? [] : @account.featured_tags
|
||||
@featured_tags = @account.suspended? ? [] : @account.featured_tags
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::IdentityProofsController < Api::BaseController
|
||||
include DeprecationConcern
|
||||
|
||||
deprecate_api '2022-03-30'
|
||||
|
||||
before_action :require_user!
|
||||
before_action :set_account
|
||||
|
||||
|
|
30
app/controllers/api/v1/accounts/pins_controller.rb
Normal file
30
app/controllers/api/v1/accounts/pins_controller.rb
Normal file
|
@ -0,0 +1,30 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Accounts::PinsController < Api::BaseController
|
||||
include Authorization
|
||||
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:accounts' }
|
||||
before_action :require_user!
|
||||
before_action :set_account
|
||||
|
||||
def create
|
||||
AccountPin.find_or_create_by!(account: current_account, target_account: @account)
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
||||
end
|
||||
|
||||
def destroy
|
||||
pin = AccountPin.find_by(account: current_account, target_account: @account)
|
||||
pin&.destroy!
|
||||
render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_account
|
||||
@account = Account.find(params[:account_id])
|
||||
end
|
||||
|
||||
def relationships_presenter
|
||||
AccountRelationshipsPresenter.new([@account], current_user.account_id)
|
||||
end
|
||||
end
|
|
@ -124,7 +124,7 @@ class Api::V1::AccountsController < Api::BaseController
|
|||
end
|
||||
|
||||
def account_params
|
||||
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code, :date_of_birth)
|
||||
params.permit(:username, :email, :password, :agreement, :locale, :reason, :time_zone, :invite_code)
|
||||
end
|
||||
|
||||
def invite
|
||||
|
|
|
@ -21,7 +21,7 @@ class Api::V1::AntennasController < Api::BaseController
|
|||
end
|
||||
|
||||
def create
|
||||
@antenna = Antenna.create!(antenna_params.merge(account: current_account))
|
||||
@antenna = Antenna.create!(antenna_params.merge(account: current_account, list_id: 0))
|
||||
render json: @antenna, serializer: REST::AntennaSerializer
|
||||
end
|
||||
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::FiltersController < Api::BaseController
|
||||
include DeprecationConcern
|
||||
|
||||
deprecate_api '2022-11-14'
|
||||
|
||||
before_action -> { doorkeeper_authorize! :read, :'read:filters' }, only: [:index, :show]
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:filters' }, except: [:index, :show]
|
||||
before_action :require_user!
|
||||
|
|
|
@ -31,7 +31,7 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr
|
|||
end
|
||||
|
||||
def show_domain_blocks_to_user?
|
||||
Setting.show_domain_blocks == 'users' && user_signed_in? && current_user.functional_or_moved?
|
||||
Setting.show_domain_blocks == 'users' && user_signed_in?
|
||||
end
|
||||
|
||||
def set_domain_blocks
|
||||
|
@ -47,6 +47,6 @@ class Api::V1::Instances::DomainBlocksController < Api::V1::Instances::BaseContr
|
|||
end
|
||||
|
||||
def show_rationale_for_user?
|
||||
Setting.show_domain_blocks_rationale == 'users' && user_signed_in? && current_user.functional_or_moved?
|
||||
Setting.show_domain_blocks_rationale == 'users' && user_signed_in?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::Instances::TermsOfServicesController < Api::V1::Instances::BaseController
|
||||
before_action :set_terms_of_service
|
||||
|
||||
def show
|
||||
cache_even_if_authenticated!
|
||||
render json: @terms_of_service, serializer: REST::TermsOfServiceSerializer
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_terms_of_service
|
||||
@terms_of_service = begin
|
||||
if params[:date].present?
|
||||
TermsOfService.published.find_by!(effective_date: params[:date])
|
||||
else
|
||||
TermsOfService.live.first || TermsOfService.published.first! # For the case when none of the published terms have become effective yet
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,9 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Api::V1::InstancesController < Api::V2::InstancesController
|
||||
include DeprecationConcern
|
||||
class Api::V1::InstancesController < Api::BaseController
|
||||
skip_before_action :require_authenticated_user!, unless: :limited_federation_mode?
|
||||
skip_around_action :set_locale
|
||||
|
||||
deprecate_api '2022-11-14'
|
||||
vary_by ''
|
||||
|
||||
# Override `current_user` to avoid reading session cookies unless in limited federation mode
|
||||
def current_user
|
||||
super if limited_federation_mode?
|
||||
end
|
||||
|
||||
def show
|
||||
cache_even_if_authenticated!
|
||||
|
|
|
@ -7,6 +7,10 @@ class Api::V1::ListsController < Api::BaseController
|
|||
before_action :require_user!
|
||||
before_action :set_list, except: [:index, :create]
|
||||
|
||||
rescue_from ArgumentError do |e|
|
||||
render json: { error: e.to_s }, status: 422
|
||||
end
|
||||
|
||||
def index
|
||||
@lists = List.where(account: current_account).all
|
||||
render json: @lists, each_serializer: REST::ListSerializer
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
class Api::V1::MediaController < Api::BaseController
|
||||
before_action -> { doorkeeper_authorize! :write, :'write:media' }
|
||||
before_action :require_user!
|
||||
before_action :set_media_attachment, except: [:create, :destroy]
|
||||
before_action :check_processing, except: [:create, :destroy]
|
||||
before_action :set_media_attachment, except: [:create]
|
||||
before_action :check_processing, except: [:create]
|
||||
|
||||
def show
|
||||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
|
||||
|
@ -25,15 +25,6 @@ class Api::V1::MediaController < Api::BaseController
|
|||
render json: @media_attachment, serializer: REST::MediaAttachmentSerializer, status: status_code_for_media_attachment
|
||||
end
|
||||
|
||||
def destroy
|
||||
@media_attachment = current_account.media_attachments.find(params[:id])
|
||||
|
||||
return render json: in_usage_error, status: 422 unless @media_attachment.status_id.nil?
|
||||
|
||||
@media_attachment.destroy
|
||||
render_empty
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def status_code_for_media_attachment
|
||||
|
@ -63,8 +54,4 @@ class Api::V1::MediaController < Api::BaseController
|
|||
def processing_error
|
||||
{ error: 'Error processing thumbnail for uploaded media' }
|
||||
end
|
||||
|
||||
def in_usage_error
|
||||
{ error: 'Media attachment is currently used by a status' }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,7 +15,7 @@ class Api::V1::Polls::VotesController < Api::BaseController
|
|||
private
|
||||
|
||||
def set_poll
|
||||
@poll = Poll.find(params[:poll_id])
|
||||
@poll = Poll.attached.find(params[:poll_id])
|
||||
authorize @poll.status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
not_found
|
||||
|
|
|
@ -15,7 +15,7 @@ class Api::V1::PollsController < Api::BaseController
|
|||
private
|
||||
|
||||
def set_poll
|
||||
@poll = Poll.find(params[:id])
|
||||
@poll = Poll.attached.find(params[:id])
|
||||
authorize @poll.status, :show?
|
||||
rescue Mastodon::NotPermittedError
|
||||
not_found
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue