9.3 KiB
This document describes the Client-to-Server API of Vervis. If you're developing a frontend application, or a forge search engine, or anything else that wants to interact with Vervis instances, and wondering what language Vervis speaks, this is the document for you.
I suppose in the future it should sit on a Docusaurus website or something like that. For now it's here.
Public Browsing
The /browse
page lists the public actors and resource hosted on the server.
However there's currently no AP version of that page.
Server Information
NodeInfo isn't implemented yet.
Registration and Authorization
Creating an account on a Vervis instance allows to:
- Create and manipulate resources (such as projects, repositories, teams)
- View non-public information
Register the application
Register client
Send a POST request to the /oauth/apps
endpoint:
curl -X POST \
-F 'client_name=Anvil' \
-F 'redirect_uris=urn:ietf:wg:oauth:2.0:oob' \
-F 'scopes=read' \
-F 'website=https://anvil.forgefed.org' \
-F 'repository=https://codeberg.org/Anvil/Anvil' \
https://vervis.example/oauth/apps
redirect_uris
currently supports specifying only one URI, and there are 2 options:- The special value
urn:ietf:wg:oauth:2.0:oob
, which means out-of-band: In this case, Vervis will respond with an HTML page containing a token that needs to be manually copied - An HTTPS URI: In this case, Vervis will redirect to the given URI
- The special value
- The only supported scope is currently
read
, and despite the misleading name, it allows all API operations
The response, upon success, is a JSON object with 2 text fields:
client_id
client_secret
Keep these stored for future use.
Obtain an Application Access Token
Send a POST request to the /oauth/token
endpoint:
curl -X POST \
-F 'client_id=your_client_id_here' \
-F 'client_secret=your_client_secret_here' \
-F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \
-F 'grant_type=client_credentials' \
https://vervis.example/oauth/token
redirect_uri
must be the one defined when registering the application
The response is a JSON object with:
access_token
: Text, keep for later usetoken_type
: Text, always "Bearer"scope
: Text, always "read"created_at
: Integer, time as POSIX seconds
Verify the Application Access Token
You can verify the token works by sending a GET request to the
/oauth/verify_credentials
endpoint:
curl \
-H 'Authorization: Bearer our_access_token_here' \
https://vervis.example/oauth/verify_credentials
Register an Account
This section isn't implemented yet. I'm about to implement it. Putting the API here for review while I'm coding.
Check if registration is enabled
Send a GET request to the /register/enabled
endpoint. A 2xx response
indicates it's enabled, otherwise it's disabled.
Check username availability
Send a GET request to the /register/available
endpoint:
curl -X GET \
-H 'Authorization: Bearer our_application_access_token_here' \
-F 'username=alice' \
https://vervis.example/register/available
A 2xx response indicates the username is available.
Create a new account
Send a POST request to the /register
endpoint:
curl -X POST \
-H 'Authorization: Bearer our_application_access_token_here' \
-F 'username=alice' \
-F 'passphrase=R6GQJ9HqLtRQ58' \
-F 'email=alice@email.example' \
https://vervis.example/register
A 2xx response indicates the account has been created. A JSON object is
returned, with a boolean email_sent
field. If true, a verification email has
been sent to the specified email address. If false, it means email verification
is disabled on this server, and the account is ready to be used.
Verify account
The email contains a token, which you can send via a POST request to the
/register/verify
endpoint, in order to verify and enable the account:
curl -X POST \
-H 'Authorization: Bearer our_application_access_token_here' \
-F 'username=alice' \
-F 'token=pRiW8ayeuN7UBW4qAKg9qRBE0DUVCIof' \
https://vervis.example/register/verify
A 2xx response indicates successful verification.
Log in as Existing User
Obtain authorization code
In a browser, send a GET request to the /oauth/authorize
endpoint:
https://vervis.example/oauth/authorize
?client_id=CLIENT_ID
&scope=read
&redirect_uri=urn:ietf:wg:oauth:2.0:oob
&response_type=code
- If
redirect_uri
is the special one as in the example above, the response will be an HTML page containing the authorization code. - Otherwise, Vervis will redirect to the
redirect_uri
, specifying the authorization code as a query parameter named "code":
redirect_uri?code=qDFUEaYrRK5c-HNmTCJbAzazwLRInJ7VHFat0wcMgCU
Obtain a User Access Token
Now that we have the code, send a POST request to the /oauth/token
endpoint
(which we previously used when registering the application):
curl -X POST \
-F 'client_id=your_client_id_here' \
-F 'client_secret=your_client_secret_here' \
-F 'redirect_uri=urn:ietf:wg:oauth:2.0:oob' \
-F 'grant_type=authorization_code' \
-F 'code=user_authzcode_here' \
-F 'scope=read' \
https://vervis.example/oauth/token
The response is a JSON object with:
access_token
: Text, keep for later usetoken_type
: Text, always "Bearer"scope
: Text, always "read"created_at
: Integer, time as POSIX seconds
Verify the User Access Token & Obtain Actor Object
You can verify the token works by sending a GET request to the
/oauth/verify_credentials
endpoint:
curl \
-H 'Authorization: Bearer our_access_token_here' \
https://vervis.example/oauth/verify_credentials
The response is a JSON object that has a url
field, whose value is the HTTPS
URI of the user's Person
ActivityPub JSON object.
Perform Authorized Requests
You can now use the access token via the Authorization
header, as in the curl
example above.
- For GET requests, it allows to obtain non-public data
- For POST requests, it allows to publish ActivityPub activities via the user outbox
Getting ActivityPub objects
You can obtain an ActivityPub object by sending GET request to its id
URI,
with Content-Type
being
application/ld+json; profile="https://www.w3.org/ns/activitystreams
. Unless
you've been given such a URI, the starting points for discovering objects are:
- Public browsing page (which doesn't yet have an AP representation)
- The user
Person
object, whose URI can be obtained from/oauth/verify_credentials
as described above
The Person Object
{
"id": "https://fig.fr33domlover.site/people/vDxKn",
"type": "Person",
"preferredUsername": "perelev",
"summary": "Cool person who makes cool stuff",
"inbox": "https://fig.fr33domlover.site/people/vDxKn/inbox",
"outbox": "https://fig.fr33domlover.site/people/vDxKn/outbox",
"followers": "https://fig.fr33domlover.site/people/vDxKn/followers",
"following": "https://fig.fr33domlover.site/people/vDxKn/following",
"sshKey": [
"https://fig.fr33domlover.site/people/vDxKn/ssh-keys/Pn9Yn"
]
}
Receiving Messages
Requests and event notifications are received as ActivityPub Activity
objects
in the Person's inbox
collection. Currently push notifications aren't
implemented, so client applications need to periodically GET the collection and
detect whether new items have appeared at the top. The inbox is a (typically
paged) reverse-chronologically OrderedCollection
of Activity
objects, as
described in the ActivityPub specification.
Common properties
These would appear in every actvity:
id
: ID URI of the activitytype
: One of the ActivityPub or ForgeFed activity typesactor
: ID URI of the actor who published this activity
These would appear in some activities:
capability
: ID URI of aGrant
activity serving as authorizationfulfills
: If the activity was published by an automated process rather than human command, these are ID URI(s) of the activities, to which the automated process was reacting
{
"id": "https://fig.fr33domlover.site/decks/W058b/outbox/nV34D",
"type": "Accept",
"actor": "https://fig.fr33domlover.site/decks/W058b",
"fulfills": [
"https://grape.fr33domlover.site/people/WZpnG/outbox/GQvnR"
],
"object": "https://grape.fr33domlover.site/people/WZpnG/outbox/GQvnR"
}
Accept
Add
Apply
Create
Follow
Grant
Invite
Join
Offer
Push
Reject
Remove
Resolve
Revoke
Undo
Publishing and Manipulating Objects
All object manipulation in Vervis is done using the ActivityPub C2S API, i.e.
by POSTing Activity
objects to the user's outbox
.
To determine the outbox URI, you can HTTP GET the Person object as mentioned
above, and grab the URI specified by its outbox
field.
Common properties
There are properties you'd often specify in the Activity
object, that aren't
specific to any activity type.
type
:Activity
actor
: URI of the person actorcapability
: URI of aGrant
activity you've received, as authorization for the action you're requestingto
,cc
,bto
,bcc
: Audience, i.e. list of URIs of actors and actor collections