Protocol Documentation

Table of Contents

Top

jonline.proto

Jonline

The internet-facing service implementing the Jonline protocol, generally exposed on port 27707 or 443 (and, when using HTTP-based client host negotiation, ports 80 and/or 443). A Jonline server is generally also expected to serve up web apps on ports 80/443, where select APIs are exposed with HTTP interfaces instead of gRPC. (Specifically, that HTTP-based client host negotiation again and Media, for interoperability purposes.)

Authentication

Jonline uses a standard OAuth2 flow for authentication, with rotating access_tokens and refresh_tokens. Authenticated calls require an access_token in request metadata to be included directly as the value of the authorization header (no Bearer prefix).

First, use the CreateAccount or Login RPCs to fetch (and store) an initial refresh_token and access_token. Clients should use the access_token until it expires, then use the refresh_token to call the AccessToken RPC for a new one. (The AccessToken RPC may, at random, also return a new refresh_token. If so, it should immediately replace the old one in client storage.)

Dumfederation

Whereas other federated social networks (e.g. ActivityPub) have both client-server and server-server APIs, Jonline only has client-server APIs. The idea is that all of the federation data for a given Jonline server is simply the value of federation_info in ServerConfiguration.

That is to say: Servers can recommend other hosts. Clients can do what they will with that information. (Eventually, this will affect CORS policies for added security.) The aim here is to optimize for ease of server administration, and ease of understanding how the system works for users.

HTTP-based client host negotiation (for external CDNs)

When first negotiating the gRPC connection to a host, say, jonline.io, before attempting to connect to jonline.io via gRPC on 27707/443, the client is expected to first attempt to GET jonline.io/backend_host over HTTP (port 80) or HTTPS (port 443) (depending upon whether the gRPC server is expected to have TLS). If the backend_host string resource is a valid domain, say, jonline.io.itsj.online, the client is expected to connect to jonline.io.itsj.online on port 27707/443 instead. To users, the server should still generally appear to be jonline.io. The client can trust jonline.io/backend_host to always point to the correct backend host for jonline.io.

This negotiation enables support for external CDNs as frontends. See https://jonline.io/about?section=cdn for more information about external CDN setup. Developers may wish to review the React/Tamagui and Flutter client implementations of this negotiation.

In the works to be released soon, Jonline will also support a "fully behind CDN" mode, where gRPC is served over port 443 and HTTP over port 80, with no HTTPS web page/media serving (other than the HTTPS that naturally underpins gRPC-Web). This is designed to use Cloudflare's gRPC proxy support. With this, both web and gRPC resources can live behind a CDN.

API Design Notes
Moderation and Visibility

Jonline APIs are designed to support Moderation and Visibility controls at the level of individual entities. However, to keep things DRY, moderation and visibility controls are only implemented for Users, Media, Groups, and Posts.

Events and future Post-like types simply use the same implementation as their contained Posts. The intent here is to maximize both shared code and implementation robustness.

Composition Over Inheritance

Jonline's APIs are designed using composition over inheritance. For instance, an Event contains a Post rather than extending it. This pattern fits well all the way from the data model (very boring, safe, and normalized), through Rust code implementing APIs, to both functional React code and more-OOP Flutter code equally well.

Predictable Atomicity

The use of composition over inheritance also means that Jonline APIs can be predictably non-atomic based on their compositional structure. For instance, UpdatePost is fully atomic.

UpdateEvent, however, is non-atomic. Given that an Event has a Post and many EventInstances, UpdateEvent will first update the Post atomically (literally calling the UpdatePost RPC), then the Event atomically, and then finally process updates to its EventInstances in a final atomic operation.

Because moderation/visibility lives at the Post level, this means that a developer error in UpdateEvents cannot prevent visibility and moderation changes from being made in Events, even if there are errors elsewhere. This should prove a robust pattern for any future entities intended to be shareable at a Group level with visibility and moderation controls (for instance, Sheet, SharedExpenseReport, SharedCalendar, etc.). The entire architecture should promote this approach to predictable atomicity.

gRPC API

Method Name Request Type Response Type Description
GetServiceVersion .google.protobuf.Empty GetServiceVersionResponse Get the version (from Cargo) of the Jonline service. Publicly accessible.
GetServerConfiguration .google.protobuf.Empty ServerConfiguration Gets the Jonline server's configuration. Publicly accessible.
CreateAccount CreateAccountRequest RefreshTokenResponse Creates a user account and provides a refresh_token (along with an access_token). Publicly accessible.
Login LoginRequest RefreshTokenResponse Logs in a user and provides a refresh_token (along with an access_token). Publicly accessible.
AccessToken AccessTokenRequest AccessTokenResponse Gets a new access_token (and possibly a new refresh_token, which should replace the old one in client storage), given a refresh_token. Publicly accessible.
GetCurrentUser .google.protobuf.Empty User Gets the current user. Authenticated.
ResetPassword ResetPasswordRequest .google.protobuf.Empty Resets the current user's - or, for admins, a given user's - password. Authenticated.
GetMedia GetMediaRequest GetMediaResponse Gets Media (Images, Videos, etc) uploaded/owned by the current user. Authenticated. To upload/download actual Media blob/binary data, use the HTTP Media APIs.
DeleteMedia Media .google.protobuf.Empty Deletes a media item by ID. Authenticated. Note that media may still be accessible for 12 hours after deletes are requested, as separate jobs clean it up from S3/MinIO. Deleting other users' media requires ADMIN permissions.
GetUsers GetUsersRequest GetUsersResponse Gets Users. Publicly accessible or Authenticated. Unauthenticated calls only return Users of GLOBAL_PUBLIC visibility.
UpdateUser User User Update a user by ID. Authenticated. Updating other users requires ADMIN permissions.
DeleteUser User .google.protobuf.Empty Deletes a user by ID. Authenticated. Deleting other users requires ADMIN permissions.
CreateFollow Follow Follow Follow (or request to follow) a user. Authenticated.
UpdateFollow Follow Follow Used to approve follow requests. Authenticated.
DeleteFollow Follow .google.protobuf.Empty Unfollow (or unrequest) a user. Authenticated.
GetGroups GetGroupsRequest GetGroupsResponse Gets Groups. Publicly accessible or Authenticated. Unauthenticated calls only return Groups of GLOBAL_PUBLIC visibility.
CreateGroup Group Group Creates a group with the current user as its admin. Authenticated. Requires the CREATE_GROUPS permission.
UpdateGroup Group Group Update a Groups's information, default membership permissions or moderation. Authenticated. Requires ADMIN permissions within the group, or ADMIN permissions for the user.
DeleteGroup Group .google.protobuf.Empty Delete a Group. Authenticated. Requires ADMIN permissions within the group, or ADMIN permissions for the user.
GetMembers GetMembersRequest GetMembersResponse Get Members (User+Membership) of a Group. Publicly accessible or Authenticated.
CreateMembership Membership Membership Requests to join a group (or joins it), or sends an invite to the user. Authenticated. Memberships and moderations are set to their defaults.
UpdateMembership Membership Membership Update aspects of a user's membership. Authenticated. Updating permissions requires ADMIN permissions within the group, or ADMIN permissions for the user. Updating moderation (approving/denying/banning) requires the same, or MODERATE_USERS permissions within the group.
DeleteMembership Membership .google.protobuf.Empty Leave a group (or cancel membership request). Authenticated.
GetPosts GetPostsRequest GetPostsResponse Gets Posts. Publicly accessible or Authenticated. Unauthenticated calls only return Posts of GLOBAL_PUBLIC visibility.
CreatePost Post Post Creates a Post. Authenticated.
UpdatePost Post Post Updates a Post. Authenticated.
DeletePost Post Post (TODO) (Soft) deletes a Post. Returns the deleted version of the Post. Authenticated.
StarPost Post Post Star a Post. Unauthenticated.
UnstarPost Post Post Unstar a Post. Unauthenticated.
GetGroupPosts GetGroupPostsRequest GetGroupPostsResponse Get GroupPosts for a Post (and optional group). Publicly accessible or Authenticated.
CreateGroupPost GroupPost GroupPost Cross-post a Post to a Group. Authenticated.
UpdateGroupPost GroupPost GroupPost Group Moderators: Approve/Reject a GroupPost. Authenticated.
DeleteGroupPost GroupPost .google.protobuf.Empty Delete a GroupPost. Authenticated.
GetEvents GetEventsRequest GetEventsResponse Gets Events. Publicly accessible or Authenticated. Unauthenticated calls only return Events of GLOBAL_PUBLIC visibility.
CreateEvent Event Event Creates an Event. Authenticated.
UpdateEvent Event Event Updates an Event. Authenticated.
DeleteEvent Event Event (TODO) (Soft) deletes a Event. Returns the deleted version of the Event. Authenticated.
GetEventAttendances GetEventAttendancesRequest EventAttendances Gets EventAttendances for an EventInstance. Publicly accessible or Authenticated.
UpsertEventAttendance EventAttendance EventAttendance Upsert an EventAttendance. Publicly accessible or Authenticated, with anonymous RSVP support. See EventAttendance and AnonymousAttendee for details. tl;dr: Anonymous RSVPs may updated/deleted with the AnonymousAttendee.auth_token returned by this RPC (the client should save this for the user, and ideally, offer a link with the token).
DeleteEventAttendance EventAttendance .google.protobuf.Empty Delete an EventAttendance. Publicly accessible or Authenticated, with anonymous RSVP support.
FederateProfile FederatedAccount FederatedAccount Federate the current user's profile with another user profile. Authenticated.
DefederateProfile FederatedAccount .google.protobuf.Empty Authenticated*.
ConfigureServer ServerConfiguration ServerConfiguration Configure the server (i.e. the response to GetServerConfiguration). Authenticated. Requires ADMIN permissions.
ResetData .google.protobuf.Empty .google.protobuf.Empty Delete ALL Media, Posts, Groups and Users except the user who performed the RPC. Authenticated. Requires ADMIN permissions. Note: Server Configuration is not deleted.
StreamReplies Post Post stream (TODO) Reply streaming interface. Currently just streams fake example data.

Top

authentication.proto

AccessTokenRequest

Request for a new access token using a refresh token.

Field Type Label Description
refresh_token string The refresh token to use to request a new access token.
expires_at google.protobuf.Timestamp optional Optional requested expiration time for the token. Server may ignore this.

AccessTokenResponse

Returned when requesting access tokens.

Field Type Label Description
refresh_token ExpirableToken optional If a refresh token is returned, it should be stored. Old refresh tokens may expire before their indicated expiration. See: https://auth0.com/docs/secure/tokens/refresh-tokens/refresh-token-rotation
access_token ExpirableToken The new access token.

CreateAccountRequest

Request to create a new account.

Field Type Label Description
username string Username for the account to be created. Must not exist.
password string Password for the account to be created. Must be at least 8 characters.
email ContactMethod optional Email to be used as a contact method.
phone ContactMethod optional Phone number to be used as a contact method.
expires_at google.protobuf.Timestamp optional Request an expiration time for the Auth Token returned. By default it will not expire.
device_name string optional (Not yet implemented.) The name of the device being used to create the account.

CreateThirdPartyRefreshTokenRequest

Request to create a new third-party refresh token. Unlike LoginRequest or CreateAccountRequest, the user must be logged in to create a third-party refresh token.

Generally, this is used to create a refresh token for another Jonline instance, e.g., accessing bullcity.social/jon's data from jonline.io. On the web side, this is implemented as follows:

  1. When the bullcity.social user wants to login on jonline.io, bullcity.social will redirect the user to jonline.io/third_party_auth?to=bullcity.social.
  2. jonline.io will force the user to login if needed on this page.
  3. jonline.io will prompt/warn the user, and then call this RPC to create a refresh + access token for bullcity.social.
  4. jonline.io will redirect the user back to bullcity.social/third_party_auth?from=jonline.io&token=<Base64RefreshTokenResponse> with the refresh token POSTed in form data.
    • (<Base64RefreshTokenResponse> is a base64-encoded RefreshTokenResponse message.)
  5. bullcity.social will ensure it can GetCurrentUser on jonline.io with its new auth token.
  6. bullcity.social will replace the current location with bullcity.social/third_party_auth?from=jonline.io.
  7. bullcity.social will use the access token to make requests to jonline.io (the same as with bullcity.social).

Note that refresh tokens

Field Type Label Description
expires_at google.protobuf.Timestamp optional The third-party refresh token's expiration time.
user_id string The third-party refresh token's user ID.
device_name string The third-party refresh token's device name.

ExpirableToken

Generic type for refresh and access tokens.

Field Type Label Description
token string The secure token value.
expires_at google.protobuf.Timestamp optional Optional expiration time for the token. If not set, the token will not expire.

LoginRequest

Request to login to an existing account.

Field Type Label Description
username string Username for the account to be logged into. Must exist.
password string Password for the account to be logged into.
expires_at google.protobuf.Timestamp optional Request an expiration time for the Auth Token returned. By default it will not expire.
device_name string optional (Not yet implemented.) The name of the device being used to login.
user_id string optional (TODO) If provided, username is ignored and login is initiated via user_id instead.

RefreshTokenMetadata

Metadata on a refresh token for the current user, used when managing refresh tokens as a user. Does not include the token itself.

Field Type Label Description
id uint64 The DB ID of the refresh token. Used when deleting the token or updating the device_name.
expires_at google.protobuf.Timestamp optional Expiration date of the refresh token.
device_name string optional The device name the refresh token is on. User-updateable.
is_this_device bool Whether the refresh token is associated with the current device (based on what user is making the request).
third_party bool

RefreshTokenResponse

Returned when creating an account, logging in, or creating a third-party refresh token.

Field Type Label Description
refresh_token ExpirableToken The persisted token the device should store and associate with the account. Used to request new access tokens.
access_token ExpirableToken An initial access token provided for convenience.
user User The user associated with the account that was created/logged into.

ResetPasswordRequest

Request to reset a password.

Field Type Label Description
user_id string optional If not set, use the current user of the request.
password string The new password to set.

UserRefreshTokensResponse

Response for GetUserRefreshTokens RPC. Returns all refresh tokens associated with the current user.

Field Type Label Description
refresh_tokens RefreshTokenMetadata repeated The refresh tokens associated with the current user.

Top

visibility_moderation.proto

Moderation

Nearly everything in Jonline has one or more Moderations on it.

From a high level:

Name Number Description
MODERATION_UNKNOWN 0 A moderation that is not known to the protocol. (Likely, the client and server use different versions of the Jonline protocol.)
UNMODERATED 1 Subject has not been moderated and is visible to all users.
PENDING 2 Subject is awaiting moderation and not visible to any users.
APPROVED 3 Subject has been approved by moderators and is visible to all users.
REJECTED 4 Subject has been rejected by moderators and is not visible to any users.

Visibility

Visibility in Jonline is a complex topic. There are several different types of visibility, and each type of entity (User, Media, Group, then Post/Event/etc. with common logic) has different rules for visibility.

From the top down, the rules break down as follows:

Name Number Description
VISIBILITY_UNKNOWN 0 A visibility that is not known to the protocol. (Likely, the client and server use different versions of the Jonline protocol.)
PRIVATE 1 Subject is only visible to the user who owns it.
LIMITED 2 Subject is only visible to explictly associated Groups and Users. See: GroupPost and UserPost.
SERVER_PUBLIC 3 Subject is visible to all authenticated users.
GLOBAL_PUBLIC 4 Subject is visible to all users on the internet.
DIRECT 5 [TODO] Subject is visible to explicitly-associated Users. Only applicable to Posts and Events. For Users, this is the same as LIMITED. See: UserPost.

Top

permissions.proto

Permission

Jonline Permissions are a set of permissions that can be granted directly to Users and Memberships. (A Membership is the link between a Group and a User.)

Subsets of these permissions are also applicable to anonymous users via anonymous_user_permissions in ServerConfiguration, and to Group non-members via non_member_permissions in Group, as well as others documented there.

Name Number Description
PERMISSION_UNKNOWN 0 A permission that could not be read using the Jonline protocol. (Perhaps, a permission from a newer Jonline version.)
VIEW_USERS 1 Allow the user to view profiles with SERVER_PUBLIC Visbility. Allow anonymous users to view profiles with GLOBAL_PUBLIC Visbility (when configured as an anonymous user permission).
PUBLISH_USERS_LOCALLY 2 Allow the user to publish profiles with SERVER_PUBLIC Visbility. This generally only applies to the user's own profile, except for Admins.
PUBLISH_USERS_GLOBALLY 3 Allow the user to publish profiles with GLOBAL_PUBLIC Visbility. This generally only applies to the user's own profile, except for Admins.
MODERATE_USERS 4 Allow the user to grant VIEW_POSTS, CREATE_POSTS, VIEW_EVENTS and CREATE_EVENTS permissions to users.
FOLLOW_USERS 5 Allow the user to follow other users.
GRANT_BASIC_PERMISSIONS 6 Allow the user to grant Basic Permissions to other users. "Basic Permissions" are defined by your ServerConfiguration's basic_user_permissions.
VIEW_GROUPS 10 Allow the user to view groups with SERVER_PUBLIC visibility. Allow anonymous users to view groups with GLOBAL_PUBLIC visibility (when configured as an anonymous user permission).
CREATE_GROUPS 11 Allow the user to create groups.
PUBLISH_GROUPS_LOCALLY 12 Allow the user to give groups SERVER_PUBLIC visibility.
PUBLISH_GROUPS_GLOBALLY 13 Allow the user to give groups GLOBAL_PUBLIC visibility.
MODERATE_GROUPS 14 The Moderate Groups permission makes a user effectively an admin of any group.
JOIN_GROUPS 15 Allow the user to (potentially request to) join groups of SERVER_PUBLIC or higher visibility.
INVITE_GROUP_MEMBERS 16 Allow the user to invite other users to groups. Only applicable as a Group permission (not at the User level).
VIEW_POSTS 20 As a user permission, allow the user to view posts with SERVER_PUBLIC or higher visibility. As a group permission, allow the user to view GroupPosts whose Posts have LIMITED or higher visibility. Allow anonymous users to view posts with GLOBAL_PUBLIC visibility (when configured as an anonymous user permission).
CREATE_POSTS 21 As a user permission, allow the user to create Posts of PRIVATE and LIMITED visibility. As a group permission, allow the user to create GroupPosts for POST and FEDERATED_POST PostContexts..
PUBLISH_POSTS_LOCALLY 22 Allow the user to publish posts with SERVER_PUBLIC visibility.
PUBLISH_POSTS_GLOBALLY 23 Allow the user to publish posts with GLOBAL_PUBLIC visibility.
MODERATE_POSTS 24 Allow the user to moderate posts.
REPLY_TO_POSTS 25 Allow the user to reply to posts.
VIEW_EVENTS 30 As a user permission, allow the user to view posts with SERVER_PUBLIC or higher visibility. As a group permission, allow the user to view GroupPosts whose Event Posts have LIMITED or higher visibility. Allow anonymous users to view events with GLOBAL_PUBLIC visibility (when configured as an anonymous user permission).
CREATE_EVENTS 31 As a user permission, allow the user to create Events of PRIVATE and LIMITED visibility. As a group permission, allow the user to create GroupPosts for EVENT and FEDERATED_EVENT_INSTANCE PostContexts..
PUBLISH_EVENTS_LOCALLY 32 Allow the user to publish events with SERVER_PUBLIC visibility.
PUBLISH_EVENTS_GLOBALLY 33 Allow the user to publish events with GLOBAL_PUBLIC visibility.
MODERATE_EVENTS 34 Allow the user to moderate events.
RSVP_TO_EVENTS 35 Allow the user to RSVP to events that allow RSVPs.
VIEW_MEDIA 40 Allow the user to view media with SERVER_PUBLIC or higher visibility. Not currently enforced. Allow anonymous users to view media with GLOBAL_PUBLIC visibility (when configured as an anonymous user permission). Not currently enforced.
CREATE_MEDIA 41 Allow the user to create media of PRIVATE and LIMITED visibility. Not currently enforced.
PUBLISH_MEDIA_LOCALLY 42 Allow the user to publish media with SERVER_PUBLIC visibility. Not currently enforced.
PUBLISH_MEDIA_GLOBALLY 43 Allow the user to publish media with GLOBAL_PUBLIC visibility. Not currently enforced.
MODERATE_MEDIA 44 Allow the user to moderate events.
BUSINESS 9998 Indicates the user is a business. Used purely for display purposes.
RUN_BOTS 9999 Allow the user to run bots. There is no enforcement of this permission (yet), but it lets other users know that the user is allowed to run bots.
ADMIN 10000 Marks the user as an admin. In the context of user permissions, allows the user to configure the server, moderate/update visibility/permissions to any User, Group, Post or Event. In the context of group permissions, allows the user to configure the group, modify members and member permissions, and moderate GroupPosts and GroupEvents.
VIEW_PRIVATE_CONTACT_METHODS 10001 Allow the user to view the private contact methods of other users. Kept separate from ADMIN to allow for more fine-grained privacy control.

Top

users.proto

Author

Post/authorship-centric version of User. UI can cross-reference user details from its own cache (for things like admin/bot icons).

Field Type Label Description
user_id string Permanent string ID for the user. Will never contain a @ symbol.
username string optional Impermanent string username for the user. Will never contain a @ symbol.
avatar MediaReference optional The user's avatar.
real_name string optional
permissions Permission repeated

ContactMethod

A contact method for a user. Models designed to support verification, but verification RPCs are not yet implemented.

Field Type Label Description
value string optional Either a mailto: or tel: URL.
visibility Visibility The visibility of the contact method.
supported_by_server bool Server-side flag indicating whether the server can verify (and otherwise interact via) the contact method.
verified bool Indicates the user has completed verification of the contact method. Verification requires supported_by_server to be true.

Follow

Model for a user's follow of another user.

Field Type Label Description
user_id string The follower in the relationship.
target_user_id string The user being followed.
target_user_moderation Moderation Tracks whether the target user needs to approve the follow.
created_at google.protobuf.Timestamp The time the follow was created.
updated_at google.protobuf.Timestamp optional The time the follow was last updated.

GetUsersRequest

Request to get one or more users by a variety of parameters. Supported parameters depend on listing_type.

Field Type Label Description
username string optional The username to search for. Substrings are supported.
user_id string optional The user ID to search for.
page int32 optional The page of results to return. Pages are 0-indexed.
listing_type UserListingType The number of results to return per page.

GetUsersResponse

Response to a GetUsersRequest.

Field Type Label Description
users User repeated The users matching the request.
has_next_page bool Whether there are more pages of results.

Membership

Model for a user's membership in a group. Memberships are generically included as part of User models when relevant in Jonline, but UIs should use the group_id to reconcile memberships with groups.

Field Type Label Description
user_id string The member (or requested/invited member).
group_id string The group the membership pertains to.
permissions Permission repeated Valid Membership Permissions are: VIEW_POSTS, CREATE_POSTS, MODERATE_POSTS, VIEW_EVENTS, CREATE_EVENTS, MODERATE_EVENTS, ADMIN, RUN_BOTS, and MODERATE_USERS
group_moderation Moderation Tracks whether group moderators need to approve the membership.
user_moderation Moderation Tracks whether the user needs to approve the membership.
created_at google.protobuf.Timestamp The time the membership was created.
updated_at google.protobuf.Timestamp optional The time the membership was last updated.

User

Model for a Jonline user. This user may have Media, Group Memberships, Posts, Events, and other objects associated with them.

Field Type Label Description
id string Permanent string ID for the user. Will never contain a @ symbol.
username string Impermanent string username for the user. Will never contain a @ symbol.
real_name string The user's real name.
email ContactMethod optional The user's email address.
phone ContactMethod optional The user's phone number.
permissions Permission repeated The user's permissions. See Permission for details.
avatar MediaReference optional The user's avatar. Note that its visibility is managed by the User and thus it may not be accessible to the current user.
bio string The user's bio.
visibility Visibility User visibility is a bit different from Post visibility. LIMITED means the user can only be seen by users they follow (as opposed to Posts' individualized visibilities). PRIVATE visibility means no one can see the user. See server_configuration.proto for details about PRIVATE users' ability to creep.
moderation Moderation The user's moderation status. See Moderation for details.
default_follow_moderation Moderation Only PENDING or UNMODERATED are valid.
follower_count int32 optional The number of users following this user.
following_count int32 optional The number of users this user is following.
group_count int32 optional The number of groups this user is a member of.
post_count int32 optional The number of posts this user has made.
response_count int32 optional The number of responses to Posts and Events this user has made.
event_count int32 optional The number of events this user has created.
current_user_follow Follow optional Presence indicates the current user is following or has a pending follow request for this user.
target_current_user_follow Follow optional Presence indicates this user is following or has a pending follow request for the current user.
current_group_membership Membership optional Returned by GetMembers calls, for use when managing Group Memberships. The Membership should match the Group from the originating GetMembersRequest, providing whether the user is a member of that Group, has been invited, requested to join, etc..
has_advanced_data bool Indicates that federated_profiles has been loaded.
federated_profiles FederatedAccount repeated Federated profiles for the user. Not always loaded. This is a list of profiles from other servers that the user has connected to their account. Managed by the user via Federate
created_at google.protobuf.Timestamp The time the user was created.
updated_at google.protobuf.Timestamp optional The time the user was last updated.

UserListingType

Ways of listing users.

Name Number Description
EVERYONE 0 Get all users.
FOLLOWING 1 Get users the current user is following.
FRIENDS 2 Get users who follow and are followed by the current user.
FOLLOWERS 3 Get users who follow the current user.
FOLLOW_REQUESTS 4 Get users who have requested to follow the current user.
ADMINS 10 [TODO] Gets admins for a server.

Top

media.proto

GetMediaRequest

Valid GetMediaRequest formats:

Field Type Label Description
media_id string optional Returns the single media item with the given ID.
user_id string optional Returns all media items for the given user.
page uint32

GetMediaResponse

Field Type Label Description
media Media repeated
has_next_page bool

Media

A Jonline Media message represents a single media item, such as a photo or video. Media data is deliberately not returnable from the gRPC API. Instead, the client should fetch media from http[s]://my.jonline.instance/media/{id}.

Media items may be created with a HTTP POST to http[s]://my.jonline.instance/media along with an "Authorization" header (your access token) and a "Content-Type" header. On success, the endpoint will return the media ID in plaintext.

POST /media supports the following headers:

GET /media supports the following:

Field Type Label Description
id string The ID of the media item.
user_id string optional The ID of the user who created the media item.
content_type string The MIME content type of the media item.
name string optional An optional title for the media item.
description string optional An optional description for the media item.
visibility Visibility Visibility of the media item.
moderation Moderation Moderation of the media item.
generated bool Indicates the media was generated by the server rather than uploaded manually by a user.
processed bool Media is generally stored as-is on upload. When background jobs process and compress the media, this flag is set to true.
created_at google.protobuf.Timestamp
updated_at google.protobuf.Timestamp

MediaReference

A reference to a media item, designed to be included in other messages as a reference. Contains the bare minimum data needed to fetch media via the HTTP API and render it, and the media item's name (for alt text usage).

Field Type Label Description
content_type string The MIME content type of the media item.
id string The ID of the media item.
name string optional An optional title for the media item.
generated bool Indicates the media was generated by the server rather than uploaded manually by a user.

Top

groups.proto

GetGroupsRequest

Request to get a group or groups by name or ID.

Field Type Label Description
group_id string optional The ID of the group to get.
group_name string optional The name of the group to get.
group_shortname string optional The shortname of the group to get. Group shortname search is case-insensitive.
listing_type GroupListingType The group listing type.
page int32 optional The page of results to get.

GetGroupsResponse

Response to a GetGroupsRequest.

Field Type Label Description
groups Group repeated The groups that matched the request.
has_next_page bool Whether there are more groups to get.

GetMembersRequest

Request to get members of a group.

Field Type Label Description
group_id string The ID of the group to get members of.
username string optional The username of the members to search for.
group_moderation Moderation optional The membership status to filter members by. If not specified, all members are returned.
page int32 optional The page of results to get.

GetMembersResponse

Response to a GetMembersRequest.

Field Type Label Description
members Member repeated The members that matched the request.
has_next_page bool Whether there are more members to get.

Group

Groups are a way to organize users and posts (and thus events). They can be used for many purposes,

Field Type Label Description
id string The group's unique ID.
name string Mutable name of the group. Must be unique, such that the derived shortname is also unique.
shortname string Immutable shortname of the group. Derived from changes to name when the Group is updated.
description string A description of the group.
avatar MediaReference optional An avatar for the group.
default_membership_permissions Permission repeated The default permissions for new members of the group.
default_membership_moderation Moderation The default moderation for new members of the group. Valid values are PENDING (requires a moderator to let you join) and UNMODERATED.
default_post_moderation Moderation The default moderation for new posts in the group.
default_event_moderation Moderation The default moderation for new events in the group.
visibility Visibility LIMITED visibility groups are only visible to members. PRIVATE groups are only visibile to users with the ADMIN group permission.
member_count uint32 The number of members in the group.
post_count uint32 The number of posts in the group.
event_count uint32 The number of events in the group.
non_member_permissions Permission repeated The permissions given to non-members of the group.
current_user_membership Membership optional The membership for the current user, if any.
created_at google.protobuf.Timestamp The time the group was created.
updated_at google.protobuf.Timestamp optional The time the group was last updated.

Member

Used when fetching group members using the GetMembers RPC.

Field Type Label Description
user User The user.
membership Membership The user's membership (or join request, or invitation, or both) in the group.

GroupListingType

The type of group listing to get.

Name Number Description
ALL_GROUPS 0 Get all groups (visible to the current user).
MY_GROUPS 1 Get groups the current user is a member of.
REQUESTED_GROUPS 2 Get groups the current user has requested to join.
INVITED_GROUPS 3 Get groups the current user has been invited to.

Top

posts.proto

GetGroupPostsRequest

Used for getting context about GroupPosts of an existing Post.

Field Type Label Description
post_id string The ID of the post to get GroupPosts for.
group_id string optional The ID of the group to get GroupPosts for.

GetGroupPostsResponse

Used for getting context about GroupPosts of an existing Post.

Field Type Label Description
group_posts GroupPost repeated The GroupPosts for the given Post or Group.

GetPostsRequest

Valid GetPostsRequest formats:

Field Type Label Description
post_id string optional Returns the single post with the given ID.
author_user_id string optional Limits results to those by the given author user ID.
group_id string optional Limits results to those in the given group ID.
reply_depth uint32 optional Only supported for depth=2 for now.
context PostContext optional Only POST and REPLY are supported for now.
post_ids string optional Returns expanded posts with the given IDs.
listing_type PostListingType The listing type of the request. See PostListingType for more info.
page uint32 The page of results to return. Defaults to 0.

GetPostsResponse

Used for getting posts.

Field Type Label Description
posts Post repeated The posts returned by the request.

GroupPost

A GroupPost is a cross-post of a Post to a Group. It contains information about the moderation of the post in the group, as well as the time it was cross-posted and the user who did the cross-posting.

Field Type Label Description
group_id string The ID of the group this post is in.
post_id string The ID of the post.
user_id string Deprecated. Deprecated.** Prefer to use shared_by. The ID of the user who cross-posted the post.
group_moderation Moderation The moderation of the post in the group.
created_at google.protobuf.Timestamp The time the post was cross-posted.
shared_by Author Author info for the user who cross-posted the post.

Post

A Post is a message that can be posted to the server. Its visibility as well as any associated GroupPosts and UserPosts determine what users see it and where.

Posts are also a fundamental unit of the system. They provide a building block of Visibility and Moderation management that is used throughout Posts, Replies, Events, and Event Instances.

Field Type Label Description
id string Unique ID of the post.
author Author optional The author of the post. This is a smaller version of User.
reply_to_post_id string optional If this is a reply, this is the ID of the post it's replying to.
title string optional The title of the post. This is invalid for replies.
link string optional The link of the post. This is invalid for replies.
content string optional The content of the post. This is required for replies.
response_count int32 The number of responses (replies and replies to replies, etc.) to this post.
reply_count int32 The number of direct replies to this post.
group_count int32 The number of groups this post is in.
media MediaReference repeated List of Media IDs associated with this post. Order is preserved.
media_generated bool Flag indicating whether Media has been generated for this Post. Currently previews are generated for any Link post.
embed_link bool Flag indicating
shareable bool Flag indicating a LIMITED or SERVER_PUBLIC post can be shared with groups and individuals, and a DIRECT post can be shared with individuals.
context PostContext Context of the Post (POST, REPLY, EVENT, or EVENT_INSTANCE.)
visibility Visibility The visibility of the Post.
moderation Moderation The moderation of the Post.
current_group_post GroupPost optional If the Post was retrieved from GetPosts with a group_id, the GroupPost metadata may be returned along with the Post.
replies Post repeated Hierarchical replies to this post. There will never be more than reply_count replies. However, there may be fewer than reply_count replies if some replies are hidden by moderation or visibility. Replies are not generally loaded by default, but can be added to Posts in the frontend.
created_at google.protobuf.Timestamp The time the post was created.
updated_at google.protobuf.Timestamp optional The time the post was last updated.
published_at google.protobuf.Timestamp optional The time the post was published (its visibility first changed to SERVER_PUBLIC or GLOBAL_PUBLIC).
last_activity_at google.protobuf.Timestamp The time the post was last interacted with (replied to, etc.)
unauthenticated_star_count int64 The number of unauthenticated stars on the post.

UserPost

A UserPost is a "direct share" of a Post to a User. Currently unused/unimplemented. See also: DIRECT Visibility.

Field Type Label Description
user_id string The ID of the user the post is shared with.
post_id string The ID of the post shared.
created_at google.protobuf.Timestamp The time the post was shared.

PostContext

Differentiates the context of a Post, as in Jonline's data models, Post is the "core" type where Jonline consolidates moderation and visibility data and logic.

Name Number Description
POST 0 "Standard" Post.
REPLY 1 Reply to a POST, REPLY, EVENT, EVENT_INSTANCE, FEDERATED_POST, or FEDERATED_EVENT_INSTANCE. Does not suport a link.
EVENT 2 An "Event" Post. The Events table should have a row for this Post. These Posts' link and title fields are modifiable.
EVENT_INSTANCE 3 An "Event Instance" Post. The EventInstances table should have a row for this Post. These Posts' link and title fields are modifiable.
FEDERATED_POST 10 A "Federated" Post. This is a Post that was created on another server. Its link field must be a link to the original Post, i.e. htttps://jonline.io/post/abcd1234. This is enforced by the CreatePost PRC.
FEDERATED_EVENT_INSTANCE 13 A "Federated" EventInstance. This is an EventInstance that was created on another server. Its link field must be a link to the original EventInstance, i.e. https://jonline.io/event/abcd1234.

PostListingType

A high-level enumeration of general ways of requesting posts.

Name Number Description
ALL_ACCESSIBLE_POSTS 0 Gets SERVER_PUBLIC and GLOBAL_PUBLIC posts as is sensible. Also usable for getting replies anywhere.
FOLLOWING_POSTS 1 Returns posts from users the user is following.
MY_GROUPS_POSTS 2 Returns posts from any group the user is a member of.
DIRECT_POSTS 3 Returns DIRECT posts that are directly addressed to the user.
POSTS_PENDING_MODERATION 4 Returns posts pending moderation by the server-level mods/admins.
GROUP_POSTS 10 Returns posts from a specific group. Requires group_id parameter.
GROUP_POSTS_PENDING_MODERATION 11 Returns pending_moderation posts from a specific group. Requires group_id parameter and user must have group (or server) admin permissions.

Top

events.proto

AnonymousAttendee

An anonymous internet user who has RSVP'd to an EventInstance.

(TODO:) The visibility on AnonymousAttendee ContactMethods should support the LIMITED visibility, which will make them visible to the event creator.

Field Type Label Description
name string A name for the anonymous user. For instance, "Bob Gomez" or "The guy on your front porch."
contact_methods ContactMethod repeated Contact methods for anonymous attendees. Currently not linked to Contact methods for users.
auth_token string optional Used to allow anonymous users to RSVP to an event. Generated by the server when an event attendance is upserted for the first time. Subsequent attendance upserts, with the same event_instance_id and anonymous_attendee.auth_token, will update existing anonymous attendance records. Invalid auth tokens used during upserts will always create a new EventAttendance.

Event

An Event is a top-level type used to organize calendar events, RSVPs, and messaging/posting about the Event. Actual time data lies in its EventInstances.

(Eventually, Jonline Events should also support ticketing.)

Field Type Label Description
id string Unique ID for the event generated by the Jonline BE.
post Post The Post containing the underlying data for the event (names). Its PostContext should be EVENT.
info EventInfo Event configuration like whether to allow (anonymous) RSVPs, etc.
instances EventInstance repeated A list of instances for the Event. Events will only include all instances if the request is for a single event.

EventAttendance

Could be called an "RSVP." Describes the attendance of a user at an EventInstance. Such as:

Field Type Label Description
id string Unique server-generated ID for the attendance.
event_instance_id string ID of the EventInstance the attendance is for.
user_attendee UserAttendee If the attendance is non-anonymous, core data about the user.
anonymous_attendee AnonymousAttendee If the attendance is anonymous, core data about the anonymous attendee.
number_of_guests uint32 Number of guests including the RSVPing user. (Minimum 1).
status AttendanceStatus The user's RSVP to an EventInstance (one of INTERESTED, REQUESTED (i.e. invited), GOING, NOT_GOING)
inviting_user_id string optional User who invited the attendee. (Not yet used.)
private_note string Public note for everyone who can see the event to see.
public_note string Private note for the event owner.
moderation Moderation Moderation status for the attendance. Moderated by the Event owner (or EventInstance owner if applicable).
created_at google.protobuf.Timestamp The time the attendance was created.
updated_at google.protobuf.Timestamp optional The time the attendance was last updated.

EventAttendances

Response to get RSVP data for an event.

Field Type Label Description
attendances EventAttendance repeated The attendance data for the event, in no particular order.
hidden_location Location optional When hide_location_until_rsvp_approved is set, the location of the event.

EventInfo

To be used for ticketing, RSVPs, etc. Stored as JSON in the database.

Field Type Label Description
allows_rsvps bool optional Whether to allow RSVPs for the event.
allows_anonymous_rsvps bool optional Whether to allow anonymous RSVPs for the event.
max_attendees uint32 optional Limit the max number of attendees. No effect unless allows_rsvps is true. Not yet supported.
hide_location_until_rsvp_approved bool optional Hide the location until the user RSVPs (and it's accepted). From a system perspective, when this is set, Events will not include the Location until the user has RSVP'd. Location will always be returned in EventAttendances if the request for the EventAttendances came from a (logged in or anonymous) user whose attendance is approved (or the event owner).
default_rsvp_moderation Moderation optional Default moderation for RSVPs from logged-in users (either PENDING or APPROVED). Anonymous RSVPs are always moderated (default to PENDING).

EventInstance

The time-based component of an Event. Has a starts_at and ends_at time, a Location, and an optional Post (and discussion thread) specific to this particular EventInstance in addition to the parent Event.

Field Type Label Description
id string Unique ID for the event instance generated by the Jonline BE.
event_id string ID of the parent Event.
post Post Optional Post containing alternate name/link/description for this particular instance. Its PostContext should be EVENT_INSTANCE.
info EventInstanceInfo Additional configuration for this instance of this EventInstance beyond the EventInfo in its parent Event.
starts_at google.protobuf.Timestamp The time the event starts (UTC/Timestamp format).
ends_at google.protobuf.Timestamp The time the event ends (UTC/Timestamp format).
location Location optional The location of the event.

EventInstanceInfo

To be used for ticketing, RSVPs, etc. Stored as JSON in the database.

Field Type Label Description
rsvp_info EventInstanceRsvpInfo optional RSVP configuration and metadata for the event instance.

EventInstanceRsvpInfo

Consolidated type for RSVP info for an EventInstance. Curently, the optional counts below are never returned by the API.

Field Type Label Description
allows_rsvps bool optional Overrides EventInfo.allows_rsvps, if set, for this instance.
allows_anonymous_rsvps bool optional Overrides EventInfo.allows_anonymous_rsvps, if set, for this instance.
max_attendees uint32 optional Overrides EventInfo.max_attendees, if set, for this instance. Not yet supported.
going_rsvps uint32 optional The number of users who have RSVP'd to the event.
going_attendees uint32 optional The number of attendees who have RSVP'd to the event. (RSVPs may have multiple attendees, i.e. guests.)
interested_rsvps uint32 optional The number of users who have signaled interest in the event.
interested_attendees uint32 optional The number of attendees who have signaled interest in the event. (RSVPs may have multiple attendees, i.e. guests.)
invited_rsvps uint32 optional The number of users who have been invited to the event.
invited_attendees uint32 optional The number of attendees who have been invited to the event. (RSVPs may have multiple attendees, i.e. guests.)

GetEventAttendancesRequest

Request to get RSVP data for an event.

Field Type Label Description
event_instance_id string The ID of the event to get RSVP data for.
anonymous_attendee_auth_token string optional If set, and if the token has an RSVP for this even, request that RSVP data in addition to the rest of the RSVP data. (The event creator can always see and moderate anonymous RSVPs.)

GetEventsRequest

Request to get Events in a formatted per-EventInstance structure. i.e. the response will carry duplicate Events with the same ID if that Event has multiple EventInstances in the time frame the client asked for.

These structured EventInstances are ordered by start time unless otherwise specified (specifically, EventListingType.NEWLY_ADDED_EVENTS).

Valid GetEventsRequest formats:

Field Type Label Description
event_id string optional Returns the single event with the given ID.
author_user_id string optional Limits results to those by the given author user ID.
group_id string optional Limits results to those in the given group ID (via GroupPost association's for the Event's internal Post).
event_instance_id string optional Limits results to those with the given event instance ID.
time_filter TimeFilter optional Filters returned EventInstances by time.
attendee_id string optional If set, only returns events that the given user is attending. If attendance_statuses is also set, returns events where that user's status is one of the given statuses.
attendance_statuses AttendanceStatus repeated If set, only return events for which the current user's attendance status matches one of the given statuses. If attendee_id is also set, only returns events where the given user's status matches one of the given statuses.
post_id string optional Finds Events for the Post with the given ID. The Post should have a PostContext of EVENT or EVENT_INSTANCE.
listing_type EventListingType The listing type, e.g. ALL_ACCESSIBLE_EVENTS, FOLLOWING_EVENTS, MY_GROUPS_EVENTS, DIRECT_EVENTS, GROUP_EVENTS, GROUP_EVENTS_PENDING_MODERATION.

GetEventsResponse

A list of Events with a maybe-incomplete (see GetEventsRequest) set of their EventInstances.

Note that GetEventsResponse may often include duplicate Events with the same ID. I.E. something like: {events: [{id: a, instances: [{id: x}]}, {id: a, instances: [{id: y}]}, ]} is a valid response. This semantically means: "Event A has both instances X and Y in the time frame the client asked for." The client should be able to handle this.

In the React/Tamagui client, this is handled by the Redux store, which effectively "compacts" all response into its own internal Events store, in a form something like: {events: {a: {id: a, instances: [{id: x}, {id: y}]}, ...}, instanceEventIds: {x:a, y:a}}. (In reality it uses EntityAdapter which is a bit more complicated, but the idea is the same.)

Field Type Label Description
events Event repeated

TimeFilter

Time filter that works on the starts_at and ends_at fields of EventInstance. API currently only supports ends_after.

Field Type Label Description
starts_after google.protobuf.Timestamp optional Filter to events that start after the given time.
ends_after google.protobuf.Timestamp optional Filter to events that end after the given time.
starts_before google.protobuf.Timestamp optional Filter to events that start before the given time.
ends_before google.protobuf.Timestamp optional Filter to events that end before the given time.

UserAttendee

Wire-identical to Author, but with a different name to avoid confusion.

Field Type Label Description
user_id string The user ID of the attendee.
username string optional The username of the attendee.
avatar MediaReference optional The attendee's user avatar.
real_name string optional
permissions Permission repeated

AttendanceStatus

EventInstance attendance statuses. State transitions may generally happen in any direction, but:

Name Number Description
INTERESTED 0 The user is (or was) interested in attending. This is the default status.
REQUESTED 1 Another user has invited the user to the event.
GOING 2 The user plans to go to the event, or went to the event.
NOT_GOING 3 The user does not plan to go to the event, or did not go to the event.

EventListingType

The listing type, e.g. ALL_ACCESSIBLE_EVENTS, FOLLOWING_EVENTS, MY_GROUPS_EVENTS, DIRECT_EVENTS, GROUP_EVENTS, GROUP_EVENTS_PENDING_MODERATION.

Events returned are ordered by start time unless otherwise specified (specifically, NEWLY_ADDED_EVENTS).

Name Number Description
ALL_ACCESSIBLE_EVENTS 0 Gets SERVER_PUBLIC and GLOBAL_PUBLIC events depending on whether the user is logged in, LIMITED events from authors the user is following, and PRIVATE events owned by, or directly addressed to, the current user.
FOLLOWING_EVENTS 1 Returns events from users the user is following.
MY_GROUPS_EVENTS 2 Returns events from any group the user is a member of.
DIRECT_EVENTS 3 Returns DIRECT events that are directly addressed to the user.
EVENTS_PENDING_MODERATION 4 Returns events pending moderation by the server-level mods/admins.
GROUP_EVENTS 10 Returns events from a specific group. Requires group_id parameterRequires group_id parameter
GROUP_EVENTS_PENDING_MODERATION 11 Returns pending_moderation events from a specific group. Requires group_id parameter and user must have group (or server) admin permissions.
NEWLY_ADDED_EVENTS 20 Returns events from either ALL_ACCESSIBLE_EVENTS or a specific author (with optional author_user_id parameter). Returned EventInstances will be ordered by creation time rather than start time.

Top

server_configuration.proto

ExternalCDNConfig

Useful for setting your Jonline instance up to run underneath a CDN. By default, the web client uses window.location.hostname to determine the backend server. If set, the web client will use this value instead. NOTE: Only applies to Tamagui web client for now.

Field Type Label Description
frontend_host string The domain where the frontend is hosted. For example, jonline.io. Typically your CDN (like Cloudflare) should own the DNS for this domain.
backend_host string The domain where the backend is hosted. For example, jonline.io.itsj.online. Typically your Kubernetes provider should own DNS for this domain.
secure_media bool (TODO) When set, the HTTP GET /media/<id>?<authorization> endpoint will be disabled by default on the HTTP (non-secure) server that sends data to the CDN. Only requests from IPs in media_ipv4_allowlist and media_ipv6_allowlist will be allowed.
media_ipv4_allowlist string optional Whitespace- and/or comma- separated list of IPv4 addresses/ranges to whom media data may be served. Only applicable if secure_media is true. For reference, Cloudflare's are at https://www.cloudflare.com/ips-v4.
media_ipv6_allowlist string optional Whitespace- and/or comma- separated list of IPv6 addresses/ranges to whom media data may be served. Only applicable if secure_media is true. For reference, Cloudflare's are at https://www.cloudflare.com/ips-v6.
cdn_grpc bool (TODO) When implemented, this actually changes the whole Jonline protocol (in terms of ports). When enabled, Jonline should not server a secure site on HTTPS, and instead serve the Tonic gRPC server there (on port 443). Jonine clients will need to be updated to always seek out a secure client on port 443 when this feature is enabled. This would let Jonline leverage Cloudflare's DDOS protection and performance on gRPC as well as HTTP. (This is a Cloudflare-specific feature requirement.)

FeatureSettings

Settings for a feature (e.g. People, Groups, Posts, Events, Media). Encompasses both the feature's visibility and moderation settings.

Field Type Label Description
visible bool Hide the Posts or Events tab from the user with this flag.
default_moderation Moderation Only UNMODERATED and PENDING are valid. When UNMODERATED, user reports may transition status to PENDING. When PENDING, users' SERVER_PUBLIC or GLOBAL_PUBLIC posts will not be visible until a moderator approves them. LIMITED visiblity posts are always visible to targeted users (who have not blocked the author) regardless of default_moderation.
default_visibility Visibility Only SERVER_PUBLIC and GLOBAL_PUBLIC are valid. GLOBAL_PUBLIC is only valid if default_user_permissions contains `GLOBALLY_PUBLISH_[USERS
custom_title string optional (TODO) Custom title, like "Section"s instead of "Group"s. This is more an idea; internationalization is obviously problematic here.

PostSettings

Specific settings for Posts and Events.

Field Type Label Description
visible bool Hide the Posts or Events tab from the user with this flag.
default_moderation Moderation Only UNMODERATED and PENDING are valid. When UNMODERATED, user reports may transition status to PENDING. When PENDING, users' SERVER_PUBLIC or GLOBAL_PUBLIC posts will not be visible until a moderator approves them. LIMITED visiblity posts are always visible to targeted users (who have not blocked the author) regardless of default_moderation.
default_visibility Visibility Only SERVER_PUBLIC and GLOBAL_PUBLIC are valid. GLOBAL_PUBLIC is only valid if default_user_permissions contains `GLOBALLY_PUBLISH_[USERS
custom_title string optional (TODO) Custom title, like "Section"s instead of "Group"s. This is more an idea; internationalization is obviously problematic here.
enable_replies bool optional Controls whether replies are shown in the UI. Note that users' ability to reply is controlled by the REPLY_TO_POSTS permission.

ServerColors

Color in ARGB hex format (i.e 0xAARRGGBB).

Field Type Label Description
primary uint32 optional App Bar/primary accent color.
navigation uint32 optional Nav/secondary accent color.
author uint32 optional Color used on author of a post in discussion threads for it.
admin uint32 optional Color used on author for admin posts.
moderator uint32 optional Color used on author for moderator posts.

ServerConfiguration

Configuration for a Jonline server instance.

Field Type Label Description
server_info ServerInfo optional The name, description, logo, color scheme, etc. of the server.
federation_info FederationInfo optional The federation configuration for the server.
anonymous_user_permissions Permission repeated Permissions for a user who isn't logged in to the server. Allows admins to disable certain features for anonymous users. Valid values are VIEW_USERS, VIEW_GROUPS, VIEW_POSTS, and VIEW_EVENTS.
default_user_permissions Permission repeated Default user permissions given to a new user. Users with MODERATE_USERS permission can also grant/revoke these permissions for others. Valid values are VIEW_USERS, PUBLISH_USERS_LOCALLY, PUBLISH_USERS_GLOBALLY, VIEW_GROUPS, CREATE_GROUPS, PUBLISH_GROUPS_LOCALLY, PUBLISH_GROUPS_GLOBALLY, JOIN_GROUPS, VIEW_POSTS, CREATE_POSTS, PUBLISH_POSTS_LOCALLY, PUBLISH_POSTS_GLOBALLY, VIEW_EVENTS, CREATE_EVENTS, PUBLISH_EVENTS_LOCALLY, and PUBLISH_EVENTS_GLOBALLY.
basic_user_permissions Permission repeated Permissions grantable by a user with the GRANT_BASIC_PERMISSIONS permission. Valid values are VIEW_USERS, PUBLISH_USERS_LOCALLY, PUBLISH_USERS_GLOBALLY, VIEW_GROUPS, CREATE_GROUPS, PUBLISH_GROUPS_LOCALLY, PUBLISH_GROUPS_GLOBALLY, JOIN_GROUPS, VIEW_POSTS, CREATE_POSTS, PUBLISH_POSTS_LOCALLY, PUBLISH_POSTS_GLOBALLY, VIEW_EVENTS, CREATE_EVENTS, PUBLISH_EVENTS_LOCALLY, and PUBLISH_EVENTS_GLOBALLY.
people_settings FeatureSettings Configuration for users on the server. If default visibility is GLOBAL_PUBLIC, default_user_permissions must contain PUBLISH_USERS_GLOBALLY.
group_settings FeatureSettings Configuration for groups on the server. If default visibility is GLOBAL_PUBLIC, default_user_permissions must contain PUBLISH_GROUPS_GLOBALLY.
post_settings PostSettings Configuration for posts on the server. If default visibility is GLOBAL_PUBLIC, default_user_permissions must contain PUBLISH_POSTS_GLOBALLY.
event_settings PostSettings Configuration for events on the server. If default visibility is GLOBAL_PUBLIC, default_user_permissions must contain PUBLISH_EVENTS_GLOBALLY.
media_settings FeatureSettings Configuration for media on the server. If default visibility is GLOBAL_PUBLIC, default_user_permissions must contain PUBLISH_MEDIA_GLOBALLY.
external_cdn_config ExternalCDNConfig optional If set, enables External CDN support for the server. This means that the non-secure HTTP server (on port 80) will not redirect to the secure server, and instead serve up Tamagui Web/Flutter clients directly. This allows you to point Cloudflare's "CNAME HTTPS Proxy" feature at your Jonline server to serve up HTML/CS/JS and Media files with caching from Cloudflare's CDN. See ExternalCDNConfig for more details on securing this setup.
private_user_strategy PrivateUserStrategy Strategy when a user sets their visibility to PRIVATE. Defaults to ACCOUNT_IS_FROZEN.
authentication_features AuthenticationFeature repeated (TODO) Allows admins to enable/disable creating accounts and logging in. Eventually, external auth too hopefully!
web_push_config WebPushConfig optional Web Push (VAPID) configuration for the server.

ServerInfo

User-facing information about the server displayed on the "about" page.

Field Type Label Description
name string optional Name of the server.
short_name string optional Short name of the server. Used in URLs, etc. (Currently unused.)
description string optional Description of the server.
privacy_policy string optional The server's privacy policy. Will be displayed during account creation and on the /about page.
logo ServerLogo optional Multi-size logo data for the server.
web_user_interface WebUserInterface optional The web UI to use (React/Tamagui (default) vs. Flutter Web)
colors ServerColors optional The color scheme for the server.
media_policy string optional The media policy for the server. Will be displayed during account creation and on the /about page.
recommended_server_hosts string repeated Deprecated. This will be replaced with FederationInfo soon.

Logo data for the server. Built atop Jonline Media APIs.

Field Type Label Description
squareMediaId string optional The media ID for the square logo.
squareMediaIdDark string optional The media ID for the square logo in dark mode.
wideMediaId string optional The media ID for the wide logo.
wideMediaIdDark string optional The media ID for the wide logo in dark mode.

WebPushConfig

Web Push (VAPID) configuration for the server.

Field Type Label Description
public_vapid_key string Public VAPID key for the server.
private_vapid_key string Private VAPID key for the server. Never serialized to the client. Admins: Edit this in the database's JSONB column directly.

AuthenticationFeature

Authentication features that can be enabled/disabled by the server admin.

Name Number Description
AUTHENTICATION_FEATURE_UNKNOWN 0 An authentication feature that is not known to the server. (Likely, the client and server use different versions of the Jonline protocol.)
CREATE_ACCOUNT 1 Users can sign up for an account.
LOGIN 2 Users can sign in with an existing account.

PrivateUserStrategy

Strategy when a user sets their visibility to PRIVATE.

Name Number Description
ACCOUNT_IS_FROZEN 0 PRIVATE Users can't see other Users (only PUBLIC_GLOBAL Visilibity Users/Posts/Events). Other users can't see them.
LIMITED_CREEPINESS 1 Users can see other users they follow, but only PUBLIC_GLOBAL Visilibity Posts/Events. Other users can't see them.
LET_ME_CREEP_ON_PPL 2 Users can see other users they follow, including their PUBLIC_SERVER Posts/Events. Other users can't see them.

WebUserInterface

Offers a choice of web UIs. Generally though, React/Tamagui is a century ahead of Flutter Web, so it's the default.

Name Number Description
FLUTTER_WEB 0 Uses Flutter Web. Loaded from /app.
HANDLEBARS_TEMPLATES 1 Uses Handlebars templates. Deprecated; will revert to Tamagui UI if chosen.
REACT_TAMAGUI 2 React UI using Tamagui (a React Native UI library).

Top

federation.proto

FederatedAccount

Some user on a Jonline server. Most commonly a different server than the one serving up FederatedAccount data, but users may also federate multiple accounts on the same server.

Field Type Label Description
host string The DNS hostname of the server that this user is on.
user_id string The user ID of the user on the server.

FederatedServer

A server that this server will federate with.

Field Type Label Description
host string The DNS hostname of the server to federate with.
configured_by_default bool optional Indicates to UI clients that they should enable/configure the indicated server by default.
pinned_by_default bool optional Indicates to UI clients that they should pin the indicated server by default (showing its Events and Posts alongside the "main" server).

FederationInfo

The federation configuration for a Jonline server.

Field Type Label Description
servers FederatedServer repeated A list of servers that this server will federate with.

GetServiceVersionResponse

Version information for the Jonline server.

Field Type Label Description
version string The version of the Jonline server. May be suffixed with the GitHub SHA of the commit that generated the binary for the server.

Scalar Value Types

.proto Type Notes C++ Java Python Go C# PHP Ruby
double double double float float64 double float Float
float float float float float32 float float Float
int32 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint32 instead. int32 int int int32 int integer Bignum or Fixnum (as required)
int64 Uses variable-length encoding. Inefficient for encoding negative numbers – if your field is likely to have negative values, use sint64 instead. int64 long int/long int64 long integer/string Bignum
uint32 Uses variable-length encoding. uint32 int int/long uint32 uint integer Bignum or Fixnum (as required)
uint64 Uses variable-length encoding. uint64 long int/long uint64 ulong integer/string Bignum or Fixnum (as required)
sint32 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int32s. int32 int int int32 int integer Bignum or Fixnum (as required)
sint64 Uses variable-length encoding. Signed int value. These more efficiently encode negative numbers than regular int64s. int64 long int/long int64 long integer/string Bignum
fixed32 Always four bytes. More efficient than uint32 if values are often greater than 2^28. uint32 int int uint32 uint integer Bignum or Fixnum (as required)
fixed64 Always eight bytes. More efficient than uint64 if values are often greater than 2^56. uint64 long int/long uint64 ulong integer/string Bignum
sfixed32 Always four bytes. int32 int int int32 int integer Bignum or Fixnum (as required)
sfixed64 Always eight bytes. int64 long int/long int64 long integer/string Bignum
bool bool boolean boolean bool bool boolean TrueClass/FalseClass
string A string must always contain UTF-8 encoded or 7-bit ASCII text. string String str/unicode string string string String (UTF-8)
bytes May contain any arbitrary sequence of bytes. string ByteString str []byte ByteString string String (ASCII-8BIT)