Merge branch 'main' into feat/check-robots-for-derefinstance

This commit is contained in:
tobi 2025-02-11 09:45:11 +01:00
commit cd6e6c80db
136 changed files with 2863 additions and 339 deletions

View file

@ -149,7 +149,7 @@ In case this post disappears, here are the steps (slightly modified):
>
> Add your fork as origin:
>
> `git remote add origin git@github.com/yourgithubname/gotosocial`
> `git remote add origin git@github.com:yourgithubname/gotosocial`
>
Be sure to run `git fetch` before building the project for the first time.
@ -489,7 +489,7 @@ You can install go-swagger following the instructions [here](https://goswagger.i
If you change Swagger annotations on any of the API paths, you can generate a new Swagger file at `./docs/api/swagger.yaml` by running:
```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 configuration

View file

@ -30,6 +30,7 @@ import (
"github.com/gin-gonic/gin"
"github.com/superseriousbusiness/gotosocial/cmd/gotosocial/action"
"github.com/superseriousbusiness/gotosocial/internal/admin"
"github.com/superseriousbusiness/gotosocial/internal/api"
apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
"github.com/superseriousbusiness/gotosocial/internal/cleaner"
@ -133,6 +134,10 @@ var Start action.GTSAction = func(ctx context.Context) error {
// Initialize caches and database
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
// that twice, we can just start the initialized caches.
state.Caches.Start()

View file

@ -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.
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.

View file

@ -46,12 +46,14 @@ If you **reject** the sign-up, you may wish to inform the applicant that their s
## 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.
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.
## Sign-Up Via Invite

View file

@ -300,6 +300,10 @@ definitions:
format: int64
type: integer
x-go-name: FollowingCount
group:
description: Account identifies as a Group actor.
type: boolean
x-go-name: Group
header:
description: Web location of the account's header image.
example: https://example.org/media/some_user/header/original/header.jpeg
@ -2439,6 +2443,10 @@ definitions:
format: int64
type: integer
x-go-name: FollowingCount
group:
description: Account identifies as a Group actor.
type: boolean
x-go-name: Group
header:
description: Web location of the account's header image.
example: https://example.org/media/some_user/header/original/header.jpeg

View file

@ -20,6 +20,28 @@ accounts-registration-open: false
# Default: 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.
# 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.

View file

@ -79,7 +79,7 @@ For example:
"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.

View file

@ -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)。
#### Borgmatic
[Borgmatic](https://torsion.org/borgmatic/) 是一个帮助使用 [Borg](https://www.borgbackup.org/) 进行备份的工具。它通过使用 YAML 的声明性配置文件驱动。BorgBase、Rsync.net 和 Hetzner 都支持 Borg。
!!! warning
!!! warning "警告"
初始化 Borg 仓库时确保使用强加密密钥进行设置并将密钥安全地存放在某处。否则将无法在将来解密备份。ArchWiki 上关于 Borgmatic 的条目解释了如何安全地将你的加密密钥传递给 Borgmatic而不在配置文件中以明文形式存储它。
如何使用 Borgmatic 备份数据库有其[单独的文档页面](https://torsion.org/borgmatic/docs/how-to/backup-your-databases/),你应当在备份前查看一下。对于使用 SQLite 的 GoToSocialBorgmatic 的简单 `config.yaml` 如下:
@ -182,11 +182,11 @@ hooks:
您需要将该文件放在您的 GoToSocial 实例上,并确保该文件是可执行的。它需要 Python 3安装 Borg 和 Borgmatic 后您应该已经具备。它仅依赖于 Python 标准库。
!!! note
!!! note "注意"
为了确保可靠运行,您应确保 GoToSocial 配置中的 [storage-local-base-path](../configuration/storage.md) 使用的是绝对路径。否则您将需要自己调整路径。
```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 \
<storage-local-base-path>
```
@ -199,7 +199,7 @@ R <storage-local-base-path>
- <storage-local-base-path>/*
```
!!! tip
!!! tip "提示"
你可以通过向 `media-to-borg-patterns.py` 传递 `--help` 来查看帮助。通过将文件位置作为脚本的最后一个参数,也可以将输出直接写入文件。
给定这组模式Borg 将从 `<storage-local-base-path>` 开始寻找文件。任何匹配路径前缀 `pp:` 的都会被包括进去。其他的则会匹配最后一个模式,从存档中排除。
@ -211,7 +211,7 @@ R <storage-local-base-path>
```ini
[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
```
建议查看的文档:

View file

@ -27,13 +27,13 @@ GoToSocial - 一个联邦制社交媒体服务器
`可用命令` 下,可以看到标准的 `server` 命令。但是也有处理管理和调试的命令,这些将在本文档中进行解释。
!!! Info "将全局配置传递给 CLI"
!!! info "将全局配置传递给 CLI"
对于所有这些命令,你仍然需要正确设置全局选项,以便 CLI 工具知道如何连接到你的数据库,以及使用哪个数据库、哪个主机和账户域等。
你可以使用环境变量设置这些选项,通过 CLI 标志传递它们(例如,`gotosocial [commands] --host example.org`),或者只需将 CLI 工具指向你的配置文件(例如,`gotosocial --config-path ./config.yaml [commands]`)。
!!! Info
!!! info "附注"
运行 CLI 命令时,你将会看到如下输出:
@ -45,7 +45,7 @@ GoToSocial - 一个联邦制社交媒体服务器
这是正常的,表示命令已按预期运行。
!!! Warning "运行管理命令后重启 GtS"
!!! warning "运行管理命令后重启 GtS"
由于 GoToSocial 的内部缓存机制,你可能需要在运行某些命令后重启 GoToSocial以使命令的效果“生效”。我们仍在寻找一种无需重启的方法。在此期间需要在运行命令后重启的命令将在下文中突出显示。
@ -86,7 +86,7 @@ gotosocial admin account create \
此命令可用于确认你的实例上的用户+账户,允许他们登录并使用账户。
!!! Info
!!! info "附注"
如果账户是使用 `admin account create` 创建的,则不必在账户上运行 `confirm`,它将已被确认。
@ -113,7 +113,7 @@ gotosocial admin account confirm --username some_username --config-path config.y
此命令可用于将用户提升为管理员。
!!! Warning "需要重启服务器"
!!! warning "需要重启服务器"
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
@ -140,7 +140,7 @@ gotosocial admin account promote --username some_username --config-path config.y
此命令可用于将用户从管理员降级为普通用户。
!!! Warning "需要重启服务器"
!!! warning "需要重启服务器"
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
@ -167,7 +167,7 @@ gotosocial admin account demote --username some_username --config-path config.ya
此命令可用于在你的实例上禁用一个账户:禁止其登录或执行任何操作,但不删除数据。
!!! Warning "需要重启服务器"
!!! warning "需要重启服务器"
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
@ -194,7 +194,7 @@ gotosocial admin account disable --username some_username --config-path config.y
此命令可用于重新启用你实例上的账户,撤销之前的 `disable` 命令。
!!! Warning "需要重启服务器"
!!! warning "需要重启服务器"
为使更改生效,此命令需要在运行命令后重启 GoToSocial。
@ -221,7 +221,7 @@ gotosocial admin account enable --username some_username --config-path config.ya
此命令可用于为指定的本站账户设置新密码。
!!! Warning "需要重启服务器"
!!! warning "需要重启服务器"
为使更改生效,此命令需要在运行命令后重启 GoToSocial。

View file

@ -2,11 +2,11 @@
无论你选择使用 SQLite 还是 Postgres 来运行 GoToSocial可能都需要偶尔执行一些维护工作以保持数据库的良好运作。
!!! tip
!!! tip "提示"
尽管此处提供的维护建议旨在不破坏现有数据,你还是应该在手动执行维护操作之前备份数据库。这样,如果输入错误或意外运行了不当命令,可以恢复备份并重试。
!!! danger
!!! danger "危险"
**强烈不建议**手动创建、删除或更新 GoToSocial 数据库中的条目,这里不会提供相关命令。即使你认为自己知道在做什么,运行 `DELETE` 等语句可能会引入非常难以排查的问题。以下维护建议旨在帮助你的实例平稳运行;如果你手动进入数据库并对条目、表和索引进行修改,它们不会拯救你的数据。

View file

@ -2,7 +2,7 @@
GoToSocial 支持屏蔽/封禁那些你不想与你的实例联合的域名。在我们的文档中,“屏蔽”和“封禁”这两个术语在涉及域名时可以互换使用,因为它们的意思相同:屏蔽你的实例与目标域名上的实例相互通信,有效地切断两个实例之间的联合。
你可以使用[实例管理面板](./settings.md#联合)查看、创建和移除域名屏蔽和域名允许。
你可以使用[实例管理面板](./settings.md#域名权限)查看、创建和移除域名屏蔽和域名允许。
本文档重点说明域名屏蔽实际*作用*是什么,以及创建新域名屏蔽时会产生哪些副作用。
@ -54,7 +54,7 @@ GoToSocial 支持屏蔽/封禁那些你不想与你的实例联合的域名。
3. 删除封禁帐户的所有贴文。
4. 删除封禁帐户及其贴文的所有媒体,包括媒体附件、头像、头图和表情符号。
!!! danger
!!! danger "危险"
目前,上述大多数副作用是**不可逆**的。如果你在屏蔽后取消屏蔽一个域名,该域名上的所有帐户将不再被标记为已封禁,并且你将能够再次与他们互动,但所有关系仍将被清除,所有贴文和媒体将被删除。
在屏蔽一个域名之前请仔细考虑。

View 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
```

View file

@ -10,12 +10,12 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,如果该资源的域未通过域屏蔽条目被屏蔽,它将会去获取该资源。
!!! info
!!! info "附注"
黑名单联合模式是 GoToSocial 的默认联合模式。它也是大多数其他 ActivityPub 服务器实现的默认联合模式。
## 白名单联合模式
!!! warning
!!! warning "警告"
白名单联合模式仍然被认为是“实验性”的,我们正在研究其在实际中的表现。它应该如其名称所示,但可能会在其他地方导致错误或出现边缘情况,我们还不确定!
`instance-federation-mode` 设置为 `allowlist` 时,你的实例将仅与通过设置面板明确设为允许的实例联合,并限制任何未被允许的实例的访问。
@ -24,7 +24,7 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
当你的实例遇到它以前未见过的贴文或账户的提及或公告时,它只会在资源所属域名被明确允许时才去获取资源。
!!! tip
!!! tip "提示"
白名单联合模式在你希望仅与选择的“可信”实例联合的情况下非常有用。然而,这会影响发现过程。在黑名单联合模式下,你会通过转发和回复自然地遇到未知实例的贴文和账户,但在白名单联合模式下,这样的偶然发现不会发生。
因此,建议你要么先从黑名单联合模式开始,然后在确定喜欢哪些其他实例后切换到白名单联合模式,要么从白名单联合模式开始,并在首次启动实例后准备好并导入白名单,以便“启动”它。
@ -54,7 +54,7 @@ GoToSocial 当前提供“黑名单”和“白名单”联合模式,可以通
如果上述任何条件不满足,请求将被拒绝。
!!! danger
!!! danger "危险"
结合屏蔽和允许是一项棘手的工作!
在导入允许和黑名单时,你应该始终手动审核列表,以确保不会无意中屏蔽你不想屏蔽的实例,因为这可能会有**非常烦人的副作用**,例如移除关注/被关注、贴文等。

View file

@ -47,11 +47,11 @@ GoToSocial 提供了三个变量,让你(管理员)可以调节何时以及
上述设置意味着从午夜开始每8小时GoToSocial 将清除任何缓存超过1天24小时的媒体。清理任务将在 00:00、08:00 和 16:00即午夜、上午8点和下午4点运行。使用此配置你可能将外站媒体在存储中保留的最长时间约为32小时。
!!! tip
!!! tip "提示"
`media-remote-cache-days` 设置为0或更小意味着外站媒体将永不被清除。然而本站孤立媒体的清理任务和其他一致性检查仍将按其他变量定义的计划运行。
!!! tip
!!! tip "提示"
如果你愿意,你也可以通过管理面板手动执行一次性清理操作([查看文档](./settings.md#媒体))。
!!! warning
!!! warning "警告"
`media-cleanup-every` 设置为非常小的值,如 `"30m"` 或更小,可能会导致你的实例不断遍历附件,导致数据使用率高而效益甚微。我们不建议将该值设置为小于约 `"8h"`,即便如此,可能也显得过度。

View file

@ -2,7 +2,7 @@
GoToSocial 当前提供“屏蔽”、“允许”和禁用的 HTTP 请求头过滤模式,可以通过在 config.yaml 中设置 `advanced-header-filter-mode`,或使用环境变量 `GTS_ADVANCED_HEADER_FILTER_MODE` 来配置。这些模式的具体说明如下。
!!! warning
!!! warning "警告"
HTTP 请求头过滤是一个进阶设置。如果你不熟悉 HTTP 请求头的使用和复杂性,修改这些设置可能会导致联合功能中断,甚至无法访问你自己的实例。
HTTP 请求头过滤仍被视为“实验性”功能。它应该能如预期工作,但可能会导致其他地方出现错误或边缘情况,这点我们尚不确定!
@ -27,5 +27,5 @@ GoToSocial 当前提供“屏蔽”、“允许”和禁用的 HTTP 请求头过
在允许模式下,请求只有在被明确允许且未被明确屏蔽的情况下才会被接受。
!!! danger
!!! danger "危险"
允许过滤模式是一个极为严格的模式,几乎肯定会阻止许多(合法的)客户端访问你的实例,包括你自己。只有在完全明确你的目标时才应启用此模式。

View file

@ -2,6 +2,10 @@
GoToSocial 在主域名上提供一个 `robots.txt` 文件。该文件包含试图屏蔽已知 AI 爬虫的一些规则,以及其他一些索引器。它还包括一些规则,以确保诸如 API 端点之类的内容不会被搜索引擎索引,因为这些内容没有被索引的必要。
## 允许/禁止统计数据收集
你可以通过修改配置 `instance-stats-mode` 来允许或禁止爬虫从 `/nodeinfo/2.0``/nodeinfo/2.1` 端点收集你的实例的统计数据,此设置会修改 `robots.txt` 文件。更多详情请参见 [实例配置](../configuration/instance.md)。
## AI 爬虫
AI 爬虫来自一个[社区维护的仓库][airobots]。目前是手动保持同步的。如果你知道有任何遗漏的爬虫,请给他们提交一个 PR

View file

@ -34,11 +34,11 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
你可以使用此部分搜索账户并对其执行管理操作。
### 联合
### 域名权限
![已封禁实例列表,有一个字段用于过滤/添加新的屏蔽。下面是批量导入/导出界面的链接](../public/admin-settings-federation.png)
联合部分,你可以创建、删除和审核明确的域名屏蔽和域名允许
域名权限部分,你可以创建、删除和查看域名阻止条目、域名允许条目、草稿、排除项和订阅
关于联合设置的更多详细信息,特别是域名允许和域名屏蔽如何结合使用,请参阅 [联合模式部分](./federation_modes.md) 和 [域名屏蔽部分](./domain_blocks.md)。
@ -46,20 +46,99 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
你可以在搜索字段中输入一个要封禁的域名,这将过滤列表以显示你是否已有该域名的屏蔽条目。
点击“封禁”会显示一个表单,允许你添加公开和/或私人评论,并提交以添加屏蔽。添加封禁后,该实例上的所有已知账户将被封禁,并阻止与该被屏蔽实例上的任何用户的新互动。
点击“封禁”会显示一个表单,允许你添加公开和/或私人评论,并提交以添加屏蔽。
添加封禁后,该实例上的所有已知账户将被封禁,并阻止与该被屏蔽实例上的任何用户的新互动。
#### 域名允许
域名允许部分的工作方式与域名屏蔽部分类似,只是用于明确的域名允许而不是域名屏蔽。
#### 批量导入/导出
#### 导入/导出
通过联合部分底部的链接(或访问 `/settings/admin/federation/import-export`),你可以批量导入/导出屏蔽列表和允许列表
你可以在这一部分批量导入/导出JSON、CSV或纯文本格式的域名权限条目
![导入中包含的域列表,提供选择某些或全部域的方法,更改其域,以及更新子域使用方法。](../public/admin-settings-federation-import-export.png)
通过输入字段或文件导入列表后,你可以在导入子集之前查看列表中的条目。你还会在使用子域的条目中收到警告,此处还提供一种轻松将其更改为主域的方法。
#### 草稿
在这一部分,你可以创建、搜索、接受和拒绝域名权限草稿。
域名权限草稿是已被提议,但尚未生效的域域名权限条目(可以手动创建或从已订阅的阻止/允许列表中添加)。
在接受前,域名权限草稿将对目标域名的联合没有任何影响。一旦被接受,它将被转换为域名阻止条目或域名允许条目,并开始执行。
#### 例外
在这一部分,您可以创建、搜索和移除域名权限例外条目。
域名权限例外可以防止某域名(及其所有子域)的权限被域名权限订阅自动管理。
例如,如果你为域名 `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)文档。
##### 将此条目设为草稿
勾选此复选框后(该复选框默认勾选),通过此订阅创建的任何权限条目将以**草稿**类型创建,需要手动批准才能生效。
建议保留此复选框为已勾选状态,除非您完全信任订阅列表,以避免无意中阻止或允许您不想阻止或允许的域。
##### 测试订阅
要测试订阅是否可以被成功解析,首先创建订阅,然后在该订阅的详情视图中,点击“测试”按钮。
如果您的实例能够获取并解析订阅地址处的权限列表,则在点击“测试”后您将看到这些权限的列表。否则,您将看到一条错误信息。
![订阅详情视图的截图,箭头指向靠近底部的测试部分。](../public/admin-settings-federation-subscription-test.png)
## 管理
实例管理设置。
@ -167,3 +246,11 @@ GoToSocial 管理设置面板使用 [管理 API](https://docs.gotosocial.org/zh-
选择的 **联系人用户** 必须是实例上的活跃(未封禁)的管理员和/或站务。
如果你是在单用户实例上并将管理员权限授予你的主账户,你只需在此处填写自己的用户名即可;无需为此专门创建管理账户。
### 实例自定义 CSS
自定义 CSS 允许您进一步调整通过浏览器访问的实例时的外观。
这些自定义 CSS 将应用于实例的所有页面。但用户主题和 CSS 仍优先于此处的自定义设置。
有关为您的实例编写自定义 CSS 的一些技巧,请参阅[自定义 CSS](../user_guide/custom_css.md)页面。

View file

@ -4,7 +4,7 @@
注意,作为实例管理员,无论你是否愿意,你都需对在你的实例上发布的内容负责。如果你的实例用户在联合网上骚扰或烦扰他人,可能会导致你的实例名誉受损,并被其他人屏蔽。妥善管理一个社区需要付出努力。因此,你应仔细考虑是否愿意且有能力进行管理,及是否只接受朋友和你非常信任的人注册账户。
!!! warning
!!! warning "警告"
为使注册流程正常运作,你的实例应[配置电子邮件发件服务](../configuration/smtp.md)。
如下所述,在注册流程中,会向你(作为管理员/站务)和申请人发送几封邮件,包括要求对方确认邮箱地址的邮件。
@ -41,7 +41,7 @@
如果你**拒绝**注册,可以选择通知申请人注册被拒,你可以通过勾选“发送邮件”复选框来实现。这将向申请人发送一封简短邮件,告知其被拒。如果需要,还可以添加自定义消息,该消息将添加在邮件底部。你还可以添加仅供其他管理员查看的私人备注。
!!! warning
!!! warning "警告"
你可能希望等申请人确认他们的电子邮件地址后再批准注册,以防申请时输入错误或提供不是他们的电子邮件地址。如果他们不能确认电子邮件地址,将无法登录和使用账户。
## 注册限制

View file

@ -6,12 +6,12 @@
被认为是骚扰信息的消息将不会存储在你的本站实例上,也不会生成通知。
!!! warning
!!! warning "警告"
骚扰信息过滤器必然是不完美的工具,因为它们可能会误判一些合法的信息为垃圾,或者确实未能抓住一些*确实*是垃圾的信息。
启用 `instance-federation-spam-filter` 应被视为当联合网络遭遇骚扰信息攻击时的一种“加固”选项。在正常情况下,你可能希望将其关闭,以避免意外过滤掉合法信息。
!!! tip
!!! tip "提示"
如果你想检查骚扰信息过滤器捕获了哪些内容(如果有的话),可以在日志中搜索 `looked like spam`
如果你[将 GoToSocial 作为 systemd 服务运行](../getting_started/installation/metal.md#optional-enable-the-systemd-service),可以使用以下命令:

View file

@ -2,7 +2,7 @@
本节涵盖了多种缓存技术,这些技术可以提高 GoToSocial 在高流量情况下的稳定性,并减轻 GoToSocial 实例的一部分工作负担。
!!! note
!!! note "注意"
这些指南仅在你运行[反向代理](../../getting_started/reverse_proxy/index.md)时才有意义。
## 指南

View file

@ -66,7 +66,7 @@ tls-certificate-key: "/path/to/private.key"
这将禁用通过 Lets Encrypt 内置的证书配置,并指示 GoToSocial 在磁盘上找到证书。
!!! tip
!!! tip "提示"
在续订证书后应重启 GoToSocial。它在这种情况下不会自动监测证书的更换。
### 使用反向代理
@ -93,7 +93,7 @@ tls-certificate-key: ""
* [Traefik](https://doc.traefik.io/traefik/https/tls/)
* [Caddy](https://caddyserver.com/docs/caddyfile/directives/tls)
!!! tip
!!! tip "提示"
在你的反向代理中配置 TLS 时,请确保你配置了一组较现代的兼容版本和加密套件。可以使用 [Mozilla SSL Configuration Generator](https://ssl-config.mozilla.org/) 的“中级”配置。
检查你的反向代理文档,以了解在证书更改后是否需要重新加载或重启它。并非所有的反向代理都会自动检测到这一点。

View file

@ -23,12 +23,12 @@ healthcheck:
上述健康检查将在 30 秒后开始,每两分钟检查一次服务是否可用,通过对 `/readyz` 进行 HEAD 请求。如果检查连续失败五次,服务将被标记为不健康。你可以在使用的编排系统中利用此功能强制重启容器。
!!! warning
!!! warning "警告"
在慢速硬件上进行数据库迁移时,迁移可能会超过上述健康检查所允许的 10 分钟。
在这样的系统上,你可能需要增加健康检查的间隔或重试次数,以确保不会在迁移中途停止 GoToSocial这会很糟糕
!!! tip
!!! tip "提示"
尽管健康检查端点不透露任何敏感信息,并且只运行非常简单的查询,你可能希望避免将它们暴露给外部世界。你可以在 nginx 中通过在 `server` 段中添加以下代码片段来实现:
```nginx

View file

@ -2,7 +2,7 @@
本指南解释了如何使用 `@me@example.org` 这样的用户名,但将 GoToSocial 实例本身运行在例如 `social.example.org` 这样的子域名的方法。这种部署布局的配置**必须**在第一次启动 GoToSocial 前完成。
!!! danger
!!! danger "警告"
一旦与他人联合后就无法更改域名布局。服务器会因此产生混淆,而你需要说服每个与你联合的实例管理员修改其数据库来解决问题。同时,你还需要在本地重新生成数据库,创建一个新的实例账户和加密密钥对。
## 背景
@ -49,7 +49,7 @@ host: social.example.org
account-domain: example.org
```
!!! info
!!! info "附注"
`host` 必须始终是运行 GoToSocial 实例的 DNS 名称。它不影响 GoToSocial 实例绑定的 IP 地址。该地址由 `bind-address` 控制。
## 反向代理
@ -62,7 +62,7 @@ account-domain: example.org
* `/.well-known/host-meta`
* `/.well-known/nodeinfo`
!!! tip
!!! tip "提示"
不要将 API 端点 `/api/...` 的请求从账户域代理或重定向到主机域。这会混淆某些客户端用来检测分域部署的启发式方法,导致登录流程中断及其他异常行为。
### nginx

View file

@ -2,7 +2,7 @@
这些指南涵盖如何提高你的 GoToSocial 部署的安全状况。它们不涉及调整 GoToSocial 的设置,而是指出一些你可以做的额外措施,以更好地保护你的实例。
!!! note
!!! note "注意"
这些指南中的任何内容旨在增强你的 GoToSocial 部署的安全性;它们不能替代良好的安全实践,比如保持你的系统定期得到修补和更新。
## 指南

View file

@ -2,7 +2,7 @@
SQLite 的运行模式假定数据库和使用它的进程或应用程序位于同一主机上。在运行 WAL 模式GoToSocial 的默认模式)时,它依赖于进程之间的共享内存来确保数据库完整性。
!!! quote
!!! quote "参考"
所有使用数据库的进程必须在同一台主机计算机上WAL 不能在网络文件系统上工作。这是因为 WAL 需要所有进程共享少量内存,而在不同主机上的进程显然不能相互共享内存。
— SQLite.org [写前日志](https://www.sqlite.org/wal.html)

View file

@ -25,7 +25,7 @@ curl \
- `write`
- `admin`
!!! warning
!!! warning "警告"
GoToSocial 目前不支持范围授权令牌,因此在此过程中获得的任何令牌都可以代表你执行所有操作,包括如果你的账户具有管理员权限时的管理员操作。然而,始终以最低权限授予你的应用是一个好习惯。例如,如果你的应用不会发布贴文,请使用 scope=read。
本着这种精神,上述示例使用了`read`,这意味着当未来支持范围令牌时,应用将仅限于执行`read`操作。
@ -44,7 +44,7 @@ curl \
}
```
!!! tip
!!! tip "提示"
确保将 `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
```
!!! tip
!!! tip "提示"
如果你在注册应用时使用了不同的范围,在上面的 URL 中将 `scope=read` 替换为你注册时使用的加号分隔的范围列表。例如,如果你注册你的应用时使用了 `scopes``read write`,那么你应该将上面的 `scope=read` 改为 `scope=read+write`
将 URL 粘贴到浏览器后,你会被引导到实例的登录表单,提示你输入邮箱地址和密码以将应用连接到你的账户。

View file

@ -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 正确分开。
如果你正在使用 HTTP 代理,那么很可能你的 `trusted-proxies` 未正确配置。如果是这种情况,尝试将反向代理的 IP 地址添加到 `trusted-proxies` 列表中,并重启你的实例
如果你使用了 HTTP 代理,那么你的 `trusted-proxies` 配置可能不正确。详情请参阅 [可信代理](../configuration/trusted_proxies.md) 文档以了解如何解决此问题
如果没有使用 HTTP 代理,那么很可能是由 NAT 引起的。在这种情况下,你应该完全禁用速率限制。

View file

@ -6,7 +6,7 @@ GoToSocial 使用 [go-swagger](https://github.com/go-swagger/go-swagger) 从代
大多数 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/)。
!!! info "注意事项:上传文件"

File diff suppressed because it is too large Load diff

View file

@ -1,8 +1,6 @@
# 基础配置
GoToSocial 的基础配置,包括域名、端口、绑定地址和传输协议等基本内容。
这里*真正*需要设置的只有 `host`,也就是你实例可以访问的域名,可能还需要设置 `port`
GoToSocial 的顶级配置,包括域名、端口、绑定地址和可信代理等基本信息。
## 设置

View file

@ -112,4 +112,47 @@ instance-deliver-to-shared-inboxes: true
# 选项: [true, false]
# 默认值: 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: ""
```

View file

@ -10,7 +10,7 @@ GoToSocial 支持 [OpenID Connect](https://openid.net/connect/),这是一种
- 你希望将用户、账户、密码等的管理委托给外部服务,以简化管理。
- 你已经在外部系统中有很多用户,不想在 GoToSocial 中手动重新创建他们。
!!! tip
!!! tip "提示"
如果用户尚不存在,且你的 IdP 没有返回非空的 `email` 作为 claims 的一部分,登录将会失败。这个 email 需要在此实例中是唯一的。尽管我们使用 `sub` claim 将外部身份与 GtS 用户关联,但创建用户时需要一个与之关联的 email。
## 设置

View 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` 后问题依然无法解决。
另一个例子是:你在家庭网络上运行 GoToSocialGoToSocial 连接到家庭网络的路由器,并且你从同样在你家庭网络设备(比如笔记本或手机)上访问 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"
################################
# 其他配置内容 #
################################
```
完成必要的配置更改后,**重启你的实例**并刷新主页。

View file

@ -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),为行为体实现了收件箱。

View file

@ -47,6 +47,58 @@ GoToSocial 外发话题标签提供的 `href` URL 指向一个提供 `text/html`
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`
@ -160,14 +212,14 @@ GoToSocial 在解析传入的 `Object` 时使用 `content` 和 `contentMap` 属
如果 `contentMap` 有多个条目,则无法确定贴文的意图内容和语言,因为映射顺序不可预测。在这种情况下,尝试从 GoToSocial 实例的[配置语言](../configuration/instance.md)中选择与其中一种语言匹配的语言和内容条目。如果无法通过这种方式匹配语言,则从 `contentMap` 中随机选择一个语言和内容条目作为“主要”语言和内容。
!!! Note
!!! note "注意"
在上述所有情况下,如果推断的语言无法解析为有效的 BCP47 语言话题标签,则语言将回退为未知。
## 互动规则
GoToSocial 使用 `interactionPolicy` 属性告知外站给定帖文允许的互动类型(有前提)。
!!! danger
!!! danger "危险"
互动规则旨在限制用户贴文上用户不希望的回复和其他互动的有害影响(例如,“回复家(reply guys)” —— 不请自来地发表冒失回复的人)。
@ -229,7 +281,7 @@ GoToSocial 使用 `interactionPolicy` 属性告知外站给定帖文允许的互
### 指定无人能进行的操作
!!! note
!!! note "注意"
即使规则指定无人可互动GoToSocial 仍做出默认假设。参见[默认假设](#默认假设)。
空数组或缺少/空的键表示无人能进行此互动。

View file

@ -2,7 +2,7 @@
在部署 GoToSocial 之前,有几个关键点需要你仔细考虑,因为这些选择将影响你如何运行和管理 GoToSocial。
!!! danger
!!! danger "危险"
在同一域名上切换不同实现是不被 Fediverse 支持的。这意味着如果你在 example.org 上运行 GoToSocial而尝试切换到其他实现如 Pleroma/Akkoma、Misskey/Calckey 等,你会遇到联合问题。
@ -24,7 +24,7 @@ GoToSocial 致力于为在小型设备上运行的使用场景优化,因此我
你应该在这种情况下预留一些余量,若有需要,可以[配置一些交换内存](#交换内存)。
!!! tip
!!! tip "提示"
在内存受限的环境中,你可以将 `cache.memory-target` 设置为低于默认的 100MB (查看数据库配置选项[这里](../configuration/database.md#settings))。设置为 50MB 已被证明可以正常运行。
这将使总内存使用稍微降低,但代价是某些请求的延迟略高,因为 GtS 需要更频繁地访问数据库。
@ -46,7 +46,7 @@ GoToSocial 使用存储来保存其数据库文件,以及存储和服务媒体
对于媒体存储,以及[缓存的外站媒体文件存储](../admin/media_caching.md),你应该预算大约 5GB-10GB 的空间。GoToSocial 会自动执行自我清理,在一段时间后从缓存中删除未使用的外站媒体。如果存储空间是个问题,你可以[调整媒体清理行为](../admin/media_caching.md#清理)以更频繁地清理和/或减少外站媒体的缓存时间。
!!! info
!!! info "附注"
如果你的 sqlite.db 文件或 Postgres 容量在一开始增长很快,请不要惊慌,这是正常的。当你首次部署实例并开始联合时,你的实例会迅速发现并存储来自其他实例的账号和贴文。然而,随着实例的长期部署,这种增长会逐渐减缓,因为你会自然而然地看到更少的新账号(即,你的实例尚未见过并因此尚未在数据库中存储的账号)。
### 单板计算机
@ -106,7 +106,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
无论你选择哪种数据库驱动,为了获得良好的性能,它们都应在快速、稳定的低延迟存储上运行。虽然可以在网络附加存储上运行数据库,但这会增加可变延迟和网络拥堵,还有源存储上的潜在 I/O 争用。
!!! tip
!!! tip "提示"
请[备份你的数据库](../admin/backup_and_restore.md)。数据库包含实例和任何用户账户的加密密钥。如果丢失这些密钥,你将无法再次从同一域进行联合!
## 域名
@ -119,7 +119,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
如果你打算这样部署 GoToSocial 实例,请阅读[分域部署](../advanced/host-account-domain.md)文档以了解详细信息。
!!! danger
!!! danger "危险"
无法在联合已经事实发生后安全地更改实例域名和账号域名。这需要重新生成数据库,并在任何已联合的服务器造成混乱情况。一旦你的实例域名和账号域名设置好,便不可更改。
## TLS
@ -128,7 +128,7 @@ SQLite 是默认的驱动,并已被证明在 1-30 用户范围内的实例表
GoToSocial 内置 Lets Encrypt 证书配置支持。它也可以从磁盘加载证书。如果你有连接到 GoToSocial 的反向代理,可以在代理层处理 TLS。
!!! tip
!!! tip "提示"
请确保配置使用现代版本的 TLSTLSv1.2 及更高版本,以确保服务器和客户端之间的通信安全。当 GoToSocial 处理 TLS 终端时,这会自动为你配置。如果使用反向代理,请使用 [Mozilla SSL 配置生成器](https://ssl-config.mozilla.org/)。
## 端口
@ -140,7 +140,7 @@ GoToSocial 需要开放端口 `80` 和 `443`。
如果你无法在机器上开放 `443``80` 端口,不要担心!你可以在 GoToSocial 中配置这些端口,但还需要配置端口转发,以将 `443``80` 上的流量准确转发到你选择的端口。
!!! tip
!!! tip "提示"
你应该在机器上配置防火墙,并配置一些防范暴力 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

View file

@ -44,7 +44,7 @@ nano docker-compose.yaml
* `snapshot`:指向当前在主分支上的代码。不保证稳定,可能经常出错。谨慎使用。
* `vX.Y.Z`:发布标签。这指向 GoToSocial 的特定、稳定的版本。
!!! tip
!!! tip "提示"
`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 实例容器。
!!! tip
!!! tip "提示"
有关将 config.yaml 文件中的变量名称转换为环境变量的帮助,请参阅[配置部分](../../configuration/index.md#environment-variables)。

View file

@ -33,7 +33,7 @@ cd /gotosocial
现在,下载与你运行的操作系统和架构相对应的最新 GoToSocial 发行版压缩包。
!!! tip
!!! tip "提示"
你可以在[这里](https://github.com/superseriousbusiness/gotosocial/releases)找到按发布时间排列的发布列表,最新的发行版位于最上面。
例如,下载适用于 64 位 Linux 的版本:
@ -52,7 +52,7 @@ tar -xzf gotosocial_${GTS_VERSION}_${GTS_TARGET}.tar.gz
这将在你的当前目录放置 `gotosocial` 二进制文件,以及包含网页前端资源的 `web` 文件夹和包含示例配置文件的 `example` 文件夹。
!!! danger
!!! danger "危险"
如果你想使用基于当前主分支代码的 GoToSocial 快照构建,可以从[这里](https://minio.s3.superseriousbusiness.org/browser/gotosocial-snapshots)下载最近的二进制 .tar.gz 文件(基于提交哈希)。仅在你很清楚自己的操作时使用,否则请使用稳定版。
## 编辑配置文件

View file

@ -48,7 +48,7 @@ sudo systemctl restart gotosocial.service
### 使用 mod_md 启用 TLS
!!! note
!!! note "注意"
`mod_md` 自 Apache 2.4.30 开始可用,仍被视为实验性的。实际上,它在实践中表现良好,是最便捷的方法。
现在我们将配置 Apache HTTP 服务器来处理 GoToSocial 请求。
@ -166,7 +166,7 @@ sudo systemctl restart apache2
### 使用外部管理证书启用 TLS
!!! note
!!! note "注意"
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的额外文档,其中还提供了不同发行版的其他内容和教程链接,可能值得查看。
如果你更喜欢手动设置或使用不同服务(如 Certbot来管理 SSL可以为你的 Apache HTTP 服务器使用更简单的设置。

View file

@ -11,7 +11,7 @@ GoToSocial 可以直接暴露到互联网上。不过,许多人更愿意使用
* 如果你使用了 Lets Encrypt在 GoToSocial 中禁用它。将 `letsencrypt-enabled` 设置为 `false`
* 配置反向代理以处理 TLS 并将请求代理到 GoToSocial
!!! warning
!!! warning "警告"
不要更改 `host` 配置选项的值。这必须保持为其他实例在互联网上看到的实际域名。相反,改变 `bind-address` 并更新 `port``trusted-proxies`
### 容器
@ -41,3 +41,7 @@ GoToSocial 可以直接暴露到互联网上。不过,许多人更愿意使用
使用反向代理时,必须特别注意允许 WebSockets 正常工作。因为许多客户端应用程序使用 WebSockets 来流式传输你的时间线。WebSockets 不用于联合。
请确保阅读 [WebSocket](websocket.md) 文档,并相应地配置你的反向代理。
## 可信代理
使用反向代理时,可能会遇到速率限制和 `trusted-proxies` 相关的问题。如有任何问题,请查阅[可信代理](../../configuration/trusted_proxies.md)文档。

View file

@ -2,7 +2,7 @@
要使用 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)。
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
!!! warning
!!! warning "警告"
我们有关于如何[配置 TLS 证书](../../advanced/certificates.md)的附加文档,还提供了有关不同发行版的附加内容和教程链接,值得一看。
你现在可以运行 certbot它将引导你完成启用 https 的步骤。
@ -145,7 +145,7 @@ sudo systemctl start gotosocial
如果你再次打开 NGINX 配置,你会发现 Certbot 添加了一些额外的行。
!!! warning
!!! warning "警告"
根据你设置 Certbot 时选择的选项,以及使用的 NGINX 版本,可能会有所不同。
```nginx

View file

@ -29,7 +29,7 @@
例如,将用户提升为管理员后,你需要重启 GoToSocial 服务器,以便从数据库加载新值。
!!! tip
!!! tip "提示"
要查看其他可用的 CLI 命令,请点击[这里](../admin/cli.md)。

View file

@ -47,6 +47,7 @@ nav:
- "配置":
- "configuration/index.md"
- "configuration/general.md"
- "configuration/trusted_proxies.md"
- "configuration/database.md"
- "configuration/web.md"
- "configuration/instance.md"
@ -87,6 +88,7 @@ nav:
- "admin/signups.md"
- "admin/federation_modes.md"
- "admin/domain_blocks.md"
- "admin/domain_permission_subscriptions.md"
- "admin/request_filtering_modes.md"
- "admin/robots.md"
- "admin/cli.md"

View file

@ -148,7 +148,7 @@ Golang 的一个特点是,它所依赖的源代码管理路径与 `go.mod` 中
>
> 把你的派生分支添加为 origin
>
> `git remote add origin git@github.com/yourgithubname/gotosocial`
> `git remote add origin git@github.com:yourgithubname/gotosocial`
>
在第一次构建项目之前,一定要运行 `git fetch`
@ -488,7 +488,7 @@ GoToSocial 使用 [go-swagger](https://goswagger.io) 根据代码注释生成 Sw
如果你更改了任何 API 路径上的 Swagger 注释,可以通过运行以下命令在 `./docs/api/swagger.yaml` 生成一个新的 Swagger 文件:
```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 配置

View file

@ -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) 文件。
这是实例首页的截图!
这是实例首页的截图!你也可以看一看本项目在 GoToSocial 上的官方账号: [https://gts.superseriousbusiness.org/@gotosocial](https://gts.superseriousbusiness.org/@gotosocial)。
![GoToSocial 实例 goblin.technology 的首页截图。它展示了实例的基本信息,如用户数和贴文数等。](https://raw.githubusercontent.com/superseriousbusiness/gotosocial/main/docs/overrides/public/instancesplash.png)
<!--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/#默认互动规则) 选择谁可以回复你的贴文。你可以选择允许任何人回复贴文,仅允许朋友回复,等等。
![互动规则设置](https://raw.githubusercontent.com/superseriousbusiness/gotosocial/main/docs/overrides/public/user-settings-interaction-policy-1.png)
@ -146,7 +146,7 @@ GoToSocial 允许你选择将个人资料暴露为 RSS 订阅源,这样人们
### 主题与自定义 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/) 供用户选择。
@ -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),以确保消息不能被篡改,身份不能被伪造。
- 内置 [Let's Encrypt](https://letsencrypt.org/) 的自动使用 HTTPS 支持。
### 多种联合模式

View file

@ -71,7 +71,7 @@
- [x] **v2 过滤规则** -- 实现过滤器 API 的第二版。
- [x] **静音账户** -- 静音账户以防止其帖文出现在主页时间线上(可选:限制时间段)。
- [x] **无评论区的帖文** -- 设计无评论区帖文的相关逻辑,让用户创建无评论区的帖文。
- [ ] **屏蔽/允许列表订阅** -- 允许实例管理员订阅纯文本的示例屏蔽/允许列表。(大部分工作已经完成)
- [x] **屏蔽/允许列表订阅** -- 允许实例管理员为其实例订阅屏蔽/允许列表。
- [x] **私信对话视图** -- 让用户能够轻松浏览他们参与的所有私信对话。
- [ ] **Oauth 令牌管理** -- 通过设置面板创建/查看/吊销 OAuth 令牌。
- [ ] **贴文编辑支持** -- 编辑已创建的贴文,而无需删除并重新编辑。并正确地将编辑传播出去。

View file

@ -6,10 +6,10 @@ GoToSocial 支持使用 `Move` 活动进行账号迁移。
迁移是软件无关的,因此你可以将账号迁移到其它软件或从任何支持 `Move` 活动的软件发起迁移,无论具体的软件是什么。例如,你可以将 GoToSocial 账号迁移到 Mastodon 账号,将 Mastodon 账号迁移到 GoToSocial 账号,将 GoToSocial 账号迁移到或从 Akkoma、Misskey、GoToSocial 等。
!!! tip
!!! tip "提示"
根据目标账号所在软件的不同,目标账号的 URI用于别名和迁移应该类似于 `https://mastodon.example.org/users/account_you_are_moving_to`。如果你不确定使用哪种格式,请咨询你要迁移或设置别名的实例管理员。
!!! warning
!!! warning "警告"
GoToSocial 要求 7 天的账号迁移冷却期,以防止过度切换实例(以及潜在的屏蔽规避风险)。
如果任何一个发起新迁移尝试的账号在最近七天内已迁移GoToSocial 将拒绝进行迁移,直到上一次迁移过去七天位置。
@ -71,8 +71,8 @@ GoToSocial 支持使用 `Move` 活动进行账号迁移。
一旦触发从其他账号到 GoToSocial 账号的迁移你唯一需要做的就是在新GoToSocial账号上接受来自旧账号粉丝的关注请求。
!!! tip
!!! tip "提示"
为了省去麻烦,可以考虑在触发迁移前将 GoToSocial 账号设置为不需要批准新的关注请求。迁移完成后再开启关注请求审核。否则,你将需要手动批准每个从旧账号迁移的粉丝。
!!! tip
!!! tip "提示"
迁移账号后,可能需要将之前账号的关注列表导入 GoToSocial 账号。[在此查看](./settings.md#import)如何通过设置面板完成此操作的详细信息。

View file

@ -36,7 +36,7 @@ GoToSocial 为贴文提供 Mastodon 风格的隐私设置。从最私密到最
### 互关可见
!!! warning
!!! warning "警告"
目前暂时无法将帖文可见性设为“互关可见”。
`互关可见` 的贴文只会显示给贴文作者和与作者*互相关注*的人。换句话说,只有在满足两个条件时,其他人才能看到:
@ -135,14 +135,14 @@ GoToSocial 允许你在贴文中附加媒体文件,大多数客户端会在贴
为了避免泄漏你的位置信息GoToSocial 努力在上传媒体时通过清零 Exif 数据点移除 Exif 信息。
!!! danger
!!! danger "危险"
为了方便和保护隐私GoToSocial 在上传图片文件时会自动移除 Exif 标签。然而,**无法自动移除 mp4 视频的 Exif 数据**(参见 [#2577](https://github.com/superseriousbusiness/gotosocial/issues/2577))。
在你将视频上传至 GoToSocial 之前,建议确保该视频的 Exif 数据标签已经被移除。你可以在线找到多种工具和服务来做到这一点。
为防止 Exif 位置信息在一开始被写入图片或视频中,你还可以关闭设备摄像头应用中的位置标记(通常称为地理标记)。
!!! tip
!!! tip "提示"
即使你在上传图片或视频之前已完全移除所有 Exif 元数据,恶意用户仍然可以通过媒体本身的内容推断出你的位置信息。
如果你属于在生产中有保密需要的组织,或正在被跟踪或监视,你可能需要考虑不要发布任何可能含有你位置线索的媒体。
@ -285,6 +285,9 @@ GoToSocial 允许你在贴文中附加媒体文件,大多数客户端会在贴
你可以在 GoToSocial 贴文中包含任意数量的话题标签,而且每个话题标签的长度限制为 100 个字符。
!!! tip "提示"
要结束一个话题标签,你只需在话题标签名后输入空格。例如,在文本 `这道 #鸡汤 十分美味` 中,话题标签由空格终止,因此 `#鸡汤` 成为话题标签。但是,你也可以使用管道字符 `|`,或使用 Unicode 字符 `\u200B` (零宽不换行空格)或 `\uFEFF` (零宽空格),来创建“词语片段”话题标签。例如,在 `这道 #鸡|汤 十分美味` 中,只有 `#鸡` 成为话题标签。同理,对于文本 `这道 #鸡​汤 十分美味` `鸡``汤` 之间有一个零宽空格),只有 `#鸡` 成为话题标签。有关零宽空格的更多信息参见https://en.wikipedia.org/wiki/Zero-width_space。
## 输入净化
为了不传播脚本、漏洞以及不稳定的 HTMLGoToSocial 执行以下类型的输入净化:

View file

@ -88,14 +88,14 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
此设置不会影响你的贴文在 ActivityPub 协议和客户端中的可见性,因此即便你选择不在网页版账户页显示任何贴文,只要他人是你的粉丝、你的贴文被转发到他们的时间线,或使用链接搜索你的某个贴文,他们仍然可以看到的贴文。
!!! warning
!!! warning "警告"
请注意,此设置的更改也会应用于之前的贴文。
也就是说,如果你之前发布了一条“不列出”可见性的贴文,而当时你的网页版账户页被设置为仅显示公开贴文,此时如果你更改此设置为一并显示公开和不列出,那你之前发布的“不列出”贴文将会与公开贴文一起显示在你的网页版账户页上。
同样地,如果你选择不显示任何贴文,那么所有贴文将从你的网页版账户页中隐藏,无论它们是在何时创建,也无论当时此选项被设置为什么。这种情况将持续直到你再次更改此设置。
!!! tip
!!! tip "提示"
结合(域名)屏蔽,如果有人通过公开贴文骚扰你,这是一种很好的“紧急”设置。虽然它不会阻止在 ActivityPub 客户端中可以看到你的贴文的人,但至少会防止他们无需身份验证就通过浏览器点击查看你的贴文,并通过 URL 轻松与他人分享。
#### 手动批准关注请求(即锁定帐户)
@ -121,10 +121,10 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
将可发现性标记打开可能需要一周或更长时间才会生效,账户不会立即出现在搜索引擎结果中。
!!! tip
!!! tip "提示"
为了避免暴露给爬虫,新帐户的可发现性默认为 false。但对于希望被抓取的面向公众的帐户将其设置为 true 是有用的。
!!! info
!!! info "附注"
可发现性设置是关于**账户的可发现性**,而不是贴文的可被搜索性。这与 Mastodon 实例或其他使用全文搜索的实例的贴文索引无关!
#### 启用公开贴文的 RSS 源
@ -133,7 +133,7 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
此源仅包括设置为“公开”的贴文(参见 [隐私设置](./posts.md#隐私设置))。
!!! warning
!!! warning "警告"
公开您的 RSS 源允许*任何人*匿名订阅您公开贴文的更新,绕过关注和关注请求。
#### 隐藏你关注/被关注的人
@ -152,7 +152,7 @@ GoToSocial 提供主题供你选择,以更改账户的外观和氛围。
请参阅 [自定义 CSS](./custom_css.md) 页面,了解有关为账户编写自定义 CSS 的一些提示。
!!! tip
!!! tip "提示"
你在此框中添加的任何自定义 CSS 都将在*选择主题之后*应用,因此你可以选择一个喜欢的预设主题,然后进行自己的调整!
## 贴文
@ -196,7 +196,7 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
如果你想将所有规则重置为初始默认值,可以点击 `重置为默认值` 按钮。
!!! danger
!!! danger "危险"
虽然 GoToSocial 尊重互动规则,但不能保证其他服务端软件也会这样做,即使你的实例禁止某些互动,其他服务器上的账户可能仍会向其粉丝发送(被禁止的)贴文回复和转发。
随着更多 ActivityPub 服务端推出互动规则支持这个问题有望减少但在此期间GoToSocial 只能在“尽力而为”范围内进行尝试,以根据你设定的规则限制与贴文的互动。
@ -209,14 +209,14 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
输入新电子邮箱地址,并点击“更改电子邮箱地址”后,必须打开新电子邮件地址的收件箱,并通过提供的链接确认地址。完成后,你的电子邮箱地址更改将被确认。
!!! info
!!! info "附注"
如果你的实例使用 OIDC 作为授权/身份提供商,你可以通过设置面板更改电子邮箱地址,但只会影响 GoToSocial 用于联系你的电子邮箱地址,而不会更改用于登录账户的电子邮箱地址。要更改此项,应联系你的 OIDC 提供商。
### 更改密码
你可以使用面板的更改密码部分为账户设置新密码。出于安全原因,你必须提供当前密码以验证更改。
!!! info
!!! info "附注"
如果你的实例使用 OIDC 作为授权/身份提供商,你将无法通过 GoToSocial 设置面板更改密码,此时应联系你的 OIDC 提供商。
有关 GoToSocial 如何管理密码的更多信息,请参阅[密码管理文档](./password_management.md)。
@ -249,7 +249,7 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
然后,使用下拉菜单选择通过 CSV 文件上传的数据类型。
!!! warning
!!! warning "警告"
在选择“类型”时要小心,否则可能会意外封禁你计划关注的一堆账户,反之亦然!
然后,选择是要**合并**新数据到 GoToSocial 账户中该类型的现有数据,还是要用 CSV 文件中包含的数据**覆盖**现有数据。
@ -264,5 +264,5 @@ markdown 设置表示你的贴文应被按 Markdown 格式解析,这是一种
合并和覆盖操作都是幂等的,这通常意味着现有数据和 CSV 文件中的重复条目不会产生问题,如果需要重试导入,可以多次导入相同的数据。
!!! info
!!! info "附注"
由于各种原因,通过导入不可能一定会重新创建上传的 CSV 文件中的每个条目。例如,假设你试图导入包含 `example_account` 的关注 CSV`example_account` 的实例已下线,或者它们的实例封禁了你的实例,或你的实例封禁了它们的实例等。在这种情况下,将无法创建对 `example_account` 的关注。

View file

@ -475,6 +475,28 @@ accounts-registration-open: false
# Default: 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.
# 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.

14
go.mod
View file

@ -46,7 +46,7 @@ require (
github.com/k3a/html2text v1.2.1
github.com/microcosm-cc/bluemonday v1.0.27
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/ncruces/go-sqlite3 v0.22.0
github.com/oklog/ulid v1.3.1
@ -78,11 +78,12 @@ require (
go.opentelemetry.io/otel/sdk/metric v1.34.0
go.opentelemetry.io/otel/trace v1.34.0
go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.32.0
golang.org/x/image v0.23.0
golang.org/x/crypto v0.33.0
golang.org/x/image v0.24.0
golang.org/x/net v0.34.0
golang.org/x/oauth2 v0.25.0
golang.org/x/text v0.21.0
golang.org/x/oauth2 v0.26.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/yaml.v3 v3.0.1
modernc.org/sqlite v0.0.0-00010101000000-000000000000
@ -211,8 +212,7 @@ require (
golang.org/x/arch v0.13.0 // indirect
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/sync v0.10.0 // indirect
golang.org/x/sys v0.29.0 // indirect
golang.org/x/sync v0.11.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/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect

30
go.sum generated
View file

@ -403,8 +403,8 @@ github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
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/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.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
github.com/minio/minio-go/v7 v7.0.85 h1:9psTLS/NTvC3MWoyjhjXpwcKoNbkongaCSF3PNpSuXo=
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.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@ -665,8 +665,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.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
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.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
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-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -681,8 +681,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/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.23.0 h1:HseQ7c2OpPKTPVzNjG5fwJsOTCiiwS4QdsYi5XU6H68=
golang.org/x/image v0.23.0/go.mod h1:wJJBTdLfCCf3tiHa1fNxpZmUI4mmoZvwMCPP0ddoNKY=
golang.org/x/image v0.24.0 h1:AN7zRgVsbvmTfNyqIbbOraYL8mSwcKncEj8ofjgzcMQ=
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-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -753,8 +753,8 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr
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-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.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
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-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -768,8 +768,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.6.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.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-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -814,8 +815,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.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.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
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/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=
@ -826,8 +827,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.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
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.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
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.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@ -840,8 +841,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.14.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.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-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=

View file

@ -145,12 +145,18 @@ func (m *Module) CallbackGETHandler(c *gin.Context) {
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{
Template: "finalize.tmpl",
Instance: instance,
Extra: map[string]any{
"name": claims.Name,
"preferredUsername": claims.PreferredUsername,
"suggestedUsername": suggestedUsername,
},
}

View file

@ -114,7 +114,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -169,7 +170,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -216,7 +218,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
{
@ -266,7 +269,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -313,7 +317,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -360,7 +365,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 1,
"last_status_at": "2023-11-02",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
{
@ -406,7 +412,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
{
@ -453,7 +460,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
{
@ -499,7 +507,8 @@ func (suite *AccountsGetTestSuite) TestAccountsGetFromTop() {
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, dst.String())
@ -584,7 +593,8 @@ func (suite *AccountsGetTestSuite) TestAccountsMinID() {
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, dst.String())

View file

@ -189,7 +189,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"target_account": {
@ -247,7 +248,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -302,7 +304,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -357,7 +360,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -429,7 +433,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -476,7 +481,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"assigned_account": null,
@ -525,7 +531,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetAll() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{
@ -683,7 +690,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetCreatedByAccount() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -730,7 +738,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetCreatedByAccount() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"assigned_account": null,
@ -779,7 +788,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetCreatedByAccount() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{
@ -937,7 +947,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetTargetAccount() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -984,7 +995,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetTargetAccount() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"assigned_account": null,
@ -1033,7 +1045,8 @@ func (suite *ReportsGetTestSuite) TestReportsGetTargetAccount() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{

View file

@ -103,7 +103,8 @@ func (suite *GetTestSuite) TestGet() {
"statuses_count": 1,
"last_status_at": "2023-11-02",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
]`, dst.String())
}

View file

@ -191,7 +191,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [
@ -333,7 +334,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [
@ -475,7 +477,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [
@ -668,7 +671,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [
@ -836,7 +840,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [
@ -1015,7 +1020,8 @@ func (suite *InstancePatchTestSuite) TestInstancePatch9() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [

View file

@ -148,7 +148,7 @@ func (suite *MutesTestSuite) TestIndefinitelyMutedAccountSerializesMuteExpiratio
// Fetch all muted accounts for the logged-in account.
// The expected body contains `"mute_expires_at":null`.
_, err = suite.getMutedAccounts(http.StatusOK, `[{"id":"01F8MH5ZK5VRH73AKHQM6Y9VNX","username":"foss_satan","acct":"foss_satan@fossbros-anonymous.io","display_name":"big gerald","locked":false,"discoverable":true,"bot":false,"created_at":"2021-09-26T10:52:36.000Z","note":"i post about like, i dunno, stuff, or whatever!!!!","url":"http://fossbros-anonymous.io/@foss_satan","avatar":"","avatar_static":"","header":"http://localhost:8080/assets/default_header.webp","header_static":"http://localhost:8080/assets/default_header.webp","header_description":"Flat gray background (default header).","followers_count":0,"following_count":0,"statuses_count":4,"last_status_at":"2024-11-01","emojis":[],"fields":[],"mute_expires_at":null}]`)
_, err = suite.getMutedAccounts(http.StatusOK, `[{"id":"01F8MH5ZK5VRH73AKHQM6Y9VNX","username":"foss_satan","acct":"foss_satan@fossbros-anonymous.io","display_name":"big gerald","locked":false,"discoverable":true,"bot":false,"created_at":"2021-09-26T10:52:36.000Z","note":"i post about like, i dunno, stuff, or whatever!!!!","url":"http://fossbros-anonymous.io/@foss_satan","avatar":"","avatar_static":"","header":"http://localhost:8080/assets/default_header.webp","header_static":"http://localhost:8080/assets/default_header.webp","header_description":"Flat gray background (default header).","followers_count":0,"following_count":0,"statuses_count":4,"last_status_at":"2024-11-01","emojis":[],"fields":[],"group":false,"mute_expires_at":null}]`)
if err != nil {
suite.FailNow(err.Error())
}

View file

@ -133,7 +133,8 @@ func (suite *ReportGetTestSuite) TestGetReport1() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}`, string(b))
}

View file

@ -159,7 +159,8 @@ func (suite *ReportsGetTestSuite) TestGetReports() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, string(b))
@ -250,7 +251,8 @@ func (suite *ReportsGetTestSuite) TestGetReports4() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, string(b))
@ -325,7 +327,8 @@ func (suite *ReportsGetTestSuite) TestGetReports6() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, string(b))
@ -384,7 +387,8 @@ func (suite *ReportsGetTestSuite) TestGetReports7() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}
]`, string(b))

View file

@ -120,7 +120,8 @@ func (suite *StatusHistoryTestSuite) TestGetHistory() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"poll": null,
"media_attachments": [],

View file

@ -139,7 +139,8 @@ func (suite *StatusMuteTestSuite) TestMuteUnmuteStatus() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [],
"mentions": [],
@ -227,7 +228,8 @@ func (suite *StatusMuteTestSuite) TestMuteUnmuteStatus() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [],
"mentions": [],

View file

@ -126,6 +126,8 @@ type Account struct {
// If set, indicates that this account is currently inactive, and has migrated to the given account.
// Key/value omitted for accounts that haven't moved, and for suspended accounts.
Moved *Account `json:"moved,omitempty"`
// Account identifies as a Group actor.
Group bool `json:"group"`
}
// WebAccount is like Account, but with

View file

@ -92,10 +92,12 @@ type Configuration struct {
InstanceSubscriptionsProcessEvery time.Duration `name:"instance-subscriptions-process-every" usage:"Period to elapse between instance subscriptions processing jobs, starting from instance-subscriptions-process-from."`
InstanceStatsMode string `name:"instance-stats-mode" usage:"Allows you to customize the way stats are served to crawlers: one of '', 'serve', 'zero', 'baffle'. Home page stats remain unchanged."`
AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."`
AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
AccountsAllowCustomCSS bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."`
AccountsCustomCSSLength int `name:"accounts-custom-css-length" usage:"Maximum permitted length (characters) of custom CSS for accounts."`
AccountsRegistrationOpen bool `name:"accounts-registration-open" usage:"Allow anyone to submit an account signup request. If false, server will be invite-only."`
AccountsReasonRequired bool `name:"accounts-reason-required" usage:"Do new account signups require a reason to be submitted on registration?"`
AccountsRegistrationDailyLimit int `name:"accounts-registration-daily-limit" usage:"Limit amount of approved account sign-ups allowed per 24hrs before registration is closed. 0 or less = no limit."`
AccountsRegistrationBacklogLimit int `name:"accounts-registration-backlog-limit" usage:"Limit how big the 'accounts pending approval' queue can grow before registration is closed. 0 or less = no limit."`
AccountsAllowCustomCSS bool `name:"accounts-allow-custom-css" usage:"Allow accounts to enable custom CSS for their profile pages and statuses."`
AccountsCustomCSSLength int `name:"accounts-custom-css-length" usage:"Maximum permitted length (characters) of custom CSS for accounts."`
MediaDescriptionMinChars int `name:"media-description-min-chars" usage:"Min required chars for an image description"`
MediaDescriptionMaxChars int `name:"media-description-max-chars" usage:"Max permitted chars for an image description"`

View file

@ -68,10 +68,12 @@ var Defaults = Configuration{
InstanceSubscriptionsProcessFrom: "23:00", // 11pm,
InstanceSubscriptionsProcessEvery: 24 * time.Hour, // 1/day.
AccountsRegistrationOpen: false,
AccountsReasonRequired: true,
AccountsAllowCustomCSS: false,
AccountsCustomCSSLength: 10000,
AccountsRegistrationOpen: false,
AccountsReasonRequired: true,
AccountsRegistrationDailyLimit: 10,
AccountsRegistrationBacklogLimit: 20,
AccountsAllowCustomCSS: false,
AccountsCustomCSSLength: 10000,
MediaDescriptionMinChars: 0,
MediaDescriptionMaxChars: 1500,

View file

@ -1132,6 +1132,56 @@ func GetAccountsReasonRequired() bool { return global.GetAccountsReasonRequired(
// SetAccountsReasonRequired safely sets the value for global configuration 'AccountsReasonRequired' field
func SetAccountsReasonRequired(v bool) { global.SetAccountsReasonRequired(v) }
// GetAccountsRegistrationDailyLimit safely fetches the Configuration value for state's 'AccountsRegistrationDailyLimit' field
func (st *ConfigState) GetAccountsRegistrationDailyLimit() (v int) {
st.mutex.RLock()
v = st.config.AccountsRegistrationDailyLimit
st.mutex.RUnlock()
return
}
// SetAccountsRegistrationDailyLimit safely sets the Configuration value for state's 'AccountsRegistrationDailyLimit' field
func (st *ConfigState) SetAccountsRegistrationDailyLimit(v int) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.AccountsRegistrationDailyLimit = v
st.reloadToViper()
}
// AccountsRegistrationDailyLimitFlag returns the flag name for the 'AccountsRegistrationDailyLimit' field
func AccountsRegistrationDailyLimitFlag() string { return "accounts-registration-daily-limit" }
// GetAccountsRegistrationDailyLimit safely fetches the value for global configuration 'AccountsRegistrationDailyLimit' field
func GetAccountsRegistrationDailyLimit() int { return global.GetAccountsRegistrationDailyLimit() }
// SetAccountsRegistrationDailyLimit safely sets the value for global configuration 'AccountsRegistrationDailyLimit' field
func SetAccountsRegistrationDailyLimit(v int) { global.SetAccountsRegistrationDailyLimit(v) }
// GetAccountsRegistrationBacklogLimit safely fetches the Configuration value for state's 'AccountsRegistrationBacklogLimit' field
func (st *ConfigState) GetAccountsRegistrationBacklogLimit() (v int) {
st.mutex.RLock()
v = st.config.AccountsRegistrationBacklogLimit
st.mutex.RUnlock()
return
}
// SetAccountsRegistrationBacklogLimit safely sets the Configuration value for state's 'AccountsRegistrationBacklogLimit' field
func (st *ConfigState) SetAccountsRegistrationBacklogLimit(v int) {
st.mutex.Lock()
defer st.mutex.Unlock()
st.config.AccountsRegistrationBacklogLimit = v
st.reloadToViper()
}
// AccountsRegistrationBacklogLimitFlag returns the flag name for the 'AccountsRegistrationBacklogLimit' field
func AccountsRegistrationBacklogLimitFlag() string { return "accounts-registration-backlog-limit" }
// GetAccountsRegistrationBacklogLimit safely fetches the value for global configuration 'AccountsRegistrationBacklogLimit' field
func GetAccountsRegistrationBacklogLimit() int { return global.GetAccountsRegistrationBacklogLimit() }
// SetAccountsRegistrationBacklogLimit safely sets the value for global configuration 'AccountsRegistrationBacklogLimit' field
func SetAccountsRegistrationBacklogLimit(v int) { global.SetAccountsRegistrationBacklogLimit(v) }
// GetAccountsAllowCustomCSS safely fetches the Configuration value for state's 'AccountsAllowCustomCSS' field
func (st *ConfigState) GetAccountsAllowCustomCSS() (v bool) {
st.mutex.RLock()

View file

@ -82,7 +82,8 @@ func (suite *NotificationTestSuite) TestStreamNotification() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}`, dst.String())
}

View file

@ -94,7 +94,8 @@ func (suite *StatusUpdateTestSuite) TestStreamNotification() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{

View file

@ -44,34 +44,43 @@ func (p *Processor) Create(
app *gtsmodel.Application,
form *apimodel.AccountCreateRequest,
) (*gtsmodel.User, gtserror.WithCode) {
const (
usersPerDay = 10
regBacklog = 20
var (
usersPerDay = config.GetAccountsRegistrationDailyLimit()
regBacklog = config.GetAccountsRegistrationBacklogLimit()
)
// Ensure no more than usersPerDay
// If usersPerDay limit is in place,
// ensure no more than usersPerDay
// have registered in the last 24h.
newUsersCount, err := p.state.DB.CountApprovedSignupsSince(ctx, time.Now().Add(-24*time.Hour))
if err != nil {
err := fmt.Errorf("db error counting new users: %w", err)
return nil, gtserror.NewErrorInternalError(err)
if usersPerDay > 0 {
newUsersCount, err := p.state.DB.CountApprovedSignupsSince(ctx, time.Now().Add(-24*time.Hour))
if err != nil {
err := fmt.Errorf("db error counting new users: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
if newUsersCount >= usersPerDay {
err := fmt.Errorf("this instance has hit its limit of new sign-ups for today (%d); you can try again tomorrow", usersPerDay)
return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
}
}
if newUsersCount >= usersPerDay {
err := fmt.Errorf("this instance has hit its limit of new sign-ups for today; you can try again tomorrow")
return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
}
// If registration backlog limit is
// in place, ensure backlog isn't full.
if regBacklog > 0 {
backlogLen, err := p.state.DB.CountUnhandledSignups(ctx)
if err != nil {
err := fmt.Errorf("db error counting registration backlog length: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
// Ensure the new users backlog isn't full.
backlogLen, err := p.state.DB.CountUnhandledSignups(ctx)
if err != nil {
err := fmt.Errorf("db error counting registration backlog length: %w", err)
return nil, gtserror.NewErrorInternalError(err)
}
if backlogLen >= regBacklog {
err := fmt.Errorf("this instance's sign-up backlog is currently full; you must wait until pending sign-ups are handled by the admin(s)")
return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
if backlogLen >= regBacklog {
err := fmt.Errorf(
"this instance's sign-up backlog is currently full (%d sign-ups pending approval); "+
"you must wait until some pending sign-ups are handled by the admin(s)", regBacklog,
)
return nil, gtserror.NewErrorUnprocessableEntity(err, err.Error())
}
}
emailAvailable, err := p.state.DB.IsEmailAvailable(ctx, form.Email)

View file

@ -0,0 +1,74 @@
// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
package user_test
import (
"context"
"net"
"testing"
"github.com/stretchr/testify/suite"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
)
type CreateTestSuite struct {
UserStandardTestSuite
}
func (suite *CreateTestSuite) TestCreateOK() {
var (
ctx = context.Background()
app = suite.testApps["application_1"]
appToken = suite.testTokens["local_account_1_client_application_token"]
form = &apimodel.AccountCreateRequest{
Reason: "a long enough explanation of why I am doing api calls",
Username: "someone_new",
Email: "someone_new@example.org",
Password: "a long enough password for this endpoint",
Agreement: true,
Locale: "en-us",
IP: net.ParseIP("192.0.2.128"),
}
)
// Create user via the API endpoint.
user, errWithCode := suite.user.Create(ctx, app, form)
if errWithCode != nil {
suite.FailNow(errWithCode.Error())
}
// Load the app-level access token that was just used.
appAccessToken, err := suite.oauthServer.LoadAccessToken(ctx, appToken.Access)
if err != nil {
suite.FailNow(err.Error())
}
// Create a user-level access token for the new user.
userAccessToken, err := suite.user.TokenForNewUser(ctx, appAccessToken, app, user)
if err != nil {
suite.FailNow(err.Error())
}
// Check returned user-level access token.
suite.NotEmpty(userAccessToken.AccessToken)
suite.Equal("Bearer", userAccessToken.TokenType)
}
func TestCreateTestSuite(t *testing.T) {
suite.Run(t, &CreateTestSuite{})
}

View file

@ -41,6 +41,7 @@ func New(
return Processor{
state: state,
converter: converter,
oauthServer: oauthServer,
emailSender: emailSender,
}
}

View file

@ -23,6 +23,7 @@ import (
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/email"
"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/internal/processing/user"
"github.com/superseriousbusiness/gotosocial/internal/state"
"github.com/superseriousbusiness/gotosocial/internal/typeutils"
@ -34,9 +35,11 @@ type UserStandardTestSuite struct {
emailSender email.Sender
db db.DB
state state.State
oauthServer oauth.Server
testUsers map[string]*gtsmodel.User
testApps map[string]*gtsmodel.Application
testTokens map[string]*gtsmodel.Token
testUsers map[string]*gtsmodel.User
sentEmails map[string]string
user user.Processor
@ -51,9 +54,12 @@ func (suite *UserStandardTestSuite) SetupTest() {
suite.db = testrig.NewTestDB(&suite.state)
suite.state.DB = suite.db
suite.state.AdminActions = admin.New(suite.state.DB, &suite.state.Workers)
suite.oauthServer = testrig.NewTestOauthServer(suite.state.DB)
suite.sentEmails = make(map[string]string)
suite.emailSender = testrig.NewEmailSender("../../../web/template/", suite.sentEmails)
suite.testApps = testrig.NewTestApplications()
suite.testTokens = testrig.NewTestTokens()
suite.testUsers = testrig.NewTestUsers()
suite.user = user.New(&suite.state, typeutils.NewConverter(&suite.state), testrig.NewTestOauthServer(suite.db), suite.emailSender)

View file

@ -388,6 +388,7 @@ func (c *Converter) accountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A
EnableRSS: enableRSS,
HideCollections: hideCollections,
Roles: roles,
Group: false,
}
// Bodge default avatar + header in,

View file

@ -72,7 +72,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontend() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
}`, string(b))
}
@ -178,8 +179,10 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendAliasedAndMoved()
"verified_at": null
}
],
"hide_collections": true
}
"hide_collections": true,
"group": false
},
"group": false
}`, string(b))
}
@ -230,7 +233,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiStruct()
}
],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
}`, string(b))
}
@ -279,7 +283,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiIDs() {
}
],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
}`, string(b))
}
@ -333,7 +338,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendSensitive() {
"color": "",
"permissions": "0",
"highlighted": false
}
},
"group": false
}`, string(b))
}
@ -370,7 +376,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendPublicPunycode()
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}`, string(b))
}
@ -409,7 +416,8 @@ func (suite *InternalToFrontendTestSuite) TestLocalInstanceAccountToFrontendPubl
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}`, string(b))
}
@ -448,7 +456,8 @@ func (suite *InternalToFrontendTestSuite) TestLocalInstanceAccountToFrontendBloc
"statuses_count": 0,
"last_status_at": null,
"emojis": [],
"fields": []
"fields": [],
"group": false
}`, string(b))
}
@ -516,7 +525,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontend() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [
{
@ -695,7 +705,8 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredStatusToFrontend() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [
{
@ -879,7 +890,8 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredBoostToFrontend() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [
{
@ -1014,7 +1026,8 @@ func (suite *InternalToFrontendTestSuite) TestWarnFilteredBoostToFrontend() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [],
"mentions": [],
@ -1301,7 +1314,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendUnknownAttachments
"statuses_count": 1,
"last_status_at": "2023-11-02",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{
@ -1466,7 +1480,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToWebStatus() {
"statuses_count": 1,
"last_status_at": "2023-11-02",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{
@ -1608,7 +1623,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendUnknownLanguage()
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [
{
@ -1748,7 +1764,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToFrontendPartialInteraction
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [],
"mentions": [],
@ -1863,7 +1880,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIStatusPendingApproval()
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [],
"mentions": [
@ -2075,7 +2093,8 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"max_toot_chars": 5000,
"rules": [],
@ -2227,7 +2246,8 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV2ToFrontend() {
"name": "admin",
"color": ""
}
]
],
"group": false
}
},
"rules": [],
@ -2340,7 +2360,8 @@ func (suite *InternalToFrontendTestSuite) TestReportToFrontend1() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
}`, string(b))
}
@ -2396,7 +2417,8 @@ func (suite *InternalToFrontendTestSuite) TestReportToFrontend2() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
}
}`, string(b))
}
@ -2461,7 +2483,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"target_account": {
@ -2519,7 +2542,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -2574,7 +2598,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -2629,7 +2654,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -2711,7 +2737,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"created_by_application_id": "01F8MGY43H3N2C8EWPR2FPYEXG"
},
@ -2758,7 +2785,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"assigned_account": null,
@ -2807,7 +2835,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() {
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
},
"media_attachments": [
{
@ -2966,7 +2995,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
"statuses_count": 4,
"last_status_at": "2024-11-01",
"emojis": [],
"fields": []
"fields": [],
"group": false
}
},
"target_account": {
@ -3014,7 +3044,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
"emojis": [],
"fields": [],
"suspended": true,
"hide_collections": true
"hide_collections": true,
"group": false
}
},
"assigned_account": {
@ -3068,7 +3099,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -3123,7 +3155,8 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontendSuspendedLoca
"name": "admin",
"color": ""
}
]
],
"group": false
},
"created_by_application_id": "01F8MGXQRHYF5QPMTMXP78QC2F"
},
@ -3270,7 +3303,8 @@ func (suite *InternalToFrontendTestSuite) TestIntReqToAPI() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"status": {
"id": "01F8MHC8VWDRBQR0N1BATDDEM5",
@ -3331,7 +3365,8 @@ func (suite *InternalToFrontendTestSuite) TestIntReqToAPI() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
},
"media_attachments": [],
"mentions": [],
@ -3421,7 +3456,8 @@ func (suite *InternalToFrontendTestSuite) TestIntReqToAPI() {
"name": "admin",
"color": ""
}
]
],
"group": false
},
"media_attachments": [],
"mentions": [
@ -3531,7 +3567,8 @@ func (suite *InternalToFrontendTestSuite) TestConversationToAPISelfConvo() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
}
],
"last_status": {
@ -3585,7 +3622,8 @@ func (suite *InternalToFrontendTestSuite) TestConversationToAPISelfConvo() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [],
"mentions": [],
@ -3698,7 +3736,8 @@ func (suite *InternalToFrontendTestSuite) TestConversationToAPI() {
"verified_at": null
}
],
"hide_collections": true
"hide_collections": true,
"group": false
}
],
"last_status": {
@ -3752,7 +3791,8 @@ func (suite *InternalToFrontendTestSuite) TestConversationToAPI() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"media_attachments": [],
"mentions": [],
@ -3837,7 +3877,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIEdits() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"poll": null,
"media_attachments": [],
@ -3873,7 +3914,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIEdits() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"poll": null,
"media_attachments": [],
@ -3909,7 +3951,8 @@ func (suite *InternalToFrontendTestSuite) TestStatusToAPIEdits() {
"last_status_at": "2024-11-01",
"emojis": [],
"fields": [],
"enable_rss": true
"enable_rss": true,
"group": false
},
"poll": null,
"media_attachments": [],

View file

@ -192,6 +192,11 @@ func (r *realSender) sendToSubscription(
// while waiting for the client to retrieve them.
TTL = 48 * time.Hour
// recordSize limits how big our notifications can be once padding is applied.
// To be polite to applications that need to relay them over services like APNS,
// which has a max message size of 4 kB, we set this comfortably smaller.
recordSize = 2048
// responseBodyMaxLen limits how much of the Web Push server response we read for error messages.
responseBodyMaxLen = 1024
)
@ -232,6 +237,7 @@ func (r *realSender) sendToSubscription(
},
&webpushgo.Options{
HTTPClient: r.httpClient,
RecordSize: recordSize,
Subscriber: "https://" + config.GetHost(),
VAPIDPublicKey: vapidKeyPair.Public,
VAPIDPrivateKey: vapidKeyPair.Private,
@ -346,8 +352,9 @@ func formatNotificationTitle(
// or the beginning of the bio text of the related account.
func formatNotificationBody(apiNotification *apimodel.Notification) string {
// bodyMaxLen is a polite maximum length for a Web Push notification's body text, in bytes. Note that this isn't
// limited per se, but Web Push servers may reject anything with a total request body size over 4k.
const bodyMaxLen = 3000
// limited per se, but Web Push servers may reject anything with a total request body size over 4k,
// and we set a lower max size above for compatibility with mobile push systems.
const bodyMaxLen = 1500
var body string
if apiNotification.Status != nil {

View file

@ -8,6 +8,8 @@ EXPECT=$(cat << "EOF"
"accounts-allow-custom-css": true,
"accounts-custom-css-length": 5000,
"accounts-reason-required": false,
"accounts-registration-backlog-limit": 100,
"accounts-registration-daily-limit": 50,
"accounts-registration-open": true,
"advanced-cookies-samesite": "strict",
"advanced-csp-extra-uris": [],
@ -252,6 +254,8 @@ GTS_INSTANCE_LANGUAGES="nl,en-gb" \
GTS_INSTANCE_STATS_MODE="baffle" \
GTS_ACCOUNTS_ALLOW_CUSTOM_CSS=true \
GTS_ACCOUNTS_CUSTOM_CSS_LENGTH=5000 \
GTS_ACCOUNTS_REGISTRATION_BACKLOG_LIMIT=100 \
GTS_ACCOUNTS_REGISTRATION_DAILY_LIMIT=50 \
GTS_ACCOUNTS_REGISTRATION_OPEN=true \
GTS_ACCOUNTS_REASON_REQUIRED=false \
GTS_MEDIA_DESCRIPTION_MIN_CHARS=69 \

View file

@ -102,10 +102,12 @@ func testDefaults() config.Configuration {
InstanceSubscriptionsProcessFrom: "23:00", // 11pm,
InstanceSubscriptionsProcessEvery: 24 * time.Hour, // 1/day.
AccountsRegistrationOpen: true,
AccountsReasonRequired: true,
AccountsAllowCustomCSS: true,
AccountsCustomCSSLength: 10000,
AccountsRegistrationOpen: true,
AccountsReasonRequired: true,
AccountsRegistrationDailyLimit: 10,
AccountsRegistrationBacklogLimit: 20,
AccountsAllowCustomCSS: true,
AccountsCustomCSSLength: 10000,
MediaDescriptionMinChars: 0,
MediaDescriptionMaxChars: 500,

View file

@ -213,6 +213,14 @@ type RemoveObjectError struct {
Err error
}
func (err *RemoveObjectError) Error() string {
// This should never happen as we will have a non-nil error with no underlying error.
if err.Err == nil {
return "unexpected remove object error result"
}
return err.Err.Error()
}
// RemoveObjectResult - container of Multi Delete S3 API result
type RemoveObjectResult struct {
ObjectName string

View file

@ -92,6 +92,9 @@ type Client struct {
// default to Auto.
lookup BucketLookupType
// lookupFn is a custom function to return URL lookup type supported by the server.
lookupFn func(u url.URL, bucketName string) BucketLookupType
// Factory for MD5 hash functions.
md5Hasher func() md5simd.Hasher
sha256Hasher func() md5simd.Hasher
@ -117,6 +120,25 @@ type Options struct {
// function to perform region lookups appropriately.
CustomRegionViaURL func(u url.URL) string
// Provide a custom function that returns BucketLookupType based
// on the input URL, this is just like s3utils.IsVirtualHostSupported()
// function but allows users to provide their own implementation.
// Once this is set it overrides all settings for opts.BucketLookup
// if this function returns BucketLookupAuto then default detection
// via s3utils.IsVirtualHostSupported() is used, otherwise the
// function is expected to return appropriate value as expected for
// the URL the user wishes to honor.
//
// BucketName is passed additionally for the caller to ensure
// handle situations where `bucketNames` have multiple `.` separators
// in such case HTTPs certs will not work properly for *.<domain>
// wildcards, so you need to specifically handle these situations
// and not return bucket as part of DNS since those requests may fail.
//
// For better understanding look at s3utils.IsVirtualHostSupported()
// implementation.
BucketLookupViaURL func(u url.URL, bucketName string) BucketLookupType
// TrailingHeaders indicates server support of trailing headers.
// Only supported for v4 signatures.
TrailingHeaders bool
@ -133,7 +155,7 @@ type Options struct {
// Global constants.
const (
libraryName = "minio-go"
libraryVersion = "v7.0.84"
libraryVersion = "v7.0.85"
)
// User Agent should always following the below style.
@ -279,6 +301,7 @@ func privateNew(endpoint string, opts *Options) (*Client, error) {
// Sets bucket lookup style, whether server accepts DNS or Path lookup. Default is Auto - determined
// by the SDK. When Auto is specified, DNS lookup is used for Amazon/Google cloud endpoints and Path for all other endpoints.
clnt.lookup = opts.BucketLookup
clnt.lookupFn = opts.BucketLookupViaURL
// healthcheck is not initialized
clnt.healthStatus = unknown
@ -1003,6 +1026,18 @@ func (c *Client) makeTargetURL(bucketName, objectName, bucketLocation string, is
// returns true if virtual hosted style requests are to be used.
func (c *Client) isVirtualHostStyleRequest(url url.URL, bucketName string) bool {
if c.lookupFn != nil {
lookup := c.lookupFn(url, bucketName)
switch lookup {
case BucketLookupDNS:
return true
case BucketLookupPath:
return false
}
// if its auto then we fallback to default detection.
return s3utils.IsVirtualHostSupported(url, bucketName)
}
if bucketName == "" {
return false
}
@ -1010,11 +1045,12 @@ func (c *Client) isVirtualHostStyleRequest(url url.URL, bucketName string) bool
if c.lookup == BucketLookupDNS {
return true
}
if c.lookup == BucketLookupPath {
return false
}
// default to virtual only for Amazon/Google storage. In all other cases use
// default to virtual only for Amazon/Google storage. In all other cases use
// path style requests
return s3utils.IsVirtualHostSupported(url, bucketName)
}

View file

@ -32,6 +32,18 @@ var awsS3EndpointMap = map[string]awsS3Endpoint{
"s3.us-east-2.amazonaws.com",
"s3.dualstack.us-east-2.amazonaws.com",
},
"us-iso-east-1": {
"s3.us-iso-east-1.c2s.ic.gov",
"s3.dualstack.us-iso-east-1.c2s.ic.gov",
},
"us-isob-east-1": {
"s3.us-isob-east-1.sc2s.sgov.gov",
"s3.dualstack.us-isob-east-1.sc2s.sgov.gov",
},
"us-iso-west-1": {
"s3.us-iso-west-1.c2s.ic.gov",
"s3.dualstack.us-iso-west-1.c2s.ic.gov",
},
"us-west-2": {
"s3.us-west-2.amazonaws.com",
"s3.dualstack.us-west-2.amazonaws.com",

View file

@ -514,7 +514,11 @@ func (c *Client) Accept(ctx context.Context, chal *Challenge) (*Challenge, error
return nil, err
}
res, err := c.post(ctx, nil, chal.URI, json.RawMessage("{}"), wantStatus(
payload := json.RawMessage("{}")
if len(chal.Payload) != 0 {
payload = chal.Payload
}
res, err := c.post(ctx, nil, chal.URI, payload, wantStatus(
http.StatusOK, // according to the spec
http.StatusAccepted, // Let's Encrypt: see https://goo.gl/WsJ7VT (acme-divergences.md)
))

View file

@ -7,6 +7,7 @@ package acme
import (
"crypto"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"net/http"
@ -527,6 +528,16 @@ type Challenge struct {
// when this challenge was used.
// The type of a non-nil value is *Error.
Error error
// Payload is the JSON-formatted payload that the client sends
// to the server to indicate it is ready to respond to the challenge.
// When unset, it defaults to an empty JSON object: {}.
// For most challenges, the client must not set Payload,
// see https://tools.ietf.org/html/rfc8555#section-7.5.1.
// Payload is used only for newer challenges (such as "device-attest-01")
// where the client must send additional data for the server to validate
// the challenge.
Payload json.RawMessage
}
// wireChallenge is ACME JSON challenge representation.

View file

@ -80,6 +80,7 @@ type handshakeTransport struct {
pendingPackets [][]byte // Used when a key exchange is in progress.
writePacketsLeft uint32
writeBytesLeft int64
userAuthComplete bool // whether the user authentication phase is complete
// If the read loop wants to schedule a kex, it pings this
// channel, and the write loop will send out a kex
@ -552,16 +553,25 @@ func (t *handshakeTransport) sendKexInit() error {
return nil
}
var errSendBannerPhase = errors.New("ssh: SendAuthBanner outside of authentication phase")
func (t *handshakeTransport) writePacket(p []byte) error {
t.mu.Lock()
defer t.mu.Unlock()
switch p[0] {
case msgKexInit:
return errors.New("ssh: only handshakeTransport can send kexInit")
case msgNewKeys:
return errors.New("ssh: only handshakeTransport can send newKeys")
case msgUserAuthBanner:
if t.userAuthComplete {
return errSendBannerPhase
}
case msgUserAuthSuccess:
t.userAuthComplete = true
}
t.mu.Lock()
defer t.mu.Unlock()
if t.writeError != nil {
return t.writeError
}

View file

@ -59,6 +59,27 @@ type GSSAPIWithMICConfig struct {
Server GSSAPIServer
}
// SendAuthBanner implements [ServerPreAuthConn].
func (s *connection) SendAuthBanner(msg string) error {
return s.transport.writePacket(Marshal(&userAuthBannerMsg{
Message: msg,
}))
}
func (*connection) unexportedMethodForFutureProofing() {}
// ServerPreAuthConn is the interface available on an incoming server
// connection before authentication has completed.
type ServerPreAuthConn interface {
unexportedMethodForFutureProofing() // permits growing ServerPreAuthConn safely later, ala testing.TB
ConnMetadata
// SendAuthBanner sends a banner message to the client.
// It returns an error once the authentication phase has ended.
SendAuthBanner(string) error
}
// ServerConfig holds server specific configuration data.
type ServerConfig struct {
// Config contains configuration shared between client and server.
@ -118,6 +139,12 @@ type ServerConfig struct {
// attempts.
AuthLogCallback func(conn ConnMetadata, method string, err error)
// PreAuthConnCallback, if non-nil, is called upon receiving a new connection
// before any authentication has started. The provided ServerPreAuthConn
// can be used at any time before authentication is complete, including
// after this callback has returned.
PreAuthConnCallback func(ServerPreAuthConn)
// ServerVersion is the version identification string to announce in
// the public handshake.
// If empty, a reasonable default is used.
@ -488,6 +515,10 @@ func (b *BannerError) Error() string {
}
func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, error) {
if config.PreAuthConnCallback != nil {
config.PreAuthConnCallback(s)
}
sessionID := s.transport.getSessionID()
var cache pubKeyCache
var perms *Permissions
@ -495,7 +526,7 @@ func (s *connection) serverAuthenticate(config *ServerConfig) (*Permissions, err
authFailures := 0
noneAuthCount := 0
var authErrs []error
var displayedBanner bool
var calledBannerCallback bool
partialSuccessReturned := false
// Set the initial authentication callbacks from the config. They can be
// changed if a PartialSuccessError is returned.
@ -542,14 +573,10 @@ userAuthLoop:
s.user = userAuthReq.User
if !displayedBanner && config.BannerCallback != nil {
displayedBanner = true
msg := config.BannerCallback(s)
if msg != "" {
bannerMsg := &userAuthBannerMsg{
Message: msg,
}
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
if !calledBannerCallback && config.BannerCallback != nil {
calledBannerCallback = true
if msg := config.BannerCallback(s); msg != "" {
if err := s.SendAuthBanner(msg); err != nil {
return nil, err
}
}
@ -762,10 +789,7 @@ userAuthLoop:
var bannerErr *BannerError
if errors.As(authErr, &bannerErr) {
if bannerErr.Message != "" {
bannerMsg := &userAuthBannerMsg{
Message: bannerErr.Message,
}
if err := s.transport.writePacket(Marshal(bannerMsg)); err != nil {
if err := s.SendAuthBanner(bannerErr.Message); err != nil {
return nil, err
}
}

View file

@ -118,6 +118,7 @@ func (g *Group) TryGo(f func() error) bool {
// SetLimit limits the number of active goroutines in this group to at most n.
// A negative value indicates no limit.
// A limit of zero will prevent any new goroutines from being added.
//
// Any subsequent call to the Go method will block until it can add an active
// goroutine without exceeding the configured limit.

3
vendor/golang.org/x/sys/cpu/cpu.go generated vendored
View file

@ -72,6 +72,9 @@ var X86 struct {
HasSSSE3 bool // Supplemental streaming SIMD extension 3
HasSSE41 bool // Streaming SIMD extension 4 and 4.1
HasSSE42 bool // Streaming SIMD extension 4 and 4.2
HasAVXIFMA bool // Advanced vector extension Integer Fused Multiply Add
HasAVXVNNI bool // Advanced vector extension Vector Neural Network Instructions
HasAVXVNNIInt8 bool // Advanced vector extension Vector Neural Network Int8 instructions
_ CacheLinePad
}

View file

@ -53,6 +53,9 @@ func initOptions() {
{Name: "sse41", Feature: &X86.HasSSE41},
{Name: "sse42", Feature: &X86.HasSSE42},
{Name: "ssse3", Feature: &X86.HasSSSE3},
{Name: "avxifma", Feature: &X86.HasAVXIFMA},
{Name: "avxvnni", Feature: &X86.HasAVXVNNI},
{Name: "avxvnniint8", Feature: &X86.HasAVXVNNIInt8},
// These capabilities should always be enabled on amd64:
{Name: "sse2", Feature: &X86.HasSSE2, Required: runtime.GOARCH == "amd64"},
@ -106,7 +109,7 @@ func archInit() {
return
}
_, ebx7, ecx7, edx7 := cpuid(7, 0)
eax7, ebx7, ecx7, edx7 := cpuid(7, 0)
X86.HasBMI1 = isSet(3, ebx7)
X86.HasAVX2 = isSet(5, ebx7) && osSupportsAVX
X86.HasBMI2 = isSet(8, ebx7)
@ -134,14 +137,24 @@ func archInit() {
X86.HasAVX512VAES = isSet(9, ecx7)
X86.HasAVX512VBMI2 = isSet(6, ecx7)
X86.HasAVX512BITALG = isSet(12, ecx7)
eax71, _, _, _ := cpuid(7, 1)
X86.HasAVX512BF16 = isSet(5, eax71)
}
X86.HasAMXTile = isSet(24, edx7)
X86.HasAMXInt8 = isSet(25, edx7)
X86.HasAMXBF16 = isSet(22, edx7)
// These features depend on the second level of extended features.
if eax7 >= 1 {
eax71, _, _, edx71 := cpuid(7, 1)
if X86.HasAVX512 {
X86.HasAVX512BF16 = isSet(5, eax71)
}
if X86.HasAVX {
X86.HasAVXIFMA = isSet(23, eax71)
X86.HasAVXVNNI = isSet(4, eax71)
X86.HasAVXVNNIInt8 = isSet(4, edx71)
}
}
}
func isSet(bitpos uint, value uint32) bool {

36
vendor/golang.org/x/sys/unix/auxv.go generated vendored Normal file
View file

@ -0,0 +1,36 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
package unix
import (
"syscall"
"unsafe"
)
//go:linkname runtime_getAuxv runtime.getAuxv
func runtime_getAuxv() []uintptr
// Auxv returns the ELF auxiliary vector as a sequence of key/value pairs.
// The returned slice is always a fresh copy, owned by the caller.
// It returns an error on non-ELF platforms, or if the auxiliary vector cannot be accessed,
// which happens in some locked-down environments and build modes.
func Auxv() ([][2]uintptr, error) {
vec := runtime_getAuxv()
vecLen := len(vec)
if vecLen == 0 {
return nil, syscall.ENOENT
}
if vecLen%2 != 0 {
return nil, syscall.EINVAL
}
result := make([]uintptr, vecLen)
copy(result, vec)
return unsafe.Slice((*[2]uintptr)(unsafe.Pointer(&result[0])), vecLen/2), nil
}

13
vendor/golang.org/x/sys/unix/auxv_unsupported.go generated vendored Normal file
View file

@ -0,0 +1,13 @@
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//go:build !go1.21 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris || zos)
package unix
import "syscall"
func Auxv() ([][2]uintptr, error) {
return nil, syscall.ENOTSUP
}

View file

@ -1102,3 +1102,90 @@ func (s *Strioctl) SetInt(i int) {
func IoctlSetStrioctlRetInt(fd int, req int, s *Strioctl) (int, error) {
return ioctlPtrRet(fd, req, unsafe.Pointer(s))
}
// Ucred Helpers
// See ucred(3c) and getpeerucred(3c)
//sys getpeerucred(fd uintptr, ucred *uintptr) (err error)
//sys ucredFree(ucred uintptr) = ucred_free
//sys ucredGet(pid int) (ucred uintptr, err error) = ucred_get
//sys ucredGeteuid(ucred uintptr) (uid int) = ucred_geteuid
//sys ucredGetegid(ucred uintptr) (gid int) = ucred_getegid
//sys ucredGetruid(ucred uintptr) (uid int) = ucred_getruid
//sys ucredGetrgid(ucred uintptr) (gid int) = ucred_getrgid
//sys ucredGetsuid(ucred uintptr) (uid int) = ucred_getsuid
//sys ucredGetsgid(ucred uintptr) (gid int) = ucred_getsgid
//sys ucredGetpid(ucred uintptr) (pid int) = ucred_getpid
// Ucred is an opaque struct that holds user credentials.
type Ucred struct {
ucred uintptr
}
// We need to ensure that ucredFree is called on the underlying ucred
// when the Ucred is garbage collected.
func ucredFinalizer(u *Ucred) {
ucredFree(u.ucred)
}
func GetPeerUcred(fd uintptr) (*Ucred, error) {
var ucred uintptr
err := getpeerucred(fd, &ucred)
if err != nil {
return nil, err
}
result := &Ucred{
ucred: ucred,
}
// set the finalizer on the result so that the ucred will be freed
runtime.SetFinalizer(result, ucredFinalizer)
return result, nil
}
func UcredGet(pid int) (*Ucred, error) {
ucred, err := ucredGet(pid)
if err != nil {
return nil, err
}
result := &Ucred{
ucred: ucred,
}
// set the finalizer on the result so that the ucred will be freed
runtime.SetFinalizer(result, ucredFinalizer)
return result, nil
}
func (u *Ucred) Geteuid() int {
defer runtime.KeepAlive(u)
return ucredGeteuid(u.ucred)
}
func (u *Ucred) Getruid() int {
defer runtime.KeepAlive(u)
return ucredGetruid(u.ucred)
}
func (u *Ucred) Getsuid() int {
defer runtime.KeepAlive(u)
return ucredGetsuid(u.ucred)
}
func (u *Ucred) Getegid() int {
defer runtime.KeepAlive(u)
return ucredGetegid(u.ucred)
}
func (u *Ucred) Getrgid() int {
defer runtime.KeepAlive(u)
return ucredGetrgid(u.ucred)
}
func (u *Ucred) Getsgid() int {
defer runtime.KeepAlive(u)
return ucredGetsgid(u.ucred)
}
func (u *Ucred) Getpid() int {
defer runtime.KeepAlive(u)
return ucredGetpid(u.ucred)
}

View file

@ -1245,6 +1245,7 @@ const (
FAN_REPORT_DFID_NAME = 0xc00
FAN_REPORT_DFID_NAME_TARGET = 0x1e00
FAN_REPORT_DIR_FID = 0x400
FAN_REPORT_FD_ERROR = 0x2000
FAN_REPORT_FID = 0x200
FAN_REPORT_NAME = 0x800
FAN_REPORT_PIDFD = 0x80
@ -1330,8 +1331,10 @@ const (
FUSE_SUPER_MAGIC = 0x65735546
FUTEXFS_SUPER_MAGIC = 0xbad1dea
F_ADD_SEALS = 0x409
F_CREATED_QUERY = 0x404
F_DUPFD = 0x0
F_DUPFD_CLOEXEC = 0x406
F_DUPFD_QUERY = 0x403
F_EXLCK = 0x4
F_GETFD = 0x1
F_GETFL = 0x3
@ -1551,6 +1554,7 @@ const (
IPPROTO_ROUTING = 0x2b
IPPROTO_RSVP = 0x2e
IPPROTO_SCTP = 0x84
IPPROTO_SMC = 0x100
IPPROTO_TCP = 0x6
IPPROTO_TP = 0x1d
IPPROTO_UDP = 0x11
@ -1623,6 +1627,8 @@ const (
IPV6_UNICAST_IF = 0x4c
IPV6_USER_FLOW = 0xe
IPV6_V6ONLY = 0x1a
IPV6_VERSION = 0x60
IPV6_VERSION_MASK = 0xf0
IPV6_XFRM_POLICY = 0x23
IP_ADD_MEMBERSHIP = 0x23
IP_ADD_SOURCE_MEMBERSHIP = 0x27
@ -1867,6 +1873,7 @@ const (
MADV_UNMERGEABLE = 0xd
MADV_WILLNEED = 0x3
MADV_WIPEONFORK = 0x12
MAP_DROPPABLE = 0x8
MAP_FILE = 0x0
MAP_FIXED = 0x10
MAP_FIXED_NOREPLACE = 0x100000
@ -1967,6 +1974,7 @@ const (
MSG_PEEK = 0x2
MSG_PROXY = 0x10
MSG_RST = 0x1000
MSG_SOCK_DEVMEM = 0x2000000
MSG_SYN = 0x400
MSG_TRUNC = 0x20
MSG_TRYHARD = 0x4
@ -2083,6 +2091,7 @@ const (
NFC_ATR_REQ_MAXSIZE = 0x40
NFC_ATR_RES_GB_MAXSIZE = 0x2f
NFC_ATR_RES_MAXSIZE = 0x40
NFC_ATS_MAXSIZE = 0x14
NFC_COMM_ACTIVE = 0x0
NFC_COMM_PASSIVE = 0x1
NFC_DEVICE_NAME_MAXSIZE = 0x8
@ -2163,6 +2172,7 @@ const (
NFNL_SUBSYS_QUEUE = 0x3
NFNL_SUBSYS_ULOG = 0x4
NFS_SUPER_MAGIC = 0x6969
NFT_BITWISE_BOOL = 0x0
NFT_CHAIN_FLAGS = 0x7
NFT_CHAIN_MAXNAMELEN = 0x100
NFT_CT_MAX = 0x17
@ -2491,6 +2501,7 @@ const (
PR_GET_PDEATHSIG = 0x2
PR_GET_SECCOMP = 0x15
PR_GET_SECUREBITS = 0x1b
PR_GET_SHADOW_STACK_STATUS = 0x4a
PR_GET_SPECULATION_CTRL = 0x34
PR_GET_TAGGED_ADDR_CTRL = 0x38
PR_GET_THP_DISABLE = 0x2a
@ -2499,6 +2510,7 @@ const (
PR_GET_TIMING = 0xd
PR_GET_TSC = 0x19
PR_GET_UNALIGN = 0x5
PR_LOCK_SHADOW_STACK_STATUS = 0x4c
PR_MCE_KILL = 0x21
PR_MCE_KILL_CLEAR = 0x0
PR_MCE_KILL_DEFAULT = 0x2
@ -2525,6 +2537,8 @@ const (
PR_PAC_GET_ENABLED_KEYS = 0x3d
PR_PAC_RESET_KEYS = 0x36
PR_PAC_SET_ENABLED_KEYS = 0x3c
PR_PMLEN_MASK = 0x7f000000
PR_PMLEN_SHIFT = 0x18
PR_PPC_DEXCR_CTRL_CLEAR = 0x4
PR_PPC_DEXCR_CTRL_CLEAR_ONEXEC = 0x10
PR_PPC_DEXCR_CTRL_EDITABLE = 0x1
@ -2592,6 +2606,7 @@ const (
PR_SET_PTRACER = 0x59616d61
PR_SET_SECCOMP = 0x16
PR_SET_SECUREBITS = 0x1c
PR_SET_SHADOW_STACK_STATUS = 0x4b
PR_SET_SPECULATION_CTRL = 0x35
PR_SET_SYSCALL_USER_DISPATCH = 0x3b
PR_SET_TAGGED_ADDR_CTRL = 0x37
@ -2602,6 +2617,9 @@ const (
PR_SET_UNALIGN = 0x6
PR_SET_VMA = 0x53564d41
PR_SET_VMA_ANON_NAME = 0x0
PR_SHADOW_STACK_ENABLE = 0x1
PR_SHADOW_STACK_PUSH = 0x4
PR_SHADOW_STACK_WRITE = 0x2
PR_SME_GET_VL = 0x40
PR_SME_SET_VL = 0x3f
PR_SME_SET_VL_ONEXEC = 0x40000
@ -2911,7 +2929,6 @@ const (
RTM_NEWNEXTHOP = 0x68
RTM_NEWNEXTHOPBUCKET = 0x74
RTM_NEWNSID = 0x58
RTM_NEWNVLAN = 0x70
RTM_NEWPREFIX = 0x34
RTM_NEWQDISC = 0x24
RTM_NEWROUTE = 0x18
@ -2920,6 +2937,7 @@ const (
RTM_NEWTCLASS = 0x28
RTM_NEWTFILTER = 0x2c
RTM_NEWTUNNEL = 0x78
RTM_NEWVLAN = 0x70
RTM_NR_FAMILIES = 0x1b
RTM_NR_MSGTYPES = 0x6c
RTM_SETDCB = 0x4f

View file

@ -116,6 +116,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x800
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -304,6 +306,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103

View file

@ -116,6 +116,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x800
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -305,6 +307,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103

View file

@ -115,6 +115,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x800
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -310,6 +312,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103

View file

@ -109,6 +109,7 @@ const (
F_SETOWN = 0x8
F_UNLCK = 0x2
F_WRLCK = 0x1
GCS_MAGIC = 0x47435300
HIDIOCGRAWINFO = 0x80084803
HIDIOCGRDESC = 0x90044802
HIDIOCGRDESCSIZE = 0x80044801
@ -119,6 +120,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x800
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -302,6 +305,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103

View file

@ -116,6 +116,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x800
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x7b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -297,6 +299,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x40182103

View file

@ -115,6 +115,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x80
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
IPV6_FLOWINFO_MASK = 0xfffffff
IPV6_FLOWLABEL_MASK = 0xfffff
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -303,6 +305,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103

View file

@ -115,6 +115,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x80
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
IPV6_FLOWINFO_MASK = 0xfffffff
IPV6_FLOWLABEL_MASK = 0xfffff
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -303,6 +305,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103

View file

@ -115,6 +115,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x80
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -303,6 +305,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103

View file

@ -115,6 +115,8 @@ const (
IN_CLOEXEC = 0x80000
IN_NONBLOCK = 0x80
IOCTL_VM_SOCKETS_GET_LOCAL_CID = 0x200007b9
IPV6_FLOWINFO_MASK = 0xffffff0f
IPV6_FLOWLABEL_MASK = 0xffff0f00
ISIG = 0x1
IUCLC = 0x200
IXOFF = 0x1000
@ -303,6 +305,7 @@ const (
SCM_TIMESTAMPING_OPT_STATS = 0x36
SCM_TIMESTAMPING_PKTINFO = 0x3a
SCM_TIMESTAMPNS = 0x23
SCM_TS_OPT_ID = 0x51
SCM_TXTIME = 0x3d
SCM_WIFI_STATUS = 0x29
SECCOMP_IOCTL_NOTIF_ADDFD = 0x80182103

Some files were not shown because too many files have changed in this diff Show more