mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 13:05:32 +09:00
docs: correct misreadable and factually wrong reference prose (#2587)
This commit is contained in:
1 parent
43924e3ac5
commit
08c9fe9886
26 files changed
+37
-37
No files matched your search
@@ -8,7 +8,7 @@ import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
An archive is a snapshot of one user account or one guild, built in the background and downloaded as a file. [Create user archive](/admin-api/users/#create-user-archive) and [Create guild archive](/admin-api/guilds/#create-guild-archive) request one. The operations here read archive state and issue time-limited download URLs.
|
||||
|
||||
Every operation needs an [ACL](/admin-api/#acl-evaluation) covering the subject type it touches. A user archive needs `archive:view_all` or `archive:trigger:user`. A guild archive needs `archive:view_all` or `archive:trigger:guild`. Reading both types at once needs `archive:view_all`.
|
||||
Every operation needs an [ACL](/admin-api/#acl-evaluation) covering the subject type it touches. A user archive needs `archive:view_all` or `archive:trigger:user`. A guild archive needs `archive:view_all` or `archive:trigger:guild`. Reading both types at once needs `archive:view_all`, or `archive:trigger:user` and `archive:trigger:guild` together.
|
||||
|
||||
:::note[An expired archive stops being readable]
|
||||
`expires_at` is 365 days after the archive is requested and is never extended. The archive record is removed at that instant, and no operation reads the stored file afterwards.
|
||||
@@ -121,8 +121,8 @@ Returns [archive](#archive-object) objects matching the supplied filters, newest
|
||||
|
||||
<sup>5</sup> The value counts as true only for `true`, `True`, or `1`. Expired archives are dropped after `limit` rows have been read, so a response can hold fewer than `limit` archives
|
||||
|
||||
:::caution[A trigger ACL cannot use the default filter]
|
||||
`all` is the default and needs `archive:view_all`. An account holding only `archive:trigger:user` or `archive:trigger:guild` has to set `subject_type` explicitly or the request returns 403 `MISSING_ACL`.
|
||||
:::note[The default filter narrows to the account's ACLs]
|
||||
`all` is the default, and Fluxer resolves it to the subject types the account's ACLs cover. An account holding only `archive:trigger:user` reads user archives, an account holding only `archive:trigger:guild` reads guild archives, and an account holding `archive:view_all` reads both. An account holding none of the three is refused with 403 `MISSING_ACL`.
|
||||
:::
|
||||
|
||||
### Response body
|
||||
|
||||
@@ -210,7 +210,7 @@ An application that is already approved, rejected, or removed fails with 409 `DI
|
||||
|
||||
An approval moves the application to `approved` and records the review time, the reviewing Admin, and the supplied reason. It adds the discoverable feature to the guild and indexes the listing, so the guild appears in [Search discovery guilds](/http-api/discovery/#search-discovery-guilds). [Guild Update](/gateway/events/#guild-update) fires to every session that can observe the guild. Indexing is skipped on an instance with no search backend configured, and the approval still succeeds.
|
||||
|
||||
Fluxer moves a rejected application to `rejected` and records the review time, the reviewing Admin, and the required reason. It leaves every guild field as it is and emits no Gateway Dispatch.
|
||||
A rejection moves the application to `rejected` and records the review time, the reviewing Admin, and the required reason. It leaves every guild field as it is and emits no Gateway Dispatch.
|
||||
|
||||
An approval whose guild can no longer be resolved still succeeds. Fluxer skips the feature grant and the Dispatch.
|
||||
|
||||
@@ -257,7 +257,7 @@ Returns an offset page of the approved listings filed under one category, most m
|
||||
|
||||
<sup>1</sup> Applied after the category filter and the member sort, so raise it to page a category
|
||||
|
||||
A rebuild of the discovery search index does not change what it answers. It reports no total, so a page shorter than `limit` is the only end-of-category signal. A listing whose guild could not be resolved sorts as if it had no members and lands at the end.
|
||||
A rebuild of the discovery search index does not change what this operation answers. It reports no total, so a page shorter than `limit` is the only end-of-category signal. A listing whose guild could not be resolved sorts as if it had no members and lands at the end.
|
||||
|
||||
### Response
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
Instance configuration is everything an operator can change at runtime. It covers single sign-on, Gateway rollout, registration policy, branding and legal links, instance policy, third party integrations, media retention, and the ordered limit configuration. The [Instance](/http-api/instance/) resource serves the subset published to unauthenticated clients.
|
||||
|
||||
Every write is a merge over the stored configuration. An omitted key leaves the stored value unchanged.
|
||||
Every write is a merge over the stored configuration, and an omitted key leaves the stored value unchanged. The limit configuration write is the one exception, and it replaces the stored document.
|
||||
|
||||
Reading configuration requires the [Admin ACL](/admin-api/#acl-registry) `instance:config:view`, and writing it requires `instance:config:update`. The limit configuration has its own pair, `instance:limit_config:view` and `instance:limit_config:update`. The heap snapshot requires `system:heap_snapshot`.
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ The operator supplies `id` on creation, and it is the primary key. It is the val
|
||||
| updated_at | ?ISO8601 timestamp | Time the region record last changed, or null when the stored row has none |
|
||||
| servers?<sup>4</sup> | array[[Admin voice server](#admin-voice-server-object) object] | The servers registered in the region |
|
||||
|
||||
<sup>1</sup> The flag is not exclusive, and setting it on a second region does not clear it on the first. Each node then treats the first region its reload enumerates as the default, and a topology with the flag on no region falls back the same way
|
||||
<sup>1</sup> The flag is not exclusive, and setting it on a second region does not clear it on the first. Each node then treats the first flagged region its reload enumerates as the default, and a topology with the flag on no region falls back to the first region its reload enumerates
|
||||
|
||||
<sup>2</sup> Setting any of these three makes the region unusable for a private call
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ The response body has this member alongside `code` and `message`.
|
||||
|
||||
## Admin API keys
|
||||
|
||||
An Admin API key is read only on a route below `/v1/admin`, and an unknown, expired, or invalid key leaves the request unauthenticated. A valid key authenticates as the user who created it and has the ACLs stored on the key.
|
||||
An Admin API key is read only on a route below `/v1/admin`, and an unknown, expired, or invalid key leaves the request unauthenticated. A valid key authenticates as the user who created it, and the request has the ACLs stored on the key.
|
||||
|
||||
An Admin operation also accepts a user session token and an OAuth2 bearer token, and a bearer token is accepted only when it belongs to the built-in Admin OAuth2 application. A bearer token from any other application returns 403 `ACCESS_DENIED`. A request with a bot token returns 401 `UNAUTHORIZED`.
|
||||
|
||||
|
||||
@@ -615,7 +615,7 @@ A group whose count is `0` is omitted. The `offline` group is also omitted once
|
||||
| range | array[integer] | Inclusive `[start, end]` range this operation replaces |
|
||||
| items | array[[member list item object](#member-list-item-object)] | Replacement items for the range |
|
||||
|
||||
`SYNC` is the only operation Fluxer sends. A client MUST ignore an operation whose `op` it does not recognise and whose range fails the bounds in [Lazy Request](/gateway/commands/#lazy-request).
|
||||
`SYNC` is the only operation Fluxer sends. A client MUST ignore an operation whose `op` it does not recognise or whose range fails the bounds in [Lazy Request](/gateway/commands/#lazy-request).
|
||||
|
||||
#### Member list item object
|
||||
|
||||
@@ -823,7 +823,7 @@ A session that set the `DEBOUNCE_MESSAGE_REACTIONS` [session flag](/gateway/comm
|
||||
| guild_id?<sup>1</sup> | snowflake | Guild the channel belongs to |
|
||||
| reactions | array[[reaction addition object](#reaction-addition-object)] | The coalesced additions, in arrival order |
|
||||
|
||||
<sup>1</sup> Taken from the first addition in the window. The window is per session, so a run that spans several messages reports every addition under the first message's channel, message, and guild, and a client MUST read each addition's own identity from that entry
|
||||
<sup>1</sup> Taken from the first addition of the group. The window is per session, and the session groups the additions by guild, channel, and message when the window closes. Each group is one Dispatch, so every addition in `reactions` is on the message these fields name
|
||||
|
||||
A window that closes holding exactly one addition sends [Message Reaction Add](#message-reaction-add) instead, and a session without the flag receives one Message Reaction Add per addition.
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ Lazy Request accepts at most 10 member list ranges per channel, each with `end`
|
||||
|
||||
Request Guild Counts accepts at most 100 guild IDs after deduplication. Request Channel Member Counts accepts at most 25 channel IDs after deduplication. Both nonces run from 1 through 64 bytes, and a nonce outside that bound is omitted from the result.
|
||||
|
||||
Identify accepts at most 256 `ignored_events` entries. A longer array closes with `4002` and reason `Invalid identify payload`. Every other bound on this page coerces or drops. [Client commands](/gateway/commands/) states the exact coercion or drop rule for each field.
|
||||
Identify accepts at most 256 `ignored_events` entries. A longer array closes with `4002` and reason `Invalid identify payload`. Every other command payload bound coerces or drops. [Client commands](/gateway/commands/) states the exact coercion or drop rule for each field.
|
||||
|
||||
## Voice admission
|
||||
|
||||
|
||||
@@ -190,4 +190,4 @@ A held or discarded Identify, an over-budget Presence Update, a dropped bounded
|
||||
|
||||
## Ordinary WebSocket closes
|
||||
|
||||
A transport can end with no Fluxer application close code, as happens on a network failure, an intermediary reset, and an ordinary `1000` or `1001` close. An established session remains available for 60,000 ms after the transport ends. Ending the transport does not extend that window or its bounded replay history.
|
||||
A transport can end with no Fluxer application close code, as happens on a network failure, an intermediary reset, and an ordinary `1000` or `1001` close. An established session remains available for 60,000 ms after the transport ends. A later transport end starts a new 60,000 ms window, and neither the window length nor the bounded replay history grows.
|
||||
@@ -82,7 +82,7 @@ Every logical message uses the Gateway payload.
|
||||
|
||||
<sup>1</sup> Heartbeat ACK and Reconnect have no `d` at all, and Invalid Session has the Boolean `false`
|
||||
|
||||
A decoded payload that is not a JSON object closes with `4002` and reason `Decode failed`. An object with no `op` closes with `4002` and reason `Invalid payload`. An object with `op` but no `d` closes with `4001` and reason `Unknown opcode`, except for Identify, which closes with `4005`.
|
||||
A decoded payload that is not a JSON object closes with `4002` and reason `Decode failed`. An object with no `op` closes with `4002` and reason `Invalid payload`. An object with `op` but no `d` closes with `4001` and reason `Unknown opcode`, except for Identify and Resume, which close with `4005`.
|
||||
|
||||
A Dispatch is a server-to-client event payload. Every live Dispatch advances the session sequence by one. A session starts at sequence 0, so the [Ready](/gateway/events/#ready) sequence is 1.
|
||||
|
||||
|
||||
@@ -257,7 +257,7 @@ Every rejection reports the same `INVALID_TOKEN`, so a caller cannot distinguish
|
||||
|
||||
<RouteHeader method="GET" path="/v1/oauth2/applications/{id}/public" unauthenticated />
|
||||
|
||||
Returns the [public application](#public-application-object) object for any application. Authentication is not required. A credential that resolves to an account also populates `current_user` and reports the owner's view of `bot_public`.
|
||||
Returns the [public application](#public-application-object) object for any application. Authentication is not required. A credential that resolves to an account also populates `current_user`, and one that resolves to the application owner reports `bot_public` as true even when the bot is not public.
|
||||
|
||||
### Path parameters
|
||||
|
||||
|
||||
@@ -856,7 +856,7 @@ The operation creates one 64-character verification token bound to the account a
|
||||
|
||||
Accepts a password recovery request for an email address. Authentication is not required. Returns 204 with no body.
|
||||
|
||||
This is a local authentication operation and it verifies CAPTCHA when CAPTCHA is enabled. Fluxer consumes both extra allowances before it validates the address, and exhausting either returns 429.
|
||||
This is a local authentication operation and it verifies CAPTCHA when CAPTCHA is enabled. Fluxer consumes both the client IP address and email address allowances before it validates the address, and exhausting either returns 429.
|
||||
|
||||
### Request headers
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ Refunds the account's most recent eligible purchase and returns the [refund](#re
|
||||
|
||||
The same invoice selection as [get refund eligibility](#get-refund-eligibility) applies.
|
||||
|
||||
Repeating the request returns the same provider refund. After a refund the provider reports as failed or cancelled, the account can attempt the refund again.
|
||||
Repeating the request returns the same provider refund. After a refund that the provider reports as failed or cancelled, the account can attempt the refund again.
|
||||
|
||||
:::note[A Pix refund is short one minor unit]
|
||||
When the resolved charge was paid with Pix and the invoice amount is greater than one minor unit, the requested refund is the invoice amount minus one minor unit.
|
||||
|
||||
@@ -174,7 +174,7 @@ The slowmode state combines the channel's configured interval with the authentic
|
||||
|
||||
<sup>1</sup> Both report no delay in a private channel, for an interval of `0`, for a bot caller, and for a caller holding `BYPASS_SLOWMODE`
|
||||
|
||||
<sup>2</sup> False whenever the delay is not accounted, so a bot caller and a private channel both report `false` even though neither is delayed
|
||||
<sup>2</sup> True only for a non-bot caller holding `BYPASS_SLOWMODE` in a guild channel with a non-zero interval, so a bot caller and a private channel both report `false` even though neither is delayed
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ The window length, both thresholds, and the number of windows the score trigger
|
||||
|
||||
## API error code registry
|
||||
|
||||
These codes appear in the top-level `code` field of an error response, transmitted as the exact JSON string shown. The registry is closed and holds exactly 257 codes. Each entry states the leading sentence of the English source message, without its final full stop. Those messages call a [guild](/http-api/guilds/) a community.
|
||||
These codes appear in the top-level `code` field of an error response, transmitted as the exact JSON string shown. The registry is closed and holds exactly 264 codes. Each entry states the leading sentence of the English source message, without its final full stop. Those messages call a [guild](/http-api/guilds/) a community.
|
||||
|
||||
:::note[The rendered `message` fills in the braced values]
|
||||
A description containing a value in braces is an ICU MessageFormat template. `You've reached the maximum of {count, plural, one {# emoji} other {# emojis}}` renders as a complete sentence with the applicable limit.
|
||||
|
||||
@@ -6,7 +6,7 @@ description: Guild audit log entries, their action registry, and the audit reaso
|
||||
|
||||
import RouteHeader from '@/components/RouteHeader.astro';
|
||||
|
||||
An audit log entry records one change made to a guild and the account that made it. It has a numeric action type, the ID of the thing changed, an option map, and a list of before-and-after values. Only [List guild audit logs](#list-guild-audit-logs) reads them.
|
||||
An audit log entry records one change made to a guild and the account that made it. It has a numeric action type, the ID of the thing changed, an option map, and a list of before-and-after values. Only [List guild audit logs](#list-guild-audit-logs) and its [Admin API counterpart](/admin-api/guilds/#list-guild-audit-logs) read them.
|
||||
|
||||
## Audit log reason
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ Every field is optional, and an omitted filter is not applied. The route reads a
|
||||
|
||||
<sup>7</sup> The sort field is camel-cased `joinedAt`, where the result object names the same value `joined_at`
|
||||
|
||||
[Input normalisation](/http-api/#input-normalisation) rewrites `""` to null, which this field rejects with 400 `INVALID_FORM_BODY`. `" "` is accepted.
|
||||
[Input normalisation](/http-api/#input-normalisation) rewrites `""` to null, which the `query` field rejects with 400 `INVALID_FORM_BODY`. `" "` is accepted.
|
||||
|
||||
With no `sort_by`, the route sorts by join time and defaults `sort_order` to `desc`. Two members with the same join time are ordered by descending `id`. `relevance` ignores `sort_order`. A Meilisearch instance orders `relevance` by its own ranking rules. An Elasticsearch instance orders `relevance` by descending `id`.
|
||||
|
||||
|
||||
@@ -81,7 +81,7 @@ An empty string stays an empty string and an empty nested object stays an empty
|
||||
|
||||
[Authentication](/authentication/) defines the accepted `Authorization` schemes, their exact token forms, and the OAuth2 scope registry. An operation that requires a credential states the scheme on its resource page. The [sudo verification object](/http-api/users/mfa/#sudo-verification-object) defines the sudo mode credential that guards sensitive account operations.
|
||||
|
||||
An OAuth2 bearer access token is accepted only where a route opts in, and the resource page says so. Everywhere else a bearer credential is refused with 403 `ACCESS_DENIED`, and an account with a suspicious activity flag is refused with 403 `ACCOUNT_SUSPICIOUS_ACTIVITY`.
|
||||
An OAuth2 bearer access token is accepted only where a route opts in, and the resource page says so. Everywhere else a bearer credential is refused with 403 `ACCESS_DENIED`. An account with a suspicious activity flag is refused with 403 `ACCOUNT_SUSPICIOUS_ACTIVITY`.
|
||||
|
||||
## Standard request headers
|
||||
|
||||
|
||||
@@ -117,9 +117,9 @@ A reply reference resolves into `referenced_message`, and a forward has none. Fl
|
||||
| 7 | USER_JOIN<sup>2</sup> | User-join system message |
|
||||
| 19 | REPLY<sup>1</sup> <sup>2</sup> | Message with a reply reference |
|
||||
|
||||
<sup>1</sup> Only this type can be modified, pinned, unpinned, or used as the target of a reply reference. Any other type rejects modification, pinning, and unpinning with 400 `CANNOT_MODIFY_SYSTEM_WEBHOOK`, and rejects being replied to with 400 `CANNOT_REPLY_TO_SYSTEM_MESSAGE`
|
||||
<sup>1</sup> Only `DEFAULT` and `REPLY` can be modified, pinned, unpinned, or used as the target of a reply reference. Any other type rejects modification, pinning, and unpinning with 400 `CANNOT_MODIFY_SYSTEM_WEBHOOK`, and rejects being replied to with 400 `CANNOT_REPLY_TO_SYSTEM_MESSAGE`
|
||||
|
||||
<sup>2</sup> Only this type can be deleted, and any other type rejects deletion with 403 `MISSING_PERMISSIONS`
|
||||
<sup>2</sup> Only `DEFAULT`, `CHANNEL_PINNED_MESSAGE`, `USER_JOIN`, and `REPLY` can be deleted, and any other type rejects deletion with 403 `MISSING_PERMISSIONS`
|
||||
|
||||
## Message flags
|
||||
|
||||
@@ -1008,7 +1008,7 @@ Fluxer aborts the multipart upload and discards its parts when no part was uploa
|
||||
:::
|
||||
|
||||
:::caution[An unowned upload is reported as invalid input]
|
||||
An upload key the identity does not own, that belongs to another channel, that was planned as singlepart, or that a message already consumed all report 400 `UPLOADED_ATTACHMENT_NOT_FOUND`. A caller cannot tell the four apart, so it cannot probe another identity's upload state.
|
||||
Fluxer reports 400 `UPLOADED_ATTACHMENT_NOT_FOUND` for an upload key the identity does not own, one that belongs to another channel, one planned as singlepart, and one a message already consumed. A caller cannot tell the four apart, so it cannot probe another identity's upload state.
|
||||
:::
|
||||
|
||||
### Side effects
|
||||
|
||||
@@ -58,7 +58,7 @@ An unrecognised scope value is rejected when the authorisation request is comple
|
||||
Scope order has no semantic meaning, so a client MUST compare scopes as a set.
|
||||
:::
|
||||
|
||||
The `scope` string of an [OAuth2 token](#oauth2-token-object) and of an [OAuth2 introspection](#oauth2-introspection-object) is sorted into the registry order above. The `scopes` array of a [current OAuth2 authorisation](#current-oauth2-authorisation-object) and of an [OAuth2 authorisation](#oauth2-authorisation-object) has the stored scopes in no defined order, with unrecognised values removed.
|
||||
The `scope` string of an [OAuth2 token](#oauth2-token-object) and of an [OAuth2 introspection](#oauth2-introspection-object) is sorted into the registry order above. The `scopes` array of a [current OAuth2 authorisation](#current-oauth2-authorisation-object) has the stored scopes in no defined order, with unrecognised values removed. The `scopes` array of an [OAuth2 authorisation](#oauth2-authorisation-object) is in no defined order, and it can hold `bot` and an unrecognised value once more than one refresh token contributes.
|
||||
|
||||
## OAuth2 error response object
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ The single credential [Create DSA report](#create-dsa-report) accepts. Fluxer bi
|
||||
| --- | --- | --- |
|
||||
| ticket<sup>1</sup> | string | The opaque credential [Create DSA report](#create-dsa-report) consumes |
|
||||
|
||||
<sup>1</sup> 64 lowercase hexadecimal characters encoding 32 random bytes, valid for one hour from verification, and consumed by the first [Create DSA report](#create-dsa-report) that presents it
|
||||
<sup>1</sup> 64 lowercase hexadecimal characters encoding 32 random bytes, valid for one hour from verification, and consumed by the first [Create DSA report](#create-dsa-report) that writes a notice with it
|
||||
|
||||
### Example
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ The operation is active only while the instance has presigned harvest downloads
|
||||
The token binds the account, the harvest ID, the stored object key, and an expiry.
|
||||
|
||||
:::note[Every rejection looks identical]
|
||||
A missing, malformed, forged, or expired token, a token for another harvest, a harvest that never completed or recorded a failure, a harvest past its deadline, and a stale object key all return 404 with the plain text body `Not Found`.
|
||||
A missing, malformed, forged, or expired token, a token for another harvest, a harvest that never completed, a harvest that recorded a failure, a harvest past its deadline, and a stale object key all return 404 with the plain text body `Not Found`.
|
||||
:::
|
||||
|
||||
### Path parameters
|
||||
|
||||
@@ -80,7 +80,7 @@ Opens a direct message with one account, or creates a group DM. Returns a [chann
|
||||
|
||||
One body field selects the channel type. `recipient_id` opens a direct message. `recipients` always creates a group DM whatever its length, so a single-element array creates a two-participant group DM, and an empty array creates a group DM whose only participant is the caller.
|
||||
|
||||
A request supplying `recipients` additionally consumes the `user:group_dm:create` bucket and passes the CAPTCHA check below, whatever the resulting participant count.
|
||||
A request supplying `recipients` additionally consumes the `user:group_dm:create` bucket and is subject to the CAPTCHA check below, whatever the resulting participant count.
|
||||
|
||||
Instance policy can disable private channel creation entirely, in which case every request returns 400 `DIRECT_MESSAGES_DISABLED` after the body has been validated and the group DM bucket and CAPTCHA have been applied.
|
||||
|
||||
|
||||
@@ -134,7 +134,7 @@ Every route-produced error response uses `Cache-Control: no-store`, and a succes
|
||||
|
||||
## Range response headers
|
||||
|
||||
A complete media response has `Accept-Ranges: bytes`, the representation `Content-Type`, and an exact `Content-Length`<sup>1</sup>. A 206 additionally sets `Content-Range` to the complete size and `Content-Length` to the selected byte count. A 416 has `Content-Range: bytes */{size}` and `Accept-Ranges: bytes` with an empty body.
|
||||
A complete media response has `Accept-Ranges: bytes`, the representation `Content-Type`, and an exact `Content-Length`<sup>1</sup>. A 206 additionally sets `Content-Range` to the selected interval over the complete size and `Content-Length` to the selected byte count. A 416 has `Content-Range: bytes */{size}` and `Accept-Ranges: bytes` with an empty body.
|
||||
|
||||
<sup>1</sup> A streamed signed external response omits `Content-Length` when the origin declared none
|
||||
|
||||
|
||||
@@ -126,7 +126,7 @@ Quality names are matched exactly and are case-sensitive. An unrecognised value
|
||||
|
||||
An image asset defaults to `high`. An attachment or signed external image defaults to `lossless`, except that a JPEG, HEIC, or HEIF source defaults to `high`. Animated WebP output defaults to `auto` on every route that reads `quality`. A video thumbnail is extracted at `high`, and `quality` then applies only to the resize step that `width` or `height` requests. A non-transforming SVG rasterisation always uses `lossless`.
|
||||
|
||||
Encoder effort defaults to 2 for animated output or `low` quality and 4 otherwise, and it applies to WebP output only. JPEG and PNG have fixed encoder settings, and GIF always encodes at effort 7. The attachment-only `effort` parameter replaces the default and is clamped to 9. Still WebP output clamps it again to 6, and so does lossy animated WebP. Only lossless animated WebP uses 7 through 9.
|
||||
Encoder effort defaults to 2 for animated output or `low` quality and 4 otherwise, and it applies to WebP output only. JPEG and PNG have fixed encoder settings, and GIF always encodes at effort 7. The attachment-only `effort` parameter replaces the default and is clamped to 9. Static WebP output clamps it again to 6, and so does lossy animated WebP. Only lossless animated WebP uses 7 through 9.
|
||||
|
||||
## Animation
|
||||
|
||||
|
||||
@@ -619,13 +619,13 @@ Default `8090`. The health and metrics port. Not published.
|
||||
|
||||
#### `FLUXER_SVC_MAX_CONCURRENT_REQUESTS`
|
||||
|
||||
Defaults to 192 for messages, 320 for snowflakes, 64 otherwise. In-flight request ceiling. The built-in defaults key off `FLUXER_SVC_NAME`. Compose forwards this name to `users`, `users-shard`, `messages`, and `messages-shard` at a default of 20, which pairs with their 20-connection Postgres pools, and leaves the six other containers on the built-in defaults.
|
||||
Defaults to 192 for messages, 320 for snowflakes, 64 otherwise. In-flight request ceiling. The built-in defaults key off `FLUXER_SVC_NAME`. Compose forwards `FLUXER_SVC_MAX_CONCURRENT_REQUESTS` to `users`, `users-shard`, `messages`, and `messages-shard` at a default of 20, which pairs with their 20-connection Postgres pools, and leaves the six other containers on the built-in defaults.
|
||||
|
||||
#### `POD_NAME`
|
||||
|
||||
No default. The shard ordinal source and node identity. Also read by the Gateway and by API RPC timing.
|
||||
|
||||
The API tunes its NATS clients through fifteen further names, none of which are in the override table or in `.env.example`: `FLUXER_SNOWFLAKE_SERVICE_SUBJECT`, `FLUXER_SNOWFLAKE_SERVICE_NATS_CLIENT_NAME`, `FLUXER_SNOWFLAKE_SERVICE_BATCH_SIZE`, `FLUXER_SNOWFLAKE_SERVICE_LOW_WATERMARK`, `FLUXER_SNOWFLAKE_SERVICE_MAX_BUFFER_AGE_MS`, `FLUXER_SNOWFLAKE_SERVICE_REQUEST_TIMEOUT_MS`, `FLUXER_USERS_SERVICE_SUBJECT`, `FLUXER_USERS_SERVICE_NATS_CLIENT_NAME`, `FLUXER_USERS_SERVICE_TIMEOUT_MS`, `FLUXER_USERS_SERVICE_INFLIGHT_MAX_ENTRIES`, `FLUXER_GIF_SERVICE_SUBJECT`, `FLUXER_GIF_SERVICE_NATS_CLIENT_NAME`, `FLUXER_GIF_SERVICE_TIMEOUT_MS`, and `FLUXER_GIF_SERVICE_REGISTER_SHARE_TIMEOUT_MS`. Each falls back to its default when the value is not a positive number.
|
||||
The API tunes its NATS clients through fourteen further names, none of which are in the override table or in `.env.example`: `FLUXER_SNOWFLAKE_SERVICE_SUBJECT`, `FLUXER_SNOWFLAKE_SERVICE_NATS_CLIENT_NAME`, `FLUXER_SNOWFLAKE_SERVICE_BATCH_SIZE`, `FLUXER_SNOWFLAKE_SERVICE_LOW_WATERMARK`, `FLUXER_SNOWFLAKE_SERVICE_MAX_BUFFER_AGE_MS`, `FLUXER_SNOWFLAKE_SERVICE_REQUEST_TIMEOUT_MS`, `FLUXER_USERS_SERVICE_SUBJECT`, `FLUXER_USERS_SERVICE_NATS_CLIENT_NAME`, `FLUXER_USERS_SERVICE_TIMEOUT_MS`, `FLUXER_USERS_SERVICE_INFLIGHT_MAX_ENTRIES`, `FLUXER_GIF_SERVICE_SUBJECT`, `FLUXER_GIF_SERVICE_NATS_CLIENT_NAME`, `FLUXER_GIF_SERVICE_TIMEOUT_MS`, and `FLUXER_GIF_SERVICE_REGISTER_SHARE_TIMEOUT_MS`. Each falls back to its default when the value is not a positive number.
|
||||
|
||||
## Voice and LiveKit
|
||||
|
||||
@@ -906,7 +906,7 @@ Default empty. The webhook signing secret. Not forwarded by the shipped Compose
|
||||
|
||||
Default `{}`. Every price ID at once. JSON object. The individual price variables are declared after it and win.
|
||||
|
||||
Twenty-four individual price variables also exist, one per product and currency: `FLUXER_STRIPE_PRICE_MONTHLY_` and `FLUXER_STRIPE_PRICE_YEARLY_` in USD, EUR, BRL, INR, PLN, and TRY, `FLUXER_STRIPE_PRICE_VISIONARY_` and `FLUXER_STRIPE_PRICE_GIFT_VISIONARY_` in USD and EUR, and `FLUXER_STRIPE_PRICE_GIFT_1_MONTH_` and `FLUXER_STRIPE_PRICE_GIFT_1_YEAR_` in the same six currencies.
|
||||
Twenty-eight individual price variables also exist, one per product and currency: `FLUXER_STRIPE_PRICE_MONTHLY_` and `FLUXER_STRIPE_PRICE_YEARLY_` in USD, EUR, BRL, INR, PLN, and TRY, `FLUXER_STRIPE_PRICE_VISIONARY_` and `FLUXER_STRIPE_PRICE_GIFT_VISIONARY_` in USD and EUR, and `FLUXER_STRIPE_PRICE_GIFT_1_MONTH_` and `FLUXER_STRIPE_PRICE_GIFT_1_YEAR_` in the same six currencies.
|
||||
|
||||
## Moderation and abuse
|
||||
|
||||
@@ -1010,11 +1010,11 @@ Defaults to the inverse of `FLUXER_SELF_HOSTED`. External blocklist feeds. Off b
|
||||
|
||||
A second family, unrelated to the rules above, tunes the IP auto-banner: `FLUXER_ABUSE_WINDOW_MS`, four `FLUXER_ABUSE_THRESHOLD_` names, four `FLUXER_ABUSE_TOKEN_DIVERSITY_` names, `FLUXER_ABUSE_BAN_TTL_SEC`, `FLUXER_ABUSE_BATCH_FLUSH_MS`, `FLUXER_ABUSE_MAX_BATCH_TICKS`, `FLUXER_ABUSE_MAX_NEW_TOKENS_PER_TICK`, `FLUXER_ABUSE_MAX_TRACKED_IPS`, `FLUXER_ABUSE_MAX_TOKEN_HASHES_PER_IP`, `FLUXER_ABUSE_MIN_SCORE_FOR_LOOKUP`, `FLUXER_ABUSE_MIN_TOKENS_FOR_LOOKUP`, and `FLUXER_ABUSE_REQUIRED_SCORE_WINDOWS_FOR_AUTO_BAN`. All are read directly from the environment, none are in `.env.example` or the Compose file, and a non-finite value or one at or below zero falls back to the default.
|
||||
|
||||
Five more names in that family bound the IP classification the auto-banner buys from ipinfo. Before them, every API replica looked the same attacking IP up at the same moment, so one IP cost one lookup per replica. `FLUXER_ABUSE_IP_CLASS_CLAIM_ENABLED` defaults to `1` and gates the shared claim that now lets one replica do the lookup for all of them. `FLUXER_ABUSE_IP_CLASS_CLAIM_TTL_SEC` defaults to `15` and sets how long a replica holds that claim. `FLUXER_ABUSE_IP_CLASS_PENDING_TTL_MS` defaults to `20000` and sets how long a replica that lost the claim waits before it tries again. `FLUXER_ABUSE_IP_CLASS_NEGATIVE_TTL_MS` defaults to `300000` and sets how long a failed classification is remembered. `FLUXER_ABUSE_IP_CLASS_HINT_TTL_MS` defaults to `600000` and sets how long a class sent by another replica stays usable. The claim key is `abuse:ipclass:claim:` plus the ban key, and replicas send classes to each other on the `abuse_tracker:ipclass` key-value channel. The four numeric names read through the same helper as the names above, so a non-finite value or one at or below zero falls back to the default. `FLUXER_ABUSE_IP_CLASS_CLAIM_ENABLED` is read as a string instead, and only `0` turns the claim off.
|
||||
Five more names in that family limit how often the auto-banner buys an IP classification from ipinfo. Before them, every API replica looked up the same attacking IP at the same moment, so one IP cost one lookup per replica. `FLUXER_ABUSE_IP_CLASS_CLAIM_ENABLED` defaults to `1` and gates the shared claim that now lets one replica do the lookup for all of them. `FLUXER_ABUSE_IP_CLASS_CLAIM_TTL_SEC` defaults to `15` and sets how long a replica holds that claim. `FLUXER_ABUSE_IP_CLASS_PENDING_TTL_MS` defaults to `20000` and sets how long a replica that lost the claim waits before it tries again. `FLUXER_ABUSE_IP_CLASS_NEGATIVE_TTL_MS` defaults to `300000` and sets how long a failed classification is remembered. `FLUXER_ABUSE_IP_CLASS_HINT_TTL_MS` defaults to `600000` and sets how long a class sent by another replica stays usable. The claim key is `abuse:ipclass:claim:` plus the ban key, and replicas send classes to each other on the `abuse_tracker:ipclass` key-value channel. The four numeric names are read through the same helper as the names above, so a non-finite value or one at or below zero falls back to the default. `FLUXER_ABUSE_IP_CLASS_CLAIM_ENABLED` is read as a string instead, and only `0` turns the claim off.
|
||||
|
||||
A `FLUXER_IPINFO_BUDGET_` family caps what the instance spends at ipinfo. `FLUXER_IPINFO_BUDGET_ENABLED` defaults to `1`, and `0` turns off all shedding. `FLUXER_IPINFO_BUDGET_MONTHLY_MAX` defaults to `140000` and is the ceiling for one UTC calendar month. Lookups run at three priorities. Admin IP bans and scheduled deletion checks are critical and reach the full ceiling. Registration risk is standard and stops at `FLUXER_IPINFO_BUDGET_STANDARD_MONTHLY_PCT` percent of it, default `90`. The IP auto-banner is background and stops at `FLUXER_IPINFO_BUDGET_BACKGROUND_MONTHLY_PCT` percent, default `60`. The lower ceilings mean background lookups stop first and critical lookups stop last. Each priority also has a token bucket for bursts, sized by `FLUXER_IPINFO_BUDGET_CRITICAL_BURST` (`60`), `FLUXER_IPINFO_BUDGET_STANDARD_BURST` (`240`) and `FLUXER_IPINFO_BUDGET_BACKGROUND_BURST` (`120`), refilled once a minute by `FLUXER_IPINFO_BUDGET_CRITICAL_REFILL_PER_MIN` (`60`), `FLUXER_IPINFO_BUDGET_STANDARD_REFILL_PER_MIN` (`120`) and `FLUXER_IPINFO_BUDGET_BACKGROUND_REFILL_PER_MIN` (`30`). The counters live in the key-value store under `ipinfo:budget:burst:` and `ipinfo:budget:month:`. A shed lookup returns an unavailable result instead of an error, and any key-value failure admits the lookup at every priority, so a cache outage never stops an admin ban or the auto-banner.
|
||||
|
||||
Two names let the local MaxMind databases answer the registration risk lookup instead of ipinfo. `FLUXER_RISK_IPINFO_PRESCREEN_ENABLED` is off by default and only `1` or `true`, in any case, turns it on. `FLUXER_RISK_IPINFO_PRESCREEN_ALLOW_ASNS` is a comma-separated list of ASN numbers, empty by default, and non-numeric entries are dropped. The list is empty out of the box, so the pre-screen does nothing until an operator fills it in. An IP skips ipinfo only when the local city database returns a country, the local ASN database returns a number, that number is in the list, and the ASN organization name is not a commercial privacy provider, an education network or a cellular network. Everything else still goes to ipinfo.
|
||||
Two names let the local MaxMind databases answer the registration risk lookup instead of ipinfo. `FLUXER_RISK_IPINFO_PRESCREEN_ENABLED` is off by default and only `1` or `true`, in any letter case, turns it on. `FLUXER_RISK_IPINFO_PRESCREEN_ALLOW_ASNS` is a comma-separated list of ASN numbers, empty by default, and non-numeric entries are dropped. The list is empty out of the box, so the pre-screen does nothing until an operator fills it in. An IP skips ipinfo only when the local city database returns a country, the local ASN database returns a number, that number is in the list, and the ASN organization name is not a commercial privacy provider, an education network or a cellular network. Everything else still goes to ipinfo.
|
||||
|
||||
## Limits
|
||||
|
||||
|
||||
@@ -36,11 +36,11 @@ Create application, redeem gift, create private channel, and add group direct me
|
||||
|
||||
Two exemptions skip the challenge. Fluxer tests both of them before it reads the token. A request that passes either one proceeds as though the instance had no provider configured.
|
||||
|
||||
The first exemption is the `captcha_exempt` capability the instance account policy grants to a contact address. A policy rule matches the address itself or the domain it belongs to, so one grant can cover a whole domain. Fluxer tests it against the resolved account's email address, then against an `email` member of the request body.
|
||||
The first exemption is the `captcha_exempt` capability the instance account policy grants to a contact address. A policy rule matches the address itself or the domain it belongs to, so one grant can cover a whole domain. Fluxer tests it against the resolved account's email address alone, so an unauthenticated request never matches this exemption.
|
||||
|
||||
The second exemption is the `APP_STORE_REVIEWER` user flag. Fluxer tests it against the resolved account, then against the account an `email` member of the request body resolves to.
|
||||
|
||||
The body checks parse the request body as JSON and read a string `email` member, and a body that is absent, is not JSON, or is not a JSON object yields no address. Those checks exempt a login or a registration attempt before any account is resolved.
|
||||
The body check parses the request body as JSON and reads a string `email` member, and a body that is absent, is not JSON, or is not a JSON object yields no address. That check exempts a login or a registration attempt before any account is resolved.
|
||||
|
||||
The exemptions run before request validation on the three authentication operations, on create application, and on redeem gift. Create private channel and add group direct message recipient validate the request first, so an invalid request is rejected before any exemption is tested.
|
||||
|
||||
|
||||
Reference in new issue
Block a user