mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-12-29 16:06:16 -06:00
Merge branch 'superseriousbusiness:main' into rss-fixes1
This commit is contained in:
commit
ee3978e86c
689 changed files with 922580 additions and 199098 deletions
23
Dockerfile
23
Dockerfile
|
|
@ -1,24 +1,7 @@
|
||||||
# syntax=docker/dockerfile:1.3
|
# syntax=docker/dockerfile:1.3
|
||||||
# Dockerfile reference: https://docs.docker.com/engine/reference/builder/
|
# Dockerfile reference: https://docs.docker.com/engine/reference/builder/
|
||||||
|
|
||||||
# stage 1: generate up-to-date swagger.yaml to put in the final container
|
# stage 1: generate the web/assets/dist bundles
|
||||||
FROM --platform=${BUILDPLATFORM} golang:1.23-alpine AS swagger
|
|
||||||
|
|
||||||
RUN \
|
|
||||||
### Installs goswagger for building swagger definitions inside this container
|
|
||||||
go install "github.com/go-swagger/go-swagger/cmd/swagger@c46c303aaa02" && \
|
|
||||||
# Makes swagger executable
|
|
||||||
chmod +x /go/bin/swagger
|
|
||||||
|
|
||||||
COPY go.mod /go/src/github.com/superseriousbusiness/gotosocial/go.mod
|
|
||||||
COPY go.sum /go/src/github.com/superseriousbusiness/gotosocial/go.sum
|
|
||||||
COPY cmd /go/src/github.com/superseriousbusiness/gotosocial/cmd
|
|
||||||
COPY internal /go/src/github.com/superseriousbusiness/gotosocial/internal
|
|
||||||
|
|
||||||
WORKDIR /go/src/github.com/superseriousbusiness/gotosocial
|
|
||||||
RUN /go/bin/swagger generate spec -o /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml --scan-models
|
|
||||||
|
|
||||||
# stage 2: generate the web/assets/dist bundles
|
|
||||||
FROM --platform=${BUILDPLATFORM} node:18-alpine AS bundler
|
FROM --platform=${BUILDPLATFORM} node:18-alpine AS bundler
|
||||||
|
|
||||||
COPY web web
|
COPY web web
|
||||||
|
|
@ -27,7 +10,7 @@ RUN yarn --cwd ./web/source install && \
|
||||||
yarn --cwd ./web/source build && \
|
yarn --cwd ./web/source build && \
|
||||||
rm -rf ./web/source
|
rm -rf ./web/source
|
||||||
|
|
||||||
# stage 3: build the executor container
|
# stage 2: build the executor container
|
||||||
FROM --platform=${TARGETPLATFORM} alpine:3.20 as executor
|
FROM --platform=${TARGETPLATFORM} alpine:3.20 as executor
|
||||||
|
|
||||||
# switch to non-root user:group for GtS
|
# switch to non-root user:group for GtS
|
||||||
|
|
@ -50,7 +33,7 @@ COPY --chown=1000:1000 gotosocial /gotosocial/gotosocial
|
||||||
|
|
||||||
# copy over the web directories with templates, assets etc
|
# copy over the web directories with templates, assets etc
|
||||||
COPY --chown=1000:1000 --from=bundler web /gotosocial/web
|
COPY --chown=1000:1000 --from=bundler web /gotosocial/web
|
||||||
COPY --chown=1000:1000 --from=swagger /go/src/github.com/superseriousbusiness/gotosocial/swagger.yaml web/assets/swagger.yaml
|
COPY --chown=1000:1000 ./web/assets/swagger.yaml /gotosocial/web/assets/swagger.yaml
|
||||||
|
|
||||||
VOLUME [ "/gotosocial/storage", "/gotosocial/.cache" ]
|
VOLUME [ "/gotosocial/storage", "/gotosocial/.cache" ]
|
||||||
ENTRYPOINT [ "/gotosocial/gotosocial", "server", "start" ]
|
ENTRYPOINT [ "/gotosocial/gotosocial", "server", "start" ]
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,8 @@ Here's a screenshot of the instance landing page! Check out the project's [offic
|
||||||
- [Known Issues](#known-issues)
|
- [Known Issues](#known-issues)
|
||||||
- [Installing GoToSocial](#installing-gotosocial)
|
- [Installing GoToSocial](#installing-gotosocial)
|
||||||
- [Supported Platforms](#supported-platforms)
|
- [Supported Platforms](#supported-platforms)
|
||||||
- [FreeBSD](#freebsd)
|
- [64-bit](#64-bit)
|
||||||
|
- [BSDs](#bsds)
|
||||||
- [32-bit](#32-bit)
|
- [32-bit](#32-bit)
|
||||||
- [OpenBSD](#openbsd)
|
- [OpenBSD](#openbsd)
|
||||||
- [Stable Releases](#stable-releases)
|
- [Stable Releases](#stable-releases)
|
||||||
|
|
@ -434,6 +435,7 @@ The following open source libraries, frameworks, and tools are used by GoToSocia
|
||||||
- [superseriousbusiness/exif-terminator](https://codeberg.org/superseriousbusiness/exif-terminator); EXIF data removal. [GNU AGPL v3 LICENSE](https://spdx.org/licenses/AGPL-3.0-or-later.html).
|
- [superseriousbusiness/exif-terminator](https://codeberg.org/superseriousbusiness/exif-terminator); EXIF data removal. [GNU AGPL v3 LICENSE](https://spdx.org/licenses/AGPL-3.0-or-later.html).
|
||||||
- [superseriousbusiness/httpsig](https://github.com/superseriousbusiness/httpsig) forked from [go-fed/httpsig](https://github.com/go-fed/httpsig); secure HTTP signature library. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html).
|
- [superseriousbusiness/httpsig](https://github.com/superseriousbusiness/httpsig) forked from [go-fed/httpsig](https://github.com/go-fed/httpsig); secure HTTP signature library. [BSD-3-Clause License](https://spdx.org/licenses/BSD-3-Clause.html).
|
||||||
- [superseriousbusiness/oauth2](https://github.com/superseriousbusiness/oauth2) forked from [go-oauth2/oauth2](https://github.com/go-oauth2/oauth2); OAuth server framework and token handling. [MIT License](https://spdx.org/licenses/MIT.html).
|
- [superseriousbusiness/oauth2](https://github.com/superseriousbusiness/oauth2) forked from [go-oauth2/oauth2](https://github.com/go-oauth2/oauth2); OAuth server framework and token handling. [MIT License](https://spdx.org/licenses/MIT.html).
|
||||||
|
- [temoto/robotstxt](https://github.com/temoto/robotstxt); robots.txt parsing. [MIT License](https://spdx.org/licenses/MIT.html).
|
||||||
- [tdewolff/minify](https://github.com/tdewolff/minify); HTML minification for Markdown-submitted posts. [MIT License](https://spdx.org/licenses/MIT.html).
|
- [tdewolff/minify](https://github.com/tdewolff/minify); HTML minification for Markdown-submitted posts. [MIT License](https://spdx.org/licenses/MIT.html).
|
||||||
- [uber-go/automaxprocs](https://github.com/uber-go/automaxprocs); GOMAXPROCS automation. [MIT License](https://spdx.org/licenses/MIT.html).
|
- [uber-go/automaxprocs](https://github.com/uber-go/automaxprocs); GOMAXPROCS automation. [MIT License](https://spdx.org/licenses/MIT.html).
|
||||||
- [ulule/limiter](https://github.com/ulule/limiter); http rate limit middleware. [MIT License](https://spdx.org/licenses/MIT.html).
|
- [ulule/limiter](https://github.com/ulule/limiter); http rate limit middleware. [MIT License](https://spdx.org/licenses/MIT.html).
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ import (
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
|
||||||
|
"github.com/superseriousbusiness/gotosocial/internal/admin"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/api"
|
"github.com/superseriousbusiness/gotosocial/internal/api"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
|
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
|
||||||
|
|
@ -133,6 +134,10 @@ var Start action.GTSAction = func(ctx context.Context) error {
|
||||||
// Initialize caches and database
|
// Initialize caches and database
|
||||||
state.DB = testrig.NewTestDB(state)
|
state.DB = testrig.NewTestDB(state)
|
||||||
|
|
||||||
|
// Set Actions on state, providing workers to
|
||||||
|
// Actions as well for triggering side effects.
|
||||||
|
state.AdminActions = admin.New(state.DB, &state.Workers)
|
||||||
|
|
||||||
// New test db inits caches so we don't need to do
|
// New test db inits caches so we don't need to do
|
||||||
// that twice, we can just start the initialized caches.
|
// that twice, we can just start the initialized caches.
|
||||||
state.Caches.Start()
|
state.Caches.Start()
|
||||||
|
|
|
||||||
|
|
@ -253,4 +253,4 @@ custom CSS allows you to further customize the way your instance looks when visi
|
||||||
|
|
||||||
This custom CSS will be applied to all pages of your instance. Users themes and CSS still take precedence over this customization.
|
This custom CSS will be applied to all pages of your instance. Users themes and CSS still take precedence over this customization.
|
||||||
|
|
||||||
See the [Custom CSS](./custom_css.md) page for some tips on writing custom CSS for your instance.
|
See the [Custom CSS](../user_guide/custom_css.md) page for some tips on writing custom CSS for your instance.
|
||||||
|
|
|
||||||
|
|
@ -46,12 +46,14 @@ If you **reject** the sign-up, you may wish to inform the applicant that their s
|
||||||
|
|
||||||
## Sign-Up Limits
|
## Sign-Up Limits
|
||||||
|
|
||||||
To avoid sign-up backlogs overwhelming admins and moderators, GoToSocial limits the sign-up pending backlog to 20 accounts. Once there are 20 accounts pending in the backlog waiting to be handled by an admin or moderator, new sign-ups will not be accepted via the form.
|
By default, to avoid sign-up backlogs overwhelming admins and moderators, GoToSocial limits the sign-up pending backlog to 20 accounts. Once there are 20 accounts pending in the backlog waiting to be handled by an admin or moderator, new sign-ups will not be accepted via the form.
|
||||||
|
|
||||||
New sign-ups will also not be accepted via the form if 10 or more new account sign-ups have been approved in the last 24 hours, to avoid instances rapidly expanding beyond the capabilities of moderators.
|
By default, new sign-ups will also not be accepted via the form if 10 or more new account sign-ups have been approved in the last 24 hours, to avoid instances rapidly expanding beyond the capabilities of moderators.
|
||||||
|
|
||||||
In both cases, applicants will be shown an error message explaining why they could not submit the form, and inviting them to try again later.
|
In both cases, applicants will be shown an error message explaining why they could not submit the form, and inviting them to try again later.
|
||||||
|
|
||||||
|
The limit of sign-ups per day, and the backlog size, can be configured or disabled altogether with the variables `accounts-registration-daily-limit` and `accounts-registration-backlog-limit`. See the [accounts config section](../configuration/accounts.md) for more info.
|
||||||
|
|
||||||
To combat spam accounts, GoToSocial account sign-ups **always** require manual approval by an administrator, and applicants must **always** confirm their email address before they are able to log in and post.
|
To combat spam accounts, GoToSocial account sign-ups **always** require manual approval by an administrator, and applicants must **always** confirm their email address before they are able to log in and post.
|
||||||
|
|
||||||
## Sign-Up Via Invite
|
## Sign-Up Via Invite
|
||||||
|
|
|
||||||
|
|
@ -4331,7 +4331,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:accounts
|
- read:statuses
|
||||||
summary: See statuses posted by the requested account.
|
summary: See statuses posted by the requested account.
|
||||||
tags:
|
tags:
|
||||||
- accounts
|
- accounts
|
||||||
|
|
@ -5004,7 +5004,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:accounts
|
||||||
summary: View + page through known accounts according to given filters.
|
summary: View + page through known accounts according to given filters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5038,7 +5038,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:accounts
|
||||||
summary: View one account.
|
summary: View one account.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5083,7 +5083,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:accounts
|
||||||
summary: Perform an admin action on an account.
|
summary: Perform an admin action on an account.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5117,7 +5117,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:accounts
|
||||||
summary: Approve pending account.
|
summary: Approve pending account.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5163,7 +5163,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:accounts
|
||||||
summary: Reject pending account.
|
summary: Reject pending account.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5241,6 +5241,9 @@ paths:
|
||||||
description: not acceptable
|
description: not acceptable
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer:
|
||||||
|
- admin:read
|
||||||
summary: View local and remote emojis available to / known by this instance.
|
summary: View local and remote emojis available to / known by this instance.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5287,7 +5290,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Upload and create a new instance emoji.
|
summary: Upload and create a new instance emoji.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5327,7 +5330,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Delete a **local** emoji with the given ID from the instance.
|
summary: Delete a **local** emoji with the given ID from the instance.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5358,6 +5361,9 @@ paths:
|
||||||
description: not acceptable
|
description: not acceptable
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer:
|
||||||
|
- admin:read
|
||||||
summary: Get the admin view of a single emoji.
|
summary: Get the admin view of a single emoji.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5429,7 +5435,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Perform admin action on a local or remote emoji known to this instance.
|
summary: Perform admin action on a local or remote emoji known to this instance.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5457,6 +5463,9 @@ paths:
|
||||||
description: not acceptable
|
description: not acceptable
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer:
|
||||||
|
- admin:read
|
||||||
summary: Get a list of existing emoji categories.
|
summary: Get a list of existing emoji categories.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5489,7 +5498,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Perform a GET to the specified ActivityPub URL and return detailed debugging information.
|
summary: Perform a GET to the specified ActivityPub URL and return detailed debugging information.
|
||||||
tags:
|
tags:
|
||||||
- debug
|
- debug
|
||||||
|
|
@ -5514,7 +5523,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Sweep/clear all in-memory caches.
|
summary: Sweep/clear all in-memory caches.
|
||||||
tags:
|
tags:
|
||||||
- debug
|
- debug
|
||||||
|
|
@ -5549,7 +5558,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:domain_allows
|
||||||
summary: View all domain allows currently in place.
|
summary: View all domain allows currently in place.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5612,7 +5621,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:domain_allows
|
||||||
summary: Create one or more domain allows, from a string or a file.
|
summary: Create one or more domain allows, from a string or a file.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5648,7 +5657,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:domain_allows
|
||||||
summary: Delete domain allow with the given ID.
|
summary: Delete domain allow with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5681,7 +5690,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:domain_allows
|
||||||
summary: View domain allow with the given ID.
|
summary: View domain allow with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5716,7 +5725,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:domain_blocks
|
||||||
summary: View all domain blocks currently in place.
|
summary: View all domain blocks currently in place.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5779,7 +5788,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:domain_blocks
|
||||||
summary: Create one or more domain blocks, from a string or a file.
|
summary: Create one or more domain blocks, from a string or a file.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5815,7 +5824,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:domain_blocks
|
||||||
summary: Delete domain block with the given ID.
|
summary: Delete domain block with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5848,7 +5857,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:domain_blocks
|
||||||
summary: View domain block with the given ID.
|
summary: View domain block with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5900,7 +5909,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Force expiry of cached public keys for all accounts on the given domain stored in your database.
|
summary: Force expiry of cached public keys for all accounts on the given domain stored in your database.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -5976,7 +5985,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: View domain permission drafts.
|
summary: View domain permission drafts.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6027,7 +6036,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create a domain permission draft with the given parameters.
|
summary: Create a domain permission draft with the given parameters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6059,7 +6068,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: Get domain permission draft with the given ID.
|
summary: Get domain permission draft with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6101,7 +6110,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Accept a domain permission draft, turning it into an enforced domain permission.
|
summary: Accept a domain permission draft, turning it into an enforced domain permission.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6143,7 +6152,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Remove a domain permission draft, optionally ignoring all future drafts targeting the given domain.
|
summary: Remove a domain permission draft, optionally ignoring all future drafts targeting the given domain.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6211,7 +6220,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: View domain permission excludes.
|
summary: View domain permission excludes.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6254,7 +6263,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create a domain permission exclude with the given parameters.
|
summary: Create a domain permission exclude with the given parameters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6288,7 +6297,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Remove a domain permission exclude.
|
summary: Remove a domain permission exclude.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6319,7 +6328,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: Get domain permission exclude with the given ID.
|
summary: Get domain permission exclude with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6387,7 +6396,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: View domain permission subscriptions.
|
summary: View domain permission subscriptions.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6462,7 +6471,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create a domain permission subscription with the given parameters.
|
summary: Create a domain permission subscription with the given parameters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6535,7 +6544,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Update a domain permission subscription with the given parameters.
|
summary: Update a domain permission subscription with the given parameters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6567,7 +6576,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: Get domain permission subscription with the given ID.
|
summary: Get domain permission subscription with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6611,7 +6620,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Remove a domain permission subscription.
|
summary: Remove a domain permission subscription.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6651,7 +6660,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Test one domain permission subscription by making your instance fetch and parse it *without creating permissions*.
|
summary: Test one domain permission subscription by making your instance fetch and parse it *without creating permissions*.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6688,7 +6697,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: View all domain permission subscriptions of the given permission type, in priority order (highest to lowest).
|
summary: View all domain permission subscriptions of the given permission type, in priority order (highest to lowest).
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6733,7 +6742,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Send a generic test email to a specified email address.
|
summary: Send a generic test email to a specified email address.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6802,7 +6811,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create new "allow" HTTP request header filter.
|
summary: Create new "allow" HTTP request header filter.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6830,7 +6839,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Delete the "allow" header filter with the given ID.
|
summary: Delete the "allow" header filter with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6859,7 +6868,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: Get "allow" header filter with the given ID.
|
summary: Get "allow" header filter with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6928,7 +6937,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create new "block" HTTP request header filter.
|
summary: Create new "block" HTTP request header filter.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6956,7 +6965,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Delete the "block" header filter with the given ID.
|
summary: Delete the "block" header filter with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -6985,11 +6994,39 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read
|
||||||
summary: Get "block" header filter with the given ID.
|
summary: Get "block" header filter with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
/api/v1/admin/instance/rules:
|
/api/v1/admin/instance/rules:
|
||||||
|
get:
|
||||||
|
description: The rules will be returned in order (sorted by Order ascending).
|
||||||
|
operationId: adminsRuleGet
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: An array with all the rules for the local instance.
|
||||||
|
schema:
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/instanceRule'
|
||||||
|
type: array
|
||||||
|
"400":
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
description: unauthorized
|
||||||
|
"404":
|
||||||
|
description: not found
|
||||||
|
"406":
|
||||||
|
description: not acceptable
|
||||||
|
"500":
|
||||||
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer:
|
||||||
|
- admin:read
|
||||||
|
summary: View instance rules, with IDs.
|
||||||
|
tags:
|
||||||
|
- admin
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
- multipart/form-data
|
- multipart/form-data
|
||||||
|
|
@ -7022,7 +7059,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Create a new instance rule.
|
summary: Create a new instance rule.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7058,10 +7095,41 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Delete an existing instance rule.
|
summary: Delete an existing instance rule.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
get:
|
||||||
|
operationId: adminRuleGet
|
||||||
|
parameters:
|
||||||
|
- description: The id of the rule.
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: The requested rule.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/instanceRule'
|
||||||
|
"400":
|
||||||
|
description: bad request
|
||||||
|
"401":
|
||||||
|
description: unauthorized
|
||||||
|
"404":
|
||||||
|
description: not found
|
||||||
|
"406":
|
||||||
|
description: not acceptable
|
||||||
|
"500":
|
||||||
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer:
|
||||||
|
- admin:read
|
||||||
|
summary: View instance rule with the given id.
|
||||||
|
tags:
|
||||||
|
- admin
|
||||||
patch:
|
patch:
|
||||||
consumes:
|
consumes:
|
||||||
- multipart/form-data
|
- multipart/form-data
|
||||||
|
|
@ -7100,7 +7168,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Update an existing instance rule.
|
summary: Update an existing instance rule.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7140,7 +7208,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Clean up remote media older than the specified number of days.
|
summary: Clean up remote media older than the specified number of days.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7174,7 +7242,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Refetch media specified in the database but missing from storage.
|
summary: Refetch media specified in the database but missing from storage.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7248,7 +7316,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:reports
|
||||||
summary: View user moderation reports.
|
summary: View user moderation reports.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7280,7 +7348,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:reports
|
||||||
summary: View user moderation report with the given id.
|
summary: View user moderation report with the given id.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -7322,71 +7390,10 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write:reports
|
||||||
summary: Mark a report as resolved.
|
summary: Mark a report as resolved.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
/api/v1/admin/rules:
|
|
||||||
get:
|
|
||||||
description: The rules will be returned in order (sorted by Order ascending).
|
|
||||||
operationId: adminsRuleGet
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: An array with all the rules for the local instance.
|
|
||||||
schema:
|
|
||||||
items:
|
|
||||||
$ref: '#/definitions/instanceRule'
|
|
||||||
type: array
|
|
||||||
"400":
|
|
||||||
description: bad request
|
|
||||||
"401":
|
|
||||||
description: unauthorized
|
|
||||||
"404":
|
|
||||||
description: not found
|
|
||||||
"406":
|
|
||||||
description: not acceptable
|
|
||||||
"500":
|
|
||||||
description: internal server error
|
|
||||||
security:
|
|
||||||
- OAuth2 Bearer:
|
|
||||||
- admin
|
|
||||||
summary: View instance rules, with IDs.
|
|
||||||
tags:
|
|
||||||
- admin
|
|
||||||
/api/v1/admin/rules/{id}:
|
|
||||||
get:
|
|
||||||
operationId: adminRuleGet
|
|
||||||
parameters:
|
|
||||||
- description: The id of the rule.
|
|
||||||
in: path
|
|
||||||
name: id
|
|
||||||
required: true
|
|
||||||
type: string
|
|
||||||
produces:
|
|
||||||
- application/json
|
|
||||||
responses:
|
|
||||||
"200":
|
|
||||||
description: The requested rule.
|
|
||||||
schema:
|
|
||||||
$ref: '#/definitions/instanceRule'
|
|
||||||
"400":
|
|
||||||
description: bad request
|
|
||||||
"401":
|
|
||||||
description: unauthorized
|
|
||||||
"404":
|
|
||||||
description: not found
|
|
||||||
"406":
|
|
||||||
description: not acceptable
|
|
||||||
"500":
|
|
||||||
description: internal server error
|
|
||||||
security:
|
|
||||||
- OAuth2 Bearer:
|
|
||||||
- admin
|
|
||||||
summary: View instance rule with the given id.
|
|
||||||
tags:
|
|
||||||
- admin
|
|
||||||
/api/v1/announcements:
|
/api/v1/announcements:
|
||||||
get:
|
get:
|
||||||
description: 'THIS ENDPOINT IS CURRENTLY NOT FULLY IMPLEMENTED: it will always return an empty array.'
|
description: 'THIS ENDPOINT IS CURRENTLY NOT FULLY IMPLEMENTED: it will always return an empty array.'
|
||||||
|
|
@ -7410,8 +7417,7 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer: []
|
||||||
- read:announcements
|
|
||||||
summary: Get an array of currently active announcements.
|
summary: Get an array of currently active announcements.
|
||||||
tags:
|
tags:
|
||||||
- announcements
|
- announcements
|
||||||
|
|
@ -7725,8 +7731,7 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer: []
|
||||||
- read:custom_emojis
|
|
||||||
summary: Get an array of custom emojis available on the instance.
|
summary: Get an array of custom emojis available on the instance.
|
||||||
tags:
|
tags:
|
||||||
- custom_emojis
|
- custom_emojis
|
||||||
|
|
@ -7766,7 +7771,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:follows
|
- read:accounts
|
||||||
summary: Export a CSV file of accounts that follow you.
|
summary: Export a CSV file of accounts that follow you.
|
||||||
tags:
|
tags:
|
||||||
- import-export
|
- import-export
|
||||||
|
|
@ -7848,7 +7853,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:account
|
- read:accounts
|
||||||
summary: Returns informational stats on the number of items that can be exported for requesting account.
|
summary: Returns informational stats on the number of items that can be exported for requesting account.
|
||||||
tags:
|
tags:
|
||||||
- import-export
|
- import-export
|
||||||
|
|
@ -8425,7 +8430,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:accounts
|
- write
|
||||||
summary: Upload some CSV-formatted data to your account.
|
summary: Upload some CSV-formatted data to your account.
|
||||||
tags:
|
tags:
|
||||||
- import-export
|
- import-export
|
||||||
|
|
@ -8519,7 +8524,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:write
|
||||||
summary: Update your instance information and/or upload a new avatar/header for the instance.
|
summary: Update your instance information and/or upload a new avatar/header for the instance.
|
||||||
tags:
|
tags:
|
||||||
- instance
|
- instance
|
||||||
|
|
@ -8571,6 +8576,8 @@ paths:
|
||||||
description: not acceptable
|
description: not acceptable
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
|
security:
|
||||||
|
- OAuth2 Bearer: []
|
||||||
tags:
|
tags:
|
||||||
- instance
|
- instance
|
||||||
/api/v1/instance/rules:
|
/api/v1/instance/rules:
|
||||||
|
|
@ -9645,7 +9652,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:notifications
|
- write:notifications
|
||||||
summary: Clear/delete all notifications for currently authorized user.
|
summary: Clear/delete all notifications for currently authorized user.
|
||||||
tags:
|
tags:
|
||||||
- notifications
|
- notifications
|
||||||
|
|
@ -10160,7 +10167,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:reports
|
- read:accounts
|
||||||
summary: See reports created by the requesting account.
|
summary: See reports created by the requesting account.
|
||||||
tags:
|
tags:
|
||||||
- reports
|
- reports
|
||||||
|
|
@ -10272,7 +10279,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:reports
|
- read:accounts
|
||||||
summary: Get one report with the given id.
|
summary: Get one report with the given id.
|
||||||
tags:
|
tags:
|
||||||
- reports
|
- reports
|
||||||
|
|
@ -10397,10 +10404,14 @@ paths:
|
||||||
x-go-name: Federated
|
x-go-name: Federated
|
||||||
- description: |-
|
- description: |-
|
||||||
ISO 8601 Datetime at which to schedule a status.
|
ISO 8601 Datetime at which to schedule a status.
|
||||||
Providing this parameter will cause ScheduledStatus to be returned instead of Status.
|
|
||||||
Must be at least 5 minutes in the future.
|
|
||||||
|
|
||||||
This feature isn't implemented yet; attemping to set it will return 501 Not Implemented.
|
Providing this parameter with a *future* time will cause ScheduledStatus to be returned instead of Status.
|
||||||
|
Must be at least 5 minutes in the future.
|
||||||
|
This feature isn't implemented yet.
|
||||||
|
|
||||||
|
Providing this parameter with a *past* time will cause the status to be backdated,
|
||||||
|
and will not push it to the user's followers. This is intended for importing old statuses.
|
||||||
|
format: date-time
|
||||||
in: formData
|
in: formData
|
||||||
name: scheduled_at
|
name: scheduled_at
|
||||||
type: string
|
type: string
|
||||||
|
|
@ -10675,7 +10686,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:statuses
|
- write:bookmarks
|
||||||
summary: Bookmark status with the given ID.
|
summary: Bookmark status with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- statuses
|
- statuses
|
||||||
|
|
@ -11033,7 +11044,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:statuses
|
- write:bookmarks
|
||||||
summary: Unbookmark status with the given ID.
|
summary: Unbookmark status with the given ID.
|
||||||
tags:
|
tags:
|
||||||
- statuses
|
- statuses
|
||||||
|
|
@ -11067,7 +11078,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:statuses
|
- write:favourites
|
||||||
summary: Unstar/unlike/unfavourite the given status.
|
summary: Unstar/unlike/unfavourite the given status.
|
||||||
tags:
|
tags:
|
||||||
- statuses
|
- statuses
|
||||||
|
|
@ -11311,8 +11322,7 @@ paths:
|
||||||
"500":
|
"500":
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer: []
|
||||||
- read:follows
|
|
||||||
summary: Get details for a hashtag, including whether you currently follow it.
|
summary: Get details for a hashtag, including whether you currently follow it.
|
||||||
tags:
|
tags:
|
||||||
- tags
|
- tags
|
||||||
|
|
@ -11640,7 +11650,7 @@ paths:
|
||||||
description: internal error
|
description: internal error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- read:user
|
- read:accounts
|
||||||
summary: Get your own user model.
|
summary: Get your own user model.
|
||||||
tags:
|
tags:
|
||||||
- user
|
- user
|
||||||
|
|
@ -11685,7 +11695,7 @@ paths:
|
||||||
description: internal error
|
description: internal error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:user
|
- write:accounts
|
||||||
summary: Request changing the email address of authenticated user.
|
summary: Request changing the email address of authenticated user.
|
||||||
tags:
|
tags:
|
||||||
- user
|
- user
|
||||||
|
|
@ -11734,7 +11744,7 @@ paths:
|
||||||
description: internal error
|
description: internal error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- write:user
|
- write:accounts
|
||||||
summary: Change the password of authenticated user.
|
summary: Change the password of authenticated user.
|
||||||
tags:
|
tags:
|
||||||
- user
|
- user
|
||||||
|
|
@ -11835,7 +11845,7 @@ paths:
|
||||||
description: internal server error
|
description: internal server error
|
||||||
security:
|
security:
|
||||||
- OAuth2 Bearer:
|
- OAuth2 Bearer:
|
||||||
- admin
|
- admin:read:accounts
|
||||||
summary: View + page through known accounts according to given filters.
|
summary: View + page through known accounts according to given filters.
|
||||||
tags:
|
tags:
|
||||||
- admin
|
- admin
|
||||||
|
|
@ -12722,32 +12732,44 @@ securityDefinitions:
|
||||||
flow: accessCode
|
flow: accessCode
|
||||||
scopes:
|
scopes:
|
||||||
admin: grants admin access to everything
|
admin: grants admin access to everything
|
||||||
admin:accounts: grants admin access to accounts
|
admin:read: grants admin read access to everything
|
||||||
|
admin:read:accounts: grants admin read access to accounts
|
||||||
|
admin:read:domain_allows: grants admin read access to domain_allows
|
||||||
|
admin:read:domain_blocks: grants admin read access to domain_blocks
|
||||||
|
admin:read:reports: grants admin read access to reports
|
||||||
|
admin:write: grants admin write access to everything
|
||||||
|
admin:write:accounts: grants write read access to accounts
|
||||||
|
admin:write:domain_allows: grants admin write access to domain_allows
|
||||||
|
admin:write:domain_blocks: grants write read access to domain_blocks
|
||||||
|
admin:write:reports: grants admin write access to reports
|
||||||
|
profile: grants read access to verify_credentials
|
||||||
|
push: grants read/write access to push
|
||||||
read: grants read access to everything
|
read: grants read access to everything
|
||||||
read:accounts: grants read access to accounts
|
read:accounts: grants read access to accounts
|
||||||
read:blocks: grant read access to blocks
|
read:blocks: grants read access to blocks
|
||||||
read:custom_emojis: grant read access to custom_emojis
|
read:bookmarks: grants read access to bookmarks
|
||||||
read:favourites: grant read access to favourites
|
read:favourites: grants read access to accounts
|
||||||
read:filters: grant read access to filters
|
read:filters: grants read access to filters
|
||||||
read:follows: grant read access to follows
|
read:follows: grants read access to follows
|
||||||
read:lists: grant read access to lists
|
read:lists: grants read access to lists
|
||||||
read:media: grant read access to media
|
read:mutes: grants read access to mutes
|
||||||
read:mutes: grant read access to mutes
|
|
||||||
read:notifications: grants read access to notifications
|
read:notifications: grants read access to notifications
|
||||||
read:search: grant read access to searches
|
read:search: grants read access to search
|
||||||
read:statuses: grants read access to statuses
|
read:statuses: grants read access to statuses
|
||||||
read:streaming: grants read access to streaming api
|
|
||||||
read:user: grants read access to user-level info
|
|
||||||
write: grants write access to everything
|
write: grants write access to everything
|
||||||
write:accounts: grants write access to accounts
|
write:accounts: grants write access to accounts
|
||||||
write:blocks: grants write access to blocks
|
write:blocks: grants write access to blocks
|
||||||
|
write:bookmarks: grants write access to bookmarks
|
||||||
|
write:conversations: grants write access to conversations
|
||||||
|
write:favourites: grants write access to favourites
|
||||||
write:filters: grants write access to filters
|
write:filters: grants write access to filters
|
||||||
write:follows: grants write access to follows
|
write:follows: grants write access to follows
|
||||||
write:lists: grants write access to lists
|
write:lists: grants write access to lists
|
||||||
write:media: grants write access to media
|
write:media: grants write access to media
|
||||||
write:mutes: grants write access to mutes
|
write:mutes: grants write access to mutes
|
||||||
|
write:notifications: grants write access to notifications
|
||||||
|
write:reports: grants write access to reports
|
||||||
write:statuses: grants write access to statuses
|
write:statuses: grants write access to statuses
|
||||||
write:user: grants write access to user-level info
|
|
||||||
tokenUrl: https://example.org/oauth/token
|
tokenUrl: https://example.org/oauth/token
|
||||||
type: oauth2
|
type: oauth2
|
||||||
swagger: "2.0"
|
swagger: "2.0"
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,28 @@ accounts-registration-open: false
|
||||||
# Default: true
|
# Default: true
|
||||||
accounts-reason-required: true
|
accounts-reason-required: true
|
||||||
|
|
||||||
|
# Int. Number of approved sign-ups allowed within
|
||||||
|
# 24hrs before new account registration is closed.
|
||||||
|
#
|
||||||
|
# Leaving this count at the default essentially limits
|
||||||
|
# your instance to growing by 10 accounts per day.
|
||||||
|
#
|
||||||
|
# Setting this number to 0 or less removes the limit.
|
||||||
|
#
|
||||||
|
# Default: 10
|
||||||
|
accounts-registration-daily-limit: 10
|
||||||
|
|
||||||
|
# Int. Number of new account sign-ups allowed in the pending
|
||||||
|
# approval queue before new account registration is closed.
|
||||||
|
#
|
||||||
|
# This can be used to essentially "throttle" the sign-up
|
||||||
|
# queue to prevent instance admins becoming overwhelmed.
|
||||||
|
#
|
||||||
|
# Setting this number to 0 or less removes the limit.
|
||||||
|
#
|
||||||
|
# Default: 20
|
||||||
|
accounts-registration-backlog-limit: 20
|
||||||
|
|
||||||
# Bool. Allow accounts on this instance to set custom CSS for their profile pages and statuses.
|
# Bool. Allow accounts on this instance to set custom CSS for their profile pages and statuses.
|
||||||
# Enabling this setting will allow accounts to upload custom CSS via the /user settings page,
|
# Enabling this setting will allow accounts to upload custom CSS via the /user settings page,
|
||||||
# which will then be rendered on the web view of the account's profile and statuses.
|
# which will then be rendered on the web view of the account's profile and statuses.
|
||||||
|
|
|
||||||
|
|
@ -171,4 +171,17 @@ instance-subscriptions-process-every: "24h"
|
||||||
# Options: ["", "zero", "serve", "baffle"]
|
# Options: ["", "zero", "serve", "baffle"]
|
||||||
# Default: ""
|
# Default: ""
|
||||||
instance-stats-mode: ""
|
instance-stats-mode: ""
|
||||||
|
|
||||||
|
# Bool. This flag controls whether local accounts may backdate statuses
|
||||||
|
# using past dates with the scheduled_at param to /api/v1/statuses.
|
||||||
|
# This flag does not affect scheduling posts in the future
|
||||||
|
# (which is currently not implemented anyway),
|
||||||
|
# nor can it prevent remote accounts from backdating their own statuses.
|
||||||
|
#
|
||||||
|
# If true, all local accounts may backdate statuses.
|
||||||
|
# If false, status backdating will be disabled and an error will be returned if it's used.
|
||||||
|
#
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
instance-allow-backdating-statuses: true
|
||||||
```
|
```
|
||||||
|
|
|
||||||
679
docs/federation/interaction_policy.md
Normal file
679
docs/federation/interaction_policy.md
Normal file
|
|
@ -0,0 +1,679 @@
|
||||||
|
# Interaction Policy
|
||||||
|
|
||||||
|
GoToSocial uses the property `interactionPolicy` on posts, in order to indicate to remote instances what sort of interactions are (conditionally) permitted to be processed and stored by the origin server, for any given post.
|
||||||
|
|
||||||
|
The `@context` document for `interactionPolicy` and related objects and properties is at `https://gotosocial.org/ns`.
|
||||||
|
|
||||||
|
!!! danger
|
||||||
|
Interaction policy is an attempt to limit the harmful effects of unwanted replies and other interactions on a user's posts (eg., "reply guys").
|
||||||
|
|
||||||
|
However, it is far from being sufficient for this purpose, as there are still many "out-of-band" ways that posts can be distributed or replied to beyond a user's initial wishes or intentions.
|
||||||
|
|
||||||
|
For example, a user might create a post with a very strict interaction policy attached to it, only to find that other server softwares do not respect that policy, and users on other instances are having discussions and replying to the post *from their instance's perspective*. The original poster's instance will automatically drop these unwanted interactions from their view, but remote instances may still show them.
|
||||||
|
|
||||||
|
Another example: someone might see a post that specifies nobody can reply to it, but screenshot the post, post the screenshot in their own new post, and tag the original post author in as a mention. Alternatively, they might just link to the URL of the post and tag the author in as a mention. In this case, they effectively "reply" to the post by creating a new thread.
|
||||||
|
|
||||||
|
For better or worse, GoToSocial can offer only a best-effort, partial, technological solution to what is more or less an issue of social behavior and boundaries.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
`interactionPolicy` is an object property attached to the post-like `Object`s `Note`, `Article`, `Question`, etc, with the following format:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
||||||
|
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
||||||
|
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
||||||
|
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In the `interactionPolicy` object:
|
||||||
|
|
||||||
|
- `canLike` is a sub-policy which indicates who is permitted to create a `Like` with the post URI as the `object` of the `Like`.
|
||||||
|
- `canReply` is a sub-policy which indicates who is permitted to create a post with `inReplyTo` set to the URI/ID of the post.
|
||||||
|
- `canAnnounce` is a sub-policy which indicates who is permitted to create an `Announce` with the post URI/ID as the `object` of the `Announce`.
|
||||||
|
|
||||||
|
And:
|
||||||
|
|
||||||
|
- `always` denotes ActivityPub URIs/IDs of `Actor`s or `Collection`s of `Actor`s who are permitted to create + distribute an interaction targeting a post without requiring manual approval by the post author.
|
||||||
|
- `approvalRequired` denotes ActivityPub URIs/IDs of `Actor`s or `Collection`s of `Actor`s who are permitted to create an interaction targeting a post, but should wait for manual approval by the post author before distributing it (see [Requesting, Obtaining, and Validating Approval](#requesting-obtaining-and-validating-approval)).
|
||||||
|
|
||||||
|
Valid URI entries in `always` and `approvalRequired` include:
|
||||||
|
|
||||||
|
- the magic ActivityStreams Public URI `https://www.w3.org/ns/activitystreams#Public`
|
||||||
|
- the URIs of the post creator's `Following` and/or `Followers` collections
|
||||||
|
- individual Actor URIs
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"https://example.org/users/someone/followers",
|
||||||
|
"https://example.org/users/someone/following",
|
||||||
|
"https://example.org/users/someone_else",
|
||||||
|
"https://somewhere.else.example.org/users/someone_on_a_different_instance"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! info
|
||||||
|
Be aware that according to JSON-LD the values of `always` and `approvalRequired` can be either single strings or arrays of strings. That is, the following are all valid:
|
||||||
|
|
||||||
|
- Single string: `"always": "https://example.org/users/someone"`
|
||||||
|
- Single-entry array: `"always": [ "https://example.org/users/someone" ]`
|
||||||
|
- Multiple-entry array: `"always": [ "https://example.org/users/someone", "https://example.org/users/someone_else" ]`
|
||||||
|
|
||||||
|
## Specifying Nobody
|
||||||
|
|
||||||
|
To specify that **nobody** can perform an interaction on a post **except** for its author (who is always permitted), implementations should set the `always` array to **just the URI of the post author**, and `approvalRequired` can be unset, `null`, or empty.
|
||||||
|
|
||||||
|
For example, the following `canLike` value indicates that nobody can `Like` the post it is attached to except for the post author:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"canLike": {
|
||||||
|
"always": "the_activitypub_uri_of_the_post_author"
|
||||||
|
},
|
||||||
|
```
|
||||||
|
|
||||||
|
Another example. The following `interactionPolicy` on a post by `https://example.org/users/someone` indicates that anyone can like the post, but nobody but the author can reply or announce:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://example.org/users/someone"
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": "https://example.org/users/someone"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
To avoid mischief, GoToSocial makes implicit assumptions about who can/can't interact, even if a policy specifies nobody. See [implicit assumptions](#implicit-assumptions).
|
||||||
|
|
||||||
|
## Conflicting / Duplicate Values
|
||||||
|
|
||||||
|
In cases where a user is present in a Collection URI, and is *also* targeted explicitly by URI, the **more specific value** takes precedence.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[...],
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://example.org/users/someone",
|
||||||
|
"approvalRequired": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `@someone@example.org` is present in `always`, and is also implicitly present in the magic ActivityStreams Public collection in `approvalRequired`. In this case, they can always reply, as the `always` value is more explicit.
|
||||||
|
|
||||||
|
Another example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[...],
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"approvalRequired": "https://example.org/users/someone"
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, `@someone@example.org` is present in `approvalRequired`, but is also implicitly present in the magic ActivityStreams Public collection in `always`. In this case everyone can reply without approval, **except** for `@someone@example.org`, who requires approval.
|
||||||
|
|
||||||
|
In case the **exact same** URI is present in both `always` and `approvalRequired`, the **highest level of permission** takes precedence (ie., a URI in `always` takes precedence over the same URI in `approvalRequired`).
|
||||||
|
|
||||||
|
## Default / fallback `interactionPolicy`
|
||||||
|
|
||||||
|
When the `interactionPolicy` property is not present at all on a post, or the `interactionPolicy` key is set but its value resolves to `null` or `{}`, implementations can assume the following implicit, default `interactionPolicy` for that post:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
As implied by the lack of any `approvalRequired` property in any of the sub-policies, the default value for `approvalRequired` is an empty array.
|
||||||
|
|
||||||
|
This default `interactionPolicy` was designed to reflect the de facto interaction policy of all posts from pre-v0.17.0 GoToSocial, and other ActivityPub server softwares, at the time of writing. That is to say, it is exactly what servers that are not interaction policy aware *already assume* about interaction permissions.
|
||||||
|
|
||||||
|
!!! info "Actors can only ever interact with a post they are permitted to see"
|
||||||
|
Note that even when assuming a default `interactionPolicy` for a post, the **visibility** of a post must still be accounted for by looking at the `to`, `cc`, and/or `audience` properties, to ensure that actors who cannot *see* a post also cannot *interact* with it. Eg., if a post is addressed to followers-only, and the default `interactionPolicy` is assumed, then someone who does not follow the post creator should still *not* be able to see *or* interact with it.
|
||||||
|
|
||||||
|
!!! tip
|
||||||
|
As is standard across AP implementations, implementations will likely still wish to limit `Announce` actities targeting the post to only the author themself if the post is addressed to followers-only.
|
||||||
|
|
||||||
|
## Defaults per sub-policy
|
||||||
|
|
||||||
|
When an interaction policy is only *partially* defined (eg., only `canReply` is set, `canLike` or `canAnnounce` keys are not set), then implementations should make the following assumptions for each sub-policy in the `interactionPolicy` object that is *undefined*.
|
||||||
|
|
||||||
|
!!! tip "Future extensions with different defaults"
|
||||||
|
Note that **the below list is not exhaustive**, and extensions to `interactionPolicy` may wish to define **different defaults** for other types of interaction.
|
||||||
|
|
||||||
|
### `canLike`
|
||||||
|
|
||||||
|
If `canLike` is missing on an `interactionPolicy`, or the value of `canLike` is `null` or `{}`, then implementations should assume:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, the default is **anyone who can see the post can like it**.
|
||||||
|
|
||||||
|
### `canReply`
|
||||||
|
|
||||||
|
If `canReply` is missing on an `interactionPolicy`, or the value of `canReply` is `null` or `{}`, then implementations should assume:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, the default is **anyone who can see the post can reply to it**.
|
||||||
|
|
||||||
|
### `canAnnounce`
|
||||||
|
|
||||||
|
If `canAnnounce` is missing on an `interactionPolicy`, or the value of `canAnnounce` is `null` or `{}`, then implementations should assume:
|
||||||
|
|
||||||
|
```json
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In other words, the default is **anyone who can see the post can announce it**.
|
||||||
|
|
||||||
|
## Indicating that verification is required / not required per sub-policy
|
||||||
|
|
||||||
|
Because not all servers have implemented interaction policies at the time of writing, it is necessary to provide a method by which implementing servers can indicate that they are both **aware of** and **will enforce** interaction policies as described below in the [Interaction Verification](#interaction-verification) section.
|
||||||
|
|
||||||
|
This indication of interaction policy participation is done via a server explicitly setting `interactionPolicy` and its sub-policies on outgoing posts, instead of relying on the defaults described above.
|
||||||
|
|
||||||
|
That is, **by setting `interactionPolicy.*` on a post, an instance indicates to other instances that they will enforce validation of interactions for each sub-policy that is explicitly set.**
|
||||||
|
|
||||||
|
This means that implementations should always explicitly set all sub-policies on an `interactionPolicy` for which they have implemented interaction controls themselves, and with which they would like other servers to comply.
|
||||||
|
|
||||||
|
For example, if a server understands and wishes to enforce the `canLike`, `canReply`, and `canAnnounce` sub-policies (as is the case with GoToSocial), then they should explicitly set those sub-policies on an outgoing post *even when the values do not differ from the implicit defaults*. This allows remote servers to know that the origin server does enforcement, and knows how to handle appropriate `Reject` / `Accept` messages for each sub-policy.
|
||||||
|
|
||||||
|
Another example: if a server only implements the `canReply` interaction sub-policy, but not `canLike` or `canAnnounce`, then they should always set `interactionPolicy.canReply`, and leave the other two sub-policies out of the `interactionPolicy` to indicate that they cannot understand or enforce them.
|
||||||
|
|
||||||
|
This means of indicating participation in interaction policies through the absence of presence of keys was designed so that the large majority of servers that *do not* set `interactionPolicy` at all, because they have not (yet) implemented it, do not need to change their behavior. Servers that do implement `interactionPolicy` can understand, by the absence of the `interactionPolicy` key on a post, that the origin server is not `interactionPolicy` aware, and behave accordingly.
|
||||||
|
|
||||||
|
## Implicit Assumptions
|
||||||
|
|
||||||
|
For common-sense safety reasons, GoToSocial makes, and will always apply, two implicit assumptions about interaction policies.
|
||||||
|
|
||||||
|
### 1. Mentioned + replied-to actors can always reply
|
||||||
|
|
||||||
|
Actors mentioned in, or replied to by, a post should **ALWAYS** be able to reply to that post without requiring approval, regardless of the post visiblity and the `interactionPolicy`, **UNLESS** the post that mentioned or replied to them is itself currently pending approval.
|
||||||
|
|
||||||
|
This is to prevent a would-be harasser from mentioning someone in an abusive post, and leaving no recourse to the mentioned user to reply.
|
||||||
|
|
||||||
|
As such, when sending out interaction policies, GoToSocial will **ALWAYS** add the URIs of mentioned users to the `canReply.always` array, unless they are already covered by the ActivityStreams magic public URI.
|
||||||
|
|
||||||
|
Likewise, when enforcing received interaction policies, GoToSocial will **ALWAYS** behave as though the URIs of mentioned users were present in the `canReply.always` array, even if they weren't.
|
||||||
|
|
||||||
|
### 2. An actor can always interact in any way with their own post
|
||||||
|
|
||||||
|
**Secondly**, an actor should **ALWAYS** be able to reply to their own post, like their own post, and boost their own post without requiring approval, **UNLESS** that post is itself currently pending approval.
|
||||||
|
|
||||||
|
As such, when sending out interaction policies, GoToSocial will **ALWAYS** add the URI of the post author to the `canLike.always`, `canReply.always`, and `canAnnounce.always` arrays, **UNLESS** they are already covered by the ActivityStreams magic public URI.
|
||||||
|
|
||||||
|
Likewise, when enforcing received interaction policies, GoToSocial will **ALWAYS** behave as though the URI of the post author themself is present in each `always` field, even if it wasn't.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
Here's some examples of what interaction policies allow users to do.
|
||||||
|
|
||||||
|
### 1. Limiting scope of a conversation
|
||||||
|
|
||||||
|
In this example, the user `@the_mighty_zork` wants to begin a conversation with the users `@booblover6969` and `@hodor`.
|
||||||
|
|
||||||
|
To avoid the discussion being derailed by others, they want replies to their post by users other than the three participants to be permitted only if they're approved by `@the_mighty_zork`.
|
||||||
|
|
||||||
|
Furthermore, they want to limit the boosting / `Announce`ing of their post to only their own followers, and to the three conversation participants.
|
||||||
|
|
||||||
|
However, anyone should be able to `Like` the post by `@the_mighty_zork`.
|
||||||
|
|
||||||
|
This can be achieved with the following `interactionPolicy`, which is attached to a post with visibility level public:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": [
|
||||||
|
"https://example.org/users/the_mighty_zork",
|
||||||
|
"https://example.org/users/booblover6969",
|
||||||
|
"https://example.org/users/hodor"
|
||||||
|
],
|
||||||
|
"approvalRequired": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": [
|
||||||
|
"https://example.org/users/the_mighty_zork",
|
||||||
|
"https://example.org/users/the_mighty_zork/followers",
|
||||||
|
"https://example.org/users/booblover6969",
|
||||||
|
"https://example.org/users/hodor"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Long solo thread
|
||||||
|
|
||||||
|
In this example, the user `@the_mighty_zork` wants to write a long solo thread.
|
||||||
|
|
||||||
|
They don't mind if people boost and like posts in the thread, but they don't want to get any replies because they don't have the energy to moderate the discussion; they just want to vent by throwing their thoughts out there.
|
||||||
|
|
||||||
|
This can be achieved by setting the following `interactionPolicy` on every post in the thread:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://example.org/users/the_mighty_zork"
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Here, anyone is allowed to like or boost, but nobody is permitted to reply (except `@the_mighty_zork` themself).
|
||||||
|
|
||||||
|
### 3. Completely open
|
||||||
|
|
||||||
|
In this example, `@the_mighty_zork` wants to write a completely open post that can be replied to, boosted, or liked by anyone who can see it:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
[...]
|
||||||
|
],
|
||||||
|
[...],
|
||||||
|
"interactionPolicy": {
|
||||||
|
"canLike": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canReply": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
},
|
||||||
|
"canAnnounce": {
|
||||||
|
"always": "https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Subsequent Replies / Scope Widening
|
||||||
|
|
||||||
|
Each subsequent reply in a conversation will have its own interaction policy, chosen by the user who created the reply. In other words, the entire *conversation* or *thread* is not controlled by one `interactionPolicy`, but the policy can differ for each subsequent post in a thread, as set by the post author.
|
||||||
|
|
||||||
|
Unfortunately, this means that even with `interactionPolicy` in place, the scope of a thread can inadvertently widen beyond the intention of the author of the first post in the thread.
|
||||||
|
|
||||||
|
For instance, in [example 1](#example-1---limiting-scope-of-a-conversation) above, `@the_mighty_zork` specifies in the first post a `canReply.always` value of
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"https://example.org/users/the_mighty_zork",
|
||||||
|
"https://example.org/users/booblover6969",
|
||||||
|
"https://example.org/users/hodor"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
In a subsequent reply, either accidentally or on purpose `@booblover6969` sets the `canReply.always` value to:
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
This widens the scope of the conversation, as now anyone can reply to `@booblover6969`'s post, and possibly also tag `@the_mighty_zork` in that reply.
|
||||||
|
|
||||||
|
To avoid this issue, it is recommended that remote instances prevent users from being able to widen scope (exact mechanism of doing this TBD).
|
||||||
|
|
||||||
|
It is also a good idea for instances to consider any interaction with a post-like `Object` that is itself currently pending approval, as also pending approval.
|
||||||
|
|
||||||
|
In other words, instances should mark all children interactions below a pending-approval parent as also pending approval, no matter what the interaction policy on the parent would ordinarily allow.
|
||||||
|
|
||||||
|
This avoids situations where someone could reply to a post, then, even if their reply is pending approval, they could reply *to their own reply* and have that marked as permitted (since as author, they would normally have [implicit permission to reply](#implicit-assumptions)).
|
||||||
|
|
||||||
|
## Interaction Verification
|
||||||
|
|
||||||
|
The [interaction policy](#interaction-policy) section described the shape of interaction policies, assumed defaults, and assumptions.
|
||||||
|
|
||||||
|
This section describes the enforcement and verification of interaction policies, ie., how servers that set interaction policies should send approval or rejection of a requested/pending interaction, and how other servers can prove that approval to interact with a post has been obtained by the interacter from the interactee.
|
||||||
|
|
||||||
|
### Requesting, Obtaining, and Validating Approval
|
||||||
|
|
||||||
|
When an actor's URI is in the `approvalRequired` array for a type of interaction, **or** their presence in a collection needs to be validated (see [Validating presence in a Followers / Following collection](#validating-presence-in-a-followers--following-collection)), implementations wishing to obtain approval for that actor to interact with a policied post should do the following:
|
||||||
|
|
||||||
|
1. Compose the interaction `Activity` (ie., `Like`, `Create` (reply), or `Announce`), as normal.
|
||||||
|
2. Address the `Activity` `to` and `cc` the expected recipients for that `Activity`, as normal.
|
||||||
|
3. `POST` the `Activity` only to the `Inbox` (or `sharedInbox`) of the author of the post being interacted with.
|
||||||
|
4. **DO NOT DISTRIBUTE THE ACTIVITY FURTHER THAN THIS AT THIS POINT**.
|
||||||
|
|
||||||
|
At this point, the interaction can be considered as *pending approval*, and should not be shown in the replies or likes collections, etc., of the post interacted with.
|
||||||
|
|
||||||
|
It may be shown to the user who sent the interaction as a sort of "interaction pending" modal, but ideally it should not be shown to other users who share an instance with that user.
|
||||||
|
|
||||||
|
From here, one of three things may happen:
|
||||||
|
|
||||||
|
#### Rejection
|
||||||
|
|
||||||
|
In this scenario, the server of the author of the post being interacted with sends back a `Reject` `Activity` with the interaction URI/ID as the `object` property.
|
||||||
|
|
||||||
|
For example, the following json object `Reject`s the attempt of `@someone@somewhere.else.example.org` to reply to a post by `@post_author@example.org`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"actor": "https://example.org/users/post_author",
|
||||||
|
"to": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
"type": "Reject"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If this happens, `@someone@somewhere.else.example.org` (and their instance) should consider the interaction as having been rejected. The instance should delete the activity from its internal storage (ie., database), or otherwise indicate that it's been rejected, and it should not distribute the `Activity` further, or retry the interaction. The server may wish to indicate to the interacter that their interaction was rejected.
|
||||||
|
|
||||||
|
#### Nothing
|
||||||
|
|
||||||
|
In this scenario, the author of the post being interacted with never sends back a `Reject` or an `Accept` `Activity`. In such a case, the interaction is considered "pending" in perpetuity. Instances may wish to implement some kind of cleanup feature, where sent and pending interactions that reach a certain age should be considered expired, and `Rejected` and then removed in the manner gestured towards above.
|
||||||
|
|
||||||
|
#### Acceptance
|
||||||
|
|
||||||
|
In this scenario, the author of the post being interacted with sends back an `Accept` `Activity` with the interaction URI/ID as the `object` property, and a dereferenceable URI of an approval object as the `result` property (see [Approval Objects](#approval-objects)).
|
||||||
|
|
||||||
|
For example, the following json object `Accept`s the attempt of `@someone@somewhere.else.example.org` to reply to a post by `@post_author@example.org`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"actor": "https://example.org/users/post_author",
|
||||||
|
"cc": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"https://example.org/users/post_author/followers"
|
||||||
|
],
|
||||||
|
"to": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"id": "https://example.org/users/post_author/activities/accept/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
"result": "https://example.org/users/post_author/reply_approvals/01JMMGABRDNA9G9BDNYJR7TC8D",
|
||||||
|
"type": "Accept"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If this happens, `@someone@somewhere.else.example.org` (and their instance) should consider the interaction as having been approved/accepted by the interactee.
|
||||||
|
|
||||||
|
At this point, `somewhere.else.example.org` should once again send out the interaction, with the following differences:
|
||||||
|
|
||||||
|
1. This time, include the `result` URI/ID from the `accept` in the `approvedBy` field of the post contained in the `Create` (see [`approvedBy`](#approvedby)).
|
||||||
|
2. This time, distribute the interaction to **all** of the recipients targed by `to`, `cc`, etc.
|
||||||
|
|
||||||
|
!!! note
|
||||||
|
While it is not strictly necessary, in the above example, actor `https://example.org/users/post_author` addresses the `Accept` activity not just to the interacting actor `https://somewhere.else.example.org/users/someone`, but to their followers collection as well (and, implicitly, to the public). This allows followers of `https://example.org/users/post_author` on other servers to also mark the interaction as accepted, and to show the interaction alongside the interacted-with post, without having to dereference + verify the URI in `approvedBy`.
|
||||||
|
|
||||||
|
### Approval Objects
|
||||||
|
|
||||||
|
An approval is an extension of a basic ActivityStreams Object, with the type `LikeApproval`, `ReplyApproval`, or `AnnounceApproval`. Each type corresponds to the type of interaction that the particular approval approves.
|
||||||
|
|
||||||
|
`LikeApproval`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://gotosocial.org/ns"
|
||||||
|
],
|
||||||
|
"attributedTo": "https://example.org/users/post_author",
|
||||||
|
"id": "https://example.org/users/post_author/approvals/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/likes/01JMPKG79EAH0NB04BHEM9D20N",
|
||||||
|
"target": "https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT",
|
||||||
|
"type": "LikeApproval"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`ReplyApproval`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://gotosocial.org/ns"
|
||||||
|
],
|
||||||
|
"attributedTo": "https://example.org/users/post_author",
|
||||||
|
"id": "https://example.org/users/post_author/approvals/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
"target": "https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT",
|
||||||
|
"type": "ReplyApproval"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
`AnnounceApproval`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
"https://gotosocial.org/ns"
|
||||||
|
],
|
||||||
|
"attributedTo": "https://example.org/users/post_author",
|
||||||
|
"id": "https://example.org/users/post_author/approvals/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/boosts/01JMPKG79EAH0NB04BHEM9D20N",
|
||||||
|
"target": "https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT",
|
||||||
|
"type": "AnnounceApproval"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
In an approval object:
|
||||||
|
|
||||||
|
- `attributedTo`: should be the `Actor` who `Accept`ed an interaction, ie., the *interactee*.
|
||||||
|
- `object`: should be the *interacting* `Like`, `Announce`, or post-like `Object`.
|
||||||
|
- `target` (optional): if included, should be the post-like `Object` that was *interacted with*.
|
||||||
|
|
||||||
|
!!! info "Approval objects should be dereferenceable"
|
||||||
|
As a consequence of the validation mechanism (see [Validating `approvedBy`](#validating-approvedby)), instances should make sure that they serve a valid ActivityPub response to dereferences of approval object URIs. If they do not, they inadvertently risk restricting the ability of remote instances to distribute their posts.
|
||||||
|
|
||||||
|
### `approvedBy`
|
||||||
|
|
||||||
|
`approvedBy` is an additional property added to the `Like`, and `Announce` activities, and any `Object`s considered to be "posts" (`Note`, `Article`, etc).
|
||||||
|
|
||||||
|
The presence of `approvedBy` signals that the author of the post targeted by the `Activity` or replied-to by the `Object` has approved/accepted the interaction, and it can now be distributed to its intended audience.
|
||||||
|
|
||||||
|
The value of `approvedBy` should be the `result` URI/ID that was sent along in an `Accept` from the interactee, which points towards a dereferenceable approval object.
|
||||||
|
|
||||||
|
For example, the following `Announce` `Activity` claims, by the presence of `approvedBy`, that it has been `Accept`ed by `@post_author@example.org`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"actor": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"to": [
|
||||||
|
"https://somewhere.else.example.org/users/someone/followers"
|
||||||
|
],
|
||||||
|
"cc": [
|
||||||
|
"https://example.org/users/post_author"
|
||||||
|
],
|
||||||
|
"id": "https://somewhere.else.example.org/users/someone/activities/announce/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://example.org/users/post_author/statuses/01J17ZZFK6W82K9MJ9SYQ33Y3D",
|
||||||
|
"approvedBy": "https://example.org/users/post_author/reply_approvals/01JMMGABRDNA9G9BDNYJR7TC8D",
|
||||||
|
"type": "Announce"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Validating `approvedBy`
|
||||||
|
|
||||||
|
When receiving an `Activity` or a post-like `Object` with an `approvedBy` value attached to it, remote instances should:
|
||||||
|
|
||||||
|
1. Validate that the host/domain of the `approvedBy` URI is equal to the host/domain of the author of the post being interacted with.
|
||||||
|
2. Dereference the `approvedBy` URI/ID to get the approval object (see [Approval Objects](#approval-objects)).
|
||||||
|
3. Check the type of the approval to ensure it's the correct one, eg., an `Announce` should have an `approvedBy` URI/ID set on it that points to an `AnnounceApproval`, not a `ReplyApproval` or a `LikeApproval`.
|
||||||
|
4. Check that the approval has an `attributedTo` value equal to the URI/ID of the actor being interacted with.
|
||||||
|
5. Check that the approval has an `object` value equal to the `id` of the interaction `Activity` or `Object`.
|
||||||
|
|
||||||
|
If the approval cannot be dereferenced, or does not pass validity checks, the interaction should be considered invalid and dropped.
|
||||||
|
|
||||||
|
!!! warning
|
||||||
|
Versions 0.17.x and 0.18.x of GoToSocial did not include a `result` pointing towards an approval type. Instead, the URI/ID of the `Accept` was sent in the `approvedBy` field.
|
||||||
|
|
||||||
|
Version 0.18.x of GoToSocial is partially forward-compatible with approval types, since it can validate approval using either a dereferenced `Accept` or a dereferenced approval type, while still sending out an `Accept` URI itself in the `approvedBy` field.
|
||||||
|
|
||||||
|
Versions of GoToSocial from 0.19.x upwards will send out an `approvedBy` pointing to an approval type, as described in this document, not an `Accept`.
|
||||||
|
|
||||||
|
### Validating presence in a Followers / Following collection
|
||||||
|
|
||||||
|
If an `Actor` interacting with an `object` (via `Like`, `inReplyTo`, or `Announce`) is permitted to do that interaction based on their presence in a `Followers` or `Following` collection in the `always` field of an interaction policy, then their server **should still wait** for an `Accept` to be received from the server of the target actor, before distributing the interaction more widely with the `approvedBy` property set to the URI/ID of the approval.
|
||||||
|
|
||||||
|
This is to prevent scenarios where third servers have to somehow verify the presence of the interacting `Actor` in the `Followers` or `Following` collection of the `Actor` being interacted with. It is simpler to allow the target server to do that verification, and to trust that their approval implicitly agrees that the interacting `Actor` is present in the relevant collection.
|
||||||
|
|
||||||
|
Likewise, when receiving an interaction from an `Actor` whose permission to interact matches with one of the `Following` or `Followers` collections in the `always` property, the server of the interacted-with `Actor` should ensure that they *always* send out an `Accept` as soon as possible, so that the interacting `Actor` server can send out the `Activity` with the proper proof of acceptance.
|
||||||
|
|
||||||
|
This process should bypass the normal "pending approval" stage whereby the server of the `Actor` being interacted with notifies them of the pending interaction, and waits for them to accept or reject, since there is no point notifying an `Actor` of a pending approval that they have already explicitly agreed to. In the GoToSocial codebase in particular, this is called "preapproval".
|
||||||
|
|
||||||
|
### Optional behaviors
|
||||||
|
|
||||||
|
This section describes optional behaviors that implementers *may* use when sending `Accept` and `Reject` messages, and *should* account for when receiving `Accept` and `Reject` messages.
|
||||||
|
|
||||||
|
#### Always send out `Accept`s
|
||||||
|
|
||||||
|
Implementers may wish to *always* send out an `Accept` to remote interacters, even when the interaction is implicitly or explicitly permitted by their presence in the `always` array. When receiving such an `Accept`, implementations may still want to update their representation of the interaction to include an `approvedBy` URI pointing at an approval. This may be useful later on when handling revocations (TODO).
|
||||||
|
|
||||||
|
#### Type hinting: inline `object` property on `Accept` and `Reject`
|
||||||
|
|
||||||
|
If desired, implementers may partially expand/inline the `object` property of an `Accept` or `Reject` to hint to remote servers about the type of interaction being `Accept`ed or `Reject`ed. When inlining in this way, the `object`'s `type` and `id` must be defined at a minimum. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"actor": "https://example.org/users/post_author",
|
||||||
|
"cc": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"https://example.org/users/post_author/followers"
|
||||||
|
],
|
||||||
|
"to": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": {
|
||||||
|
"type": "Note",
|
||||||
|
"id": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
[...]
|
||||||
|
},
|
||||||
|
"result": "https://example.org/users/post_author/approvals/01JMPS01E54DG9JCF2ZK3JDMXE",
|
||||||
|
"type": "Accept"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Set `target` property on `Accept` and `Reject`
|
||||||
|
|
||||||
|
If desired, implementers may set the `target` property on outgoing `Accept` or `Reject` activities to the `id` of the post being interacted with, to make it easier for remote servers to understand the shape and relevance of the interaction that's being `Accept`ed or `Reject`ed.
|
||||||
|
|
||||||
|
For example, the following json object `Accept`s the attempt of `@someone@somewhere.else.example.org` to reply to a post by `@post_author@example.org` that has the id `https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"actor": "https://example.org/users/post_author",
|
||||||
|
"cc": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"https://example.org/users/post_author/followers"
|
||||||
|
],
|
||||||
|
"to": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
"target": "https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT",
|
||||||
|
"result": "https://example.org/users/post_author/approvals/01JMPS01E54DG9JCF2ZK3JDMXE",
|
||||||
|
"type": "Accept"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
If desired, the `target` property can also be partially expanded/inlined to type hint about the post that was interacted with. When inlining in this way, the `target`'s `type` and `id` must be defined at a minimum. For example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": "https://www.w3.org/ns/activitystreams",
|
||||||
|
"actor": "https://example.org/users/post_author",
|
||||||
|
"cc": [
|
||||||
|
"https://www.w3.org/ns/activitystreams#Public",
|
||||||
|
"https://example.org/users/post_author/followers"
|
||||||
|
],
|
||||||
|
"to": "https://somewhere.else.example.org/users/someone",
|
||||||
|
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
||||||
|
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
||||||
|
"target": {
|
||||||
|
"type": "Note",
|
||||||
|
"id": "https://example.org/users/post_author/statuses/01JJYV141Y5M4S65SC1XCP65NT"
|
||||||
|
[ ... ]
|
||||||
|
},
|
||||||
|
"result": "https://example.org/users/post_author/approvals/01JMPS01E54DG9JCF2ZK3JDMXE",
|
||||||
|
"type": "Accept"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
@ -79,7 +79,7 @@ For example:
|
||||||
"updated": "2022-11-17T11:36:05Z"
|
"updated": "2022-11-17T11:36:05Z"
|
||||||
}
|
}
|
||||||
[...]
|
[...]
|
||||||
}`
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The text `:shocked_pikachu:` in the `content` of the above `Note` should be replaced by clients with a small (inline) version of the emoji image, when rendering the `Note` and displaying it to users.
|
The text `:shocked_pikachu:` in the `content` of the above `Note` should be replaced by clients with a small (inline) version of the emoji image, when rendering the `Note` and displaying it to users.
|
||||||
|
|
@ -219,530 +219,9 @@ If `contentMap` has multiple entries, we have no way of determining the intended
|
||||||
|
|
||||||
## Interaction Policy
|
## Interaction Policy
|
||||||
|
|
||||||
GoToSocial uses the property `interactionPolicy` on posts in order to indicate to remote instances what sort of interactions will be (conditionally) permitted for any given post.
|
GoToSocial uses the property `interactionPolicy` on posts, in order to indicate to remote instances what sort of interactions are (conditionally) permitted to be processed and stored by the origin server, for any given post.
|
||||||
|
|
||||||
!!! danger
|
For more details on this, see the separate [interaction policy](./interaction_policy.md) document.
|
||||||
|
|
||||||
Interaction policy is an attempt to limit the harmful effects of unwanted replies and other interactions on a user's posts (eg., "reply guys").
|
|
||||||
|
|
||||||
However, it is far from being sufficient for this purpose, as there are still many "out-of-band" ways that posts can be distributed or replied to beyond a user's initial wishes or intentions.
|
|
||||||
|
|
||||||
For example, a user might create a post with a very strict interaction policy attached to it, only to find that other server softwares do not respect that policy, and users on other instances are having discussions and replying to the post *from their instance's perspective*. The original poster's instance will automatically drop these unwanted interactions from their view, but remote instances may still show them.
|
|
||||||
|
|
||||||
Another example: someone might see a post that specifies nobody can reply to it, but screenshot the post, post the screenshot in their own new post, and tag the original post author in as a mention. Alternatively, they might just link to the URL of the post and tag the author in as a mention. In this case, they effectively "reply" to the post by creating a new thread.
|
|
||||||
|
|
||||||
For better or worse, GoToSocial can offer only a best-effort, partial, technological solution to what is more or less an issue of social behavior and boundaries.
|
|
||||||
|
|
||||||
### Overview
|
|
||||||
|
|
||||||
`interactionPolicy` is a property attached to the status-like `Object`s `Note`, `Article`, `Question`, etc, with the following format:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
|
||||||
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
|
||||||
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
|
||||||
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
In this object:
|
|
||||||
|
|
||||||
- `canLike` indicates who can create a `Like` with the post URI as the `Object` of the `Like`.
|
|
||||||
- `canReply` indicates who can create a post with `inReplyTo` set to the URI of the post.
|
|
||||||
- `canAnnounce` indicates who can create an `Announce` with the post URI as the `Object` of the `Announce`.
|
|
||||||
|
|
||||||
And:
|
|
||||||
|
|
||||||
- `always` is an array of ActivityPub URIs/IDs of `Actor`s or `Collection`s of `Actor`s who do not require an `Accept` in order to distribute an interaction to their followers (more on this below).
|
|
||||||
- `approvalRequired` is an array of ActivityPub URIs/IDs of `Actor`s or `Collection`s of `Actor`s who can interact, but should wait for an `Accept` before distributing an interaction to their followers.
|
|
||||||
|
|
||||||
Valid URI entries in `always` and `approvalRequired` include the magic ActivityStreams Public URI `https://www.w3.org/ns/activitystreams#Public`, the URIs of the post creator's `Following` and/or `Followers` collections, and individual Actor URIs. For example:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public",
|
|
||||||
"https://example.org/users/someone/followers",
|
|
||||||
"https://example.org/users/someone/following",
|
|
||||||
"https://example.org/users/someone_else",
|
|
||||||
"https://somewhere.else.example.org/users/someone_on_a_different_instance"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
### Specifying Nobody
|
|
||||||
|
|
||||||
!!! note
|
|
||||||
GoToSocial makes implicit assumptions about who can/can't interact, even if a policy specifies nobody. See [implicit assumptions](#implicit-assumptions).
|
|
||||||
|
|
||||||
An empty array, or a missing or null key, indicates that nobody can do the interaction.
|
|
||||||
|
|
||||||
For example, the following `canLike` value indicates that nobody can `Like` the post:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"canLike": {
|
|
||||||
"always": [],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
```
|
|
||||||
|
|
||||||
Likewise, a `canLike` value of `null` also indicates that nobody can `Like` the post:
|
|
||||||
|
|
||||||
```json
|
|
||||||
"canLike": null
|
|
||||||
```
|
|
||||||
|
|
||||||
or
|
|
||||||
|
|
||||||
```json
|
|
||||||
"canLike": {
|
|
||||||
"always": null,
|
|
||||||
"approvalRequired": null
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
And a missing `canLike` value does the same thing:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canReply": {
|
|
||||||
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
|
||||||
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [ "zero_or_more_uris_that_can_always_do_this" ],
|
|
||||||
"approvalRequired": [ "zero_or_more_uris_that_require_approval_to_do_this" ]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Conflicting / Duplicate Values
|
|
||||||
|
|
||||||
In cases where a user is present in a Collection URI, and is *also* targeted explicitly by URI, the **more specific value** takes precedence.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[...],
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone"
|
|
||||||
],
|
|
||||||
"approvalRequired": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `@someone@example.org` is present in the `always` array, and is also implicitly present in the magic ActivityStreams Public collection in the `approvalRequired` array. In this case, they can always reply, as the `always` value is more explicit.
|
|
||||||
|
|
||||||
Another example:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[...],
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": [
|
|
||||||
"https://example.org/users/someone"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, `@someone@example.org` is present in the `approvalRequired` array, but is also implicitly present in the magic ActivityStreams Public collection in the `always` array. In this case everyone can reply without approval, **except** for `@someone@example.org`, who requires approval.
|
|
||||||
|
|
||||||
In case the **exact same** URI is present in both `always` and `approvalRequired`, the **highest level of permission** takes precedence (ie., a URI in `always` takes precedence over the same URI in `approvalRequired`).
|
|
||||||
|
|
||||||
### Implicit Assumptions
|
|
||||||
|
|
||||||
GoToSocial makes several implicit assumptions about `interactionPolicy`s.
|
|
||||||
|
|
||||||
**Firstly**, users [mentioned](#mentions) in, or replied to by, a post should **ALWAYS** be able to reply to that post without requiring approval, regardless of the post visiblity and the `interactionPolicy`, **UNLESS** the post that mentioned or replied to them is itself currently pending approval.
|
|
||||||
|
|
||||||
This is to prevent a would-be harasser from mentioning someone in an abusive post, and leaving no recourse to the mentioned user to reply.
|
|
||||||
|
|
||||||
As such, when sending out interaction policies, GoToSocial will **ALWAYS** add the URIs of mentioned users to the `canReply.always` array, unless they are already covered by the ActivityStreams magic public URI.
|
|
||||||
|
|
||||||
Likewise, when enforcing received interaction policies, GoToSocial will **ALWAYS** behave as though the URIs of mentioned users were present in the `canReply.always` array, even if they weren't.
|
|
||||||
|
|
||||||
**Secondly**, a user should **ALWAYS** be able to reply to their own post, like their own post, and boost their own post without requiring approval, **UNLESS** that post is itself currently pending approval.
|
|
||||||
|
|
||||||
As such, when sending out interaction policies, GoToSocial will **ALWAYS** add the URI of the post author to the `canLike.always`, `canReply.always`, and `canAnnounce.always` arrays, unless they are already covered by the ActivityStreams magic public URI.
|
|
||||||
|
|
||||||
Likewise, when enforcing received interaction policies, GoToSocial will **ALWAYS** behave as though the URI of the post author is present in these `always` arrays, even if it wasn't.
|
|
||||||
|
|
||||||
### Defaults
|
|
||||||
|
|
||||||
When the `interactionPolicy` property is not present at all on a post, GoToSocial assumes a default `interactionPolicy` for that post appropriate to the visibility level of the post, and the post author.
|
|
||||||
|
|
||||||
For a **public** or **unlocked** post by `@someone@example.org`, the default `interactionPolicy` is:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For a **followers-only** post by `@someone@example.org`, the assumed `interactionPolicy` is:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone",
|
|
||||||
"https://example.org/users/someone/followers",
|
|
||||||
[...URIs of any mentioned users...]
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone",
|
|
||||||
"https://example.org/users/someone/followers",
|
|
||||||
[...URIs of any mentioned users...]
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
For a **direct** post by `@someone@example.org`, the assumed `interactionPolicy` is:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone",
|
|
||||||
[...URIs of any mentioned users...]
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone",
|
|
||||||
[...URIs of any mentioned users...]
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/someone"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 1 - Limiting scope of a conversation
|
|
||||||
|
|
||||||
In this example, the user `@the_mighty_zork` wants to begin a conversation with the users `@booblover6969` and `@hodor`.
|
|
||||||
|
|
||||||
To avoid the discussion being derailed by others, they want replies to their post by users other than the three participants to be permitted only if they're approved by `@the_mighty_zork`.
|
|
||||||
|
|
||||||
Furthermore, they want to limit the boosting / `Announce`ing of their post to only their own followers, and to the three conversation participants.
|
|
||||||
|
|
||||||
However, anyone should be able to `Like` the post by `@the_mighty_zork`.
|
|
||||||
|
|
||||||
This can be achieved with the following `interactionPolicy`, which is attached to a post with visibility level public:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/the_mighty_zork",
|
|
||||||
"https://example.org/users/booblover6969",
|
|
||||||
"https://example.org/users/hodor"
|
|
||||||
],
|
|
||||||
"approvalRequired": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/the_mighty_zork",
|
|
||||||
"https://example.org/users/the_mighty_zork/followers",
|
|
||||||
"https://example.org/users/booblover6969",
|
|
||||||
"https://example.org/users/hodor"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2 - Long solo thread
|
|
||||||
|
|
||||||
In this example, the user `@the_mighty_zork` wants to write a long solo thread.
|
|
||||||
|
|
||||||
They don't mind if people boost and like posts in the thread, but they don't want to get any replies because they don't have the energy to moderate the discussion; they just want to vent by throwing their thoughts out there.
|
|
||||||
|
|
||||||
This can be achieved by setting the following `interactionPolicy` on every post in the thread:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://example.org/users/the_mighty_zork"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Here, anyone is allowed to like or boost, but nobody is permitted to reply (except `@the_mighty_zork` themself).
|
|
||||||
|
|
||||||
### Example 3 - Completely open
|
|
||||||
|
|
||||||
In this example, `@the_mighty_zork` wants to write a completely open post that can be replied to, boosted, or liked by anyone who can see it (ie., the default behavior for unlocked and public posts):
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
[...],
|
|
||||||
"interactionPolicy": {
|
|
||||||
"canLike": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canReply": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
},
|
|
||||||
"canAnnounce": {
|
|
||||||
"always": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
],
|
|
||||||
"approvalRequired": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[...]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
### Requesting, Obtaining, and Validating Approval
|
|
||||||
|
|
||||||
When a user's URI is in the `approvalRequired` array for a type of interaction, and that user wishes to obtain approval to distribute an interaction, they should do the following:
|
|
||||||
|
|
||||||
1. Compose the interaction `Activity` (ie., `Like`, `Create` (reply), or `Announce`), as normal.
|
|
||||||
2. Address the `Activity` `to` and `cc` the expected recipients for that `Activity`, as normal.
|
|
||||||
3. `POST` the `Activity` only to the `Inbox` (or `sharedInbox`) of the author of the post being interacted with.
|
|
||||||
4. **DO NOT DISTRIBUTE THE ACTIVITY FURTHER THAN THIS AT THIS POINT**.
|
|
||||||
|
|
||||||
At this point, the interaction can be considered as pending approval, and should not be shown in the replies or likes collections, etc., of the post interacted with.
|
|
||||||
|
|
||||||
It may be shown to the user who sent the interaction as a sort of "interaction pending" modal, but ideally it should not be shown to other users who share an instance with that user.
|
|
||||||
|
|
||||||
From here, one of three things may happen:
|
|
||||||
|
|
||||||
#### Rejection
|
|
||||||
|
|
||||||
In this scenario, the author of the post being interacted with sends back a `Reject` `Activity` with the URI/ID of the interaction `Activity` as the `Object` property.
|
|
||||||
|
|
||||||
For example, the following json object `Reject`s the attempt of `@someone@somewhere.else.example.org` to reply to a post by `@post_author@example.org`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
|
||||||
"actor": "https://example.org/users/post_author",
|
|
||||||
"to": "https://somewhere.else.example.org/users/someone",
|
|
||||||
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
|
||||||
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
|
||||||
"type": "Reject"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If this happens, `@someone@somewhere.else.example.org` (and their instance) should consider the interaction as having been rejected. The instance should delete the activity from its internal storage (ie., database), or otherwise indicate that it's been rejected, and it should not distribute the `Activity` further, or retry the interaction.
|
|
||||||
|
|
||||||
#### Nothing
|
|
||||||
|
|
||||||
In this scenario, the author of the post being interacted with never sends back a `Reject` or an `Accept` `Activity`. In such a case, the interaction is considered "pending" in perpetuity. Instances may wish to implement some kind of cleanup feature, where sent and pending interactions that reach a certain age should be considered expired, and `Rejected` and then removed in the manner gestured towards above.
|
|
||||||
|
|
||||||
#### Acceptance
|
|
||||||
|
|
||||||
In this scenario, the author of the post being interacted with sends back an `Accept` `Activity` with the URI/ID of the interaction `Activity` as the `Object` property.
|
|
||||||
|
|
||||||
For example, the following json object `Accept`s the attempt of `@someone@somewhere.else.example.org` to reply to a post by `@post_author@example.org`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"@context": "https://www.w3.org/ns/activitystreams",
|
|
||||||
"actor": "https://example.org/users/post_author",
|
|
||||||
"cc": [
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public",
|
|
||||||
"https://example.org/users/post_author/followers"
|
|
||||||
],
|
|
||||||
"to": "https://somewhere.else.example.org/users/someone",
|
|
||||||
"id": "https://example.org/users/post_author/activities/reject/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
|
||||||
"object": "https://somewhere.else.example.org/users/someone/statuses/01J17XY2VXGMNNPH1XR7BG2524",
|
|
||||||
"type": "Accept"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
If this happens, `@someone@somewhere.else.example.org` (and their instance) should consider the interaction as having been approved / accepted. The instance can then feel free to distribute the interaction `Activity` to all of the recipients targed by `to`, `cc`, etc, with the additional property `approvedBy` ([see below](#approvedby)).
|
|
||||||
|
|
||||||
!!! Note
|
|
||||||
In the above example, actor `https://example.org/users/post_author` addresses the `Accept` activity not just to the interacting actor `https://somewhere.else.example.org/users/someone`, but to their followers collection as well (and, implicitly, to the public). This allows followers of `https://example.org/users/post_author` on other servers to also mark the interaction as accepted, and to show the interaction alongside the interacted-with post.
|
|
||||||
|
|
||||||
### Validating presence in a Followers / Following collection
|
|
||||||
|
|
||||||
If an `Actor` interacting with an `Object` (via `Like`, `inReplyTo`, or `Announce`) is permitted to do that interaction based on their presence in a `Followers` or `Following` collection in the `always` field of an interaction policy, then their server should *still* wait for an `Accept` to be received from the server of the target account, before distributing the interaction more widely with the `approvedBy` property set to the URI of the `Accept`.
|
|
||||||
|
|
||||||
This is to prevent scenarios where third servers have to somehow verify the presence of the interacting `Actor` in the `Followers` or `Following` collection of the `Actor` being interacted with. It is simpler to allow the target server to do that verification, and to trust that their `Accept` implicitly agrees that the interacting `Actor` is present in the relevant collection.
|
|
||||||
|
|
||||||
Likewise, when receiving an interaction from an `Actor` whose permission to interact matches with one of the `Following` or `Followers` collections in the `always` property, the server of the interacted-with `Actor` should ensure that they *always* send out an `Accept` as soon as possible, so that the interacting `Actor` server can send out the `Activity` with the proper proof of acceptance.
|
|
||||||
|
|
||||||
This process should bypass the normal "pending approval" stage whereby the server of the `Actor` being interacted with notifies them of the pending interaction, and waits for them to accept or reject, since there is no point notifying an `Actor` of a pending approval that they have already explicitly agreed to. In the GoToSocial codebase in particular, this is called "preapproval".
|
|
||||||
|
|
||||||
### `approvedBy`
|
|
||||||
|
|
||||||
`approvedBy` is an additional property added to the `Like`, and `Announce` activities, and any `Object`s considered to be "posts" (`Note`, `Article`, etc).
|
|
||||||
|
|
||||||
The presence of `approvedBy` signals that the author of the post targeted by the `Activity` or replied-to by the `Object` has approved/accepted the interaction, and it can now be distributed to its intended audience.
|
|
||||||
|
|
||||||
The value of `approvedBy` should be the URI of the `Accept` `Activity` created by the author of the post being interacted with.
|
|
||||||
|
|
||||||
For example, the following `Announce` `Activity` indicates, by the presence of `approvedBy`, that it has been `Accept`ed by `@post_author@example.org`:
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"actor": "https://somewhere.else.example.org/users/someone",
|
|
||||||
"to": [
|
|
||||||
"https://somewhere.else.example.org/users/someone/followers"
|
|
||||||
],
|
|
||||||
"cc": [
|
|
||||||
"https://example.org/users/post_author"
|
|
||||||
],
|
|
||||||
"id": "https://somewhere.else.example.org/users/someone/activities/announce/01J0K2YXP9QCT5BE1JWQSAM3B6",
|
|
||||||
"object": "https://example.org/users/post_author/statuses/01J17ZZFK6W82K9MJ9SYQ33Y3D",
|
|
||||||
"approvedBy": "https://example.org/users/post_author/activities/accept/01J18043HGECBDZQPT09CP6F2X",
|
|
||||||
"type": "Announce"
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
When receiving an `Activity` with an `approvedBy` value attached to it, remote instances should dereference the URI value of the field to get the `Accept` `Activity`.
|
|
||||||
|
|
||||||
They should then validate that the `Accept` `Activity` has an `object` value equal to the `id` of the interaction `Activity` or `Object`, and an `actor` value equal to the author of the post being interacted with.
|
|
||||||
|
|
||||||
Moreover, they should ensure that the URL host/domain of the dereferenced `Accept` is equal to the URL host/domain of the author of the post being interacted with.
|
|
||||||
|
|
||||||
If the `Accept` cannot be dereferenced, or does not pass validity checks, the interaction should be considered invalid and dropped.
|
|
||||||
|
|
||||||
As a consequence of this validadtion mechanism, instances should make sure that they serve a valid ActivityPub Object in response to dereferences of `Accept` URIs that pertain to an `interactionPolicy`. If they do not, they inadvertently risk restricting the ability of remote instances to distribute their posts.
|
|
||||||
|
|
||||||
### Subsequent Replies / Scope Widening
|
|
||||||
|
|
||||||
Each subsequent reply in a conversation will have its own interaction policy, chosen by the user who created the reply. In other words, the entire *conversation* or *thread* is not controlled by one `interactionPolicy`, but the policy can differ for each subsequent post in a thread, as set by the post author.
|
|
||||||
|
|
||||||
Unfortunately, this means that even with `interactionPolicy` in place, the scope of a thread can inadvertently widen beyond the intention of the author of the first post in the thread.
|
|
||||||
|
|
||||||
For instance, in [example 1](#example-1---limiting-scope-of-a-conversation) above, `@the_mighty_zork` specifies in the first post a `canReply.always` value of
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"https://example.org/users/the_mighty_zork",
|
|
||||||
"https://example.org/users/booblover6969",
|
|
||||||
"https://example.org/users/hodor"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
In a subsequent reply, either accidentally or on purpose `@booblover6969` sets the `canReply.always` value to:
|
|
||||||
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
"https://www.w3.org/ns/activitystreams#Public"
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
This widens the scope of the conversation, as now anyone can reply to `@booblover6969`'s post, and possibly also tag `@the_mighty_zork` in that reply.
|
|
||||||
|
|
||||||
To avoid this issue, it is recommended that remote instances prevent users from being able to widen scope (exact mechanism of doing this TBD).
|
|
||||||
|
|
||||||
It is also a good idea for instances to consider any interaction with a post- or status-like `Object` that is itself currently pending approval, as also pending approval.
|
|
||||||
|
|
||||||
In other words, instances should mark all children interactions below a pending-approval parent as also pending approval, no matter what the interaction policy on the parent would ordinarily allow.
|
|
||||||
|
|
||||||
This avoids situations where someone could reply to a post, then, even if their reply is pending approval, they could reply *to their own reply* and have that marked as permitted (since as author, they would normally have [implicit permission to reply](#implicit-assumptions)).
|
|
||||||
|
|
||||||
## Polls
|
## Polls
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -42,10 +42,10 @@ If desired, update the GoToSocial Docker image tag to the version of GtS you wan
|
||||||
|
|
||||||
* `latest`: the default. This points to the latest stable release of GoToSocial.
|
* `latest`: the default. This points to the latest stable release of GoToSocial.
|
||||||
* `snapshot`: points to whatever code is currently on the main branch. Not guaranteed to be stable, and may often be broken. Use with caution.
|
* `snapshot`: points to whatever code is currently on the main branch. Not guaranteed to be stable, and may often be broken. Use with caution.
|
||||||
* `vX.Y.Z`: release tag. This points to a specific, stable, release of GoToSocial.
|
* `X.Y.Z`: release tag. This points to a specific, stable, release of GoToSocial.
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
Both the `latest` and `snapshot` tags are moving tags, whereas the `vX.Y.Z` tags are immutable. The result of pulling a moving tag might change from day to day. `latest` on one system might not be the same `latest` on a different system. It's recommended to use the `vX.Y.Z` tags instead so you always know exactly which version of GoToSocial you're running. The list of releases can be found [right here](https://github.com/superseriousbusiness/gotosocial/releases), with the newest release at the top.
|
Both the `latest` and `snapshot` tags are moving tags, whereas the `vX.Y.Z` tags are immutable. The result of pulling a moving tag might change from day to day. `latest` on one system might not be the same `latest` on a different system. It's recommended to use the `X.Y.Z` tags instead so you always know exactly which version of GoToSocial you're running. The list of releases can be found [right here](https://github.com/superseriousbusiness/gotosocial/releases), with the newest release at the top.
|
||||||
|
|
||||||
### Host
|
### Host
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -134,14 +134,14 @@ GoToSocial CLI 工具还提供了从实例备份和恢复数据的命令,这
|
||||||
* 备份是加密的。
|
* 备份是加密的。
|
||||||
* 内置工具可以列出快照并从中恢复。
|
* 内置工具可以列出快照并从中恢复。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
[Rsync.net](https://rsync.net/)、[BorgBase](https://www.borgbase.com/) 和 [Hetzner Storage](https://www.hetzner.com/storage/storage-box) 提供了可用于备份的经济实惠的存储。Rsync.net 有一种专门为 Borg 设计的备份产品,比他们的常规存储产品便宜得多。如果你只想使用 Borg 管理的备份,请在[此处注册](https://www.rsync.net/products/borg.html)。
|
[Rsync.net](https://rsync.net/)、[BorgBase](https://www.borgbase.com/) 和 [Hetzner Storage](https://www.hetzner.com/storage/storage-box) 提供了可用于备份的经济实惠的存储。Rsync.net 有一种专门为 Borg 设计的备份产品,比他们的常规存储产品便宜得多。如果你只想使用 Borg 管理的备份,请在[此处注册](https://www.rsync.net/products/borg.html)。
|
||||||
|
|
||||||
#### Borgmatic
|
#### Borgmatic
|
||||||
|
|
||||||
[Borgmatic](https://torsion.org/borgmatic/) 是一个帮助使用 [Borg](https://www.borgbackup.org/) 进行备份的工具。它通过使用 YAML 的声明性配置文件驱动。BorgBase、Rsync.net 和 Hetzner 都支持 Borg。
|
[Borgmatic](https://torsion.org/borgmatic/) 是一个帮助使用 [Borg](https://www.borgbackup.org/) 进行备份的工具。它通过使用 YAML 的声明性配置文件驱动。BorgBase、Rsync.net 和 Hetzner 都支持 Borg。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
初始化 Borg 仓库时,确保使用强加密密钥进行设置,并将密钥安全地存放在某处。否则将无法在将来解密备份。ArchWiki 上关于 Borgmatic 的条目解释了如何安全地将你的加密密钥传递给 Borgmatic,而不在配置文件中以明文形式存储它。
|
初始化 Borg 仓库时,确保使用强加密密钥进行设置,并将密钥安全地存放在某处。否则将无法在将来解密备份。ArchWiki 上关于 Borgmatic 的条目解释了如何安全地将你的加密密钥传递给 Borgmatic,而不在配置文件中以明文形式存储它。
|
||||||
|
|
||||||
如何使用 Borgmatic 备份数据库有其[单独的文档页面](https://torsion.org/borgmatic/docs/how-to/backup-your-databases/),你应当在备份前查看一下。对于使用 SQLite 的 GoToSocial,Borgmatic 的简单 `config.yaml` 如下:
|
如何使用 Borgmatic 备份数据库有其[单独的文档页面](https://torsion.org/borgmatic/docs/how-to/backup-your-databases/),你应当在备份前查看一下。对于使用 SQLite 的 GoToSocial,Borgmatic 的简单 `config.yaml` 如下:
|
||||||
|
|
@ -182,11 +182,11 @@ hooks:
|
||||||
|
|
||||||
您需要将该文件放在您的 GoToSocial 实例上,并确保该文件是可执行的。它需要 Python 3,安装 Borg 和 Borgmatic 后您应该已经具备。它仅依赖于 Python 标准库。
|
您需要将该文件放在您的 GoToSocial 实例上,并确保该文件是可执行的。它需要 Python 3,安装 Borg 和 Borgmatic 后您应该已经具备。它仅依赖于 Python 标准库。
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
为了确保可靠运行,您应确保 GoToSocial 配置中的 [storage-local-base-path](../configuration/storage.md) 使用的是绝对路径。否则您将需要自己调整路径。
|
为了确保可靠运行,您应确保 GoToSocial 配置中的 [storage-local-base-path](../configuration/storage.md) 使用的是绝对路径。否则您将需要自己调整路径。
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ gotosocial admin media list-attachments --local-only | \
|
$ gotosocial --config-path /path/to/config.yaml admin media list-attachments --local-only | \
|
||||||
/path/to/media-to-borg-patterns.py \
|
/path/to/media-to-borg-patterns.py \
|
||||||
<storage-local-base-path>
|
<storage-local-base-path>
|
||||||
```
|
```
|
||||||
|
|
@ -199,7 +199,7 @@ R <storage-local-base-path>
|
||||||
- <storage-local-base-path>/*
|
- <storage-local-base-path>/*
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
你可以通过向 `media-to-borg-patterns.py` 传递 `--help` 来查看帮助。通过将文件位置作为脚本的最后一个参数,也可以将输出直接写入文件。
|
你可以通过向 `media-to-borg-patterns.py` 传递 `--help` 来查看帮助。通过将文件位置作为脚本的最后一个参数,也可以将输出直接写入文件。
|
||||||
|
|
||||||
给定这组模式,Borg 将从 `<storage-local-base-path>` 开始寻找文件。任何匹配路径前缀 `pp:` 的都会被包括进去。其他的则会匹配最后一个模式,从存档中排除。
|
给定这组模式,Borg 将从 `<storage-local-base-path>` 开始寻找文件。任何匹配路径前缀 `pp:` 的都会被包括进去。其他的则会匹配最后一个模式,从存档中排除。
|
||||||
|
|
@ -211,7 +211,7 @@ R <storage-local-base-path>
|
||||||
|
|
||||||
```ini
|
```ini
|
||||||
[Service]
|
[Service]
|
||||||
ExecStartPre=/path/to/gotosocial admin media list-attachments --local-only | /path/to/media-to-borg-patterns.py <storage-local-base-path> /etc/borgmatic/gotosocial_patterns
|
ExecStartPre=/path/to/gotosocial --config-path /path/to/config.yaml admin media list-attachments --local-only | /path/to/media-to-borg-patterns.py <storage-local-base-path> /etc/borgmatic/gotosocial_patterns
|
||||||
```
|
```
|
||||||
|
|
||||||
建议查看的文档:
|
建议查看的文档:
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,13 @@ GoToSocial - 一个联邦制社交媒体服务器
|
||||||
|
|
||||||
在 `可用命令` 下,可以看到标准的 `server` 命令。但是也有处理管理和调试的命令,这些将在本文档中进行解释。
|
在 `可用命令` 下,可以看到标准的 `server` 命令。但是也有处理管理和调试的命令,这些将在本文档中进行解释。
|
||||||
|
|
||||||
!!! Info "将全局配置传递给 CLI"
|
!!! info "将全局配置传递给 CLI"
|
||||||
|
|
||||||
对于所有这些命令,你仍然需要正确设置全局选项,以便 CLI 工具知道如何连接到你的数据库,以及使用哪个数据库、哪个主机和账户域等。
|
对于所有这些命令,你仍然需要正确设置全局选项,以便 CLI 工具知道如何连接到你的数据库,以及使用哪个数据库、哪个主机和账户域等。
|
||||||
|
|
||||||
你可以使用环境变量设置这些选项,通过 CLI 标志传递它们(例如,`gotosocial [commands] --host example.org`),或者只需将 CLI 工具指向你的配置文件(例如,`gotosocial --config-path ./config.yaml [commands]`)。
|
你可以使用环境变量设置这些选项,通过 CLI 标志传递它们(例如,`gotosocial [commands] --host example.org`),或者只需将 CLI 工具指向你的配置文件(例如,`gotosocial --config-path ./config.yaml [commands]`)。
|
||||||
|
|
||||||
!!! Info
|
!!! info "附注"
|
||||||
|
|
||||||
运行 CLI 命令时,你将会看到如下输出:
|
运行 CLI 命令时,你将会看到如下输出:
|
||||||
|
|
||||||
|
|
@ -45,7 +45,7 @@ GoToSocial - 一个联邦制社交媒体服务器
|
||||||
|
|
||||||
这是正常的,表示命令已按预期运行。
|
这是正常的,表示命令已按预期运行。
|
||||||
|
|
||||||
!!! Warning "运行管理命令后重启 GtS"
|
!!! warning "运行管理命令后重启 GtS"
|
||||||
|
|
||||||
由于 GoToSocial 的内部缓存机制,你可能需要在运行某些命令后重启 GoToSocial,以使命令的效果“生效”。我们仍在寻找一种无需重启的方法。在此期间,需要在运行命令后重启的命令将在下文中突出显示。
|
由于 GoToSocial 的内部缓存机制,你可能需要在运行某些命令后重启 GoToSocial,以使命令的效果“生效”。我们仍在寻找一种无需重启的方法。在此期间,需要在运行命令后重启的命令将在下文中突出显示。
|
||||||
|
|
||||||
|
|
@ -86,7 +86,7 @@ gotosocial admin account create \
|
||||||
|
|
||||||
此命令可用于确认你的实例上的用户+账户,允许他们登录并使用账户。
|
此命令可用于确认你的实例上的用户+账户,允许他们登录并使用账户。
|
||||||
|
|
||||||
!!! Info
|
!!! info "附注"
|
||||||
|
|
||||||
如果账户是使用 `admin account create` 创建的,则不必在账户上运行 `confirm`,它将已被确认。
|
如果账户是使用 `admin account create` 创建的,则不必在账户上运行 `confirm`,它将已被确认。
|
||||||
|
|
||||||
|
|
@ -113,7 +113,7 @@ gotosocial admin account confirm --username some_username --config-path config.y
|
||||||
|
|
||||||
此命令可用于将用户提升为管理员。
|
此命令可用于将用户提升为管理员。
|
||||||
|
|
||||||
!!! Warning "需要重启服务器"
|
!!! warning "需要重启服务器"
|
||||||
|
|
||||||
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
||||||
|
|
||||||
|
|
@ -140,7 +140,7 @@ gotosocial admin account promote --username some_username --config-path config.y
|
||||||
|
|
||||||
此命令可用于将用户从管理员降级为普通用户。
|
此命令可用于将用户从管理员降级为普通用户。
|
||||||
|
|
||||||
!!! Warning "需要重启服务器"
|
!!! warning "需要重启服务器"
|
||||||
|
|
||||||
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
||||||
|
|
||||||
|
|
@ -167,7 +167,7 @@ gotosocial admin account demote --username some_username --config-path config.ya
|
||||||
|
|
||||||
此命令可用于在你的实例上禁用一个账户:禁止其登录或执行任何操作,但不删除数据。
|
此命令可用于在你的实例上禁用一个账户:禁止其登录或执行任何操作,但不删除数据。
|
||||||
|
|
||||||
!!! Warning "需要重启服务器"
|
!!! warning "需要重启服务器"
|
||||||
|
|
||||||
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ gotosocial admin account disable --username some_username --config-path config.y
|
||||||
|
|
||||||
此命令可用于重新启用你实例上的账户,撤销之前的 `disable` 命令。
|
此命令可用于重新启用你实例上的账户,撤销之前的 `disable` 命令。
|
||||||
|
|
||||||
!!! Warning "需要重启服务器"
|
!!! warning "需要重启服务器"
|
||||||
|
|
||||||
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
||||||
|
|
||||||
|
|
@ -221,7 +221,7 @@ gotosocial admin account enable --username some_username --config-path config.ya
|
||||||
|
|
||||||
此命令可用于为指定的本站账户设置新密码。
|
此命令可用于为指定的本站账户设置新密码。
|
||||||
|
|
||||||
!!! Warning "需要重启服务器"
|
!!! warning "需要重启服务器"
|
||||||
|
|
||||||
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@
|
||||||
|
|
||||||
无论你选择使用 SQLite 还是 Postgres 来运行 GoToSocial,可能都需要偶尔执行一些维护工作,以保持数据库的良好运作。
|
无论你选择使用 SQLite 还是 Postgres 来运行 GoToSocial,可能都需要偶尔执行一些维护工作,以保持数据库的良好运作。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
|
|
||||||
尽管此处提供的维护建议旨在不破坏现有数据,你还是应该在手动执行维护操作之前备份数据库。这样,如果输入错误或意外运行了不当命令,可以恢复备份并重试。
|
尽管此处提供的维护建议旨在不破坏现有数据,你还是应该在手动执行维护操作之前备份数据库。这样,如果输入错误或意外运行了不当命令,可以恢复备份并重试。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
|
|
||||||
**强烈不建议**手动创建、删除或更新 GoToSocial 数据库中的条目,这里不会提供相关命令。即使你认为自己知道在做什么,运行 `DELETE` 等语句可能会引入非常难以排查的问题。以下维护建议旨在帮助你的实例平稳运行;如果你手动进入数据库并对条目、表和索引进行修改,它们不会拯救你的数据。
|
**强烈不建议**手动创建、删除或更新 GoToSocial 数据库中的条目,这里不会提供相关命令。即使你认为自己知道在做什么,运行 `DELETE` 等语句可能会引入非常难以排查的问题。以下维护建议旨在帮助你的实例平稳运行;如果你手动进入数据库并对条目、表和索引进行修改,它们不会拯救你的数据。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
GoToSocial 支持屏蔽/封禁那些你不想与你的实例联合的域名。在我们的文档中,“屏蔽”和“封禁”这两个术语在涉及域名时可以互换使用,因为它们的意思相同:屏蔽你的实例与目标域名上的实例相互通信,有效地切断两个实例之间的联合。
|
GoToSocial 支持屏蔽/封禁那些你不想与你的实例联合的域名。在我们的文档中,“屏蔽”和“封禁”这两个术语在涉及域名时可以互换使用,因为它们的意思相同:屏蔽你的实例与目标域名上的实例相互通信,有效地切断两个实例之间的联合。
|
||||||
|
|
||||||
你可以使用[实例管理面板](./settings.md#联合)查看、创建和移除域名屏蔽和域名允许。
|
你可以使用[实例管理面板](./settings.md#域名权限)查看、创建和移除域名屏蔽和域名允许。
|
||||||
|
|
||||||
本文档重点说明域名屏蔽实际*作用*是什么,以及创建新域名屏蔽时会产生哪些副作用。
|
本文档重点说明域名屏蔽实际*作用*是什么,以及创建新域名屏蔽时会产生哪些副作用。
|
||||||
|
|
||||||
|
|
@ -54,7 +54,7 @@ GoToSocial 支持屏蔽/封禁那些你不想与你的实例联合的域名。
|
||||||
3. 删除封禁帐户的所有贴文。
|
3. 删除封禁帐户的所有贴文。
|
||||||
4. 删除封禁帐户及其贴文的所有媒体,包括媒体附件、头像、头图和表情符号。
|
4. 删除封禁帐户及其贴文的所有媒体,包括媒体附件、头像、头图和表情符号。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
目前,上述大多数副作用是**不可逆**的。如果你在屏蔽后取消屏蔽一个域名,该域名上的所有帐户将不再被标记为已封禁,并且你将能够再次与他们互动,但所有关系仍将被清除,所有贴文和媒体将被删除。
|
目前,上述大多数副作用是**不可逆**的。如果你在屏蔽后取消屏蔽一个域名,该域名上的所有帐户将不再被标记为已封禁,并且你将能够再次与他们互动,但所有关系仍将被清除,所有贴文和媒体将被删除。
|
||||||
|
|
||||||
在屏蔽一个域名之前请仔细考虑。
|
在屏蔽一个域名之前请仔细考虑。
|
||||||
|
|
|
||||||
145
docs/locales/zh/admin/domain_permission_subscriptions.md
Normal file
145
docs/locales/zh/admin/domain_permission_subscriptions.md
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
# 域名权限订阅
|
||||||
|
|
||||||
|
你可以通过[管理设置面板](./settings.md#订阅)创建和管理域名权限订阅。
|
||||||
|
|
||||||
|
域名权限订阅允许你指定一个域名权限列表托管的URL。默认情况下,每24小时在当前时区晚上11点进行自动更新,你的实例将获取并解析你订阅的每个列表,基于在列表中发现的条目,按照优先级(从高到低)顺序创建域(或域名权限草稿)。
|
||||||
|
|
||||||
|
每个域名权限订阅可以用来创建域名允许或域名阻止条目。
|
||||||
|
|
||||||
|
!!! warning "警告"
|
||||||
|
目前,通过阻止列表订阅只能创建“屏蔽”级别的域名阻止条目;其他严重程度尚不支持。订阅阻止列表中严重程度为“隐藏”或“限制”等的条目将被跳过。
|
||||||
|
|
||||||
|
## 优先级
|
||||||
|
|
||||||
|
当存在多个域名权限订阅时,它们将按照优先级顺序(从最高优先级(255)到最低优先级(0))被获取和解析。
|
||||||
|
|
||||||
|
在优先级较高的列表上发现的权限条目将覆盖优先级较低的列表上的权限条目。
|
||||||
|
|
||||||
|
例如,一名实例管理员订阅了两个允许列表,“重要列表”优先级为255,“不太重要的列表”优先级为128。每个订阅列表都包含了`good-eggs.example.org`的条目。
|
||||||
|
|
||||||
|
那么优先级较高的订阅会负责创建和管理`good-eggs.example.org`的域名允许条目。
|
||||||
|
|
||||||
|
如果移除了优先级较高的订阅,那么下次获取所有订阅时,“不太重要的列表”将创建(或接管)该域名允许条目。
|
||||||
|
|
||||||
|
## 孤立权限
|
||||||
|
|
||||||
|
目前没有被域名权限订阅管理的域名权限条目(阻止条目和允许条目)被认为是“孤立”权限。这包括管理员手动在设置面板中创建的权限,或者是通过导入/导出页面手动导入的权限。
|
||||||
|
|
||||||
|
如果你愿意,在创建域名权限订阅时,可以将该订阅的[“接管孤立权限条目”](./settings.md#接管孤立权限条目)设置为 true。如果一个启用了“接管孤立权限条目”的域名权限订阅遇到一个孤立权限,并且该条目 *也在该订阅地址指向的列表中*,那么它将把该孤立条目的订阅ID设置为其自身ID,来“接收”此孤立条目。
|
||||||
|
|
||||||
|
例如,一个实例管理员手动为域名`horrid-trolls.example.org`创建了域名阻止条目。稍后,他们创建了一个域名阻止列表订阅,并将“收养孤儿”设置为真,且该订阅包含`horrid-trolls.example.org`。当实例获取并解析列表,并从中创建域名权限条目时,`horrid-trolls.example.org`这个孤立的域名阻止条目将被刚刚配置的域名权限订阅接收。现在,如果域名权限订阅被移除,且在移除时勾选了移除订阅所拥有的所有权限选项,那么`horrid-trolls.example.org`这个域名阻止条目也将被移除。
|
||||||
|
|
||||||
|
## 域名权限订阅的几种有趣的应用场景
|
||||||
|
|
||||||
|
### 1. 创建白名单联合实例集群
|
||||||
|
|
||||||
|
域名权限订阅使得创建白名单联合实例集群集群变得更加容易,也就是说,一组实例理论上可以形成自己的迷你联邦宇宙,每个实例在[白名单联合模式](./federation_modes.md#白名单联合模式)下运行,并订阅同一个合作管理的、托管在某处的允许列表。
|
||||||
|
|
||||||
|
例如,实例 `instance-a.example.org`、`instance-b.example.org` 和 `instance-c.example.org` 决定他们只想彼此联合。
|
||||||
|
|
||||||
|
他们可以使用像 GitHub 这样的版本管理平台托管一个纯文本格式的允许列表,比如在 `https://raw.githubusercontent.com/our-cluster/allowlist/refs/heads/main/allows.txt`。
|
||||||
|
|
||||||
|
纯文本格式的允许列表内容如下:
|
||||||
|
|
||||||
|
```text
|
||||||
|
instance-a.example.org
|
||||||
|
instance-b.example.org
|
||||||
|
instance-c.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
每个实例管理员都将他们的联合模式设置为`白名单`,并创建一个类型为“允许”,订阅地址为 `https://raw.githubusercontent.com/our-cluster/allowlist/refs/heads/main/allows.txt` 的订阅,这会为他们自己的域名以及集群中的其他域名创建域名允许条目。
|
||||||
|
|
||||||
|
在某个时候,来自 `instance-d.example.org` 的某人(在站外)申请被添加到集群中。现有的管理员同意,并更新他们的纯文本格式允许列表为:
|
||||||
|
|
||||||
|
```text
|
||||||
|
instance-a.example.org
|
||||||
|
instance-b.example.org
|
||||||
|
instance-c.example.org
|
||||||
|
instance-d.example.org
|
||||||
|
```
|
||||||
|
|
||||||
|
下次每个实例获取列表时,将为 `instance-d.example.org` 创建一个新的域名允许条目,它将能够与该列表中的其他域进行联合。
|
||||||
|
|
||||||
|
### 2. 合作管理阻止列表
|
||||||
|
|
||||||
|
域名权限订阅使得合作管理和订阅共享的、包含非法/极右/其他不良账户和内容的域名的阻止列表变得容易。
|
||||||
|
|
||||||
|
例如,实例 `instance-e.example.org`、`instance-f.example.org` 和 `instance-g.example.org` 的管理员认定:他们厌倦了通过与坏人玩打地鼠游戏来重复工作。为了让生活更轻松,他们决定合作开发一个共享的阻止列表。
|
||||||
|
|
||||||
|
他们使用像 GitHub 这样的版本管理平台在类似 `https://raw.githubusercontent.com/baddies/blocklist/refs/heads/main/blocks.csv` 的地方托管一个阻止列表。
|
||||||
|
|
||||||
|
当有人发现另一个他们不喜欢的实例时,他们可以通过合并请求或类似方法添加这个有问题的实例到域名列表中。
|
||||||
|
|
||||||
|
例如,有人从一个新实例 `fashy-arseholes.example.org` 收到一个不愉快的回复。他们使用他们的协作工具,建议将 `fashy-arseholes.example.org` 添加到阻止列表。经过一些审议和讨论后,该域被添加到列表中。
|
||||||
|
|
||||||
|
下次 `instance-e.example.org`、`instance-f.example.org` 和 `instance-g.example.org` 获取阻止列表时,将为 `fashy-arseholes.example.org` 创建一个阻止条目。
|
||||||
|
|
||||||
|
### 3. 订阅阻止列表,但忽略其中的一部分
|
||||||
|
|
||||||
|
假设上一节中的 `instance-g.example.org` 认定他们同意大部分协作策划的阻止列表,但出于某种原因,他们实际上希望继续与 `fashy-arseholes.example.org` 联合。
|
||||||
|
|
||||||
|
这可以通过以下三种方法实现:
|
||||||
|
|
||||||
|
1. `instance-g.example.org` 的管理员订阅共享阻止列表,但他们将其["创建为草稿"](./settings.md#将此条目设为草稿)选项设置为 true。当他们的实例获取阻止列表时,会为 `fashy-arseholes.example.org` 创建一个阻止条目草稿。`instance-g` 的管理员只需将权限保留为草稿或拒绝它,因此它永远不会生效。
|
||||||
|
2. 在重新获取阻止列表之前,`instance-g.example.org` 的管理员为 `instance-g.example.org` 创建一个[域名权限例外](./settings.md#例外)条目。设置保存后,域名权限订阅将无法`instance-g.example.org` 域名创建权限,因此在列表下次被获取时,共享阻止列表上对于 `instance-g.example.org` 的阻止不会在 `instance-g.example.org` 的实例数据库中创建。
|
||||||
|
3. `instance-g.example.org` 的管理员在其实例上为 `fashy-arseholes.example.org` 创建一个显式的域名允许条目。`instance-g` 实例在`黑名单`联合模式下运行,因此[显式允许条目将覆盖域名阻止条目](./federation_modes.md#黑名单模式)。`fashy-arseholes` 域名将保持未被阻止的状态。
|
||||||
|
|
||||||
|
### 4. 直接订阅另一个实例的阻止列表
|
||||||
|
|
||||||
|
GoToSocial 能够获取和解析 JSON 格式的域名权限列表,所以可以通过他们的 `/api/v1/instance/domain_blocks` (Mastodon) 或 `/api/v1/instance/peers?filter=suspended` (GoToSocial)端点(如果已公开)直接订阅另一个实例的屏蔽列表。
|
||||||
|
|
||||||
|
例如,Mastodon 实例 `peepee.poopoo.example.org` 公开他们的阻止列表,而GoToSocial实例的所有者 `instance-h.example.org` 认定他们非常喜欢该 Mastodon 管理员的标准。他们创建一个JSON类型的域名权限订阅,并将地址设为 `https://peepee.poopoo.example.org/api/v1/instance/domain_blocks`。他们的实例将每24小时获取一次对方 Mastodon 实例的阻止列表JSON,并根据其中发现的条目创建权限。
|
||||||
|
|
||||||
|
## 域名权限订阅列表的格式示例
|
||||||
|
|
||||||
|
以下是 GoToSocial 能够解析的不同权限列表格式的示例。
|
||||||
|
|
||||||
|
每个列表包含三个域,`bumfaces.net`、`peepee.poopoo` 和 `nothanks.com`。
|
||||||
|
|
||||||
|
### CSV
|
||||||
|
|
||||||
|
CSV列表使用内容类型 `text/csv`。
|
||||||
|
|
||||||
|
Mastodon域名权限通常使用这种格式导出。
|
||||||
|
|
||||||
|
```csv
|
||||||
|
#domain,#severity,#reject_media,#reject_reports,#public_comment,#obfuscate
|
||||||
|
bumfaces.net,suspend,false,false,这个实例上有坏蛋,false
|
||||||
|
peepee.poopoo,suspend,false,false,骚扰,false
|
||||||
|
nothanks.com,suspend,false,false,,false
|
||||||
|
```
|
||||||
|
|
||||||
|
### JSON (application/json)
|
||||||
|
|
||||||
|
JSON列表使用内容类型 `application/json`。
|
||||||
|
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"domain": "bumfaces.net",
|
||||||
|
"suspended_at": "2020-05-13T13:29:12.000Z",
|
||||||
|
"public_comment": "这个实例上有坏蛋"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "peepee.poopoo",
|
||||||
|
"suspended_at": "2020-05-13T13:29:12.000Z",
|
||||||
|
"public_comment": "骚扰"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"domain": "nothanks.com",
|
||||||
|
"suspended_at": "2020-05-13T13:29:12.000Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 纯文本 (text/plain)
|
||||||
|
|
||||||
|
纯文本列表使用内容类型 `text/plain`。
|
||||||
|
|
||||||
|
注意在纯文本列表中无法包含像“obfuscate”或“public comment”这样的字段,因为它们只是一个以换行符分隔的域名列表。
|
||||||
|
|
||||||
|
```text
|
||||||
|
bumfaces.net
|
||||||
|
peepee.poopoo
|
||||||
|
nothanks.com
|
||||||
|
```
|
||||||
|
|
@ -10,12 +10,12 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
|
||||||
|
|
||||||
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,如果该资源的域未通过域屏蔽条目被屏蔽,它将会去获取该资源。
|
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,如果该资源的域未通过域屏蔽条目被屏蔽,它将会去获取该资源。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
黑名单联合模式是 GoToSocial 的默认联合模式。它也是大多数其他 ActivityPub 服务器实现的默认联合模式。
|
黑名单联合模式是 GoToSocial 的默认联合模式。它也是大多数其他 ActivityPub 服务器实现的默认联合模式。
|
||||||
|
|
||||||
## 白名单联合模式
|
## 白名单联合模式
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
白名单联合模式仍然被认为是“实验性”的,我们正在研究其在实际中的表现。它应该如其名称所示,但可能会在其他地方导致错误或出现边缘情况,我们还不确定!
|
白名单联合模式仍然被认为是“实验性”的,我们正在研究其在实际中的表现。它应该如其名称所示,但可能会在其他地方导致错误或出现边缘情况,我们还不确定!
|
||||||
|
|
||||||
当 `instance-federation-mode` 设置为 `allowlist` 时,你的实例将仅与通过设置面板明确设为允许的实例联合,并限制任何未被允许的实例的访问。
|
当 `instance-federation-mode` 设置为 `allowlist` 时,你的实例将仅与通过设置面板明确设为允许的实例联合,并限制任何未被允许的实例的访问。
|
||||||
|
|
@ -24,7 +24,7 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
|
||||||
|
|
||||||
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,它只会在资源所属域名被明确允许时才去获取资源。
|
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,它只会在资源所属域名被明确允许时才去获取资源。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
白名单联合模式在你希望仅与选择的“可信”实例联合的情况下非常有用。然而,这会影响发现过程。在黑名单联合模式下,你会通过转发和回复自然地遇到未知实例的贴文和账户,但在白名单联合模式下,这样的偶然发现不会发生。
|
白名单联合模式在你希望仅与选择的“可信”实例联合的情况下非常有用。然而,这会影响发现过程。在黑名单联合模式下,你会通过转发和回复自然地遇到未知实例的贴文和账户,但在白名单联合模式下,这样的偶然发现不会发生。
|
||||||
|
|
||||||
因此,建议你要么先从黑名单联合模式开始,然后在确定喜欢哪些其他实例后切换到白名单联合模式,要么从白名单联合模式开始,并在首次启动实例后准备好并导入白名单,以便“启动”它。
|
因此,建议你要么先从黑名单联合模式开始,然后在确定喜欢哪些其他实例后切换到白名单联合模式,要么从白名单联合模式开始,并在首次启动实例后准备好并导入白名单,以便“启动”它。
|
||||||
|
|
@ -54,7 +54,7 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
|
||||||
|
|
||||||
如果上述任何条件不满足,请求将被拒绝。
|
如果上述任何条件不满足,请求将被拒绝。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
结合屏蔽和允许是一项棘手的工作!
|
结合屏蔽和允许是一项棘手的工作!
|
||||||
|
|
||||||
在导入允许和黑名单时,你应该始终手动审核列表,以确保不会无意中屏蔽你不想屏蔽的实例,因为这可能会有**非常烦人的副作用**,例如移除关注/被关注、贴文等。
|
在导入允许和黑名单时,你应该始终手动审核列表,以确保不会无意中屏蔽你不想屏蔽的实例,因为这可能会有**非常烦人的副作用**,例如移除关注/被关注、贴文等。
|
||||||
|
|
|
||||||
|
|
@ -47,11 +47,11 @@ GoToSocial 提供了三个变量,让你(管理员)可以调节何时以及
|
||||||
|
|
||||||
上述设置意味着从午夜开始每8小时,GoToSocial 将清除任何缓存超过1天(24小时)的媒体。清理任务将在 00:00、08:00 和 16:00,即午夜、上午8点和下午4点运行。使用此配置,你可能将外站媒体在存储中保留的最长时间约为32小时。
|
上述设置意味着从午夜开始每8小时,GoToSocial 将清除任何缓存超过1天(24小时)的媒体。清理任务将在 00:00、08:00 和 16:00,即午夜、上午8点和下午4点运行。使用此配置,你可能将外站媒体在存储中保留的最长时间约为32小时。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
将 `media-remote-cache-days` 设置为0或更小意味着外站媒体将永不被清除。然而,本站孤立媒体的清理任务和其他一致性检查仍将按其他变量定义的计划运行。
|
将 `media-remote-cache-days` 设置为0或更小意味着外站媒体将永不被清除。然而,本站孤立媒体的清理任务和其他一致性检查仍将按其他变量定义的计划运行。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
如果你愿意,你也可以通过管理面板手动执行一次性清理操作([查看文档](./settings.md#媒体))。
|
如果你愿意,你也可以通过管理面板手动执行一次性清理操作([查看文档](./settings.md#媒体))。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
将 `media-cleanup-every` 设置为非常小的值,如 `"30m"` 或更小,可能会导致你的实例不断遍历附件,导致数据使用率高而效益甚微。我们不建议将该值设置为小于约 `"8h"`,即便如此,可能也显得过度。
|
将 `media-cleanup-every` 设置为非常小的值,如 `"30m"` 或更小,可能会导致你的实例不断遍历附件,导致数据使用率高而效益甚微。我们不建议将该值设置为小于约 `"8h"`,即便如此,可能也显得过度。
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
GoToSocial 当前提供“屏蔽”、“允许”和禁用的 HTTP 请求头过滤模式,可以通过在 config.yaml 中设置 `advanced-header-filter-mode`,或使用环境变量 `GTS_ADVANCED_HEADER_FILTER_MODE` 来配置。这些模式的具体说明如下。
|
GoToSocial 当前提供“屏蔽”、“允许”和禁用的 HTTP 请求头过滤模式,可以通过在 config.yaml 中设置 `advanced-header-filter-mode`,或使用环境变量 `GTS_ADVANCED_HEADER_FILTER_MODE` 来配置。这些模式的具体说明如下。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
HTTP 请求头过滤是一个进阶设置。如果你不熟悉 HTTP 请求头的使用和复杂性,修改这些设置可能会导致联合功能中断,甚至无法访问你自己的实例。
|
HTTP 请求头过滤是一个进阶设置。如果你不熟悉 HTTP 请求头的使用和复杂性,修改这些设置可能会导致联合功能中断,甚至无法访问你自己的实例。
|
||||||
|
|
||||||
HTTP 请求头过滤仍被视为“实验性”功能。它应该能如预期工作,但可能会导致其他地方出现错误或边缘情况,这点我们尚不确定!
|
HTTP 请求头过滤仍被视为“实验性”功能。它应该能如预期工作,但可能会导致其他地方出现错误或边缘情况,这点我们尚不确定!
|
||||||
|
|
@ -27,5 +27,5 @@ GoToSocial 当前提供“屏蔽”、“允许”和禁用的 HTTP 请求头过
|
||||||
|
|
||||||
在允许模式下,请求只有在被明确允许且未被明确屏蔽的情况下才会被接受。
|
在允许模式下,请求只有在被明确允许且未被明确屏蔽的情况下才会被接受。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
允许过滤模式是一个极为严格的模式,几乎肯定会阻止许多(合法的)客户端访问你的实例,包括你自己。只有在完全明确你的目标时才应启用此模式。
|
允许过滤模式是一个极为严格的模式,几乎肯定会阻止许多(合法的)客户端访问你的实例,包括你自己。只有在完全明确你的目标时才应启用此模式。
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@
|
||||||
|
|
||||||
GoToSocial 在主域名上提供一个 `robots.txt` 文件。该文件包含试图屏蔽已知 AI 爬虫的一些规则,以及其他一些索引器。它还包括一些规则,以确保诸如 API 端点之类的内容不会被搜索引擎索引,因为这些内容没有被索引的必要。
|
GoToSocial 在主域名上提供一个 `robots.txt` 文件。该文件包含试图屏蔽已知 AI 爬虫的一些规则,以及其他一些索引器。它还包括一些规则,以确保诸如 API 端点之类的内容不会被搜索引擎索引,因为这些内容没有被索引的必要。
|
||||||
|
|
||||||
|
## 允许/禁止统计数据收集
|
||||||
|
|
||||||
|
你可以通过修改配置 `instance-stats-mode` 来允许或禁止爬虫从 `/nodeinfo/2.0` 和 `/nodeinfo/2.1` 端点收集你的实例的统计数据,此设置会修改 `robots.txt` 文件。更多详情请参见 [实例配置](../configuration/instance.md)。
|
||||||
|
|
||||||
## AI 爬虫
|
## AI 爬虫
|
||||||
|
|
||||||
AI 爬虫来自一个[社区维护的仓库][airobots]。目前是手动保持同步的。如果你知道有任何遗漏的爬虫,请给他们提交一个 PR!
|
AI 爬虫来自一个[社区维护的仓库][airobots]。目前是手动保持同步的。如果你知道有任何遗漏的爬虫,请给他们提交一个 PR!
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,11 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
|
||||||
|
|
||||||
你可以使用此部分搜索账户并对其执行管理操作。
|
你可以使用此部分搜索账户并对其执行管理操作。
|
||||||
|
|
||||||
### 联合
|
### 域名权限
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
在联合部分,你可以创建、删除和审核明确的域名屏蔽和域名允许。
|
在域名权限部分,你可以创建、删除和查看域名阻止条目、域名允许条目、草稿、排除项和订阅。
|
||||||
|
|
||||||
关于联合设置的更多详细信息,特别是域名允许和域名屏蔽如何结合使用,请参阅 [联合模式部分](./federation_modes.md) 和 [域名屏蔽部分](./domain_blocks.md)。
|
关于联合设置的更多详细信息,特别是域名允许和域名屏蔽如何结合使用,请参阅 [联合模式部分](./federation_modes.md) 和 [域名屏蔽部分](./domain_blocks.md)。
|
||||||
|
|
||||||
|
|
@ -46,20 +46,99 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
|
||||||
|
|
||||||
你可以在搜索字段中输入一个要封禁的域名,这将过滤列表以显示你是否已有该域名的屏蔽条目。
|
你可以在搜索字段中输入一个要封禁的域名,这将过滤列表以显示你是否已有该域名的屏蔽条目。
|
||||||
|
|
||||||
点击“封禁”会显示一个表单,允许你添加公开和/或私人评论,并提交以添加屏蔽。添加封禁后,该实例上的所有已知账户将被封禁,并阻止与该被屏蔽实例上的任何用户的新互动。
|
点击“封禁”会显示一个表单,允许你添加公开和/或私人评论,并提交以添加屏蔽。
|
||||||
|
|
||||||
|
添加封禁后,该实例上的所有已知账户将被封禁,并阻止与该被屏蔽实例上的任何用户的新互动。
|
||||||
|
|
||||||
#### 域名允许
|
#### 域名允许
|
||||||
|
|
||||||
域名允许部分的工作方式与域名屏蔽部分类似,只是用于明确的域名允许而不是域名屏蔽。
|
域名允许部分的工作方式与域名屏蔽部分类似,只是用于明确的域名允许而不是域名屏蔽。
|
||||||
|
|
||||||
#### 批量导入/导出
|
#### 导入/导出
|
||||||
|
|
||||||
通过联合部分底部的链接(或访问 `/settings/admin/federation/import-export`),你可以批量导入/导出屏蔽列表和允许列表。
|
你可以在这一部分批量导入/导出JSON、CSV或纯文本格式的域名权限条目。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
通过输入字段或文件导入列表后,你可以在导入子集之前查看列表中的条目。你还会在使用子域的条目中收到警告,此处还提供一种轻松将其更改为主域的方法。
|
通过输入字段或文件导入列表后,你可以在导入子集之前查看列表中的条目。你还会在使用子域的条目中收到警告,此处还提供一种轻松将其更改为主域的方法。
|
||||||
|
|
||||||
|
#### 草稿
|
||||||
|
|
||||||
|
在这一部分,你可以创建、搜索、接受和拒绝域名权限草稿。
|
||||||
|
|
||||||
|
域名权限草稿是已被提议,但尚未生效的域域名权限条目(可以手动创建或从已订阅的阻止/允许列表中添加)。
|
||||||
|
|
||||||
|
在接受前,域名权限草稿将对目标域名的联合没有任何影响。一旦被接受,它将被转换为域名阻止条目或域名允许条目,并开始执行。
|
||||||
|
|
||||||
|
#### 例外
|
||||||
|
|
||||||
|
在这一部分,您可以创建、搜索和移除域名权限例外条目。
|
||||||
|
|
||||||
|
域名权限例外可以防止某域名(及其所有子域)的权限被域名权限订阅自动管理。
|
||||||
|
|
||||||
|
例如,如果你为域名 `example.org` 创建例外条目,那么在创建域名权限草稿和域名阻止/允许条目时,阻止列表或允许列表订阅将排除 `example.org` 及其任何子域(如 `sub.example.org`,`another.sub.example.org` 等)的条目。
|
||||||
|
|
||||||
|
此功能可以让你在明确知道是否要与某个域名进行联合的情况下,手动管理被设为例外的域名的权限,不受域名权限订阅中包含的条目的影响。
|
||||||
|
|
||||||
|
请注意,仅针对某个域名创建排除条目本身并不会对与该域名的联合产生影响,它只有与权限订阅结合使用时才会发挥作用。
|
||||||
|
|
||||||
|
#### 订阅
|
||||||
|
|
||||||
|
在这一部分,你可以创建、搜索、编辑、测试和移除域名权限订阅。
|
||||||
|
|
||||||
|
域名权限订阅允许您指定权限列表的托管地址。默认情况下,每天晚上11点,你的实例将获取并解析订阅的每个列表,并根据列表中的条目创建域名权限(或域名权限草稿)。
|
||||||
|
|
||||||
|
##### 标题
|
||||||
|
|
||||||
|
您可以选择使用标题字段为订阅设置标题,以便对自己和其他管理员进行提醒。
|
||||||
|
|
||||||
|
例如,您可能会订阅 `https://lists.example.org/baddies.csv` 上的列表,并将该订阅的标题设置为某些反映该列表内容的描述,如“基础阻止列表(最为恶劣的实例)”或类似描述。
|
||||||
|
|
||||||
|
##### 订阅优先级
|
||||||
|
|
||||||
|
当你指定了多个域名权限订阅时,它们将按优先级顺序从最高优先级 (255) 到最低优先级 (0) 被获取和解析。
|
||||||
|
|
||||||
|
在优先级排名靠前的列表中发现的权限将覆盖在优先级排名靠后的列表中的权限。
|
||||||
|
|
||||||
|
有关优先级的更多信息,参见单独的[域名权限订阅](./domain_permission_subscriptions.md)文档。
|
||||||
|
|
||||||
|
##### 权限类型
|
||||||
|
|
||||||
|
你可以使用此下拉菜单选择为在订阅地址中发现的权限创建的条目类型,可以为阻止或允许。
|
||||||
|
|
||||||
|
##### 内容类型
|
||||||
|
|
||||||
|
您可以使用此下拉菜单选择订阅地址指向的列表的内容类型。
|
||||||
|
|
||||||
|
要订阅与 Mastodon 格式兼容的权限列表,可以选择 CSV,要使用纯文本域名列表,可以选择 plain,也可以选择 JSON,用于订阅以 JSON 格式导出的列表。
|
||||||
|
|
||||||
|
##### 基础认证(Basic Auth)
|
||||||
|
|
||||||
|
勾选此复选框,可以为订阅列表提供基础认证用户名和/或密码凭证,这些凭证将在每次向订阅地址请求列表时一并发送。
|
||||||
|
|
||||||
|
##### 接管孤立权限条目
|
||||||
|
|
||||||
|
如果勾选此框,那么在以下情况下,任何现有的域名权限将由该订阅管理:
|
||||||
|
|
||||||
|
1. 该权限条目没有关联的订阅 ID(即,它们不受任何域权限订阅管理)。
|
||||||
|
2. 该权限条目与此订阅地址中包含的域名权限匹配。
|
||||||
|
|
||||||
|
有关孤立权限的更多信息,参见单独的[域名权限订阅](./domain_permission_subscriptions.md)文档。
|
||||||
|
|
||||||
|
##### 将此条目设为草稿
|
||||||
|
|
||||||
|
勾选此复选框后(该复选框默认勾选),通过此订阅创建的任何权限条目将以**草稿**类型创建,需要手动批准才能生效。
|
||||||
|
|
||||||
|
建议保留此复选框为已勾选状态,除非您完全信任订阅列表,以避免无意中阻止或允许您不想阻止或允许的域。
|
||||||
|
|
||||||
|
##### 测试订阅
|
||||||
|
|
||||||
|
要测试订阅是否可以被成功解析,首先创建订阅,然后在该订阅的详情视图中,点击“测试”按钮。
|
||||||
|
|
||||||
|
如果您的实例能够获取并解析订阅地址处的权限列表,则在点击“测试”后您将看到这些权限的列表。否则,您将看到一条错误信息。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 管理
|
## 管理
|
||||||
|
|
||||||
实例管理设置。
|
实例管理设置。
|
||||||
|
|
@ -167,3 +246,11 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
|
||||||
选择的 **联系人用户** 必须是实例上的活跃(未封禁)的管理员和/或站务。
|
选择的 **联系人用户** 必须是实例上的活跃(未封禁)的管理员和/或站务。
|
||||||
|
|
||||||
如果你是在单用户实例上并将管理员权限授予你的主账户,你只需在此处填写自己的用户名即可;无需为此专门创建管理账户。
|
如果你是在单用户实例上并将管理员权限授予你的主账户,你只需在此处填写自己的用户名即可;无需为此专门创建管理账户。
|
||||||
|
|
||||||
|
### 实例自定义 CSS
|
||||||
|
|
||||||
|
自定义 CSS 允许您进一步调整通过浏览器访问的实例时的外观。
|
||||||
|
|
||||||
|
这些自定义 CSS 将应用于实例的所有页面。但用户主题和 CSS 仍优先于此处的自定义设置。
|
||||||
|
|
||||||
|
有关为您的实例编写自定义 CSS 的一些技巧,请参阅[自定义 CSS](../user_guide/custom_css.md)页面。
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
注意,作为实例管理员,无论你是否愿意,你都需对在你的实例上发布的内容负责。如果你的实例用户在联合网上骚扰或烦扰他人,可能会导致你的实例名誉受损,并被其他人屏蔽。妥善管理一个社区需要付出努力。因此,你应仔细考虑是否愿意且有能力进行管理,及是否只接受朋友和你非常信任的人注册账户。
|
注意,作为实例管理员,无论你是否愿意,你都需对在你的实例上发布的内容负责。如果你的实例用户在联合网上骚扰或烦扰他人,可能会导致你的实例名誉受损,并被其他人屏蔽。妥善管理一个社区需要付出努力。因此,你应仔细考虑是否愿意且有能力进行管理,及是否只接受朋友和你非常信任的人注册账户。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
为使注册流程正常运作,你的实例应[配置电子邮件发件服务](../configuration/smtp.md)。
|
为使注册流程正常运作,你的实例应[配置电子邮件发件服务](../configuration/smtp.md)。
|
||||||
|
|
||||||
如下所述,在注册流程中,会向你(作为管理员/站务)和申请人发送几封邮件,包括要求对方确认邮箱地址的邮件。
|
如下所述,在注册流程中,会向你(作为管理员/站务)和申请人发送几封邮件,包括要求对方确认邮箱地址的邮件。
|
||||||
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
如果你**拒绝**注册,可以选择通知申请人注册被拒,你可以通过勾选“发送邮件”复选框来实现。这将向申请人发送一封简短邮件,告知其被拒。如果需要,还可以添加自定义消息,该消息将添加在邮件底部。你还可以添加仅供其他管理员查看的私人备注。
|
如果你**拒绝**注册,可以选择通知申请人注册被拒,你可以通过勾选“发送邮件”复选框来实现。这将向申请人发送一封简短邮件,告知其被拒。如果需要,还可以添加自定义消息,该消息将添加在邮件底部。你还可以添加仅供其他管理员查看的私人备注。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
你可能希望等申请人确认他们的电子邮件地址后再批准注册,以防申请时输入错误或提供不是他们的电子邮件地址。如果他们不能确认电子邮件地址,将无法登录和使用账户。
|
你可能希望等申请人确认他们的电子邮件地址后再批准注册,以防申请时输入错误或提供不是他们的电子邮件地址。如果他们不能确认电子邮件地址,将无法登录和使用账户。
|
||||||
|
|
||||||
## 注册限制
|
## 注册限制
|
||||||
|
|
|
||||||
|
|
@ -6,12 +6,12 @@
|
||||||
|
|
||||||
被认为是骚扰信息的消息将不会存储在你的本站实例上,也不会生成通知。
|
被认为是骚扰信息的消息将不会存储在你的本站实例上,也不会生成通知。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
骚扰信息过滤器必然是不完美的工具,因为它们可能会误判一些合法的信息为垃圾,或者确实未能抓住一些*确实*是垃圾的信息。
|
骚扰信息过滤器必然是不完美的工具,因为它们可能会误判一些合法的信息为垃圾,或者确实未能抓住一些*确实*是垃圾的信息。
|
||||||
|
|
||||||
启用 `instance-federation-spam-filter` 应被视为当联合网络遭遇骚扰信息攻击时的一种“加固”选项。在正常情况下,你可能希望将其关闭,以避免意外过滤掉合法信息。
|
启用 `instance-federation-spam-filter` 应被视为当联合网络遭遇骚扰信息攻击时的一种“加固”选项。在正常情况下,你可能希望将其关闭,以避免意外过滤掉合法信息。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
如果你想检查骚扰信息过滤器捕获了哪些内容(如果有的话),可以在日志中搜索 `looked like spam`。
|
如果你想检查骚扰信息过滤器捕获了哪些内容(如果有的话),可以在日志中搜索 `looked like spam`。
|
||||||
|
|
||||||
如果你[将 GoToSocial 作为 systemd 服务运行](../getting_started/installation/metal.md#optional-enable-the-systemd-service),可以使用以下命令:
|
如果你[将 GoToSocial 作为 systemd 服务运行](../getting_started/installation/metal.md#optional-enable-the-systemd-service),可以使用以下命令:
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
本节涵盖了多种缓存技术,这些技术可以提高 GoToSocial 在高流量情况下的稳定性,并减轻 GoToSocial 实例的一部分工作负担。
|
本节涵盖了多种缓存技术,这些技术可以提高 GoToSocial 在高流量情况下的稳定性,并减轻 GoToSocial 实例的一部分工作负担。
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
这些指南仅在你运行[反向代理](../../getting_started/reverse_proxy/index.md)时才有意义。
|
这些指南仅在你运行[反向代理](../../getting_started/reverse_proxy/index.md)时才有意义。
|
||||||
|
|
||||||
## 指南
|
## 指南
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ tls-certificate-key: "/path/to/private.key"
|
||||||
|
|
||||||
这将禁用通过 Lets Encrypt 内置的证书配置,并指示 GoToSocial 在磁盘上找到证书。
|
这将禁用通过 Lets Encrypt 内置的证书配置,并指示 GoToSocial 在磁盘上找到证书。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
在续订证书后应重启 GoToSocial。它在这种情况下不会自动监测证书的更换。
|
在续订证书后应重启 GoToSocial。它在这种情况下不会自动监测证书的更换。
|
||||||
|
|
||||||
### 使用反向代理
|
### 使用反向代理
|
||||||
|
|
@ -93,7 +93,7 @@ tls-certificate-key: ""
|
||||||
* [Traefik](https://doc.traefik.io/traefik/https/tls/)
|
* [Traefik](https://doc.traefik.io/traefik/https/tls/)
|
||||||
* [Caddy](https://caddyserver.com/docs/caddyfile/directives/tls)
|
* [Caddy](https://caddyserver.com/docs/caddyfile/directives/tls)
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
在你的反向代理中配置 TLS 时,请确保你配置了一组较现代的兼容版本和加密套件。可以使用 [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/) 的“中级”配置。
|
在你的反向代理中配置 TLS 时,请确保你配置了一组较现代的兼容版本和加密套件。可以使用 [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/) 的“中级”配置。
|
||||||
|
|
||||||
检查你的反向代理文档,以了解在证书更改后是否需要重新加载或重启它。并非所有的反向代理都会自动检测到这一点。
|
检查你的反向代理文档,以了解在证书更改后是否需要重新加载或重启它。并非所有的反向代理都会自动检测到这一点。
|
||||||
|
|
|
||||||
|
|
@ -23,12 +23,12 @@ healthcheck:
|
||||||
|
|
||||||
上述健康检查将在 30 秒后开始,每两分钟检查一次服务是否可用,通过对 `/readyz` 进行 HEAD 请求。如果检查连续失败五次,服务将被标记为不健康。你可以在使用的编排系统中利用此功能强制重启容器。
|
上述健康检查将在 30 秒后开始,每两分钟检查一次服务是否可用,通过对 `/readyz` 进行 HEAD 请求。如果检查连续失败五次,服务将被标记为不健康。你可以在使用的编排系统中利用此功能强制重启容器。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
在慢速硬件上进行数据库迁移时,迁移可能会超过上述健康检查所允许的 10 分钟。
|
在慢速硬件上进行数据库迁移时,迁移可能会超过上述健康检查所允许的 10 分钟。
|
||||||
|
|
||||||
在这样的系统上,你可能需要增加健康检查的间隔或重试次数,以确保不会在迁移中途停止 GoToSocial(这会很糟糕!)。
|
在这样的系统上,你可能需要增加健康检查的间隔或重试次数,以确保不会在迁移中途停止 GoToSocial(这会很糟糕!)。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
尽管健康检查端点不透露任何敏感信息,并且只运行非常简单的查询,你可能希望避免将它们暴露给外部世界。你可以在 nginx 中通过在 `server` 段中添加以下代码片段来实现:
|
尽管健康检查端点不透露任何敏感信息,并且只运行非常简单的查询,你可能希望避免将它们暴露给外部世界。你可以在 nginx 中通过在 `server` 段中添加以下代码片段来实现:
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
本指南解释了如何使用 `@me@example.org` 这样的用户名,但将 GoToSocial 实例本身运行在例如 `social.example.org` 这样的子域名的方法。这种部署布局的配置**必须**在第一次启动 GoToSocial 前完成。
|
本指南解释了如何使用 `@me@example.org` 这样的用户名,但将 GoToSocial 实例本身运行在例如 `social.example.org` 这样的子域名的方法。这种部署布局的配置**必须**在第一次启动 GoToSocial 前完成。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "警告"
|
||||||
一旦与他人联合后就无法更改域名布局。服务器会因此产生混淆,而你需要说服每个与你联合的实例管理员修改其数据库来解决问题。同时,你还需要在本地重新生成数据库,创建一个新的实例账户和加密密钥对。
|
一旦与他人联合后就无法更改域名布局。服务器会因此产生混淆,而你需要说服每个与你联合的实例管理员修改其数据库来解决问题。同时,你还需要在本地重新生成数据库,创建一个新的实例账户和加密密钥对。
|
||||||
|
|
||||||
## 背景
|
## 背景
|
||||||
|
|
@ -49,7 +49,7 @@ host: social.example.org
|
||||||
account-domain: example.org
|
account-domain: example.org
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
`host` 必须始终是运行 GoToSocial 实例的 DNS 名称。它不影响 GoToSocial 实例绑定的 IP 地址。该地址由 `bind-address` 控制。
|
`host` 必须始终是运行 GoToSocial 实例的 DNS 名称。它不影响 GoToSocial 实例绑定的 IP 地址。该地址由 `bind-address` 控制。
|
||||||
|
|
||||||
## 反向代理
|
## 反向代理
|
||||||
|
|
@ -62,7 +62,7 @@ account-domain: example.org
|
||||||
* `/.well-known/host-meta`
|
* `/.well-known/host-meta`
|
||||||
* `/.well-known/nodeinfo`
|
* `/.well-known/nodeinfo`
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
不要将 API 端点 `/api/...` 的请求从账户域代理或重定向到主机域。这会混淆某些客户端用来检测分域部署的启发式方法,导致登录流程中断及其他异常行为。
|
不要将 API 端点 `/api/...` 的请求从账户域代理或重定向到主机域。这会混淆某些客户端用来检测分域部署的启发式方法,导致登录流程中断及其他异常行为。
|
||||||
|
|
||||||
### nginx
|
### nginx
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
这些指南涵盖如何提高你的 GoToSocial 部署的安全状况。它们不涉及调整 GoToSocial 的设置,而是指出一些你可以做的额外措施,以更好地保护你的实例。
|
这些指南涵盖如何提高你的 GoToSocial 部署的安全状况。它们不涉及调整 GoToSocial 的设置,而是指出一些你可以做的额外措施,以更好地保护你的实例。
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
这些指南中的任何内容旨在增强你的 GoToSocial 部署的安全性;它们不能替代良好的安全实践,比如保持你的系统定期得到修补和更新。
|
这些指南中的任何内容旨在增强你的 GoToSocial 部署的安全性;它们不能替代良好的安全实践,比如保持你的系统定期得到修补和更新。
|
||||||
|
|
||||||
## 指南
|
## 指南
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
SQLite 的运行模式假定数据库和使用它的进程或应用程序位于同一主机上。在运行 WAL 模式(GoToSocial 的默认模式)时,它依赖于进程之间的共享内存来确保数据库完整性。
|
SQLite 的运行模式假定数据库和使用它的进程或应用程序位于同一主机上。在运行 WAL 模式(GoToSocial 的默认模式)时,它依赖于进程之间的共享内存来确保数据库完整性。
|
||||||
|
|
||||||
!!! quote
|
!!! quote "参考"
|
||||||
所有使用数据库的进程必须在同一台主机计算机上;WAL 不能在网络文件系统上工作。这是因为 WAL 需要所有进程共享少量内存,而在不同主机上的进程显然不能相互共享内存。
|
所有使用数据库的进程必须在同一台主机计算机上;WAL 不能在网络文件系统上工作。这是因为 WAL 需要所有进程共享少量内存,而在不同主机上的进程显然不能相互共享内存。
|
||||||
|
|
||||||
— SQLite.org [写前日志](https://www.sqlite.org/wal.html)
|
— SQLite.org [写前日志](https://www.sqlite.org/wal.html)
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ curl \
|
||||||
- `write`
|
- `write`
|
||||||
- `admin`
|
- `admin`
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
GoToSocial 目前不支持范围授权令牌,因此在此过程中获得的任何令牌都可以代表你执行所有操作,包括如果你的账户具有管理员权限时的管理员操作。然而,始终以最低权限授予你的应用是一个好习惯。例如,如果你的应用不会发布贴文,请使用 scope=read。
|
GoToSocial 目前不支持范围授权令牌,因此在此过程中获得的任何令牌都可以代表你执行所有操作,包括如果你的账户具有管理员权限时的管理员操作。然而,始终以最低权限授予你的应用是一个好习惯。例如,如果你的应用不会发布贴文,请使用 scope=read。
|
||||||
|
|
||||||
本着这种精神,上述示例使用了`read`,这意味着当未来支持范围令牌时,应用将仅限于执行`read`操作。
|
本着这种精神,上述示例使用了`read`,这意味着当未来支持范围令牌时,应用将仅限于执行`read`操作。
|
||||||
|
|
@ -44,7 +44,7 @@ curl \
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
确保将 `client_id` 和 `client_secret` 的值保存到某个位置,以便在需要时参考。
|
确保将 `client_id` 和 `client_secret` 的值保存到某个位置,以便在需要时参考。
|
||||||
|
|
||||||
## 授权你的应用代表你操作
|
## 授权你的应用代表你操作
|
||||||
|
|
@ -57,7 +57,7 @@ curl \
|
||||||
https://example.org/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=read
|
https://example.org/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&response_type=code&scope=read
|
||||||
```
|
```
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
如果你在注册应用时使用了不同的范围,在上面的 URL 中将 `scope=read` 替换为你注册时使用的加号分隔的范围列表。例如,如果你注册你的应用时使用了 `scopes` 值 `read write`,那么你应该将上面的 `scope=read` 改为 `scope=read+write`。
|
如果你在注册应用时使用了不同的范围,在上面的 URL 中将 `scope=read` 替换为你注册时使用的加号分隔的范围列表。例如,如果你注册你的应用时使用了 `scopes` 值 `read write`,那么你应该将上面的 `scope=read` 改为 `scope=read+write`。
|
||||||
|
|
||||||
将 URL 粘贴到浏览器后,你会被引导到实例的登录表单,提示你输入邮箱地址和密码以将应用连接到你的账户。
|
将 URL 粘贴到浏览器后,你会被引导到实例的登录表单,提示你输入邮箱地址和密码以将应用连接到你的账户。
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,11 @@
|
||||||
|
|
||||||
### 我总是超出速率限制!为什么?
|
### 我总是超出速率限制!为什么?
|
||||||
|
|
||||||
如果你发现自己的速率限制在正常使用时经常被超出(对于你自己和其他请求者也是如此),这可能是因为 GoToSocial 无法通过 IP 地址区分客户端。你可以通过查看实例的日志来调查这个问题。如果(几乎)所有记录的 IP 地址似乎都是相同的 IP 地址(类似于 `172.x.x.x`),那么速率限制将导致问题。
|
如果你发现自己的速率限制在正常使用时经常被超出(对于你自己和其他请求者也是如此),这可能是因为 GoToSocial 无法通过 IP 地址区分客户端。你可以通过查看实例的日志来调查这个问题。如果(几乎)所有记录的客户端 IP 地址似乎都是相同的 IP 地址(类似于 `172.x.x.x`),那么速率限制将导致问题。
|
||||||
|
|
||||||
这种情况通常发生在你的服务器运行在 NAT(端口转发)中,或者在没有正确配置的 HTTP 代理之后,导致你的实例将所有传入 IP 地址视为相同的地址:即你的反向代理或网关的 IP 地址。这意味着所有传入请求*共享同一个速率限制*,而不是按 IP 正确分开。
|
这种情况通常发生在你的服务器运行在 NAT(端口转发)中,或者在没有正确配置的 HTTP 代理之后,导致你的实例将所有传入 IP 地址视为相同的地址:即你的反向代理或网关的 IP 地址。这意味着所有传入请求*共享同一个速率限制*,而不是按 IP 正确分开。
|
||||||
|
|
||||||
如果你正在使用 HTTP 代理,那么很可能你的 `trusted-proxies` 未正确配置。如果是这种情况,尝试将反向代理的 IP 地址添加到 `trusted-proxies` 列表中,并重启你的实例。
|
如果你使用了 HTTP 代理,那么你的 `trusted-proxies` 配置可能不正确。详情请参阅 [可信代理](../configuration/trusted_proxies.md) 文档以了解如何解决此问题。
|
||||||
|
|
||||||
如果没有使用 HTTP 代理,那么很可能是由 NAT 引起的。在这种情况下,你应该完全禁用速率限制。
|
如果没有使用 HTTP 代理,那么很可能是由 NAT 引起的。在这种情况下,你应该完全禁用速率限制。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ GoToSocial 使用 [go-swagger](https://github.com/go-swagger/go-swagger) 从代
|
||||||
|
|
||||||
大多数 GoToSocial API 端点需要用户级别的 OAuth 令牌。有关如何使用 OAuth 令牌进行 API 认证的指南,请参阅[认证文档](./authentication.md)。
|
大多数 GoToSocial API 端点需要用户级别的 OAuth 令牌。有关如何使用 OAuth 令牌进行 API 认证的指南,请参阅[认证文档](./authentication.md)。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
如果你想更多地使用该规范,还可以直接查看 [swagger.yaml](./swagger.yaml),然后将其粘贴到 [Swagger Editor](https://editor.swagger.io/) 等工具中。这样你可以尝试自动生成不同语言的 GoToSocial API 客户端(不支持,但可以尝试),或者将文档转换为 JSON 或 OpenAPI v3 规范等。更多信息请参见[这里](https://swagger.io/tools/open-source/getting-started/)。
|
如果你想更多地使用该规范,还可以直接查看 [swagger.yaml](./swagger.yaml),然后将其粘贴到 [Swagger Editor](https://editor.swagger.io/) 等工具中。这样你可以尝试自动生成不同语言的 GoToSocial API 客户端(不支持,但可以尝试),或者将文档转换为 JSON 或 OpenAPI v3 规范等。更多信息请参见[这里](https://swagger.io/tools/open-source/getting-started/)。
|
||||||
|
|
||||||
!!! info "注意事项:上传文件"
|
!!! info "注意事项:上传文件"
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,8 +1,6 @@
|
||||||
# 基础配置
|
# 基础配置
|
||||||
|
|
||||||
GoToSocial 的基础配置,包括域名、端口、绑定地址和传输协议等基本内容。
|
GoToSocial 的顶级配置,包括域名、端口、绑定地址和可信代理等基本信息。
|
||||||
|
|
||||||
这里*真正*需要设置的只有 `host`,也就是你实例可以访问的域名,可能还需要设置 `port`。
|
|
||||||
|
|
||||||
## 设置
|
## 设置
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,4 +112,47 @@ instance-deliver-to-shared-inboxes: true
|
||||||
# 选项: [true, false]
|
# 选项: [true, false]
|
||||||
# 默认值: false
|
# 默认值: false
|
||||||
instance-inject-mastodon-version: false
|
instance-inject-mastodon-version: false
|
||||||
|
|
||||||
|
# 字符串。hh:mm 格式的 24 小时制时间。
|
||||||
|
# 示例: ["14:30", "00:00", "04:00"]
|
||||||
|
# 默认值: "23:00" (晚上11点)。
|
||||||
|
instance-subscriptions-process-from: "23:00"
|
||||||
|
|
||||||
|
|
||||||
|
# 时间间隔。表示更新订阅的周期。
|
||||||
|
# 示例:["24h", "72h", "12h"]
|
||||||
|
# 默认值: "24h"(每天一次)。
|
||||||
|
instance-subscriptions-process-every: "24h"
|
||||||
|
|
||||||
|
# 字符串。允许你自定义是否以及如何在 /api/v1|v2/instance
|
||||||
|
# 和 /nodeinfo 端点向爬虫提供统计数据。
|
||||||
|
#
|
||||||
|
# 请注意,无论你在这里进行何种设置,/api/v1|v2/instance
|
||||||
|
# 端点都不会被 robots.txt 允许抓取,因为这些是客户端
|
||||||
|
# API端点。
|
||||||
|
#
|
||||||
|
# "" / 空字符串(默认模式): 在 instance 和 nodeinfo 端点提供准确的统计数据,
|
||||||
|
# 并在 robots.txt 中禁止爬虫抓取这些端点。这种模式相当于礼貌地
|
||||||
|
# 要求爬虫不抓取,但不能保证它们会遵从这些规则,
|
||||||
|
# 因为遗憾的是,许多爬虫甚至不会检查robots.txt。
|
||||||
|
#
|
||||||
|
# "zero": 在 instance 和 nodeinfo 端点提供全为零的统计数据,
|
||||||
|
# 并在 robots.txt 中禁止爬虫抓取这些端点。
|
||||||
|
# 这种模式阻止行为不端的爬虫收集有关您的实例的统计数据,
|
||||||
|
# 因为所有收集的值都将为0。这(在统计数据方面)
|
||||||
|
# 是保护您的实例隐私的最安全方法。
|
||||||
|
#
|
||||||
|
# "serve": 在 instance 和 nodeinfo 端点提供准确的统计数据,
|
||||||
|
# 并允许爬虫抓取这些端点。如果您希望为
|
||||||
|
# 联邦宇宙统计信息收集项目做贡献,此模式将非常有用。
|
||||||
|
#
|
||||||
|
# "baffle": 在 instance 和 nodeinfo 端点提供随机且荒谬的统计数据,
|
||||||
|
# 并在 robots.txt 中禁止爬虫抓取这些端点。
|
||||||
|
# 这种模式可以用于使不尊重 robots.txt 的爬虫感到困惑。
|
||||||
|
# 警告,此做法可能会引起不尊重 robots.txt 的爬虫开发者的怨恨,
|
||||||
|
# 因此可能会给您的实例带来风险。
|
||||||
|
#
|
||||||
|
# 选项: ["", "zero", "serve", "baffle"]
|
||||||
|
# 默认: ""
|
||||||
|
instance-stats-mode: ""
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ GoToSocial 支持 [OpenID Connect](https://openid.net/connect/),这是一种
|
||||||
- 你希望将用户、账户、密码等的管理委托给外部服务,以简化管理。
|
- 你希望将用户、账户、密码等的管理委托给外部服务,以简化管理。
|
||||||
- 你已经在外部系统中有很多用户,不想在 GoToSocial 中手动重新创建他们。
|
- 你已经在外部系统中有很多用户,不想在 GoToSocial 中手动重新创建他们。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
如果用户尚不存在,且你的 IdP 没有返回非空的 `email` 作为 claims 的一部分,登录将会失败。这个 email 需要在此实例中是唯一的。尽管我们使用 `sub` claim 将外部身份与 GtS 用户关联,但创建用户时需要一个与之关联的 email。
|
如果用户尚不存在,且你的 IdP 没有返回非空的 `email` 作为 claims 的一部分,登录将会失败。这个 email 需要在此实例中是唯一的。尽管我们使用 `sub` claim 将外部身份与 GtS 用户关联,但创建用户时需要一个与之关联的 email。
|
||||||
|
|
||||||
## 设置
|
## 设置
|
||||||
|
|
|
||||||
171
docs/locales/zh/configuration/trusted_proxies.md
Normal file
171
docs/locales/zh/configuration/trusted_proxies.md
Normal file
|
|
@ -0,0 +1,171 @@
|
||||||
|
# 可信代理
|
||||||
|
|
||||||
|
为了正确执行[速率限制](../api/ratelimiting.md),GoToSocial 依赖于“可信代理”的概念,以准确确定访问你的实例的客户端的 IP 地址。
|
||||||
|
|
||||||
|
“可信代理”是一个中间网络跳转层,GoToSocial 可以配置为信任由该代理层提供的正确的客户端 IP 地址。
|
||||||
|
|
||||||
|
例如,如果你使用 Docker + Nginx 的反向代理配置中运行,那么 Nginx 的 Docker 网络地址应该被配置为可信代理,因为从广域互联网传入的所有流量将通过 Nginx 进入 GoToSocial。
|
||||||
|
|
||||||
|
如果没有正确设置 `trusted-proxies`, GoToSocial 将看到所有的入站客户端的 IP 地址都是同一个地址,这会导致速率限制的问题,因为 GoToSocial 使用客户端 IP 地址来执行速率限制。
|
||||||
|
|
||||||
|
## 总结:如何正确设置 `trusted-proxies`
|
||||||
|
|
||||||
|
如果你的 `trusted-proxies` 设置没有正确配置,你可能会在实例的网页视图中看到以下警告(v0.18.0及以上版本):
|
||||||
|
|
||||||
|
> 警告!此实例的配置中 trusted-proxies 的设置似乎不正确。这可能导致速率限制问题,进而导致联合问题。
|
||||||
|
>
|
||||||
|
> 如果你是实例管理员,你应该通过将 `SUGGESTED_IP_RANGE` 添加到你的 trusted-proxies 来修复此问题。
|
||||||
|
|
||||||
|
要解决这个问题,可以复制消息中的IP范围,并编辑你的 `config.yaml` 文件,将IP范围添加到你的 `trusted-proxies` 中。
|
||||||
|
|
||||||
|
!!! tip "即使你没有看到上述警告,你也可能会遇到速率限制!"
|
||||||
|
如果你使用的是低于 v0.18.0 版本的 GoToSocial,或者你在 Cloudflare(不推荐) 这样的 CDN 之后运行,你将不会看到警告消息。相反,你会在 GoToSocial 日志中看到所有客户端的 IP 都是同一个地址。在这种情况下,可以将重复出现的客户端IP值作为`SUGGESTED_IP_RANGE`。
|
||||||
|
|
||||||
|
在下面例子中,我们假定`SUGGESTED_IP_RANGE`为`172.17.0.1/16`(默认的Docker桥接网络子网)。
|
||||||
|
|
||||||
|
修改之前(默认配置):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
trusted-proxies:
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "::1"
|
||||||
|
```
|
||||||
|
|
||||||
|
修改之后(新配置):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
trusted-proxies:
|
||||||
|
- "172.17.0.1/16"
|
||||||
|
- "127.0.0.1/32"
|
||||||
|
- "::1"
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你使用[环境变量](../configuration/index.md#环境变量)来配置你的实例,可以通过设置环境变量`GTS_TRUSTED_PROXIES`为以逗号分隔的IP范围列表来配置`trusted-proxies`,如下所示:
|
||||||
|
|
||||||
|
```env
|
||||||
|
GTS_TRUSTED_PROXIES="172.17.0.1/16,127.0.0.1/32,::1"
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你使用 docker compose,你的 docker-compose.yaml 文件在更改后应如下所示(注意 yaml 使用 `:` 而不是 `=`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
environment:
|
||||||
|
############################
|
||||||
|
# 其他环境变量 #
|
||||||
|
############################
|
||||||
|
## 对于反向代理设置:
|
||||||
|
GTS_TRUSTED_PROXIES: "172.17.0.1/16,127.0.0.1/32,::1"
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
```
|
||||||
|
|
||||||
|
一旦你完成了必要的配置更改,**重启你的实例**并刷新主页。
|
||||||
|
|
||||||
|
如果消息消失,则问题已解决!
|
||||||
|
|
||||||
|
如果你仍然看到警告消息,但显示了一个不同的建议添加到`trusted-proxies`的 IP 范围,那么重复上述步骤,在你的配置中添加新的建议 IP 范围。
|
||||||
|
|
||||||
|
!!! tip "Cloudflare 的 IP 地址列表"
|
||||||
|
如果你在 GoToSocial 实例前面使用 CDN/代理,例如 Cloudflare (不推荐),那么你可能需要将一个或多个 Cloudflare IP 地址添加到你的 `trusted-proxies` 中,以便速率限制正常工作。你可以在这里找到Cloudflare 的 IP 地址列表: https://www.cloudflare.com/ips/
|
||||||
|
|
||||||
|
## 我可能无法正确配置 `trusted-proxies`,可以直接禁用警告吗?
|
||||||
|
|
||||||
|
在某些情况下,很难实际正确配置 `trusted-proxies` 来检测入站请求的真实客户端 IP,或者确保真实客户端 IP 是准确、但是仍显示为在私有网络内的。
|
||||||
|
|
||||||
|
例如,如果你在家用网络上运行 GoToSocial,且实例位于无法注入 `X-Forwarded-For` 标头的家庭互联网路由器之后,那么建议你添加到 `trusted-proxies` 的条目看起来会像 `192.168.x.x`,但将其添加到 `trusted-proxies` 后问题依然无法解决。
|
||||||
|
|
||||||
|
另一个例子是:你在家庭网络上运行 GoToSocial,GoToSocial 连接到家庭网络的路由器,并且你从同样在你家庭网络设备(比如笔记本或手机)上访问 Web 前端。在这种情况下,你的路由器可能会直接将你发送到你的 GoToSocial 实例,且你的请求不会离开家用网络,因此 GtS 将正确地认为*你的*客户端 IP 地址是一个私人网络地址,但*其他*从更广泛的互联网传入的请求将显示其真实的远程客户端 IP 地址。在这种情况下,`trusted-proxies` 的警告实际上不适用。
|
||||||
|
|
||||||
|
如果你已尝试编辑 `trusted-proxies` 设置,但仍看到警告,可能上面的一个例子适用于你。你可以通过以下两种方式之一继续:
|
||||||
|
|
||||||
|
### 为家庭网络添加速率限制例外(推荐)
|
||||||
|
|
||||||
|
如果 `trusted-proxies` 警告中的建议 IP 范围看起来像 `192.168.x.x`,但你在 GoToSocial 日志中仍看到其他客户端 IP 不以 `192.168` 开头,那么可以尝试只为家庭网络上的设备添加速率限制例外,同时对外部 IP 地址保持速率限制。
|
||||||
|
|
||||||
|
例如,如果你的建议是类似 `192.168.1.128/32`,那么将 `/32` 换为 `/24`,以便使范围覆盖 `192.168.1.0` -> `192.168.1.255`,并将其添加到 `config.yaml` 文件中的 `advanced-rate-limit-exceptions` 设置中。
|
||||||
|
|
||||||
|
默认设置(修改前):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
advanced-rate-limit-exceptions: []
|
||||||
|
```
|
||||||
|
|
||||||
|
设置修改后:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
advanced-rate-limit-exceptions:
|
||||||
|
- "192.168.1.128/24"
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你使用[环境变量](../configuration/index.md#环境变量)来配置实例,可以将环境变量 `GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS` 设为以逗号分隔的 IP 范围列表,来配置 `advanced-rate-limit-exceptions`,如下所示:
|
||||||
|
|
||||||
|
```env
|
||||||
|
GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS="192.168.1.128/24"
|
||||||
|
```
|
||||||
|
|
||||||
|
如果使用 docker compose,修改后的 docker-compose.yaml 文件应如下所示(注意 yaml 使用 `: ` 而不是 `=`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
environment:
|
||||||
|
############################
|
||||||
|
# 其他环境变量 #
|
||||||
|
############################
|
||||||
|
GTS_ADVANCED_RATE_LIMIT_EXCEPTIONS: "192.168.1.128/24"
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
```
|
||||||
|
|
||||||
|
完成必要的配置更改后,**重启你的实例**并刷新主页。
|
||||||
|
|
||||||
|
### 完全关闭速率限制(最后手段)
|
||||||
|
|
||||||
|
如果其他方法无效,你可以完全禁用速率限制,这也会禁用 `trusted-proxies` 检查和警告。
|
||||||
|
|
||||||
|
!!! warning "警告"
|
||||||
|
完全关闭速率限制应被视为最后的手段,因为速率限制有助于保护你的实例免受骚扰信息和爬虫攻击。
|
||||||
|
|
||||||
|
要关闭速率限制,请在 `config.yaml` 中将 `advanced-rate-limit-requests` 设置为 0。
|
||||||
|
|
||||||
|
默认配置前:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
advanced-rate-limit-requests: 300
|
||||||
|
```
|
||||||
|
|
||||||
|
设置后:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
advanced-rate-limit-requests: 0
|
||||||
|
```
|
||||||
|
|
||||||
|
如果你使用[环境变量](../configuration/index.md#环境变量)来配置实例,可以通过将环境变量 `GTS_ADVANCED_RATE_LIMIT_REQUESTS` 设置为 0,来配置 `advanced-rate-limit-requests`,如下所示:
|
||||||
|
|
||||||
|
```env
|
||||||
|
GTS_ADVANCED_RATE_LIMIT_REQUESTS="0"
|
||||||
|
```
|
||||||
|
|
||||||
|
如果使用 docker compose,改变后的 docker-compose.yaml 文件应如下所示(注意 yaml 使用 `: ` 而不是 `=`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
environment:
|
||||||
|
############################
|
||||||
|
# 其他环境变量 #
|
||||||
|
############################
|
||||||
|
GTS_ADVANCED_RATE_LIMIT_REQUESTS: "0"
|
||||||
|
################################
|
||||||
|
# 其他配置内容 #
|
||||||
|
################################
|
||||||
|
```
|
||||||
|
|
||||||
|
完成必要的配置更改后,**重启你的实例**并刷新主页。
|
||||||
|
|
@ -1,5 +1,13 @@
|
||||||
# 行为体与行为体属性
|
# 行为体与行为体属性
|
||||||
|
|
||||||
|
## `Service` 与 `Person` 行为体
|
||||||
|
|
||||||
|
GoToSocial 将大多数账号视为[此处](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-person)描述的 ActivityStreams `Person` 类型。
|
||||||
|
|
||||||
|
然而,被用户标记为机器人的账号将使用[此处](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-service)描述的 `Service` 类型。
|
||||||
|
|
||||||
|
这种类型的区分可供外站实例区分机器人账号和“普通”用户账号。
|
||||||
|
|
||||||
## 收件箱
|
## 收件箱
|
||||||
|
|
||||||
GoToSocial 按照 [ActivityPub 规范](https://www.w3.org/TR/activitypub/#inbox),为行为体实现了收件箱。
|
GoToSocial 按照 [ActivityPub 规范](https://www.w3.org/TR/activitypub/#inbox),为行为体实现了收件箱。
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,58 @@ GoToSocial 外发话题标签提供的 `href` URL 指向一个提供 `text/html`
|
||||||
|
|
||||||
GoToSocial 对给定 `text/html` 的内容不做任何保证,外站不应该将 URL 解释为规范的 ActivityPub ID/URI 属性。`href` URL 仅作为可能包含该话题标签更多信息的一个端点。
|
GoToSocial 对给定 `text/html` 的内容不做任何保证,外站不应该将 URL 解释为规范的 ActivityPub ID/URI 属性。`href` URL 仅作为可能包含该话题标签更多信息的一个端点。
|
||||||
|
|
||||||
|
## 表情符号(Emoji)
|
||||||
|
|
||||||
|
GoToSocial 使用 `http://joinmastodon.org/ns#Emoji` 类型,以允许用户在贴文中添加自定义表情符号。
|
||||||
|
|
||||||
|
例如:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"@context": [
|
||||||
|
"https://gotosocial.org/ns",
|
||||||
|
"https://www.w3.org/ns/activitystreams",
|
||||||
|
{
|
||||||
|
"Emoji": "toot:Emoji",
|
||||||
|
"sensitive": "as:sensitive",
|
||||||
|
"toot": "http://joinmastodon.org/ns#"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"type": "Note",
|
||||||
|
"content": "<p>这里有个臭烘烘的东西 -> :shocked_pikachu:</p>",
|
||||||
|
[...],
|
||||||
|
"tag": {
|
||||||
|
"icon": {
|
||||||
|
"mediaType": "image/png",
|
||||||
|
"type": "Image",
|
||||||
|
"url": "https://example.org/fileserver/01BPSX2MKCRVMD4YN4D71G9CP5/emoji/original/01AZY1Y5YQD6TREB5W50HGTCSZ.png"
|
||||||
|
},
|
||||||
|
"id": "https://example.org/emoji/01AZY1Y5YQD6TREB5W50HGTCSZ",
|
||||||
|
"name": ":shocked_pikachu:",
|
||||||
|
"type": "Emoji",
|
||||||
|
"updated": "2022-11-17T11:36:05Z"
|
||||||
|
}
|
||||||
|
[...]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
上述 `Note` 的 `content` 中的文本 `:shocked_pikachu:` 应当被客户端替换为表情符号图片的小型(内联)版本,在渲染 `Note` 时一并向用户展示。
|
||||||
|
|
||||||
|
表情符号的 `updated` 和 `icon.url` 属性可被外站实例用于判断它们对 GoToSocial 表情符号图片的表示是否是最新版本。必要时也可以在其 `id` URI 间接引用 `Emoji`,以便外站对照检查它们缓存的表情符号元数据是否未最新版本。
|
||||||
|
|
||||||
|
默认情况下,GoToSocial 对可以上传和发送的表情符号图片的大小设置了 50kb 的限制,并对可以联合并传入的表情符号图片大小设置了 100kb 的限制,但这两项设置都可由用户配置。
|
||||||
|
|
||||||
|
GoToSocial 可以发送和接收类型为 `image/png`、`image/jpeg`、`image/gif` 和 `image/webp` 的表情符号图片。
|
||||||
|
|
||||||
|
!!! info "附注"
|
||||||
|
请注意,`tag` 属性可以是对象的数组,也可以是单个对象。
|
||||||
|
|
||||||
|
### `null` / 空 `id` 属性
|
||||||
|
|
||||||
|
一些服务端软件,如 Akkoma,将表情符号包含为贴文中的[匿名对象](https://www.w3.org/TR/activitypub/#obj-id)。也就是说,它们将 `id` 属性设置为 `null`,以表明该表情符号不能在任何特定的端点被间接引用。
|
||||||
|
|
||||||
|
在接收到这样的表情符号时,GoToSocial 会在数据库中为该表情符号生成一个伪 id,格式为 `https://[host]/dummy_emoji_path?shortcode=[shortcode]`,例如,`https://example.org/dummy_emoji_path?shortcode=shocked_pikachu`。
|
||||||
|
|
||||||
## 提及
|
## 提及
|
||||||
|
|
||||||
GoToSocial 用户可以在贴文中使用 `@[用户名]@[域名]` 格式提及其他用户。例如,如果一个 GoToSocial 用户想提及实例 `example.org` 上的用户 `someone`,可以在贴文中包含 `@someone@example.org`。
|
GoToSocial 用户可以在贴文中使用 `@[用户名]@[域名]` 格式提及其他用户。例如,如果一个 GoToSocial 用户想提及实例 `example.org` 上的用户 `someone`,可以在贴文中包含 `@someone@example.org`。
|
||||||
|
|
@ -160,14 +212,14 @@ GoToSocial 在解析传入的 `Object` 时使用 `content` 和 `contentMap` 属
|
||||||
|
|
||||||
如果 `contentMap` 有多个条目,则无法确定贴文的意图内容和语言,因为映射顺序不可预测。在这种情况下,尝试从 GoToSocial 实例的[配置语言](../configuration/instance.md)中选择与其中一种语言匹配的语言和内容条目。如果无法通过这种方式匹配语言,则从 `contentMap` 中随机选择一个语言和内容条目作为“主要”语言和内容。
|
如果 `contentMap` 有多个条目,则无法确定贴文的意图内容和语言,因为映射顺序不可预测。在这种情况下,尝试从 GoToSocial 实例的[配置语言](../configuration/instance.md)中选择与其中一种语言匹配的语言和内容条目。如果无法通过这种方式匹配语言,则从 `contentMap` 中随机选择一个语言和内容条目作为“主要”语言和内容。
|
||||||
|
|
||||||
!!! Note
|
!!! note "注意"
|
||||||
在上述所有情况下,如果推断的语言无法解析为有效的 BCP47 语言话题标签,则语言将回退为未知。
|
在上述所有情况下,如果推断的语言无法解析为有效的 BCP47 语言话题标签,则语言将回退为未知。
|
||||||
|
|
||||||
## 互动规则
|
## 互动规则
|
||||||
|
|
||||||
GoToSocial 使用 `interactionPolicy` 属性告知外站给定帖文允许的互动类型(有前提)。
|
GoToSocial 使用 `interactionPolicy` 属性告知外站给定帖文允许的互动类型(有前提)。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
|
|
||||||
互动规则旨在限制用户贴文上用户不希望的回复和其他互动的有害影响(例如,“回复家(reply guys)” —— 不请自来地发表冒失回复的人)。
|
互动规则旨在限制用户贴文上用户不希望的回复和其他互动的有害影响(例如,“回复家(reply guys)” —— 不请自来地发表冒失回复的人)。
|
||||||
|
|
||||||
|
|
@ -229,7 +281,7 @@ GoToSocial 使用 `interactionPolicy` 属性告知外站给定帖文允许的互
|
||||||
|
|
||||||
### 指定无人能进行的操作
|
### 指定无人能进行的操作
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
即使规则指定无人可互动,GoToSocial 仍做出默认假设。参见[默认假设](#默认假设)。
|
即使规则指定无人可互动,GoToSocial 仍做出默认假设。参见[默认假设](#默认假设)。
|
||||||
|
|
||||||
空数组或缺少/空的键表示无人能进行此互动。
|
空数组或缺少/空的键表示无人能进行此互动。
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
在部署 GoToSocial 之前,有几个关键点需要你仔细考虑,因为这些选择将影响你如何运行和管理 GoToSocial。
|
在部署 GoToSocial 之前,有几个关键点需要你仔细考虑,因为这些选择将影响你如何运行和管理 GoToSocial。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
|
|
||||||
在同一域名上切换不同实现是不被 Fediverse 支持的。这意味着如果你在 example.org 上运行 GoToSocial,而尝试切换到其他实现如 Pleroma/Akkoma、Misskey/Calckey 等,你会遇到联合问题。
|
在同一域名上切换不同实现是不被 Fediverse 支持的。这意味着如果你在 example.org 上运行 GoToSocial,而尝试切换到其他实现如 Pleroma/Akkoma、Misskey/Calckey 等,你会遇到联合问题。
|
||||||
|
|
||||||
|
|
@ -24,7 +24,7 @@ GoToSocial 致力于为在小型设备上运行的使用场景优化,因此我
|
||||||
|
|
||||||
你应该在这种情况下预留一些余量,若有需要,可以[配置一些交换内存](#交换内存)。
|
你应该在这种情况下预留一些余量,若有需要,可以[配置一些交换内存](#交换内存)。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
在内存受限的环境中,你可以将 `cache.memory-target` 设置为低于默认的 100MB (查看数据库配置选项[这里](../configuration/database.md#settings))。设置为 50MB 已被证明可以正常运行。
|
在内存受限的环境中,你可以将 `cache.memory-target` 设置为低于默认的 100MB (查看数据库配置选项[这里](../configuration/database.md#settings))。设置为 50MB 已被证明可以正常运行。
|
||||||
|
|
||||||
这将使总内存使用稍微降低,但代价是某些请求的延迟略高,因为 GtS 需要更频繁地访问数据库。
|
这将使总内存使用稍微降低,但代价是某些请求的延迟略高,因为 GtS 需要更频繁地访问数据库。
|
||||||
|
|
@ -46,7 +46,7 @@ GoToSocial 使用存储来保存其数据库文件,以及存储和服务媒体
|
||||||
|
|
||||||
对于媒体存储,以及[缓存的外站媒体文件存储](../admin/media_caching.md),你应该预算大约 5GB-10GB 的空间。GoToSocial 会自动执行自我清理,在一段时间后从缓存中删除未使用的外站媒体。如果存储空间是个问题,你可以[调整媒体清理行为](../admin/media_caching.md#清理)以更频繁地清理和/或减少外站媒体的缓存时间。
|
对于媒体存储,以及[缓存的外站媒体文件存储](../admin/media_caching.md),你应该预算大约 5GB-10GB 的空间。GoToSocial 会自动执行自我清理,在一段时间后从缓存中删除未使用的外站媒体。如果存储空间是个问题,你可以[调整媒体清理行为](../admin/media_caching.md#清理)以更频繁地清理和/或减少外站媒体的缓存时间。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
如果你的 sqlite.db 文件或 Postgres 容量在一开始增长很快,请不要惊慌,这是正常的。当你首次部署实例并开始联合时,你的实例会迅速发现并存储来自其他实例的账号和贴文。然而,随着实例的长期部署,这种增长会逐渐减缓,因为你会自然而然地看到更少的新账号(即,你的实例尚未见过并因此尚未在数据库中存储的账号)。
|
如果你的 sqlite.db 文件或 Postgres 容量在一开始增长很快,请不要惊慌,这是正常的。当你首次部署实例并开始联合时,你的实例会迅速发现并存储来自其他实例的账号和贴文。然而,随着实例的长期部署,这种增长会逐渐减缓,因为你会自然而然地看到更少的新账号(即,你的实例尚未见过并因此尚未在数据库中存储的账号)。
|
||||||
|
|
||||||
### 单板计算机
|
### 单板计算机
|
||||||
|
|
@ -106,7 +106,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
|
||||||
|
|
||||||
无论你选择哪种数据库驱动,为了获得良好的性能,它们都应在快速、稳定的低延迟存储上运行。虽然可以在网络附加存储上运行数据库,但这会增加可变延迟和网络拥堵,还有源存储上的潜在 I/O 争用。
|
无论你选择哪种数据库驱动,为了获得良好的性能,它们都应在快速、稳定的低延迟存储上运行。虽然可以在网络附加存储上运行数据库,但这会增加可变延迟和网络拥堵,还有源存储上的潜在 I/O 争用。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
请[备份你的数据库](../admin/backup_and_restore.md)。数据库包含实例和任何用户账户的加密密钥。如果丢失这些密钥,你将无法再次从同一域进行联合!
|
请[备份你的数据库](../admin/backup_and_restore.md)。数据库包含实例和任何用户账户的加密密钥。如果丢失这些密钥,你将无法再次从同一域进行联合!
|
||||||
|
|
||||||
## 域名
|
## 域名
|
||||||
|
|
@ -119,7 +119,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
|
||||||
|
|
||||||
如果你打算这样部署 GoToSocial 实例,请阅读[分域部署](../advanced/host-account-domain.md)文档以了解详细信息。
|
如果你打算这样部署 GoToSocial 实例,请阅读[分域部署](../advanced/host-account-domain.md)文档以了解详细信息。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
无法在联合已经事实发生后安全地更改实例域名和账号域名。这需要重新生成数据库,并在任何已联合的服务器造成混乱情况。一旦你的实例域名和账号域名设置好,便不可更改。
|
无法在联合已经事实发生后安全地更改实例域名和账号域名。这需要重新生成数据库,并在任何已联合的服务器造成混乱情况。一旦你的实例域名和账号域名设置好,便不可更改。
|
||||||
|
|
||||||
## TLS
|
## TLS
|
||||||
|
|
@ -128,7 +128,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
|
||||||
|
|
||||||
GoToSocial 内置 Lets Encrypt 证书配置支持。它也可以从磁盘加载证书。如果你有连接到 GoToSocial 的反向代理,可以在代理层处理 TLS。
|
GoToSocial 内置 Lets Encrypt 证书配置支持。它也可以从磁盘加载证书。如果你有连接到 GoToSocial 的反向代理,可以在代理层处理 TLS。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
请确保配置使用现代版本的 TLS,TLSv1.2 及更高版本,以确保服务器和客户端之间的通信安全。当 GoToSocial 处理 TLS 终端时,这会自动为你配置。如果使用反向代理,请使用 [Mozilla SSL 配置生成器](https://ssl-config.mozilla.org/)。
|
请确保配置使用现代版本的 TLS,TLSv1.2 及更高版本,以确保服务器和客户端之间的通信安全。当 GoToSocial 处理 TLS 终端时,这会自动为你配置。如果使用反向代理,请使用 [Mozilla SSL 配置生成器](https://ssl-config.mozilla.org/)。
|
||||||
|
|
||||||
## 端口
|
## 端口
|
||||||
|
|
@ -140,7 +140,7 @@ GoToSocial 需要开放端口 `80` 和 `443`。
|
||||||
|
|
||||||
如果你无法在机器上开放 `443` 和 `80` 端口,不要担心!你可以在 GoToSocial 中配置这些端口,但还需要配置端口转发,以将 `443` 和 `80` 上的流量准确转发到你选择的端口。
|
如果你无法在机器上开放 `443` 和 `80` 端口,不要担心!你可以在 GoToSocial 中配置这些端口,但还需要配置端口转发,以将 `443` 和 `80` 上的流量准确转发到你选择的端口。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
你应该在机器上配置防火墙,并配置一些防范暴力 SSH 登录尝试的保护措施。参阅我们的[防火墙文档](../advanced/security/firewall.md)以获取配置建议和可帮助你的工具。
|
你应该在机器上配置防火墙,并配置一些防范暴力 SSH 登录尝试的保护措施。参阅我们的[防火墙文档](../advanced/security/firewall.md)以获取配置建议和可帮助你的工具。
|
||||||
|
|
||||||
## 集群 / 多节点部署
|
## 集群 / 多节点部署
|
||||||
|
|
@ -167,7 +167,7 @@ GoToSocial 不支持[集群或任何形式的多节点部署](https://github.com
|
||||||
|
|
||||||
虽然可以在没有交换内存的情况下运行系统,但为了安全地做到这一点并确保一致的性能和服务可用性,你需要相应调整内核、系统和工作负载。这需要对内核的内存管理系统及你所运行的工作负载的内存使用模式有良好的理解。
|
虽然可以在没有交换内存的情况下运行系统,但为了安全地做到这一点并确保一致的性能和服务可用性,你需要相应调整内核、系统和工作负载。这需要对内核的内存管理系统及你所运行的工作负载的内存使用模式有良好的理解。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
交换内存用于确保内核可以高效地回收内存。这在系统没有经历内存争用时也很有用,比如在进程启动时仅使用过的内存腾出。这允许更多活跃使用的东西被缓存于内存中。内存交换不是让你的程序变慢的原因。内存争用才是造成缓慢的原因。
|
交换内存用于确保内核可以高效地回收内存。这在系统没有经历内存争用时也很有用,比如在进程启动时仅使用过的内存腾出。这允许更多活跃使用的东西被缓存于内存中。内存交换不是让你的程序变慢的原因。内存争用才是造成缓慢的原因。
|
||||||
|
|
||||||
[sysctl]: https://man7.org/linux/man-pages/man8/sysctl.8.html
|
[sysctl]: https://man7.org/linux/man-pages/man8/sysctl.8.html
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ nano docker-compose.yaml
|
||||||
* `snapshot`:指向当前在主分支上的代码。不保证稳定,可能经常出错。谨慎使用。
|
* `snapshot`:指向当前在主分支上的代码。不保证稳定,可能经常出错。谨慎使用。
|
||||||
* `vX.Y.Z`:发布标签。这指向 GoToSocial 的特定、稳定的版本。
|
* `vX.Y.Z`:发布标签。这指向 GoToSocial 的特定、稳定的版本。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
`latest` 和 `snapshot` 标签是动态标签,而 `vX.Y.Z` 标签是固定的。拉取动态标签的结果可能每天都会变化。同一系统上的 `latest` 可能与不同系统上的 `latest` 不同。建议使用 `vX.Y.Z` 标签,以便你始终确切知道运行的是 GoToSocial 的哪个版本。发布列表可以在[这里](https://github.com/superseriousbusiness/gotosocial/releases)找到,最新的发布在顶部。
|
`latest` 和 `snapshot` 标签是动态标签,而 `vX.Y.Z` 标签是固定的。拉取动态标签的结果可能每天都会变化。同一系统上的 `latest` 可能与不同系统上的 `latest` 不同。建议使用 `vX.Y.Z` 标签,以便你始终确切知道运行的是 GoToSocial 的哪个版本。发布列表可以在[这里](https://github.com/superseriousbusiness/gotosocial/releases)找到,最新的发布在顶部。
|
||||||
|
|
||||||
### 主机
|
### 主机
|
||||||
|
|
@ -87,7 +87,7 @@ nano docker-compose.yaml
|
||||||
如果你决定稍后设置/更改这些变量,请确保在更改后重新创建 GoToSocial 实例容器。
|
如果你决定稍后设置/更改这些变量,请确保在更改后重新创建 GoToSocial 实例容器。
|
||||||
|
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
|
|
||||||
有关将 config.yaml 文件中的变量名称转换为环境变量的帮助,请参阅[配置部分](../../configuration/index.md#environment-variables)。
|
有关将 config.yaml 文件中的变量名称转换为环境变量的帮助,请参阅[配置部分](../../configuration/index.md#environment-variables)。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ cd /gotosocial
|
||||||
|
|
||||||
现在,下载与你运行的操作系统和架构相对应的最新 GoToSocial 发行版压缩包。
|
现在,下载与你运行的操作系统和架构相对应的最新 GoToSocial 发行版压缩包。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
你可以在[这里](https://github.com/superseriousbusiness/gotosocial/releases)找到按发布时间排列的发布列表,最新的发行版位于最上面。
|
你可以在[这里](https://github.com/superseriousbusiness/gotosocial/releases)找到按发布时间排列的发布列表,最新的发行版位于最上面。
|
||||||
|
|
||||||
例如,下载适用于 64 位 Linux 的版本:
|
例如,下载适用于 64 位 Linux 的版本:
|
||||||
|
|
@ -52,7 +52,7 @@ tar -xzf gotosocial_${GTS_VERSION}_${GTS_TARGET}.tar.gz
|
||||||
|
|
||||||
这将在你的当前目录放置 `gotosocial` 二进制文件,以及包含网页前端资源的 `web` 文件夹和包含示例配置文件的 `example` 文件夹。
|
这将在你的当前目录放置 `gotosocial` 二进制文件,以及包含网页前端资源的 `web` 文件夹和包含示例配置文件的 `example` 文件夹。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
如果你想使用基于当前主分支代码的 GoToSocial 快照构建,可以从[这里](https://minio.s3.superseriousbusiness.org/browser/gotosocial-snapshots)下载最近的二进制 .tar.gz 文件(基于提交哈希)。仅在你很清楚自己的操作时使用,否则请使用稳定版。
|
如果你想使用基于当前主分支代码的 GoToSocial 快照构建,可以从[这里](https://minio.s3.superseriousbusiness.org/browser/gotosocial-snapshots)下载最近的二进制 .tar.gz 文件(基于提交哈希)。仅在你很清楚自己的操作时使用,否则请使用稳定版。
|
||||||
|
|
||||||
## 编辑配置文件
|
## 编辑配置文件
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ sudo systemctl restart gotosocial.service
|
||||||
|
|
||||||
### 使用 mod_md 启用 TLS
|
### 使用 mod_md 启用 TLS
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
`mod_md` 自 Apache 2.4.30 开始可用,仍被视为实验性的。实际上,它在实践中表现良好,是最便捷的方法。
|
`mod_md` 自 Apache 2.4.30 开始可用,仍被视为实验性的。实际上,它在实践中表现良好,是最便捷的方法。
|
||||||
|
|
||||||
现在我们将配置 Apache HTTP 服务器来处理 GoToSocial 请求。
|
现在我们将配置 Apache HTTP 服务器来处理 GoToSocial 请求。
|
||||||
|
|
@ -166,7 +166,7 @@ sudo systemctl restart apache2
|
||||||
|
|
||||||
### 使用外部管理证书启用 TLS
|
### 使用外部管理证书启用 TLS
|
||||||
|
|
||||||
!!! note
|
!!! note "注意"
|
||||||
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的额外文档,其中还提供了不同发行版的其他内容和教程链接,可能值得查看。
|
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的额外文档,其中还提供了不同发行版的其他内容和教程链接,可能值得查看。
|
||||||
|
|
||||||
如果你更喜欢手动设置或使用不同服务(如 Certbot)来管理 SSL,可以为你的 Apache HTTP 服务器使用更简单的设置。
|
如果你更喜欢手动设置或使用不同服务(如 Certbot)来管理 SSL,可以为你的 Apache HTTP 服务器使用更简单的设置。
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ GoToSocial 可以直接暴露到互联网上。不过,许多人更愿意使用
|
||||||
* 如果你使用了 Lets Encrypt,在 GoToSocial 中禁用它。将 `letsencrypt-enabled` 设置为 `false`
|
* 如果你使用了 Lets Encrypt,在 GoToSocial 中禁用它。将 `letsencrypt-enabled` 设置为 `false`
|
||||||
* 配置反向代理以处理 TLS 并将请求代理到 GoToSocial
|
* 配置反向代理以处理 TLS 并将请求代理到 GoToSocial
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
不要更改 `host` 配置选项的值。这必须保持为其他实例在互联网上看到的实际域名。相反,改变 `bind-address` 并更新 `port` 和 `trusted-proxies`。
|
不要更改 `host` 配置选项的值。这必须保持为其他实例在互联网上看到的实际域名。相反,改变 `bind-address` 并更新 `port` 和 `trusted-proxies`。
|
||||||
|
|
||||||
### 容器
|
### 容器
|
||||||
|
|
@ -41,3 +41,7 @@ GoToSocial 可以直接暴露到互联网上。不过,许多人更愿意使用
|
||||||
使用反向代理时,必须特别注意允许 WebSockets 正常工作。因为许多客户端应用程序使用 WebSockets 来流式传输你的时间线。WebSockets 不用于联合。
|
使用反向代理时,必须特别注意允许 WebSockets 正常工作。因为许多客户端应用程序使用 WebSockets 来流式传输你的时间线。WebSockets 不用于联合。
|
||||||
|
|
||||||
请确保阅读 [WebSocket](websocket.md) 文档,并相应地配置你的反向代理。
|
请确保阅读 [WebSocket](websocket.md) 文档,并相应地配置你的反向代理。
|
||||||
|
|
||||||
|
## 可信代理
|
||||||
|
|
||||||
|
使用反向代理时,可能会遇到速率限制和 `trusted-proxies` 相关的问题。如有任何问题,请查阅[可信代理](../../configuration/trusted_proxies.md)文档。
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
要使用 NGINX 作为 GoToSocial 的反向代理,你需要在服务器上安装它。如果你打算让 NGINX 处理 TLS,你还需要[配置 TLS 证书](../../advanced/certificates.md)。
|
要使用 NGINX 作为 GoToSocial 的反向代理,你需要在服务器上安装它。如果你打算让 NGINX 处理 TLS,你还需要[配置 TLS 证书](../../advanced/certificates.md)。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
通过在 `server` 块中包含 `http2 on;` 来启用 NGINX 的 HTTP/2。这样可以加快客户端的体验。请参阅 [ngx_http_v2_module 文档](https://nginx.org/en/docs/http/ngx_http_v2_module.html#example)。
|
通过在 `server` 块中包含 `http2 on;` 来启用 NGINX 的 HTTP/2。这样可以加快客户端的体验。请参阅 [ngx_http_v2_module 文档](https://nginx.org/en/docs/http/ngx_http_v2_module.html#example)。
|
||||||
|
|
||||||
NGINX 已为[多个发行版打包](https://repology.org/project/nginx/versions)。你很可能可以使用发行版的包管理器来安装它。你也可以使用 Docker Hub 上发布的[官方 NGINX 镜像](https://hub.docker.com/_/nginx)通过容器运行 NGINX。
|
NGINX 已为[多个发行版打包](https://repology.org/project/nginx/versions)。你很可能可以使用发行版的包管理器来安装它。你也可以使用 Docker Hub 上发布的[官方 NGINX 镜像](https://hub.docker.com/_/nginx)通过容器运行 NGINX。
|
||||||
|
|
@ -112,7 +112,7 @@ sudo systemctl restart nginx
|
||||||
|
|
||||||
## 设置 TLS
|
## 设置 TLS
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的附加文档,还提供了有关不同发行版的附加内容和教程链接,值得一看。
|
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的附加文档,还提供了有关不同发行版的附加内容和教程链接,值得一看。
|
||||||
|
|
||||||
你现在可以运行 certbot,它将引导你完成启用 https 的步骤。
|
你现在可以运行 certbot,它将引导你完成启用 https 的步骤。
|
||||||
|
|
@ -145,7 +145,7 @@ sudo systemctl start gotosocial
|
||||||
|
|
||||||
如果你再次打开 NGINX 配置,你会发现 Certbot 添加了一些额外的行。
|
如果你再次打开 NGINX 配置,你会发现 Certbot 添加了一些额外的行。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
根据你设置 Certbot 时选择的选项,以及使用的 NGINX 版本,可能会有所不同。
|
根据你设置 Certbot 时选择的选项,以及使用的 NGINX 版本,可能会有所不同。
|
||||||
|
|
||||||
```nginx
|
```nginx
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
例如,将用户提升为管理员后,你需要重启 GoToSocial 服务器,以便从数据库加载新值。
|
例如,将用户提升为管理员后,你需要重启 GoToSocial 服务器,以便从数据库加载新值。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
|
|
||||||
要查看其他可用的 CLI 命令,请点击[这里](../admin/cli.md)。
|
要查看其他可用的 CLI 命令,请点击[这里](../admin/cli.md)。
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ nav:
|
||||||
- "配置":
|
- "配置":
|
||||||
- "configuration/index.md"
|
- "configuration/index.md"
|
||||||
- "configuration/general.md"
|
- "configuration/general.md"
|
||||||
|
- "configuration/trusted_proxies.md"
|
||||||
- "configuration/database.md"
|
- "configuration/database.md"
|
||||||
- "configuration/web.md"
|
- "configuration/web.md"
|
||||||
- "configuration/instance.md"
|
- "configuration/instance.md"
|
||||||
|
|
@ -87,6 +88,7 @@ nav:
|
||||||
- "admin/signups.md"
|
- "admin/signups.md"
|
||||||
- "admin/federation_modes.md"
|
- "admin/federation_modes.md"
|
||||||
- "admin/domain_blocks.md"
|
- "admin/domain_blocks.md"
|
||||||
|
- "admin/domain_permission_subscriptions.md"
|
||||||
- "admin/request_filtering_modes.md"
|
- "admin/request_filtering_modes.md"
|
||||||
- "admin/robots.md"
|
- "admin/robots.md"
|
||||||
- "admin/cli.md"
|
- "admin/cli.md"
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@ Golang 的一个特点是,它所依赖的源代码管理路径与 `go.mod` 中
|
||||||
>
|
>
|
||||||
> 把你的派生分支添加为 origin:
|
> 把你的派生分支添加为 origin:
|
||||||
>
|
>
|
||||||
> `git remote add origin git@github.com/yourgithubname/gotosocial`
|
> `git remote add origin git@github.com:yourgithubname/gotosocial`
|
||||||
>
|
>
|
||||||
|
|
||||||
在第一次构建项目之前,一定要运行 `git fetch`。
|
在第一次构建项目之前,一定要运行 `git fetch`。
|
||||||
|
|
@ -488,7 +488,7 @@ GoToSocial 使用 [go-swagger](https://goswagger.io) 根据代码注释生成 Sw
|
||||||
如果你更改了任何 API 路径上的 Swagger 注释,可以通过运行以下命令在 `./docs/api/swagger.yaml` 生成一个新的 Swagger 文件:
|
如果你更改了任何 API 路径上的 Swagger 注释,可以通过运行以下命令在 `./docs/api/swagger.yaml` 生成一个新的 Swagger 文件:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
swagger generate spec --scan-models --exclude-deps -o docs/api/swagger.yaml
|
go run github.com/go-swagger/go-swagger/cmd/swagger generate spec --scan-models --exclude-deps --output docs/api/swagger.yaml
|
||||||
```
|
```
|
||||||
|
|
||||||
### CI/CD 配置
|
### CI/CD 配置
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ GoToSocial 是一个用 Golang 编写的 [ActivityPub](https://activitypub.rocks
|
||||||
|
|
||||||
要从源代码构建,请查看 [CONTRIBUTING.md](https://github.com/superseriousbusiness/gotosocial/blob/main/docs/locales/zh/repo/CONTRIBUTING.md) 文件。
|
要从源代码构建,请查看 [CONTRIBUTING.md](https://github.com/superseriousbusiness/gotosocial/blob/main/docs/locales/zh/repo/CONTRIBUTING.md) 文件。
|
||||||
|
|
||||||
这是实例首页的截图!
|
这是实例首页的截图!你也可以看一看本项目在 GoToSocial 上的官方账号: [https://gts.superseriousbusiness.org/@gotosocial](https://gts.superseriousbusiness.org/@gotosocial)。
|
||||||
|
|
||||||

|

|
||||||
<!--overview-end-->
|
<!--overview-end-->
|
||||||
|
|
@ -126,7 +126,7 @@ GoToSocial 提供公开、不列出/悄悄公开、仅粉丝和私信(最好
|
||||||
|
|
||||||
### 回复控制
|
### 回复控制
|
||||||
|
|
||||||
GoToSocial 允许你通过 [互动规则](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#default-interaction-policies) 选择谁可以回复你的贴文。你可以选择允许任何人回复贴文,仅允许朋友回复,等等。
|
GoToSocial 允许你通过 [互动规则](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#默认互动规则) 选择谁可以回复你的贴文。你可以选择允许任何人回复贴文,仅允许朋友回复,等等。
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ GoToSocial 允许你选择将个人资料暴露为 RSS 订阅源,这样人们
|
||||||
|
|
||||||
### 主题与自定义 CSS
|
### 主题与自定义 CSS
|
||||||
|
|
||||||
用户可以为他们的账户页 [选择多种有趣的主题](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#select-theme),或甚至编写自己的 [自定义 CSS](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#custom-css)。
|
用户可以为他们的账户页 [选择多种有趣的主题](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#选择主题),或甚至编写自己的 [自定义 CSS](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#自定义-CSS)。
|
||||||
|
|
||||||
管理员也可以轻松地为用户 [添加自定义主题](https://docs.gotosocial.org/zh-cn/latest/admin/themes/) 供用户选择。
|
管理员也可以轻松地为用户 [添加自定义主题](https://docs.gotosocial.org/zh-cn/latest/admin/themes/) 供用户选择。
|
||||||
|
|
||||||
|
|
@ -225,10 +225,11 @@ GoToSocial 仅需约 250-350MiB 的 RAM,并且只要求极少的 CPU 频率,
|
||||||
|
|
||||||
### 隐私+安全功能
|
### 隐私+安全功能
|
||||||
|
|
||||||
- 内置 [Let's Encrypt](https://letsencrypt.org/) 的自动使用 HTTPS 支持。
|
- 严格执行贴文隐私保护与屏蔽逻辑。
|
||||||
- 严格执行贴文可见性和屏蔽逻辑。
|
- [支持配置通过网页访问账户时的贴文的可见范围](https://docs.gotosocial.org/zh-cn/latest/user_guide/settings/#个人资料上显示的贴文可见性级别)。
|
||||||
- 导入与导出允许联合实例列表和拒绝联合实例列表。订阅社区创建的屏蔽列表(类似于用于实例间联合的广告拦截器!)(功能仍在进行中)。
|
- [导入/导出](https://docs.gotosocial.org/zh-cn/latest/admin/settings/#导入导出) 社区创建的域名允许和域名阻止列表,并[订阅](https://docs.gotosocial.org/zh-cn/latest/admin/domain_permission_subscriptions)这些列表。
|
||||||
- HTTP 签名认证:GoToSocial 在发送和接收消息时要求 [HTTP 签名](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12),以确保消息不能被篡改,身份不能被伪造。
|
- HTTP 签名认证:GoToSocial 在发送和接收消息时要求 [HTTP 签名](https://datatracker.ietf.org/doc/html/draft-cavage-http-signatures-12),以确保消息不能被篡改,身份不能被伪造。
|
||||||
|
- 内置 [Let's Encrypt](https://letsencrypt.org/) 的自动使用 HTTPS 支持。
|
||||||
|
|
||||||
### 多种联合模式
|
### 多种联合模式
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,7 @@
|
||||||
- [x] **v2 过滤规则** -- 实现过滤器 API 的第二版。
|
- [x] **v2 过滤规则** -- 实现过滤器 API 的第二版。
|
||||||
- [x] **静音账户** -- 静音账户以防止其帖文出现在主页时间线上(可选:限制时间段)。
|
- [x] **静音账户** -- 静音账户以防止其帖文出现在主页时间线上(可选:限制时间段)。
|
||||||
- [x] **无评论区的帖文** -- 设计无评论区帖文的相关逻辑,让用户创建无评论区的帖文。
|
- [x] **无评论区的帖文** -- 设计无评论区帖文的相关逻辑,让用户创建无评论区的帖文。
|
||||||
- [ ] **屏蔽/允许列表订阅** -- 允许实例管理员订阅纯文本的示例屏蔽/允许列表。(大部分工作已经完成)
|
- [x] **屏蔽/允许列表订阅** -- 允许实例管理员为其实例订阅屏蔽/允许列表。
|
||||||
- [x] **私信对话视图** -- 让用户能够轻松浏览他们参与的所有私信对话。
|
- [x] **私信对话视图** -- 让用户能够轻松浏览他们参与的所有私信对话。
|
||||||
- [ ] **Oauth 令牌管理** -- 通过设置面板创建/查看/吊销 OAuth 令牌。
|
- [ ] **Oauth 令牌管理** -- 通过设置面板创建/查看/吊销 OAuth 令牌。
|
||||||
- [ ] **贴文编辑支持** -- 编辑已创建的贴文,而无需删除并重新编辑。并正确地将编辑传播出去。
|
- [ ] **贴文编辑支持** -- 编辑已创建的贴文,而无需删除并重新编辑。并正确地将编辑传播出去。
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,10 @@ GoToSocial 支持使用 `Move` 活动进行账号迁移。
|
||||||
|
|
||||||
迁移是软件无关的,因此你可以将账号迁移到其它软件或从任何支持 `Move` 活动的软件发起迁移,无论具体的软件是什么。例如,你可以将 GoToSocial 账号迁移到 Mastodon 账号,将 Mastodon 账号迁移到 GoToSocial 账号,将 GoToSocial 账号迁移到或从 Akkoma、Misskey、GoToSocial 等。
|
迁移是软件无关的,因此你可以将账号迁移到其它软件或从任何支持 `Move` 活动的软件发起迁移,无论具体的软件是什么。例如,你可以将 GoToSocial 账号迁移到 Mastodon 账号,将 Mastodon 账号迁移到 GoToSocial 账号,将 GoToSocial 账号迁移到或从 Akkoma、Misskey、GoToSocial 等。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
根据目标账号所在软件的不同,目标账号的 URI(用于别名和迁移)应该类似于 `https://mastodon.example.org/users/account_you_are_moving_to`。如果你不确定使用哪种格式,请咨询你要迁移或设置别名的实例管理员。
|
根据目标账号所在软件的不同,目标账号的 URI(用于别名和迁移)应该类似于 `https://mastodon.example.org/users/account_you_are_moving_to`。如果你不确定使用哪种格式,请咨询你要迁移或设置别名的实例管理员。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
GoToSocial 要求 7 天的账号迁移冷却期,以防止过度切换实例(以及潜在的屏蔽规避风险)。
|
GoToSocial 要求 7 天的账号迁移冷却期,以防止过度切换实例(以及潜在的屏蔽规避风险)。
|
||||||
|
|
||||||
如果任何一个发起新迁移尝试的账号在最近七天内已迁移,GoToSocial 将拒绝进行迁移,直到上一次迁移过去七天位置。
|
如果任何一个发起新迁移尝试的账号在最近七天内已迁移,GoToSocial 将拒绝进行迁移,直到上一次迁移过去七天位置。
|
||||||
|
|
@ -71,8 +71,8 @@ GoToSocial 支持使用 `Move` 活动进行账号迁移。
|
||||||
|
|
||||||
一旦触发从其他账号到 GoToSocial 账号的迁移,你唯一需要做的就是在新(GoToSocial)账号上接受来自旧账号粉丝的关注请求。
|
一旦触发从其他账号到 GoToSocial 账号的迁移,你唯一需要做的就是在新(GoToSocial)账号上接受来自旧账号粉丝的关注请求。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
为了省去麻烦,可以考虑在触发迁移前将 GoToSocial 账号设置为不需要批准新的关注请求。迁移完成后再开启关注请求审核。否则,你将需要手动批准每个从旧账号迁移的粉丝。
|
为了省去麻烦,可以考虑在触发迁移前将 GoToSocial 账号设置为不需要批准新的关注请求。迁移完成后再开启关注请求审核。否则,你将需要手动批准每个从旧账号迁移的粉丝。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
迁移账号后,可能需要将之前账号的关注列表导入 GoToSocial 账号。[在此查看](./settings.md#import)如何通过设置面板完成此操作的详细信息。
|
迁移账号后,可能需要将之前账号的关注列表导入 GoToSocial 账号。[在此查看](./settings.md#import)如何通过设置面板完成此操作的详细信息。
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ GoToSocial 为贴文提供 Mastodon 风格的隐私设置。从最私密到最
|
||||||
|
|
||||||
### 互关可见
|
### 互关可见
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
目前暂时无法将帖文可见性设为“互关可见”。
|
目前暂时无法将帖文可见性设为“互关可见”。
|
||||||
|
|
||||||
`互关可见` 的贴文只会显示给贴文作者和与作者*互相关注*的人。换句话说,只有在满足两个条件时,其他人才能看到:
|
`互关可见` 的贴文只会显示给贴文作者和与作者*互相关注*的人。换句话说,只有在满足两个条件时,其他人才能看到:
|
||||||
|
|
@ -135,14 +135,14 @@ GoToSocial 允许你在贴文中附加媒体文件,大多数客户端会在贴
|
||||||
|
|
||||||
为了避免泄漏你的位置信息,GoToSocial 努力在上传媒体时通过清零 Exif 数据点移除 Exif 信息。
|
为了避免泄漏你的位置信息,GoToSocial 努力在上传媒体时通过清零 Exif 数据点移除 Exif 信息。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
为了方便和保护隐私,GoToSocial 在上传图片文件时会自动移除 Exif 标签。然而,**无法自动移除 mp4 视频的 Exif 数据**(参见 [#2577](https://github.com/superseriousbusiness/gotosocial/issues/2577))。
|
为了方便和保护隐私,GoToSocial 在上传图片文件时会自动移除 Exif 标签。然而,**无法自动移除 mp4 视频的 Exif 数据**(参见 [#2577](https://github.com/superseriousbusiness/gotosocial/issues/2577))。
|
||||||
|
|
||||||
在你将视频上传至 GoToSocial 之前,建议确保该视频的 Exif 数据标签已经被移除。你可以在线找到多种工具和服务来做到这一点。
|
在你将视频上传至 GoToSocial 之前,建议确保该视频的 Exif 数据标签已经被移除。你可以在线找到多种工具和服务来做到这一点。
|
||||||
|
|
||||||
为防止 Exif 位置信息在一开始被写入图片或视频中,你还可以关闭设备摄像头应用中的位置标记(通常称为地理标记)。
|
为防止 Exif 位置信息在一开始被写入图片或视频中,你还可以关闭设备摄像头应用中的位置标记(通常称为地理标记)。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
即使你在上传图片或视频之前已完全移除所有 Exif 元数据,恶意用户仍然可以通过媒体本身的内容推断出你的位置信息。
|
即使你在上传图片或视频之前已完全移除所有 Exif 元数据,恶意用户仍然可以通过媒体本身的内容推断出你的位置信息。
|
||||||
|
|
||||||
如果你属于在生产中有保密需要的组织,或正在被跟踪或监视,你可能需要考虑不要发布任何可能含有你位置线索的媒体。
|
如果你属于在生产中有保密需要的组织,或正在被跟踪或监视,你可能需要考虑不要发布任何可能含有你位置线索的媒体。
|
||||||
|
|
@ -285,6 +285,9 @@ GoToSocial 允许你在贴文中附加媒体文件,大多数客户端会在贴
|
||||||
|
|
||||||
你可以在 GoToSocial 贴文中包含任意数量的话题标签,而且每个话题标签的长度限制为 100 个字符。
|
你可以在 GoToSocial 贴文中包含任意数量的话题标签,而且每个话题标签的长度限制为 100 个字符。
|
||||||
|
|
||||||
|
!!! tip "提示"
|
||||||
|
要结束一个话题标签,你只需在话题标签名后输入空格。例如,在文本 `这道 #鸡汤 十分美味` 中,话题标签由空格终止,因此 `#鸡汤` 成为话题标签。但是,你也可以使用管道字符 `|`,或使用 Unicode 字符 `\u200B` (零宽不换行空格)或 `\uFEFF` (零宽空格),来创建“词语片段”话题标签。例如,在 `这道 #鸡|汤 十分美味` 中,只有 `#鸡` 成为话题标签。同理,对于文本 `这道 #鸡汤 十分美味` (`鸡` 和 `汤` 之间有一个零宽空格),只有 `#鸡` 成为话题标签。有关零宽空格的更多信息,参见:https://en.wikipedia.org/wiki/Zero-width_space。
|
||||||
|
|
||||||
## 输入净化
|
## 输入净化
|
||||||
|
|
||||||
为了不传播脚本、漏洞以及不稳定的 HTML,GoToSocial 执行以下类型的输入净化:
|
为了不传播脚本、漏洞以及不稳定的 HTML,GoToSocial 执行以下类型的输入净化:
|
||||||
|
|
|
||||||
|
|
@ -88,14 +88,14 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
|
||||||
|
|
||||||
此设置不会影响你的贴文在 ActivityPub 协议和客户端中的可见性,因此即便你选择不在网页版账户页显示任何贴文,只要他人是你的粉丝、你的贴文被转发到他们的时间线,或使用链接搜索你的某个贴文,他们仍然可以看到的贴文。
|
此设置不会影响你的贴文在 ActivityPub 协议和客户端中的可见性,因此即便你选择不在网页版账户页显示任何贴文,只要他人是你的粉丝、你的贴文被转发到他们的时间线,或使用链接搜索你的某个贴文,他们仍然可以看到的贴文。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
请注意,此设置的更改也会应用于之前的贴文。
|
请注意,此设置的更改也会应用于之前的贴文。
|
||||||
|
|
||||||
也就是说,如果你之前发布了一条“不列出”可见性的贴文,而当时你的网页版账户页被设置为仅显示公开贴文,此时如果你更改此设置为一并显示公开和不列出,那你之前发布的“不列出”贴文将会与公开贴文一起显示在你的网页版账户页上。
|
也就是说,如果你之前发布了一条“不列出”可见性的贴文,而当时你的网页版账户页被设置为仅显示公开贴文,此时如果你更改此设置为一并显示公开和不列出,那你之前发布的“不列出”贴文将会与公开贴文一起显示在你的网页版账户页上。
|
||||||
|
|
||||||
同样地,如果你选择不显示任何贴文,那么所有贴文将从你的网页版账户页中隐藏,无论它们是在何时创建,也无论当时此选项被设置为什么。这种情况将持续直到你再次更改此设置。
|
同样地,如果你选择不显示任何贴文,那么所有贴文将从你的网页版账户页中隐藏,无论它们是在何时创建,也无论当时此选项被设置为什么。这种情况将持续直到你再次更改此设置。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
结合(域名)屏蔽,如果有人通过公开贴文骚扰你,这是一种很好的“紧急”设置。虽然它不会阻止在 ActivityPub 客户端中可以看到你的贴文的人,但至少会防止他们无需身份验证就通过浏览器点击查看你的贴文,并通过 URL 轻松与他人分享。
|
结合(域名)屏蔽,如果有人通过公开贴文骚扰你,这是一种很好的“紧急”设置。虽然它不会阻止在 ActivityPub 客户端中可以看到你的贴文的人,但至少会防止他们无需身份验证就通过浏览器点击查看你的贴文,并通过 URL 轻松与他人分享。
|
||||||
|
|
||||||
#### 手动批准关注请求(即锁定帐户)
|
#### 手动批准关注请求(即锁定帐户)
|
||||||
|
|
@ -121,10 +121,10 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
|
||||||
|
|
||||||
将可发现性标记打开可能需要一周或更长时间才会生效,账户不会立即出现在搜索引擎结果中。
|
将可发现性标记打开可能需要一周或更长时间才会生效,账户不会立即出现在搜索引擎结果中。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
为了避免暴露给爬虫,新帐户的可发现性默认为 false。但对于希望被抓取的面向公众的帐户,将其设置为 true 是有用的。
|
为了避免暴露给爬虫,新帐户的可发现性默认为 false。但对于希望被抓取的面向公众的帐户,将其设置为 true 是有用的。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
可发现性设置是关于**账户的可发现性**,而不是贴文的可被搜索性。这与 Mastodon 实例或其他使用全文搜索的实例的贴文索引无关!
|
可发现性设置是关于**账户的可发现性**,而不是贴文的可被搜索性。这与 Mastodon 实例或其他使用全文搜索的实例的贴文索引无关!
|
||||||
|
|
||||||
#### 启用公开贴文的 RSS 源
|
#### 启用公开贴文的 RSS 源
|
||||||
|
|
@ -133,7 +133,7 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
|
||||||
|
|
||||||
此源仅包括设置为“公开”的贴文(参见 [隐私设置](./posts.md#隐私设置))。
|
此源仅包括设置为“公开”的贴文(参见 [隐私设置](./posts.md#隐私设置))。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
公开您的 RSS 源允许*任何人*匿名订阅您公开贴文的更新,绕过关注和关注请求。
|
公开您的 RSS 源允许*任何人*匿名订阅您公开贴文的更新,绕过关注和关注请求。
|
||||||
|
|
||||||
#### 隐藏你关注/被关注的人
|
#### 隐藏你关注/被关注的人
|
||||||
|
|
@ -152,7 +152,7 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
|
||||||
|
|
||||||
请参阅 [自定义 CSS](./custom_css.md) 页面,了解有关为账户编写自定义 CSS 的一些提示。
|
请参阅 [自定义 CSS](./custom_css.md) 页面,了解有关为账户编写自定义 CSS 的一些提示。
|
||||||
|
|
||||||
!!! tip
|
!!! tip "提示"
|
||||||
你在此框中添加的任何自定义 CSS 都将在*选择主题之后*应用,因此你可以选择一个喜欢的预设主题,然后进行自己的调整!
|
你在此框中添加的任何自定义 CSS 都将在*选择主题之后*应用,因此你可以选择一个喜欢的预设主题,然后进行自己的调整!
|
||||||
|
|
||||||
## 贴文
|
## 贴文
|
||||||
|
|
@ -196,7 +196,7 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
|
||||||
|
|
||||||
如果你想将所有规则重置为初始默认值,可以点击 `重置为默认值` 按钮。
|
如果你想将所有规则重置为初始默认值,可以点击 `重置为默认值` 按钮。
|
||||||
|
|
||||||
!!! danger
|
!!! danger "危险"
|
||||||
虽然 GoToSocial 尊重互动规则,但不能保证其他服务端软件也会这样做,即使你的实例禁止某些互动,其他服务器上的账户可能仍会向其粉丝发送(被禁止的)贴文回复和转发。
|
虽然 GoToSocial 尊重互动规则,但不能保证其他服务端软件也会这样做,即使你的实例禁止某些互动,其他服务器上的账户可能仍会向其粉丝发送(被禁止的)贴文回复和转发。
|
||||||
|
|
||||||
随着更多 ActivityPub 服务端推出互动规则支持,这个问题有望减少,但在此期间,GoToSocial 只能在“尽力而为”范围内进行尝试,以根据你设定的规则限制与贴文的互动。
|
随着更多 ActivityPub 服务端推出互动规则支持,这个问题有望减少,但在此期间,GoToSocial 只能在“尽力而为”范围内进行尝试,以根据你设定的规则限制与贴文的互动。
|
||||||
|
|
@ -209,14 +209,14 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
|
||||||
|
|
||||||
输入新电子邮箱地址,并点击“更改电子邮箱地址”后,必须打开新电子邮件地址的收件箱,并通过提供的链接确认地址。完成后,你的电子邮箱地址更改将被确认。
|
输入新电子邮箱地址,并点击“更改电子邮箱地址”后,必须打开新电子邮件地址的收件箱,并通过提供的链接确认地址。完成后,你的电子邮箱地址更改将被确认。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
如果你的实例使用 OIDC 作为授权/身份提供商,你可以通过设置面板更改电子邮箱地址,但只会影响 GoToSocial 用于联系你的电子邮箱地址,而不会更改用于登录账户的电子邮箱地址。要更改此项,应联系你的 OIDC 提供商。
|
如果你的实例使用 OIDC 作为授权/身份提供商,你可以通过设置面板更改电子邮箱地址,但只会影响 GoToSocial 用于联系你的电子邮箱地址,而不会更改用于登录账户的电子邮箱地址。要更改此项,应联系你的 OIDC 提供商。
|
||||||
|
|
||||||
### 更改密码
|
### 更改密码
|
||||||
|
|
||||||
你可以使用面板的更改密码部分为账户设置新密码。出于安全原因,你必须提供当前密码以验证更改。
|
你可以使用面板的更改密码部分为账户设置新密码。出于安全原因,你必须提供当前密码以验证更改。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
如果你的实例使用 OIDC 作为授权/身份提供商,你将无法通过 GoToSocial 设置面板更改密码,此时应联系你的 OIDC 提供商。
|
如果你的实例使用 OIDC 作为授权/身份提供商,你将无法通过 GoToSocial 设置面板更改密码,此时应联系你的 OIDC 提供商。
|
||||||
|
|
||||||
有关 GoToSocial 如何管理密码的更多信息,请参阅[密码管理文档](./password_management.md)。
|
有关 GoToSocial 如何管理密码的更多信息,请参阅[密码管理文档](./password_management.md)。
|
||||||
|
|
@ -249,7 +249,7 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
|
||||||
|
|
||||||
然后,使用下拉菜单选择通过 CSV 文件上传的数据类型。
|
然后,使用下拉菜单选择通过 CSV 文件上传的数据类型。
|
||||||
|
|
||||||
!!! warning
|
!!! warning "警告"
|
||||||
在选择“类型”时要小心,否则可能会意外封禁你计划关注的一堆账户,反之亦然!
|
在选择“类型”时要小心,否则可能会意外封禁你计划关注的一堆账户,反之亦然!
|
||||||
|
|
||||||
然后,选择是要**合并**新数据到 GoToSocial 账户中该类型的现有数据,还是要用 CSV 文件中包含的数据**覆盖**现有数据。
|
然后,选择是要**合并**新数据到 GoToSocial 账户中该类型的现有数据,还是要用 CSV 文件中包含的数据**覆盖**现有数据。
|
||||||
|
|
@ -264,5 +264,5 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
|
||||||
|
|
||||||
合并和覆盖操作都是幂等的,这通常意味着现有数据和 CSV 文件中的重复条目不会产生问题,如果需要重试导入,可以多次导入相同的数据。
|
合并和覆盖操作都是幂等的,这通常意味着现有数据和 CSV 文件中的重复条目不会产生问题,如果需要重试导入,可以多次导入相同的数据。
|
||||||
|
|
||||||
!!! info
|
!!! info "附注"
|
||||||
由于各种原因,通过导入不可能一定会重新创建上传的 CSV 文件中的每个条目。例如,假设你试图导入包含 `example_account` 的关注 CSV,但 `example_account` 的实例已下线,或者它们的实例封禁了你的实例,或你的实例封禁了它们的实例等。在这种情况下,将无法创建对 `example_account` 的关注。
|
由于各种原因,通过导入不可能一定会重新创建上传的 CSV 文件中的每个条目。例如,假设你试图导入包含 `example_account` 的关注 CSV,但 `example_account` 的实例已下线,或者它们的实例封禁了你的实例,或你的实例封禁了它们的实例等。在这种情况下,将无法创建对 `example_account` 的关注。
|
||||||
|
|
|
||||||
|
|
@ -32,32 +32,44 @@
|
||||||
// tokenUrl: https://example.org/oauth/token
|
// tokenUrl: https://example.org/oauth/token
|
||||||
// scopes:
|
// scopes:
|
||||||
// read: grants read access to everything
|
// read: grants read access to everything
|
||||||
// read:accounts: grants read access to accounts
|
|
||||||
// read:blocks: grant read access to blocks
|
|
||||||
// read:custom_emojis: grant read access to custom_emojis
|
|
||||||
// read:favourites: grant read access to favourites
|
|
||||||
// read:filters: grant read access to filters
|
|
||||||
// read:follows: grant read access to follows
|
|
||||||
// read:lists: grant read access to lists
|
|
||||||
// read:media: grant read access to media
|
|
||||||
// read:mutes: grant read access to mutes
|
|
||||||
// read:search: grant read access to searches
|
|
||||||
// read:statuses: grants read access to statuses
|
|
||||||
// read:streaming: grants read access to streaming api
|
|
||||||
// read:user: grants read access to user-level info
|
|
||||||
// read:notifications: grants read access to notifications
|
|
||||||
// write: grants write access to everything
|
// write: grants write access to everything
|
||||||
|
// push: grants read/write access to push
|
||||||
|
// profile: grants read access to verify_credentials
|
||||||
|
// read:accounts: grants read access to accounts
|
||||||
// write:accounts: grants write access to accounts
|
// write:accounts: grants write access to accounts
|
||||||
|
// read:blocks: grants read access to blocks
|
||||||
// write:blocks: grants write access to blocks
|
// write:blocks: grants write access to blocks
|
||||||
|
// read:bookmarks: grants read access to bookmarks
|
||||||
|
// write:bookmarks: grants write access to bookmarks
|
||||||
|
// write:conversations: grants write access to conversations
|
||||||
|
// read:favourites: grants read access to accounts
|
||||||
|
// write:favourites: grants write access to favourites
|
||||||
|
// read:filters: grants read access to filters
|
||||||
// write:filters: grants write access to filters
|
// write:filters: grants write access to filters
|
||||||
|
// read:follows: grants read access to follows
|
||||||
// write:follows: grants write access to follows
|
// write:follows: grants write access to follows
|
||||||
|
// read:lists: grants read access to lists
|
||||||
// write:lists: grants write access to lists
|
// write:lists: grants write access to lists
|
||||||
// write:media: grants write access to media
|
// write:media: grants write access to media
|
||||||
|
// read:mutes: grants read access to mutes
|
||||||
// write:mutes: grants write access to mutes
|
// write:mutes: grants write access to mutes
|
||||||
|
// read:notifications: grants read access to notifications
|
||||||
|
// write:notifications: grants write access to notifications
|
||||||
|
// write:reports: grants write access to reports
|
||||||
|
// read:search: grants read access to search
|
||||||
|
// read:statuses: grants read access to statuses
|
||||||
// write:statuses: grants write access to statuses
|
// write:statuses: grants write access to statuses
|
||||||
// write:user: grants write access to user-level info
|
|
||||||
// admin: grants admin access to everything
|
// admin: grants admin access to everything
|
||||||
// admin:accounts: grants admin access to accounts
|
// admin:read: grants admin read access to everything
|
||||||
|
// admin:write: grants admin write access to everything
|
||||||
|
// admin:read:accounts: grants admin read access to accounts
|
||||||
|
// admin:write:accounts: grants write read access to accounts
|
||||||
|
// admin:read:reports: grants admin read access to reports
|
||||||
|
// admin:write:reports: grants admin write access to reports
|
||||||
|
// admin:read:domain_allows: grants admin read access to domain_allows
|
||||||
|
// admin:write:domain_allows: grants admin write access to domain_allows
|
||||||
|
// admin:read:domain_blocks: grants admin read access to domain_blocks
|
||||||
|
// admin:write:domain_blocks: grants write read access to domain_blocks
|
||||||
// OAuth2 Application:
|
// OAuth2 Application:
|
||||||
// type: oauth2
|
// type: oauth2
|
||||||
// flow: application
|
// flow: application
|
||||||
|
|
|
||||||
|
|
@ -458,6 +458,19 @@ instance-subscriptions-process-every: "24h"
|
||||||
# Default: ""
|
# Default: ""
|
||||||
instance-stats-mode: ""
|
instance-stats-mode: ""
|
||||||
|
|
||||||
|
# Bool. This flag controls whether local accounts may backdate statuses
|
||||||
|
# using past dates with the scheduled_at param to /api/v1/statuses.
|
||||||
|
# This flag does not affect scheduling posts in the future
|
||||||
|
# (which is currently not implemented anyway),
|
||||||
|
# nor can it prevent remote accounts from backdating their own statuses.
|
||||||
|
#
|
||||||
|
# If true, all local accounts may backdate statuses.
|
||||||
|
# If false, status backdating will be disabled and an error will be returned if it's used.
|
||||||
|
#
|
||||||
|
# Options: [true, false]
|
||||||
|
# Default: true
|
||||||
|
instance-allow-backdating-statuses: true
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
##### ACCOUNTS CONFIG #####
|
##### ACCOUNTS CONFIG #####
|
||||||
###########################
|
###########################
|
||||||
|
|
@ -475,6 +488,28 @@ accounts-registration-open: false
|
||||||
# Default: true
|
# Default: true
|
||||||
accounts-reason-required: true
|
accounts-reason-required: true
|
||||||
|
|
||||||
|
# Int. Number of approved sign-ups allowed within
|
||||||
|
# 24hrs before new account registration is closed.
|
||||||
|
#
|
||||||
|
# Leaving this count at the default essentially limits
|
||||||
|
# your instance to growing by 10 accounts per day.
|
||||||
|
#
|
||||||
|
# Setting this number to 0 or less removes the limit.
|
||||||
|
#
|
||||||
|
# Default: 10
|
||||||
|
accounts-registration-daily-limit: 10
|
||||||
|
|
||||||
|
# Int. Number of new account sign-ups allowed in the pending
|
||||||
|
# approval queue before new account registration is closed.
|
||||||
|
#
|
||||||
|
# This can be used to essentially "throttle" the sign-up
|
||||||
|
# queue to prevent instance admins becoming overwhelmed.
|
||||||
|
#
|
||||||
|
# Setting this number to 0 or less removes the limit.
|
||||||
|
#
|
||||||
|
# Default: 20
|
||||||
|
accounts-registration-backlog-limit: 20
|
||||||
|
|
||||||
# Bool. Allow accounts on this instance to set custom CSS for their profile pages and statuses.
|
# Bool. Allow accounts on this instance to set custom CSS for their profile pages and statuses.
|
||||||
# Enabling this setting will allow accounts to upload custom CSS via the /user settings page,
|
# Enabling this setting will allow accounts to upload custom CSS via the /user settings page,
|
||||||
# which will then be rendered on the web view of the account's profile and statuses.
|
# which will then be rendered on the web view of the account's profile and statuses.
|
||||||
|
|
|
||||||
45
go.mod
45
go.mod
|
|
@ -1,12 +1,14 @@
|
||||||
module github.com/superseriousbusiness/gotosocial
|
module github.com/superseriousbusiness/gotosocial
|
||||||
|
|
||||||
go 1.23
|
go 1.23.0
|
||||||
|
|
||||||
|
toolchain go1.23.3
|
||||||
|
|
||||||
// Replace go-swagger with our version that fixes (ours particularly) use of Go1.23
|
// Replace go-swagger with our version that fixes (ours particularly) use of Go1.23
|
||||||
replace github.com/go-swagger/go-swagger => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix
|
replace github.com/go-swagger/go-swagger => github.com/superseriousbusiness/go-swagger v0.31.0-gts-go1.23-fix
|
||||||
|
|
||||||
// Replace modernc/sqlite with our version that fixes the concurrency INTERRUPT issue
|
// Replace modernc/sqlite with our version that fixes the concurrency INTERRUPT issue
|
||||||
replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround
|
replace modernc.org/sqlite => gitlab.com/NyaaaWhatsUpDoc/sqlite v1.35.0-concurrency-workaround
|
||||||
|
|
||||||
require (
|
require (
|
||||||
codeberg.org/gruf/go-bytes v1.0.2
|
codeberg.org/gruf/go-bytes v1.0.2
|
||||||
|
|
@ -28,7 +30,7 @@ require (
|
||||||
codeberg.org/gruf/go-structr v0.8.11
|
codeberg.org/gruf/go-structr v0.8.11
|
||||||
codeberg.org/superseriousbusiness/exif-terminator v0.9.1
|
codeberg.org/superseriousbusiness/exif-terminator v0.9.1
|
||||||
github.com/DmitriyVTitov/size v1.5.0
|
github.com/DmitriyVTitov/size v1.5.0
|
||||||
github.com/KimMachineGun/automemlimit v0.7.0
|
github.com/KimMachineGun/automemlimit v0.7.1
|
||||||
github.com/SherClockHolmes/webpush-go v1.4.0
|
github.com/SherClockHolmes/webpush-go v1.4.0
|
||||||
github.com/buckket/go-blurhash v1.1.0
|
github.com/buckket/go-blurhash v1.1.0
|
||||||
github.com/coreos/go-oidc/v3 v3.12.0
|
github.com/coreos/go-oidc/v3 v3.12.0
|
||||||
|
|
@ -38,7 +40,7 @@ require (
|
||||||
github.com/gin-gonic/gin v1.10.0
|
github.com/gin-gonic/gin v1.10.0
|
||||||
github.com/go-playground/form/v4 v4.2.1
|
github.com/go-playground/form/v4 v4.2.1
|
||||||
github.com/go-swagger/go-swagger v0.31.0
|
github.com/go-swagger/go-swagger v0.31.0
|
||||||
github.com/google/go-cmp v0.6.0
|
github.com/google/go-cmp v0.7.0
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/feeds v1.2.0
|
github.com/gorilla/feeds v1.2.0
|
||||||
github.com/gorilla/websocket v1.5.3
|
github.com/gorilla/websocket v1.5.3
|
||||||
|
|
@ -46,21 +48,22 @@ require (
|
||||||
github.com/k3a/html2text v1.2.1
|
github.com/k3a/html2text v1.2.1
|
||||||
github.com/microcosm-cc/bluemonday v1.0.27
|
github.com/microcosm-cc/bluemonday v1.0.27
|
||||||
github.com/miekg/dns v1.1.63
|
github.com/miekg/dns v1.1.63
|
||||||
github.com/minio/minio-go/v7 v7.0.84
|
github.com/minio/minio-go/v7 v7.0.85
|
||||||
github.com/mitchellh/mapstructure v1.5.0
|
github.com/mitchellh/mapstructure v1.5.0
|
||||||
github.com/ncruces/go-sqlite3 v0.22.0
|
github.com/ncruces/go-sqlite3 v0.23.0
|
||||||
github.com/oklog/ulid v1.3.1
|
github.com/oklog/ulid v1.3.1
|
||||||
github.com/prometheus/client_golang v1.20.5
|
github.com/prometheus/client_golang v1.20.5
|
||||||
github.com/rivo/uniseg v0.4.7
|
github.com/rivo/uniseg v0.4.7
|
||||||
github.com/spf13/cobra v1.8.1
|
github.com/spf13/cobra v1.9.1
|
||||||
github.com/spf13/viper v1.19.0
|
github.com/spf13/viper v1.19.0
|
||||||
github.com/stretchr/testify v1.10.0
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/superseriousbusiness/activity v1.10.0-gts
|
github.com/superseriousbusiness/activity v1.11.0-gts
|
||||||
github.com/superseriousbusiness/httpsig v1.2.0-SSB
|
github.com/superseriousbusiness/httpsig v1.2.0-SSB
|
||||||
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8
|
github.com/superseriousbusiness/oauth2/v4 v4.3.2-SSB.0.20230227143000-f4900831d6c8
|
||||||
github.com/tdewolff/minify/v2 v2.21.3
|
github.com/tdewolff/minify/v2 v2.21.3
|
||||||
github.com/technologize/otel-go-contrib v1.1.1
|
github.com/technologize/otel-go-contrib v1.1.1
|
||||||
github.com/tetratelabs/wazero v1.8.2
|
github.com/temoto/robotstxt v1.1.2
|
||||||
|
github.com/tetratelabs/wazero v1.9.0
|
||||||
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80
|
||||||
github.com/ulule/limiter/v3 v3.11.2
|
github.com/ulule/limiter/v3 v3.11.2
|
||||||
github.com/uptrace/bun v1.2.9
|
github.com/uptrace/bun v1.2.9
|
||||||
|
|
@ -78,11 +81,12 @@ require (
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.34.0
|
go.opentelemetry.io/otel/sdk/metric v1.34.0
|
||||||
go.opentelemetry.io/otel/trace v1.34.0
|
go.opentelemetry.io/otel/trace v1.34.0
|
||||||
go.uber.org/automaxprocs v1.6.0
|
go.uber.org/automaxprocs v1.6.0
|
||||||
golang.org/x/crypto v0.32.0
|
golang.org/x/crypto v0.34.0
|
||||||
golang.org/x/image v0.23.0
|
golang.org/x/image v0.24.0
|
||||||
golang.org/x/net v0.34.0
|
golang.org/x/net v0.35.0
|
||||||
golang.org/x/oauth2 v0.25.0
|
golang.org/x/oauth2 v0.26.0
|
||||||
golang.org/x/text v0.21.0
|
golang.org/x/sys v0.30.0
|
||||||
|
golang.org/x/text v0.22.0
|
||||||
gopkg.in/mcuadros/go-syslog.v2 v2.3.0
|
gopkg.in/mcuadros/go-syslog.v2 v2.3.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
modernc.org/sqlite v0.0.0-00010101000000-000000000000
|
modernc.org/sqlite v0.0.0-00010101000000-000000000000
|
||||||
|
|
@ -136,7 +140,7 @@ require (
|
||||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||||
github.com/go-playground/validator/v10 v10.24.0 // indirect
|
github.com/go-playground/validator/v10 v10.24.0 // indirect
|
||||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect
|
||||||
github.com/goccy/go-json v0.10.4 // indirect
|
github.com/goccy/go-json v0.10.5 // indirect
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
github.com/golang-jwt/jwt/v5 v5.2.1 // indirect
|
||||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d // indirect
|
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d // indirect
|
||||||
|
|
@ -191,7 +195,7 @@ require (
|
||||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||||
github.com/spf13/afero v1.11.0 // indirect
|
github.com/spf13/afero v1.11.0 // indirect
|
||||||
github.com/spf13/cast v1.6.0 // indirect
|
github.com/spf13/cast v1.6.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
github.com/subosito/gotenv v1.6.0 // indirect
|
github.com/subosito/gotenv v1.6.0 // indirect
|
||||||
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
|
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe // indirect
|
||||||
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect
|
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB // indirect
|
||||||
|
|
@ -211,8 +215,7 @@ require (
|
||||||
golang.org/x/arch v0.13.0 // indirect
|
golang.org/x/arch v0.13.0 // indirect
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||||
golang.org/x/mod v0.22.0 // indirect
|
golang.org/x/mod v0.22.0 // indirect
|
||||||
golang.org/x/sync v0.10.0 // indirect
|
golang.org/x/sync v0.11.0 // indirect
|
||||||
golang.org/x/sys v0.29.0 // indirect
|
|
||||||
golang.org/x/tools v0.28.0 // indirect
|
golang.org/x/tools v0.28.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect
|
||||||
|
|
@ -220,7 +223,7 @@ require (
|
||||||
google.golang.org/protobuf v1.36.3 // indirect
|
google.golang.org/protobuf v1.36.3 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
modernc.org/libc v1.55.3 // indirect
|
modernc.org/libc v1.61.13 // indirect
|
||||||
modernc.org/mathutil v1.6.0 // indirect
|
modernc.org/mathutil v1.7.1 // indirect
|
||||||
modernc.org/memory v1.8.0 // indirect
|
modernc.org/memory v1.8.2 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
||||||
109
go.sum
generated
109
go.sum
generated
|
|
@ -79,8 +79,8 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
|
||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||||
github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g=
|
github.com/DmitriyVTitov/size v1.5.0 h1:/PzqxYrOyOUX1BXj6J9OuVRVGe+66VL4D9FlUaW515g=
|
||||||
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
|
github.com/DmitriyVTitov/size v1.5.0/go.mod h1:le6rNI4CoLQV1b9gzp1+3d7hMAD/uu2QcJ+aYbNgiU0=
|
||||||
github.com/KimMachineGun/automemlimit v0.7.0 h1:7G06p/dMSf7G8E6oq+f2uOPuVncFyIlDI/pBWK49u88=
|
github.com/KimMachineGun/automemlimit v0.7.1 h1:QcG/0iCOLChjfUweIMC3YL5Xy9C3VBeNmCZHrZfJMBw=
|
||||||
github.com/KimMachineGun/automemlimit v0.7.0/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM=
|
github.com/KimMachineGun/automemlimit v0.7.1/go.mod h1:QZxpHaGOQoYvFhv/r4u3U0JTC2ZcOwbSr11UZF46UBM=
|
||||||
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
|
||||||
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||||
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
|
||||||
|
|
@ -125,7 +125,7 @@ github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08 h1:ox2F0PSMlrAAiAdk
|
||||||
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
|
github.com/cnf/structhash v0.0.0-20201127153200-e1b16c1ebc08/go.mod h1:pCxVEbcm3AMg7ejXyorUXi6HQCzOIBf7zEDVPtw0/U4=
|
||||||
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
|
github.com/coreos/go-oidc/v3 v3.12.0 h1:sJk+8G2qq94rDI6ehZ71Bol3oUHy63qNYmkiSjrc/Jo=
|
||||||
github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
github.com/coreos/go-oidc/v3 v3.12.0/go.mod h1:gE3LgjOgFoHi9a4ce4/tJczr0Ai2/BoDhf0r5lltWI0=
|
||||||
github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
@ -236,8 +236,8 @@ github.com/go-test/deep v1.0.8 h1:TDsG77qcSprGbC6vTN8OuXp5g+J+b5Pcguhf7Zt61VM=
|
||||||
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
github.com/go-test/deep v1.0.8/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo=
|
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo=
|
||||||
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM=
|
||||||
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
|
github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
|
||||||
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
|
|
@ -285,8 +285,9 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
||||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
|
||||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||||
|
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
|
|
@ -403,8 +404,8 @@ github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||||
github.com/minio/minio-go/v7 v7.0.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2yed0E=
|
github.com/minio/minio-go/v7 v7.0.85 h1:9psTLS/NTvC3MWoyjhjXpwcKoNbkongaCSF3PNpSuXo=
|
||||||
github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
|
github.com/minio/minio-go/v7 v7.0.85/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
|
||||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||||
|
|
@ -424,8 +425,8 @@ github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs=
|
||||||
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/ncruces/go-sqlite3 v0.22.0 h1:FkGSBhd0TY6e66k1LVhyEpA+RnG/8QkQNed5pjIk4cs=
|
github.com/ncruces/go-sqlite3 v0.23.0 h1:90j/ar8Ywu2AtsfDl5WhO9sgP/rNk76BcKGIzAHO8AQ=
|
||||||
github.com/ncruces/go-sqlite3 v0.22.0/go.mod h1:ueXOZXYZS2OFQirCU3mHneDwJm5fGKHrtccYBeGEV7M=
|
github.com/ncruces/go-sqlite3 v0.23.0/go.mod h1:gq2nriHSczOs11SqGW5+0X+SgLdkdj4K+j4F/AhQ+8g=
|
||||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||||
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
github.com/ncruces/julianday v1.0.0 h1:fH0OKwa7NWvniGQtxdJRxAgkBMolni2BjDHaWTxqt7M=
|
||||||
|
|
@ -495,10 +496,10 @@ github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNo
|
||||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
|
||||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM=
|
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
|
||||||
github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y=
|
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
|
||||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
|
@ -519,8 +520,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||||
github.com/superseriousbusiness/activity v1.10.0-gts h1:uYIHU0/jDpLxj0lA3Jg24lM8p3X/Vb3J7hn3yQJR+C8=
|
github.com/superseriousbusiness/activity v1.11.0-gts h1:JD7x8uaKHqWXC5d55KV0n1Mktng+j374v86q5RoO3Ms=
|
||||||
github.com/superseriousbusiness/activity v1.10.0-gts/go.mod h1:9l74ZCv8zw07vipNMzahq8oQZt2xPaJZ+L+gLicQntQ=
|
github.com/superseriousbusiness/activity v1.11.0-gts/go.mod h1:9l74ZCv8zw07vipNMzahq8oQZt2xPaJZ+L+gLicQntQ=
|
||||||
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe h1:ksl2oCx/Qo8sNDc3Grb8WGKBM9nkvhCm25uvlT86azE=
|
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe h1:ksl2oCx/Qo8sNDc3Grb8WGKBM9nkvhCm25uvlT86azE=
|
||||||
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe/go.mod h1:gH4P6gN1V+wmIw5o97KGaa1RgXB/tVpC2UNzijhg3E4=
|
github.com/superseriousbusiness/go-jpeg-image-structure/v2 v2.0.0-20220321154430-d89a106fdabe/go.mod h1:gH4P6gN1V+wmIw5o97KGaa1RgXB/tVpC2UNzijhg3E4=
|
||||||
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB h1:8psprYSK1KdOSH7yQ4PbJq0YYaGQY+gzdW/B0ExDb/8=
|
github.com/superseriousbusiness/go-png-image-structure/v2 v2.0.1-SSB h1:8psprYSK1KdOSH7yQ4PbJq0YYaGQY+gzdW/B0ExDb/8=
|
||||||
|
|
@ -540,8 +541,10 @@ github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739 h1:IkjBCtQOOjIn03
|
||||||
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
github.com/tdewolff/test v1.0.11-0.20240106005702-7de5f7df4739/go.mod h1:XPuWBzvdUzhCuxWO1ojpXsyzsA5bFoS3tO/Q3kFuTG8=
|
||||||
github.com/technologize/otel-go-contrib v1.1.1 h1:wZH9aSPNWZWIkEh3vfaKfMb15AJ80jJ1aVj/4GZdqIw=
|
github.com/technologize/otel-go-contrib v1.1.1 h1:wZH9aSPNWZWIkEh3vfaKfMb15AJ80jJ1aVj/4GZdqIw=
|
||||||
github.com/technologize/otel-go-contrib v1.1.1/go.mod h1:dCN/wj2WyUO8aFZFdIN+6tfJHImjTML/8r2YVYAy3So=
|
github.com/technologize/otel-go-contrib v1.1.1/go.mod h1:dCN/wj2WyUO8aFZFdIN+6tfJHImjTML/8r2YVYAy3So=
|
||||||
github.com/tetratelabs/wazero v1.8.2 h1:yIgLR/b2bN31bjxwXHD8a3d+BogigR952csSDdLYEv4=
|
github.com/temoto/robotstxt v1.1.2 h1:W2pOjSJ6SWvldyEuiFXNxz3xZ8aiWX5LbfDiOFd7Fxg=
|
||||||
github.com/tetratelabs/wazero v1.8.2/go.mod h1:yAI0XTsMBhREkM/YDAK/zNou3GoiAce1P6+rp/wQhjs=
|
github.com/temoto/robotstxt v1.1.2/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0 h1:IcZ56OuxrtaEz8UYNRHBrUa9bYeX9oVY93KspZZBf/I=
|
||||||
|
github.com/tetratelabs/wazero v1.9.0/go.mod h1:TSbcXCfFP0L2FGkRPxHphadXPjo1T6W+CseNNY7EkjM=
|
||||||
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E=
|
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274 h1:G6Z6HvJuPjG6XfNGi/feOATzeJrfgTNJY+rGrHbA04E=
|
||||||
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8=
|
github.com/tidwall/btree v0.0.0-20191029221954-400434d76274/go.mod h1:huei1BkDWJ3/sLXmO+bsCNELL+Bp2Kks9OLyQFkzvA8=
|
||||||
github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo=
|
github.com/tidwall/buntdb v1.1.2 h1:noCrqQXL9EKMtcdwJcmuVKSEjqu1ua99RHHgbLTEHRo=
|
||||||
|
|
@ -615,8 +618,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||||
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
github.com/yuin/goldmark v1.7.8 h1:iERMLn0/QJeHFhxSt3p6PeN9mGnvIKSpG9YYorDMnic=
|
||||||
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
github.com/yuin/goldmark v1.7.8/go.mod h1:uzxRWxtg69N339t3louHJ7+O03ezfj6PlliRlaOzY1E=
|
||||||
gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround h1:BLmmUkkZ2KiS8k2lePZRQo7Z5puFrfxuFq9BrJQmS9o=
|
gitlab.com/NyaaaWhatsUpDoc/sqlite v1.35.0-concurrency-workaround h1:rSPHdoNXzXyWQUUeMEy8pdOFn8lH7XqdBRTS9G+jdTg=
|
||||||
gitlab.com/NyaaaWhatsUpDoc/sqlite v1.34.5-concurrency-workaround/go.mod h1:YLuNmX9NKs8wRNK2ko1LW1NGYcc9FkBO69JOt1AR9JE=
|
gitlab.com/NyaaaWhatsUpDoc/sqlite v1.35.0-concurrency-workaround/go.mod h1:9cr2sicr7jIaWTBKQmAxQLfBv9LL0su4ZTEV+utt3ic=
|
||||||
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80=
|
||||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
|
|
@ -665,8 +668,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
|
||||||
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
|
||||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||||
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk=
|
||||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
golang.org/x/crypto v0.34.0 h1:+/C6tk6rf/+t5DhUketUbD1aNGqiSX3j15Z6xuIDlBA=
|
||||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
golang.org/x/crypto v0.34.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ=
|
||||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||||
|
|
@ -681,8 +684,8 @@ golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUF
|
||||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||||
golang.org/x/image v0.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
|
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
|
||||||
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
|
golang.org/x/image v0.24.0/go.mod h1:4b/ITuLfqYq1hqZcjofwctIhi7sZh2WaCjvsBNjjya8=
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
|
|
@ -745,16 +748,16 @@ golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||||
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
|
||||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||||
golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0=
|
golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8=
|
||||||
golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k=
|
golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk=
|
||||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70=
|
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
|
||||||
golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
|
@ -768,8 +771,9 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
|
||||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
|
||||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
|
golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w=
|
||||||
|
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
|
|
@ -814,8 +818,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
|
|
@ -826,8 +830,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
|
||||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||||
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM=
|
||||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
|
||||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
|
||||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
@ -840,8 +844,9 @@ golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||||
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
|
||||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
|
||||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||||
|
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
|
||||||
|
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
|
||||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||||
|
|
@ -1006,26 +1011,26 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
|
||||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
|
||||||
modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ=
|
modernc.org/cc/v4 v4.24.4 h1:TFkx1s6dCkQpd6dKurBNmpo+G8Zl4Sq/ztJ+2+DEsh0=
|
||||||
modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ=
|
modernc.org/cc/v4 v4.24.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
|
||||||
modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y=
|
modernc.org/ccgo/v4 v4.23.16 h1:Z2N+kk38b7SfySC1ZkpGLN2vthNJP1+ZzGZIlH7uBxo=
|
||||||
modernc.org/ccgo/v4 v4.19.2/go.mod h1:ysS3mxiMV38XGRTTcgo0DQTeTmAO4oCmJl1nX9VFI3s=
|
modernc.org/ccgo/v4 v4.23.16/go.mod h1:nNma8goMTY7aQZQNTyN9AIoJfxav4nvTnvKThAeMDdo=
|
||||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||||
modernc.org/gc/v2 v2.4.1 h1:9cNzOqPyMJBvrUipmynX0ZohMhcxPtMccYgGOJdOiBw=
|
modernc.org/gc/v2 v2.6.3 h1:aJVhcqAte49LF+mGveZ5KPlsp4tdGdAOT4sipJXADjw=
|
||||||
modernc.org/gc/v2 v2.4.1/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
modernc.org/gc/v2 v2.6.3/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
|
||||||
modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U=
|
modernc.org/libc v1.61.13 h1:3LRd6ZO1ezsFiX1y+bHd1ipyEHIJKvuprv0sLTBwLW8=
|
||||||
modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w=
|
modernc.org/libc v1.61.13/go.mod h1:8F/uJWL/3nNil0Lgt1Dpz+GgkApWh04N3el3hxJcA6E=
|
||||||
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
|
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||||
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
|
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
modernc.org/memory v1.8.2 h1:cL9L4bcoAObu4NkxOlKWBWtNHIsnnACGF/TbqQ6sbcI=
|
||||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
modernc.org/memory v1.8.2/go.mod h1:ZbjSvMO5NQ1A2i3bWeDiVMxIorXwdClKE/0SZ+BMotU=
|
||||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
|
||||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
|
||||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
|
||||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
|
||||||
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
|
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||||
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
|
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||||
mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
|
mvdan.cc/xurls/v2 v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,11 @@ const (
|
||||||
// Not in the AS spec, just used internally to indicate
|
// Not in the AS spec, just used internally to indicate
|
||||||
// that we don't *yet* know what type of Object something is.
|
// that we don't *yet* know what type of Object something is.
|
||||||
ObjectUnknown = "Unknown"
|
ObjectUnknown = "Unknown"
|
||||||
|
|
||||||
|
// Extensions and unofficial additions.
|
||||||
|
ObjectLikeApproval = "LikeApproval"
|
||||||
|
ObjectReplyApproval = "ReplyApproval"
|
||||||
|
ObjectAnnounceApproval = "AnnounceApproval"
|
||||||
)
|
)
|
||||||
|
|
||||||
// isActivity returns whether AS type name is of an Activity (NOT IntransitiveActivity).
|
// isActivity returns whether AS type name is of an Activity (NOT IntransitiveActivity).
|
||||||
|
|
|
||||||
|
|
@ -128,16 +128,13 @@ func ToPollOptionable(t vocab.Type) (PollOptionable, bool) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAccept returns whether AS vocab type name
|
// IsAccept returns whether AS vocab type name
|
||||||
// is something that can be cast to Accept.
|
// is something that can be cast to Acceptable.
|
||||||
func IsAcceptable(typeName string) bool {
|
func IsAcceptable(typeName string) bool {
|
||||||
return typeName == ActivityAccept
|
return typeName == ActivityAccept
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToAcceptable safely tries to cast vocab.Type as vocab.ActivityStreamsAccept.
|
// ToAcceptable safely tries to cast vocab.Type as Acceptable.
|
||||||
//
|
func ToAcceptable(t vocab.Type) (Acceptable, bool) {
|
||||||
// TODO: Add additional "Accept" types here, eg., "ApproveReply" from
|
|
||||||
// https://codeberg.org/fediverse/fep/src/branch/main/fep/5624/fep-5624.md
|
|
||||||
func ToAcceptable(t vocab.Type) (vocab.ActivityStreamsAccept, bool) {
|
|
||||||
acceptable, ok := t.(vocab.ActivityStreamsAccept)
|
acceptable, ok := t.(vocab.ActivityStreamsAccept)
|
||||||
if !ok || !IsAcceptable(t.GetTypeName()) {
|
if !ok || !IsAcceptable(t.GetTypeName()) {
|
||||||
return nil, false
|
return nil, false
|
||||||
|
|
@ -145,6 +142,28 @@ func ToAcceptable(t vocab.Type) (vocab.ActivityStreamsAccept, bool) {
|
||||||
return acceptable, true
|
return acceptable, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsApprovable returns whether AS vocab type name
|
||||||
|
// is something that can be cast to Approvable.
|
||||||
|
func IsApprovable(typeName string) bool {
|
||||||
|
switch typeName {
|
||||||
|
case ObjectLikeApproval,
|
||||||
|
ObjectReplyApproval,
|
||||||
|
ObjectAnnounceApproval:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToAcceptable safely tries to cast vocab.Type as Approvable.
|
||||||
|
func ToApprovable(t vocab.Type) (Approvable, bool) {
|
||||||
|
approvable, ok := t.(Approvable)
|
||||||
|
if !ok || !IsApprovable(t.GetTypeName()) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return approvable, true
|
||||||
|
}
|
||||||
|
|
||||||
// Activityable represents the minimum activitypub interface for representing an 'activity'.
|
// Activityable represents the minimum activitypub interface for representing an 'activity'.
|
||||||
// (see: IsActivityable() for types implementing this, though you MUST make sure to check
|
// (see: IsActivityable() for types implementing this, though you MUST make sure to check
|
||||||
// the typeName as this bare interface may be implementable by non-Activityable types).
|
// the typeName as this bare interface may be implementable by non-Activityable types).
|
||||||
|
|
@ -247,6 +266,19 @@ type PollOptionable interface {
|
||||||
// interface for representing an Accept.
|
// interface for representing an Accept.
|
||||||
type Acceptable interface {
|
type Acceptable interface {
|
||||||
Activityable
|
Activityable
|
||||||
|
|
||||||
|
WithTarget
|
||||||
|
WithResult
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approvable represents the minimum activitypub interface
|
||||||
|
// for a LikeApproval, ReplyApproval, or AnnounceApproval.
|
||||||
|
type Approvable interface {
|
||||||
|
vocab.Type
|
||||||
|
|
||||||
|
WithAttributedTo
|
||||||
|
WithObject
|
||||||
|
WithTarget
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attachmentable represents the minimum activitypub interface for representing a 'mediaAttachment'. (see: IsAttachmentable).
|
// Attachmentable represents the minimum activitypub interface for representing a 'mediaAttachment'. (see: IsAttachmentable).
|
||||||
|
|
@ -708,3 +740,9 @@ type WithApprovedBy interface {
|
||||||
GetGoToSocialApprovedBy() vocab.GoToSocialApprovedByProperty
|
GetGoToSocialApprovedBy() vocab.GoToSocialApprovedByProperty
|
||||||
SetGoToSocialApprovedBy(vocab.GoToSocialApprovedByProperty)
|
SetGoToSocialApprovedBy(vocab.GoToSocialApprovedByProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithVotersCount represents an activity or object the result property.
|
||||||
|
type WithResult interface {
|
||||||
|
GetActivityStreamsResult() vocab.ActivityStreamsResultProperty
|
||||||
|
SetActivityStreamsResult(vocab.ActivityStreamsResultProperty)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -198,48 +198,12 @@ func ResolveCollectionPage(ctx context.Context, body io.ReadCloser) (CollectionP
|
||||||
return ToCollectionPageIterator(t)
|
return ToCollectionPageIterator(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResolveAcceptable tries to resolve the given reader
|
|
||||||
// into an ActivityStreams Acceptable representation.
|
|
||||||
func ResolveAcceptable(
|
|
||||||
ctx context.Context,
|
|
||||||
body io.ReadCloser,
|
|
||||||
) (Acceptable, error) {
|
|
||||||
// Get "raw" map
|
|
||||||
// destination.
|
|
||||||
raw := getMap()
|
|
||||||
// Release.
|
|
||||||
defer putMap(raw)
|
|
||||||
|
|
||||||
// Decode data as JSON into 'raw' map
|
|
||||||
// and get the resolved AS vocab.Type.
|
|
||||||
// (this handles close of given body).
|
|
||||||
t, err := decodeType(ctx, body, raw)
|
|
||||||
if err != nil {
|
|
||||||
return nil, gtserror.SetWrongType(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Attempt to cast as acceptable.
|
|
||||||
acceptable, ok := ToAcceptable(t)
|
|
||||||
if !ok {
|
|
||||||
err := gtserror.Newf("cannot resolve vocab type %T as acceptable", t)
|
|
||||||
return nil, gtserror.SetWrongType(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return acceptable, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// emptydest is an empty JSON decode
|
// emptydest is an empty JSON decode
|
||||||
// destination useful for "noop" decodes
|
// destination useful for "noop" decodes
|
||||||
// to check underlying reader is empty.
|
// to check underlying reader is empty.
|
||||||
var emptydest = &struct{}{}
|
var emptydest = &struct{}{}
|
||||||
|
|
||||||
// decodeType tries to read and parse the data
|
// decodeType is the package-internal version of DecodeType.
|
||||||
// at provided io.ReadCloser as a JSON ActivityPub
|
|
||||||
// type, failing if not parseable as JSON or not
|
|
||||||
// resolveable as one of our known AS types.
|
|
||||||
//
|
|
||||||
// NOTE: this function handles closing
|
|
||||||
// given body when it is finished with.
|
|
||||||
//
|
//
|
||||||
// The given map pointer will also be populated with
|
// The given map pointer will also be populated with
|
||||||
// the 'raw' JSON data, for further processing.
|
// the 'raw' JSON data, for further processing.
|
||||||
|
|
@ -284,3 +248,23 @@ func decodeType(
|
||||||
|
|
||||||
return t, nil
|
return t, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DecodeType tries to read and parse the data
|
||||||
|
// at provided io.ReadCloser as a JSON ActivityPub
|
||||||
|
// type, failing if not parseable as JSON or not
|
||||||
|
// resolveable as one of our known AS types.
|
||||||
|
//
|
||||||
|
// NOTE: this function handles closing
|
||||||
|
// given body when it is finished with.
|
||||||
|
func DecodeType(
|
||||||
|
ctx context.Context,
|
||||||
|
body io.ReadCloser,
|
||||||
|
) (vocab.Type, error) {
|
||||||
|
// Get "raw" map
|
||||||
|
// destination.
|
||||||
|
raw := getMap()
|
||||||
|
// Release.
|
||||||
|
defer putMap(raw)
|
||||||
|
|
||||||
|
return decodeType(ctx, body, raw)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,12 +145,18 @@ func (m *Module) CallbackGETHandler(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Since we require lowercase usernames at this point, lowercase the one
|
||||||
|
// from the claims and use this to autofill the form with a suggestion.
|
||||||
|
//
|
||||||
|
// Pending https://github.com/superseriousbusiness/gotosocial/issues/1813
|
||||||
|
suggestedUsername := strings.ToLower(claims.PreferredUsername)
|
||||||
|
|
||||||
page := apiutil.WebPage{
|
page := apiutil.WebPage{
|
||||||
Template: "finalize.tmpl",
|
Template: "finalize.tmpl",
|
||||||
Instance: instance,
|
Instance: instance,
|
||||||
Extra: map[string]any{
|
Extra: map[string]any{
|
||||||
"name": claims.Name,
|
"name": claims.Name,
|
||||||
"preferredUsername": claims.PreferredUsername,
|
"suggestedUsername": suggestedUsername,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountAliasPOSTHandler swagger:operation POST /api/v1/accounts/alias accountAlias
|
// AccountAliasPOSTHandler swagger:operation POST /api/v1/accounts/alias accountAlias
|
||||||
|
|
@ -77,9 +76,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountAliasPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountAliasPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/validate"
|
"github.com/superseriousbusiness/gotosocial/internal/validate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -74,9 +73,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountCreatePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountCreatePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, false, false)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, false,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -66,9 +65,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountDeletePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountDeletePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -80,7 +82,7 @@ func (m *Module) AccountDeletePOSTHandler(c *gin.Context) {
|
||||||
|
|
||||||
// Self account delete requires password to ensure it's for real.
|
// Self account delete requires password to ensure it's for real.
|
||||||
if form.Password == "" {
|
if form.Password == "" {
|
||||||
err = errors.New("no password provided in account delete request")
|
err := errors.New("no password provided in account delete request")
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountGETHandler swagger:operation GET /api/v1/accounts/{id} accountGet
|
// AccountGETHandler swagger:operation GET /api/v1/accounts/{id} accountGet
|
||||||
|
|
@ -66,9 +65,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountGETHandler(c *gin.Context) {
|
func (m *Module) AccountGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountMovePOSTHandler swagger:operation POST /api/v1/accounts/move accountMove
|
// AccountMovePOSTHandler swagger:operation POST /api/v1/accounts/move accountMove
|
||||||
|
|
@ -74,9 +73,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountMovePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountMovePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountUpdateCredentialsPATCHHandler swagger:operation PATCH /api/v1/accounts/update_credentials accountUpdate
|
// AccountUpdateCredentialsPATCHHandler swagger:operation PATCH /api/v1/accounts/update_credentials accountUpdate
|
||||||
|
|
@ -236,9 +235,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountUpdateCredentialsPATCHHandler(c *gin.Context) {
|
func (m *Module) AccountUpdateCredentialsPATCHHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountVerifyGETHandler swagger:operation GET /api/v1/accounts/verify_credentials accountVerify
|
// AccountVerifyGETHandler swagger:operation GET /api/v1/accounts/verify_credentials accountVerify
|
||||||
|
|
@ -56,9 +55,13 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountVerifyGETHandler(c *gin.Context) {
|
func (m *Module) AccountVerifyGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeProfile,
|
||||||
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountBlockPOSTHandler swagger:operation POST /api/v1/accounts/{id}/block accountBlock
|
// AccountBlockPOSTHandler swagger:operation POST /api/v1/accounts/{id}/block accountBlock
|
||||||
|
|
@ -66,9 +65,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountBlockPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountBlockPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteBlocks,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountFeaturedTagsGETHandler swagger:operation GET /api/v1/accounts/{id}/featured_tags accountsFeaturedTags
|
// AccountFeaturedTagsGETHandler swagger:operation GET /api/v1/accounts/{id}/featured_tags accountsFeaturedTags
|
||||||
|
|
@ -68,9 +67,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountFeaturedTagsGETHandler(c *gin.Context) {
|
func (m *Module) AccountFeaturedTagsGETHandler(c *gin.Context) {
|
||||||
_, err := oauth.Authed(c, true, true, true, true)
|
_, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountFollowPOSTHandler swagger:operation POST /api/v1/accounts/{id}/follow accountFollow
|
// AccountFollowPOSTHandler swagger:operation POST /api/v1/accounts/{id}/follow accountFollow
|
||||||
|
|
@ -91,9 +90,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountFollowPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountFollowPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteFollows,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -119,9 +118,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountFollowersGETHandler(c *gin.Context) {
|
func (m *Module) AccountFollowersGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -119,9 +118,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountFollowingGETHandler(c *gin.Context) {
|
func (m *Module) AccountFollowingGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountListsGETHandler swagger:operation GET /api/v1/accounts/{id}/lists accountLists
|
// AccountListsGETHandler swagger:operation GET /api/v1/accounts/{id}/lists accountLists
|
||||||
|
|
@ -69,9 +68,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountListsGETHandler(c *gin.Context) {
|
func (m *Module) AccountListsGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadLists,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountLookupGETHandler swagger:operation GET /api/v1/accounts/lookup accountLookupGet
|
// AccountLookupGETHandler swagger:operation GET /api/v1/accounts/lookup accountLookupGet
|
||||||
|
|
@ -66,9 +65,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountLookupGETHandler(c *gin.Context) {
|
func (m *Module) AccountLookupGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/util"
|
"github.com/superseriousbusiness/gotosocial/internal/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -86,9 +85,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountMutePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountMutePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteMutes,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountNotePOSTHandler swagger:operation POST /api/v1/accounts/{id}/note accountNote
|
// AccountNotePOSTHandler swagger:operation POST /api/v1/accounts/{id}/note accountNote
|
||||||
|
|
@ -75,9 +74,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountNotePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountNotePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountAvatarDELETEHandler swagger:operation DELETE /api/v1/profile/avatar accountAvatarDelete
|
// AccountAvatarDELETEHandler swagger:operation DELETE /api/v1/profile/avatar accountAvatarDelete
|
||||||
|
|
@ -102,9 +101,12 @@ func (m *Module) AccountHeaderDELETEHandler(c *gin.Context) {
|
||||||
// accountDeleteProfileAttachment checks that an authenticated account is present and allowed to alter itself,
|
// accountDeleteProfileAttachment checks that an authenticated account is present and allowed to alter itself,
|
||||||
// runs an attachment deletion processor method, and returns the updated account.
|
// runs an attachment deletion processor method, and returns the updated account.
|
||||||
func (m *Module) accountDeleteProfileAttachment(c *gin.Context, processDelete func(context.Context, *gtsmodel.Account) (*apimodel.Account, gtserror.WithCode)) {
|
func (m *Module) accountDeleteProfileAttachment(c *gin.Context, processDelete func(context.Context, *gtsmodel.Account) (*apimodel.Account, gtserror.WithCode)) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountRelationshipsGETHandler swagger:operation GET /api/v1/accounts/relationships accountRelationships
|
// AccountRelationshipsGETHandler swagger:operation GET /api/v1/accounts/relationships accountRelationships
|
||||||
|
|
@ -73,9 +72,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountRelationshipsGETHandler(c *gin.Context) {
|
func (m *Module) AccountRelationshipsGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -89,7 +91,7 @@ func (m *Module) AccountRelationshipsGETHandler(c *gin.Context) {
|
||||||
// check fallback -- let's be generous and see if maybe it's just set as 'id'?
|
// check fallback -- let's be generous and see if maybe it's just set as 'id'?
|
||||||
id := c.Query("id")
|
id := c.Query("id")
|
||||||
if id == "" {
|
if id == "" {
|
||||||
err = errors.New("no account id(s) specified in query")
|
err := errors.New("no account id(s) specified in query")
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ErrorHandler(c, gtserror.NewErrorBadRequest(err, err.Error()), m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountSearchGETHandler swagger:operation GET /api/v1/accounts/search accountSearchGet
|
// AccountSearchGETHandler swagger:operation GET /api/v1/accounts/search accountSearchGet
|
||||||
|
|
@ -107,9 +106,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountSearchGETHandler(c *gin.Context) {
|
func (m *Module) AccountSearchGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountStatusesGETHandler swagger:operation GET /api/v1/accounts/{id}/statuses accountStatuses
|
// AccountStatusesGETHandler swagger:operation GET /api/v1/accounts/{id}/statuses accountStatuses
|
||||||
|
|
@ -109,7 +108,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - read:accounts
|
// - read:statuses
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -134,9 +133,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountStatusesGETHandler(c *gin.Context) {
|
func (m *Module) AccountStatusesGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadStatuses,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountThemesGETHandler swagger:operation GET /api/v1/accounts/themes accountThemes
|
// AccountThemesGETHandler swagger:operation GET /api/v1/accounts/themes accountThemes
|
||||||
|
|
@ -60,9 +59,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountThemesGETHandler(c *gin.Context) {
|
func (m *Module) AccountThemesGETHandler(c *gin.Context) {
|
||||||
_, err := oauth.Authed(c, true, true, true, true)
|
_, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountUnblockPOSTHandler swagger:operation POST /api/v1/accounts/{id}/unblock accountUnblock
|
// AccountUnblockPOSTHandler swagger:operation POST /api/v1/accounts/{id}/unblock accountUnblock
|
||||||
|
|
@ -67,9 +66,9 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountUnblockPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountUnblockPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c, true, true, true, true)
|
||||||
if err != nil {
|
if errWithCode != nil {
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountUnfollowPOSTHandler swagger:operation POST /api/v1/accounts/{id}/unfollow accountUnfollow
|
// AccountUnfollowPOSTHandler swagger:operation POST /api/v1/accounts/{id}/unfollow accountUnfollow
|
||||||
|
|
@ -67,9 +66,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountUnfollowPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountUnfollowPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteFollows,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountUnmutePOSTHandler swagger:operation POST /api/v1/accounts/{id}/unmute accountUnmute
|
// AccountUnmutePOSTHandler swagger:operation POST /api/v1/accounts/{id}/unmute accountUnmute
|
||||||
|
|
@ -69,9 +68,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountUnmutePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountUnmutePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeWriteMutes,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountActionPOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/action adminAccountAction
|
// AccountActionPOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/action adminAccountAction
|
||||||
|
|
@ -64,7 +63,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -87,9 +86,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountActionPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountActionPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountApprovePOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/approve adminAccountApprove
|
// AccountApprovePOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/approve adminAccountApprove
|
||||||
|
|
@ -48,7 +47,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -68,9 +67,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountApprovePOSTHandler(c *gin.Context) {
|
func (m *Module) AccountApprovePOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountGETHandler swagger:operation GET /api/v1/admin/accounts/{id} adminAccountGet
|
// AccountGETHandler swagger:operation GET /api/v1/admin/accounts/{id} adminAccountGet
|
||||||
|
|
@ -48,7 +47,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -68,9 +67,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountGETHandler(c *gin.Context) {
|
func (m *Module) AccountGETHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,6 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// AccountRejectPOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/reject adminAccountReject
|
// AccountRejectPOSTHandler swagger:operation POST /api/v1/admin/accounts/{id}/reject adminAccountReject
|
||||||
|
|
@ -70,7 +69,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -90,9 +89,12 @@ import (
|
||||||
// '500':
|
// '500':
|
||||||
// description: internal server error
|
// description: internal server error
|
||||||
func (m *Module) AccountRejectPOSTHandler(c *gin.Context) {
|
func (m *Module) AccountRejectPOSTHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminWriteAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -148,7 +148,7 @@
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -182,14 +182,16 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Module) AccountsGETV1Handler(c *gin.Context) {
|
func (m *Module) AccountsGETV1Handler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -121,7 +121,7 @@
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:accounts
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -155,14 +155,16 @@ import (
|
||||||
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
"github.com/superseriousbusiness/gotosocial/internal/paging"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Module) AccountsGETV2Handler(c *gin.Context) {
|
func (m *Module) AccountsGETV2Handler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminReadAccounts,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
@ -89,7 +89,7 @@ func (m *Module) DebugAPUrlHandler(c *gin.Context) {}
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -27,13 +27,15 @@ import (
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
"github.com/superseriousbusiness/gotosocial/internal/gtserror"
|
||||||
"github.com/superseriousbusiness/gotosocial/internal/oauth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Module) DebugAPUrlHandler(c *gin.Context) {
|
func (m *Module) DebugAPUrlHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminWrite,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -58,9 +60,12 @@ func (m *Module) DebugAPUrlHandler(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Module) DebugClearCachesHandler(c *gin.Context) {
|
func (m *Module) DebugClearCachesHandler(c *gin.Context) {
|
||||||
authed, err := oauth.Authed(c, true, true, true, true)
|
authed, errWithCode := apiutil.TokenAuth(c,
|
||||||
if err != nil {
|
true, true, true, true,
|
||||||
apiutil.ErrorHandler(c, gtserror.NewErrorUnauthorized(err, err.Error()), m.processor.InstanceGetV1)
|
apiutil.ScopeAdminWrite,
|
||||||
|
)
|
||||||
|
if errWithCode != nil {
|
||||||
|
apiutil.ErrorHandler(c, errWithCode, m.processor.InstanceGetV1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:domain_allows
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:domain_allows
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:domain_allows
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:domain_allows
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -93,7 +93,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:domain_blocks
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:write:domain_blocks
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ import (
|
||||||
//
|
//
|
||||||
// security:
|
// security:
|
||||||
// - OAuth2 Bearer:
|
// - OAuth2 Bearer:
|
||||||
// - admin
|
// - admin:read:domain_blocks
|
||||||
//
|
//
|
||||||
// responses:
|
// responses:
|
||||||
// '200':
|
// '200':
|
||||||
|
|
|
||||||
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