mirror of
https://github.com/versia-pub/docs.git
synced 2026-03-13 02:49:16 +01:00
docs: ♻️ Rewrite various docs pages, add null fields everywhere they were missing, make some Note and User fields mandatory
This commit is contained in:
parent
e6f7a27d3e
commit
e9b5ccd76c
31 changed files with 412 additions and 148 deletions
|
|
@ -49,7 +49,7 @@ Accept: application/jrd+json
|
|||
|
||||
## Instance Discovery
|
||||
|
||||
Instaance metadata can be accessed by making a `GET` request to the instance's Versia metadata endpoint, documented in the [Endpoints](/api/endpoints#instance-metadata) document.
|
||||
Instance metadata can be accessed by making a `GET` request to the instance's Versia metadata endpoint, documented in the [Endpoints](/api/endpoints#instance-metadata) document.
|
||||
|
||||
### Example
|
||||
|
||||
|
|
@ -80,7 +80,10 @@ Accept: application/vnd.versia+json
|
|||
"pub.versia:reports"
|
||||
]
|
||||
},
|
||||
"host": "versia.social",
|
||||
"created_at": "2021-07-01T00:00:00Z"
|
||||
"domain": "versia.social",
|
||||
"created_at": "2021-07-01T00:00:00Z",
|
||||
"description": null,
|
||||
"logo": null,
|
||||
"banner": null
|
||||
}
|
||||
```
|
||||
|
|
@ -50,7 +50,7 @@ curl https://b.social/.well-known/webfinger?resource=acct:joe@b.social -H "Accep
|
|||
<Note>
|
||||
In a real Versia implementation, usernames would **not** be included in user profile's URL, as they can be changed. Instead, the `id` could be used.
|
||||
|
||||
This is done for simplicity in this example.
|
||||
This is done for brevity here.
|
||||
</Note>
|
||||
|
||||
### Fetching the User
|
||||
|
|
@ -58,10 +58,10 @@ curl https://b.social/.well-known/webfinger?resource=acct:joe@b.social -H "Accep
|
|||
`a.social` fetches the user profile of `joe` from `b.social` using the URL provided in the WebFinger response.
|
||||
|
||||
```bash
|
||||
# The request is signed by a.social's instance private key
|
||||
curl https://b.social/.versia/entities/User/joe \
|
||||
-H "Accept: application/vnd.versia+json" \
|
||||
-H "User-Agent: CoolServer/1.0 (https://coolserver.com)" \
|
||||
# The request is signed by a.social's instance private key
|
||||
-H "Versia-Signature: /CjB2L9bcvRg+uP19B4/rqy7Ji9/cqMFPlL3GVCIndnQjYyOpBzJEAl9weDnXm7Jrqa3y6sBC+EYWKThO2r9Bw==" \
|
||||
-H "Versia-Signed-By: a.social" \
|
||||
-H "Versia-Signed-At: 1729241687"
|
||||
|
|
@ -71,17 +71,30 @@ curl https://b.social/.versia/entities/User/joe \
|
|||
|
||||
```json
|
||||
{
|
||||
"id": "bde22zi3ca8762", // [!code focus:10]
|
||||
"id": "bde22zi3ca8762", // [!code focus:3]
|
||||
"type": "User",
|
||||
"created_at": "2024-10-13T18:48:19Z",
|
||||
"avatar": {
|
||||
"image/webp": {
|
||||
"content": "https://cdn.b.social/avatars/joe.webp",
|
||||
"remote": true
|
||||
"remote": true,
|
||||
"description": null,
|
||||
"size": null,
|
||||
"hash": null,
|
||||
"thumbhash": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"fps": null,
|
||||
"duration": null
|
||||
}
|
||||
}, // [!code focus:3]
|
||||
"display_name": "Joe Swanson (Winter Arc :gigachad:)",
|
||||
"username": "joe",
|
||||
"bio": null,
|
||||
"header": null,
|
||||
"fields": [],
|
||||
"manually_approves_followers": false,
|
||||
"indexable": true,
|
||||
"extensions": {
|
||||
"pub.versia:custom_emojis": {
|
||||
"emojis": [
|
||||
|
|
@ -90,7 +103,15 @@ curl https://b.social/.versia/entities/User/joe \
|
|||
"content": {
|
||||
"image/png": {
|
||||
"content": "https://cdn.b.social/emojis/gigachad.png",
|
||||
"remote": true
|
||||
"remote": true,
|
||||
"description": null,
|
||||
"size": null,
|
||||
"hash": null,
|
||||
"thumbhash": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"fps": null,
|
||||
"duration": null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -112,21 +133,44 @@ Finally, `a.social` serializes the note to send it to `joe`.
|
|||
"type": "Note",
|
||||
"created_at": "2024-12-01T12:19:06Z",
|
||||
"author": "alice",
|
||||
"category": "microblog", // [!code focus:11]
|
||||
"category": "microblog",
|
||||
"content": {
|
||||
"text/html": {
|
||||
"text/html": { // [!code focus:12]
|
||||
"content": "Hello, <a class=\"u-url mention\" href=\"https://b.social/users/bde22zi3ca8762\">@joe@b.social</a>! How are you doing today?",
|
||||
"remote": false,
|
||||
"description": null,
|
||||
"size": null,
|
||||
"hash": null,
|
||||
"thumbhash": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"fps": null,
|
||||
"duration": null
|
||||
},
|
||||
"text/plain": {
|
||||
"content": "Hello, @joe@b.social! How are you doing today?",
|
||||
"remote": false,
|
||||
"description": null,
|
||||
"size": null,
|
||||
"hash": null,
|
||||
"thumbhash": null,
|
||||
"width": null,
|
||||
"height": null,
|
||||
"fps": null,
|
||||
"duration": null
|
||||
}
|
||||
},
|
||||
"group": "public",
|
||||
"mentions": [ // [!code focus:3]
|
||||
"b.social:bde22zi3ca8762"
|
||||
]
|
||||
],
|
||||
"attachments": [],
|
||||
"is_sensitive": false,
|
||||
"previews": [],
|
||||
"replies_to": null,
|
||||
"quotes": null,
|
||||
"subject": null,
|
||||
"device": null,
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export const metadata = {
|
|||
|
||||
Versia uses the HTTP protocol for all communications between instances. HTTP requests must conform to certain standards to ensure compatibility between different implementations, as well as to ensure the security and integrity of the data being exchanged.
|
||||
|
||||
ALL kinds of HTTP requests/responses between instances **MUST** include a [Signature](/signatures), signed with either the relevant [User](/entities/user)'s private key or the [instance's private key](/entities/instance-metadata).
|
||||
HTTP requests/responses between instances **must** include a [Signature](/signatures), signed with the [instance's private key](/entities/instance-metadata), as defined in [Signatures](/signatures).
|
||||
|
||||
## Requests
|
||||
|
||||
|
|
@ -16,22 +16,26 @@ ALL kinds of HTTP requests/responses between instances **MUST** include a [Signa
|
|||
<Col>
|
||||
<Properties name="HTTP Request">
|
||||
<Property name="Accept" type="string" required={true}>
|
||||
Must include `application/vnd.versia+json`, unless specified otherwise.
|
||||
Must be `application/vnd.versia+json`, unless specified otherwise. Basic `application/json` is **not** allowed.
|
||||
</Property>
|
||||
<Property name="Content-Type" type="string" required={true}>
|
||||
Must include `application/vnd.versia+json; charset=utf-8`, if the request has a body.
|
||||
Must be `application/vnd.versia+json; charset=utf-8` if the request has a body.
|
||||
</Property>
|
||||
<Property name="Versia-Signature" type="string" required={false}>
|
||||
<Property name="Versia-Signature" type="string" required={true}>
|
||||
See [Signatures](/signatures) for more information.
|
||||
</Property>
|
||||
<Property name="Versia-Signed-By" type="URI" required={false} typeLink="/types#uri">
|
||||
<Property name="Versia-Signed-By" type="Domain" required={true} typeLink="/api/basics#domain">
|
||||
See [Signatures](/signatures).
|
||||
</Property>
|
||||
<Property name="Versia-Signed-At" type="string" required={false}>
|
||||
<Property name="Versia-Signed-At" type="number" required={true}>
|
||||
See [Signatures](/signatures).
|
||||
</Property>
|
||||
<Property name="User-Agent" type="string" required={false}>
|
||||
A string identifying the software making the request.
|
||||
A string identifying the software making the request. Should contain the name of the software, its version, and a link to its homepage.
|
||||
|
||||
``` {{ 'title': 'Example User-Agent' }}
|
||||
CoolServer/1.0 (https://coolserver.com)
|
||||
```
|
||||
</Property>
|
||||
</Properties>
|
||||
</Col>
|
||||
|
|
@ -50,9 +54,9 @@ ALL kinds of HTTP requests/responses between instances **MUST** include a [Signa
|
|||
|
||||
## Rate limits
|
||||
|
||||
Implementations **MUST** respect the rate limits of remote instances.
|
||||
Implementations **must** respect the rate limits of remote instances.
|
||||
|
||||
IETF draft [draft-polli-ratelimit-headers-02](https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-02.html) **MUST** be used to communicate rate limits. Other rate limit headers/formats are not allowed.
|
||||
IETF draft [draft-polli-ratelimit-headers-02](https://www.ietf.org/archive/id/draft-polli-ratelimit-headers-02.html) **must** be used to communicate rate limits. Other rate limit headers/formats are not allowed.
|
||||
|
||||
<Note>
|
||||
This IETF draft is, well, a draft. However, there are no standards for rate limiting in HTTP, so this is the best we have.
|
||||
|
|
@ -66,13 +70,13 @@ IETF draft [draft-polli-ratelimit-headers-02](https://www.ietf.org/archive/id/dr
|
|||
<Property name="Content-Type" type="string" required={true}>
|
||||
Must include `application/vnd.versia+json; charset=utf-8`, unless specified otherwise.
|
||||
</Property>
|
||||
<Property name="Versia-Signature" type="string" required={false}>
|
||||
<Property name="Versia-Signature" type="string" required={true}>
|
||||
See [Signatures](/signatures) for more information.
|
||||
</Property>
|
||||
<Property name="Versia-Signed-By" type="URI" required={false} typeLink="/types#uri">
|
||||
<Property name="Versia-Signed-By" type="Domain" required={true} typeLink="/api/basics#domain">
|
||||
See [Signatures](/signatures).
|
||||
</Property>
|
||||
<Property name="Versia-Signed-At" type="string" required={false}>
|
||||
<Property name="Versia-Signed-At" type="number" required={true}>
|
||||
See [Signatures](/signatures).
|
||||
</Property>
|
||||
</Properties>
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ Ever [Instance](/entities/instance-metadata) has a personal HTTP endpoint called
|
|||
|
||||
Let's consider the following example:
|
||||
|
||||
> Alice, on the instance `alice.example`, sends a message to Bob on the instance `bob.example`.
|
||||
Alice, on the instance `alice.example`, sends a message to Bob on the instance `bob.example`.
|
||||
|
||||
To perform this action, Alice's instance sends a `POST` request to Bob's instance's inbox endpoint. This request contains the [Note](/entities/note) entity that Alice wants to send to Bob, with [the appropriate metadata](/federation/http) to ensure the message is valid.
|
||||
|
||||
|
|
@ -39,4 +39,12 @@ Bob's instance receives the message and processes it according to the rules defi
|
|||
|
||||
In addition to inboxes, every user has an outbox (at `/.versia/v0.6/entities/User/<id>/collections/outbox`). The outbox is simply a [Collection](/structures/collection) of all the messages that a user has sent. When a user sends a message to another user, a copy of that message is accessible in the sender's outbox.
|
||||
|
||||
<Warning>
|
||||
Implementations **should** filter out entities that are not relevant to the request author when returning the outbox.
|
||||
|
||||
For example, if Alice sends a [Note](/entities/note) to Bob on `direct` visibility:
|
||||
- Alice's instance **should** return the [Note](/entities/note) in response to a request from Bob's instance.
|
||||
- Alice's instance **should not** display the [Note](/entities/note) in her outbox in response to a request from Joe's instance.
|
||||
</Warning>
|
||||
|
||||
Outboxes are very useful for "backfilling" data when a new instance joins the network. By resolving the outboxes of all new users it encounters, a new instance can quickly catch up on all old messages.
|
||||
|
|
@ -6,7 +6,7 @@ export const metadata = {
|
|||
|
||||
# Validation
|
||||
|
||||
Implementations **MUST** strictly validate all incoming data to ensure that it is well-formed and adheres to the Versia Protocol. If a request is invalid, the instance **MUST** return a `400 Bad Request` HTTP status code.
|
||||
Implementations **MUST** strictly validate all incoming data to ensure that it is well-formed and adheres to the Versia Protocol. If a request is invalid, the instance **MUST** return a `422 Unprocessable Entity` HTTP status code.
|
||||
|
||||
<Note>
|
||||
Remember that while *your* implementation may disallow or restrict some user input, other implementations may not. You **should not** apply those restrictions to data coming from other instances.
|
||||
|
|
@ -16,13 +16,13 @@ Implementations **MUST** strictly validate all incoming data to ensure that it i
|
|||
|
||||
Things that should be validated include, but are not limited to:
|
||||
|
||||
- The presence of **all required fields**.
|
||||
- The presence of **all required fields**, and the presence of `null` on optional fields.
|
||||
- The **format** of all fields (integers should not be strings, timestamps should be in RFC 3339 format, etc.).
|
||||
- The presence of **all required headers**.
|
||||
- The presence of a **valid signature**.
|
||||
- The **length** of all fields (for example, the `username` field on a `User` entity) should be at least 1 character long.
|
||||
- Do not set arbitrary limits on the length of fields that other instances may send you. For example, a `bio` field should not be limited to 160 characters, even if your own implementation has such a limit.
|
||||
- If you do set limits, they should be reasonable, well-documented and should allow Users to easily view the remote original, by, for example, linking to it.
|
||||
- If you do set limits, they should be reasonable, well-documented and should allow Users to easily view the remote original, by, for example, linking to it. A limit of `100 000` characters for a `bio` field is acceptable, but a limit of `160` characters is not.
|
||||
- The **type**, **precision** and **scale** of all numeric fields.
|
||||
- For example, a `size` field on a `ContentFormat` structure should be a positive integer, not a negative number or a floating-point number.
|
||||
<Note>
|
||||
|
|
@ -30,7 +30,7 @@ Things that should be validated include, but are not limited to:
|
|||
|
||||
Using the same type with a higher bit count, for example using a u128 instead of a u64, is acceptable. Beware of performance impacts this may cause.
|
||||
</Note>
|
||||
- The **validity** of all URLs and URIs (run them through your favorite URL parser, optionally fetch the linked URL).
|
||||
- The **validity** of all URLs and URIs (run them through your favorite URL parser).
|
||||
- The **time** of all dates and times (people should not be born in the future, or in the year 0).
|
||||
|
||||
It is your implementation's duty to reject data from other instances that does not adhere to the strict spec. **This is crucial to ensure the integrity of your instance and the network as a whole**. Allowing data that is technically valid but semantically incorrect can lead to the degradation of the entire Versia ecosystem.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue