diff --git a/docs/objects/server-metadata.md b/docs/objects/server-metadata.md index 67d5c46..752b3f4 100644 --- a/docs/objects/server-metadata.md +++ b/docs/objects/server-metadata.md @@ -19,26 +19,22 @@ Here is an example server metadata object: "admins": [ // ... ], - "logo": [ - { - "content": "https://cdn.example.com/logo.png", - "content_type": "image/png" + "logo": { + "image/png": { + "content": "https://cdn.example.com/logo.png" }, - { - "content": "https://cdn.example.com/logo.webp", - "content_type": "image/webp" + "image/webp": { + "content": "https://cdn.example.com/logo.webp" } - ], - "banner": [ - { - "content": "https://cdn.example.com/banner.png", - "content_type": "image/png" + }, + "banner": { + "image/png": { + "content": "https://cdn.example.com/banner.png" }, - { - "content": "https://cdn.example.com/banner.webp", - "content_type": "image/webp" + "image/webp": { + "content": "https://cdn.example.com/banner.webp" } - ], + }, "supported_extensions": [ "org.lysand:reactions" ], "extensions": { // Example extension @@ -51,78 +47,108 @@ Here is an example server metadata object: ### Type -The `type` field on a Server Metadata object is a string that represents the type of the object. It is used to determine how the object should be displayed to the user. It should be `ServerMetadata`. +| Name | Type | Required | Notes | +| :--- | :----- | :------- | ------------------------ | +| type | String | Yes | Must be "ServerMetadata" | ### Name -The `name` field on a Server Metadata object is a string that represents the name of the server. The `name` field is required on all Server Metadata objects. +| Name | Type | Required | +| :--- | :----- | :------- | +| name | String | Yes | + +Represents the name of the server. The `name` field is required on all Server Metadata objects. This should be the name of the server instance itself, such as "Rosie's Lysand Server", not the software name such as "Mastodon". It is recommended that servers limit the length of the name from 1 to 50 characters, but it is up to the server to decide how long the name can be. The protocol does not have an upper limit for the length of the name. ### Version -The `version` field on a Server Metadata object is a string that represents the version of the server. It is recommended that servers use [SemVer](https://semver.org) to version their servers, but it is not required. The protocol does not have any requirements for the format of the version. +| Name | Type | Required | Notes | +| :------ | :----- | :------- | ----------------------- | +| version | String | Yes | Should be SemVer format | -The `version` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have a version. +Represents the version of the server software. It is recommended that servers use [SemVer](https://semver.org) to version their servers, but it is not required. ### Description -The `description` field on a Server Metadata object is a string that represents the description of the server. It should include information about the server, such as what it is about and what it is used for. +| Name | Type | Required | +| :---------- | :----- | :------- | +| description | String | No | + + +This is a short description of this particular server. It should include information about the server, such as what it is about and what it is used for. For example, a server focused on a specific topic may include information about that topic in the description. -The `description` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have a description. - It is recommended that servers limit the length of the description from 1 to 500 characters, but it is up to the server to decide how long the description can be. The protocol does not have an upper limit for the length of the description. ### Website -The `website` field on a Server Metadata object is a string that represents the website of the server. his may be used to link to the server's website, such as a status page or a public modlog. +| Name | Type | Required | +| :------ | :----- | :------- | +| website | String | No | -The `website` field is not required on Server Metadata objects. If it is not provided, it is assumed that the server does not have a website. +Represents the website of the server. This may be used to link to the server's website, such as a status page or a public modlog. ### Moderators -The `moderators` field on a Server Metadata object is an array of URIs that represent the moderators of the server. +| Name | Type | Required | +| :--------- | :-------------- | :------- | +| moderators | Array of string | No | -The `moderators` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have any moderators, or is not willing to provide a list. +Rrray of URIs to the server moderators. + +If it is not provided, it is assumed that the server does not have any moderators, or is not willing to provide a list. ### Admins +| Name | Type | Required | +| :----- | :-------------- | :------- | +| admins | Array of string | No | + The `admins` field on a Server Metadata object is an array of URIs that represent the admins of the server. The `admins` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have any admins, or is not willing to provide a list. ### Logo -The `logo` field on a Server Metadata object is an array of `ContentFormat` objects. It is meant to serve as a logo for the server. +| Name | Type | Required | +| :--- | :------------ | :------- | +| logo | ContentFormat | No | -The `logo` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have a logo. -The logo content_type **MUST** be an image format, such as `image/png` or `image/jpeg`. The logo content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. +The `logo` field on a Server Metadata is a [ContentFormat](../structures/content-format) object. + +The logo content_type **MUST** be an image format, such as `image/png` or `image/jpeg` (animated images are permitted). The logo content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. Lysand heavily recommends that servers provide both the original format and a modern format for each logo, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. Clients should display the most modern format that they support, such as WebP, AVIF, JXL, or HEIF. If the client does not support any modern formats, it should display the original format. -> **Note:** Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. +> [!NOTE] +> Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. ### Banner -The `banner` field on a Server Metadata object is an array of `ContentFormat` objects. It is meant to serve as a banner for the server. +| Name | Type | Required | +| :----- | :------------ | :------- | +| banner | ContentFormat | No | -The `banner` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not have a banner. +The `banner` field on a Server Metadata is a [ContentFormat](../structures/content-format) object. -The banner content_type **MUST** be an image format, such as `image/png` or `image/jpeg`. The banner content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. +The banner content_type **MUST** be an image format, such as `image/png` or `image/jpeg` (animated images are permitted). The banner content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. Lysand heavily recommends that servers provide both the original format and a modern format for each banner, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. Clients should display the most modern format that they support, such as WebP, AVIF, JXL, or HEIF. If the client does not support any modern formats, it should display the original format. -> **Note:** Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. +> [!NOTE] +> Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. ### Supported Extensions -The `supported_extensions` field on a Server Metadata object is an array that contains a list of extension names that the server supports. +| Name | Type | Required | +| :------------------- | :-------------- | :---------------- | +| supported_extensions | Array of string | Yes, can be empty | -The `supported_extensions` field is not required on all Server Metadata objects. If it is not provided, it is assumed that the server does not support any extensions. \ No newline at end of file +List of extension names that the server supports, in namespaced format (`"org.lysand:reactions"`). \ No newline at end of file diff --git a/docs/objects/undo.md b/docs/objects/undo.md index cc7f4bb..cb95849 100644 --- a/docs/objects/undo.md +++ b/docs/objects/undo.md @@ -1,16 +1,16 @@ -##### 1.6.3.1.7. Undo +# Undo -An `Undo` action is an action that represents a user undoing an action. It is used to cancel an action or delete an already existing object. +An `Undo` object signifies the reversal of a previously executed action by a user. It is primarily used to revoke an action or remove an existing object. -An `Undo` object **MUST** have an `object` field that contains the URI of the object that the user is undoing. The object **MUST** be a `Publication` object. +An `Undo` object **MUST** contain an `object` field that holds the URI of the object being reversed. -Servers **MUST** not allow users to undo actions that they did not create. +Servers **MUST NOT** permit users to reverse actions that they did not initiate. -Servers that receive `Undo` actions **MUST** undo the action that is being undone. For example, if a user likes a post, and then undoes the like, the server **MUST** remove the like from the post. Similarly, if an `Undo` action is received for a `Follow` action, the server **MUST** unfollow the user. +Upon receiving `Undo` actions, servers **MUST** reverse the action being undone. For instance, if a user expresses liking a post and subsequently undoes the like action, the server **MUST** eliminate the like from the post. Similarly, if an `Undo` action is received for a `Follow` action, the server **MUST** cease following the user. -If the `Undo` action has a Publication or other object as the `object` field, the server **MUST** stop showing the object to users. Deleting the original object is recommended, but not required. +If the `Undo` action has a Publication or another object as the `object` field, the server **MUST** discontinue displaying the object to users. It is recommended, but not mandatory, to delete the original object. -An `Undo` action on a `Patch` object **MUST** be treated as cancellation of the `Note` object, not of the patch itself. +An `Undo` action on a `Patch` object **MUST** be interpreted as the cancellation of the `Note` object, not the patch itself. Example: ```json5 diff --git a/docs/objects/user.md b/docs/objects/user.md index d9fb911..5492b32 100644 --- a/docs/objects/user.md +++ b/docs/objects/user.md @@ -1,6 +1,6 @@ # User -Users are Actors that represent a user on the server. They are the only type of Actor. +Users, represented as Actors, are unique entities on the server. They are the sole type of Actor. Here is an example user: @@ -12,55 +12,47 @@ Here is an example user: "created_at": "2021-01-01T00:00:00.000Z", "display_name": "Gordon Ramsay", "username": "gordonramsay", - "avatar": [ - { + "avatar": { + "image/png": { "content": "https://cdn.test.com/avatars/ab5081cf-b11f-408f-92c2-7c246f290593.png", - "content_type": "image/png" }, - { + "image/webp": { "content": "https://cdn.test.com/avatars/ab5081cf-b11f-408f-92c2-7c246f290593.webp", - "content_type": "image/webp" } - ], - "header": [ - { + }, + "header": { + "image/png": { "content": "https://cdn.test.com/banners/ab5081cf-b11f-408f-92c2-7c246f290593.png", - "content_type": "image/png" }, - { + "image/webp": { "content": "https://cdn.test.com/banners/ab5081cf-b11f-408f-92c2-7c246f290593.webp", - "content_type": "image/webp" } - ], + }, "indexable": true, "public_key": { "public_key": "...", "actor": "https://test.com/users/02e1e3b2-cb1f-4e4a-b82e-98866bee5de7" }, - "bio": [ - { + "bio": { + "text/plain": { "content": "My name is Gordon Ramsay, I'm a silly quirky little pony that LOVES to roleplay in the bedroom!", - "content_type": "text/plain" }, - { + "text/html": { "content": "My name is Gordon Ramsay, I'm a silly quirky little pony that LOVES to roleplay in the bedroom!", - "content_type": "text/html" } - ], + }, "fields": [ { - "key": [ - { + "key": { + "text/plain": { "content": "Where I live", - "content_type": "text/plain" } - ], - "value": [ - { + }, + "value": { + "text/plain": { "content": "Portland, Oregon", - "content_type": "text/plain" } - ], + } } ], "featured": "https://test.com/users/02e1e3b2-cb1f-4e4a-b82e-98866bee5de7/featured", @@ -75,19 +67,21 @@ Here is an example user: ## Fields +All text fields can incorporate [Custom Emojis](../extensions/custom-emojis) as part of the Custom Emojis protocol extension. If a server doesn't support the Custom Emojis extension, no additional work is required to ensure text field compatibility: custom emojis are denoted as part of the plaintext content using `:emoji-name:` syntax, which won't disrupt text formatting. + ### Type -The `type` of a `User` is always `User`. +The `type` of a `User` is invariably `User`. -### ID +### ID -The `id` field on an Actor is a UUID that represents the unique identifier of the actor as a string. It is used to identify the actor, and **MUST** be unique across all actors of the server. +The `id` field on an Actor is a UUID that signifies the unique identifier of the actor as a string. It is utilized to identify the actor, and **MUST** be unique across all actors of the server. ### Public Key -The `public_key` field on an Actor is an [`ActorPublicKeyData`](/cryptography/keys) object. It is used to verify that the actor is who they say they are. The key **MUST** be encoded in base64. +The `public_key` field on an Actor is an [`ActorPublicKeyData`](../cryptography/keys) object. It is employed to authenticate the actor's identity. The key **MUST** be encoded in base64. -All actors **MUST** have a `public_key` field. All servers **SHOULD** verify that the actor is who they say they are using the `public_key` field, which is used to encode any HTTP requests emitted on behalf of the actor. +All actors **MUST** have a `public_key` field. All servers **SHOULD** authenticate the actor's identity using the `public_key` field, which is used to encode any HTTP requests emitted on behalf of the actor. > For more information on cryptographic signing, please see the [Signing](/cryptography/signing) page. @@ -99,69 +93,75 @@ const publicKey = btoa(String.fromCharCode(...new Uint8Array(await crypto.subtle ### Display Name -The `display_name` field on an Actor is a string that represents the display name of the actor. It is used to display the actor's name to the user. +The `display_name` field on an Actor is a string that signifies the actor's display name. It is used to present the actor's name to the user. -The `display_name` field is not required on all actors. If it is not provided, it is assumed that the actor does not have a display name, and the actor's username should be used instead +The `display_name` field is optional. If it is not provided, it is assumed that the actor does not have a display name, and the actor's username should be used instead. -Display names **MUST** be treated as changeable, and **MUST NOT** be used to identify the actor. +Display names **MUST** be treated as mutable, and **MUST NOT** be used to identify the actor. -It is recommended that servers limit the length of the display name from 1 to 50 characters, but it is up to the server to decide how long the display name can be. The protocol does not have an upper limit for the length of the display name. +It is recommended that servers limit the display name length from 1 to 50 characters, but the server has the discretion to decide the display name length. The protocol does not impose an upper limit for the display name length. ### Username -The `username` field on an Actor is a string that represents the username of the actor. It is used to loosely identify the actor, and **MUST** be unique across all actors of a server. +The `username` field on an Actor is a string that signifies the actor's username. It is used to loosely identify the actor, and **MUST** be unique across all actors of a server. -The `username` field is required on all actors. +The `username` field is mandatory on all actors. -The `username` field **MUST NOT** be used to identify the actor internally or across the protocol. It is only meant to be used as a display name, and as such is changeable by the user. +The `username` field **MUST NOT** be used to identify the actor internally or across the protocol. It is only meant to be used as a display name, and as such is mutable by the user. The `username` field **MUST** be a string that contains only alphanumeric characters, underscores, and dashes. It **MUST NOT** contain any spaces or other special characters. It **MUST** match this regex: `/^[a-zA-Z0-9_-]+$/` -It is recommended that servers limit the length of the username from 1 to 20 characters, but it is up to the server to decide how long the username can be. The protocol does not have an upper limit for the length of the username. +It is recommended that servers limit the username length from 1 to 20 characters, but the server has the discretion to decide the username length. The protocol does not impose an upper limit for the username length. + +#### Implementation Details + +Usernames are intended to be mutable, but clients should guard this action with warnings and confirmations to prevent accidental changes. Servers should also rate limit username changes to prevent abuse. + +Since user search is done via the username, servers could implement a username history system to be able to find users by their old usernames. However, users might not want to be found by their old usernames, so this feature should be implemented with privacy in mind. ### Indexable -The `indexable` field on an Actor is a boolean that represents whether or not the actor should be indexed by search engines. This field is required and must be included. +The `indexable` field on an Actor is a boolean that signifies whether or not the actor should be indexed by search engines. This field is mandatory and must be included. Servers and search engines should respect the `indexable` field, and **SHOULD NOT** index the actor if the `indexable` field is set to `false`. This is to protect the privacy of users that do not want to be indexed by search engines. +#### Implementation Details + +This field should also trigger a change in the `robots.txt` file of the server, to prevent search engines from indexing the user's profile, or some other kind of mechanism to prevent indexing (some search engines support using meta tags or headers for example) + ### Avatar -The `avatar` field on an Actor is an array of `ContentFormat` objects. +The `avatar` field on an Actor is a [ContentFormat](../structures/content-format) object. It is intended to serve as a profile picture for users. -The `avatar` field is not required on actors. If it is not provided, it is assumed that the actor does not have an avatar. +The `avatar` field is optional. If it is not provided, it is assumed that the actor does not have an avatar. The avatar content_type **MUST** be an image format, such as `image/png` or `image/jpeg`. The avatar content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. -Lysand heavily recommends that servers provide both the original format and a modern format for each avatar, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. +It is strongly recommended that servers provide both the original format and a modern format for each avatar, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. Clients should display the most modern format that they support, such as WebP, AVIF, JXL, or HEIF. If the client does not support any modern formats, it should display the original format. -> **Note:** Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. - ### Header -The `header` field on an Actor is an array that an array of`ContentFormat` objects. It is meant to serve as a banner for users. +The `header` field on an Actor is a [ContentFormat](../structures/content-format) object. It is intended to serve as a banner for users. -The `header` field is not required on all actors. If it is not provided, it is assumed that the actor does not have a header. +The `header` field is optional. If it is not provided, it is assumed that the actor does not have a header. -The header content_type **MUST** be an image format, such as `image/png` or `image/jpeg`. The header content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. +The header content_type **MUST** be an image format, such as `image/png` or `image/jpeg` (animated images are permitted). The header content_type **MUST NOT** be a video format, such as `video/mp4` or `video/webm`. -Lysand heavily recommends that servers provide both the original format and a modern format for each header, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. +It is strongly recommended that servers provide both the original format and a modern format for each header, such as WebP, AVIF, JXL, or HEIF. This is to reduce bandwidth usage and improve performance for clients. Clients should display the most modern format that they support, such as WebP, AVIF, JXL, or HEIF. If the client does not support any modern formats, it should display the original format. -> **Note:** Servers may find it useful to use a CDN that can automatically convert images to modern formats, such as Cloudflare. This will offload image processing from the server, and improve performance for clients. - ### Bio -The `bio` field on an Actor is an array of `ContentFormat` objects. +The `bio` field on an Actor is a [ContentFormat](../structures/content-format) object. -The `bio` field is not required on all actors. If it is not provided, it is assumed that the actor does not have a bio. +The `bio` field is optional. If it is not provided, it is assumed that the actor does not have a bio. -The `bio` field is used to display a short description of the actor to the user. It is recommended that servers limit the length of the bio from 500 to a couple thousand characters, but it is up to the server to decide how long the bio can be. The protocol does not have an upper limit for the length of the bio. +The `bio` field is used to display a short description of the actor to the user. It is recommended that servers limit the bio length from 500 to a couple thousand characters, but the server has the discretion to decide the bio length. The protocol does not impose an upper limit for the bio length. The `bio` **MUST** be a text format, such as `text/plain` or `text/html`. The `bio` **MUST NOT** be a binary format, such as `image/png` or `video/mp4`. @@ -169,31 +169,30 @@ An example value for the `bio` field would be: ```json5 { // ... - "bio": [ - { + "bio": { + "text/plain": { "content": "This is my bio!", - "content_type": "text/plain" }, - { + "text/html": { "content": "This is my bio!", - "content_type": "text/html" } - ] + } // ... } ``` -> **Note:** Lysand heavily recommends that servers support the `text/html` content type, as it is the most rich content type that is supported by most clients. - -> **Note**: Lysand also recommends that servers always include a `text/plain` version of each object, as it is the most basic content type that is supported by all clients, such as command line clients. +> [!NOTE] +> Lysand heavily recommends that servers support the `text/html` content type, as it is the most rich content type that is supported by most clients. +> +> Lysand also recommends that servers always include a `text/plain` version of each object, as it is the most basic content type that is supported by all clients, such as command line clients. It is up to the client to choose which content format to display to the user. The client may choose to display the first content format that it supports, or it may choose to display the content format that it thinks is the most appropriate. ### Fields -The `fields` field on an Actor is an array that contains a list of `Field` objects. It is used to display custom fields to the user, such as additional metadata. +The `fields` field on an Actor is an array that contains a list of `Field` objects. It is used to display custom fields of key-value pairs to the user, such as additional metadata. -The `fields` field is not required on all actors. If it is not provided, it is assumed that the actor does not have any fields. +The `fields` field is optional. If it is not provided, it is assumed that the actor does not have any fields. An example value for the `fields` field would be: ```json5 @@ -201,19 +200,18 @@ An example value for the `fields` field would be: // ... "fields": [ { - "key": [ - { + "key": { + "text/plain": { "content": "Where I live", - "content_type": "text/plain" } - ], - "value": [ - { + }, + "value": { + "text/plain": { "content": "Portland, Oregon", - "content_type": "text/plain" } - ], + } } + // Other fields... ] // ... } @@ -222,43 +220,49 @@ An example value for the `fields` field would be: Fields are formatted as follows: ```ts interface Field { - key: ContentFormat[]; - value: ContentFormat[]; + key: ContentFormat; + value: ContentFormat; } ``` -Both `key` and `value` should be presented to the user as a couple. +Both `key` and `value` should be presented to the user as a pair. The `key` and `value` fields **MUST** be text formats, such as `text/plain` or `text/html`. They **MUST NOT** be binary formats, such as `image/png` or `video/mp4`. ### Featured -Please see [Featured Publications](/federation/endpoints) for more information. +Please refer to [Featured Publications](../federation/endpoints) for more information. ### Followers -Please see [User Followers](/federation/endpoints) for more information. +Please refer to [User Followers](../federation/endpoints) for more information. ### Following -Please see [User Following](/federation/endpoints) for more information. +Please refer to [User Following](../federation/endpoints) for more information. ### Likes -Please see [User Likes](/federation/endpoints) for more information. +Please refer to [User Likes](../federation/endpoints) for more information. ### Dislikes -Please see [User Dislikes](/federation/endpoints) for more information. +Please refer to [User Dislikes](../federation/endpoints) for more information. ### Inbox -The `inbox` field on an Actor is a string that represents the URI of the actor's inbox. It is used to identify the actor's inbox for federation. +The `inbox` field on an Actor is a string that displays the URI of the actor's inbox. It is used to identify the actor's inbox for federation. -Please see [Inbox](/federation/endpoints) for more information. +Please refer to [Inbox](../federation/endpoints) for more information. ### Outbox -The `outbox` field on an Actor is a string that represents the URI of the actor's outbox. It is used to identify the actor's outbox for federation. +The `outbox` field on an Actor is a string that displays the URI of the actor's outbox. It is used to identify the actor's outbox for federation. -Please see [Outbox](/federation/endpoints) for more information. \ No newline at end of file +Please refer to [Outbox](../federation/endpoints) for more information. + +## Related Extensions + +These extensions might add or affect the User object if used: +- [Custom Emojis](../extensions/custom-emojis) +- [Vanity Profile](../extensions/vanity) \ No newline at end of file