Understanding follow request

In addition to the documentation, I am trying to understand the ActivityPub protocol through replaying messages to a personal server. I am trying to understand how Follow requests work, but running into problems.

  1. Where in the protocol documentation is the Follow example JSON?
  2. What is the UUID value in the ID? How is that generated?
  3. Why is the following request failing? I receive an internal error, as noted below:

$ curl \ -H 'Content-Type: application/activity+json' \ https://testserver.farhan.codes/inbox/ -d '{"@context":["https://www.w3.org/ns/activitystreams","https://dev.farhan.codes/schemas/litepub-0.1.jsonld",{"@language":"und"}],"actor":"https://dev.farhan.codes/users/farhan","cc":["https://www.w3.org/ns/activitystreams#Public"],"id":"https://testserver.farhan.codes/activities/47e0a50f-fa4b-4339-bf3c-ec7e927379e7","object":"https://testserver.farhan.codes/users/farhan","published":"2020-06-11T06:02:42.553779Z","state":"pending","to":["https://testserver.farhan.codes/users/farhan"],"type":"Follow"}' {"errors":{"detail":"Internal server error"}}

Please advise. Thanks!

The answer to the second appears to be arbitrary by the server.
However, I cannot find the answer to the other two questions in the documentation.

Why would a replay fail? Is this a problem in the protocol?

I don’t think there is one.

This is generated arbitrarily by the server that sends it. To make sure your implementation is interoperable, you shouldn’t attempt to interpret it beyond making sure it’s a valid URI.

You need to have the actor object publicly available at the URL you specify for actor (the receiving server will fetch it), it needs to have a public RSA key, and you need to sign your request with the private counterpart of that key. See this and this for details.

The server in your example is down, but judging by the URI structure I am guessing this is a Pleroma server.

There are several problems with the request in your example:

  1. It’s not signed, Pleroma requires requests to be signed, or for the activity to be publicly fetchable
  2. The id of the activity is not on the same host the actor is, which is also a requirement for Pleroma.
  1. What would a signed request look like? The specific JSON-LD?

  2. How would a “generic” request from any particular system look like? What does the JSON-LD look like?

I can’t find an example or documentation that says how I need to do this…

What would the JSON-LD of a signed request look like? Can you give me an example? I cannot find one anywhere and my attempts to reverse engineer a follow request do not know the signing you are referencing.

I’ve been stuck for weeks now…

@dansup’s FediDB might be able to help with HTTP Signatures, but I’m not sure if it is still in private beta (you may request access from dansup).

HTTP signature is sent as an HTTP header. You should definitely read the Mastodon tutorial I linked.

Here’s what an activity request looks like with both HTTP signature (in headers) and LD-signature (signature field in JSON-LD itself):

POST /activitypub/sharedInbox HTTP/1.1
Signature: keyId="http://smithereen.local:8080/users/1#main-key",headers="(request-target) host date",signature="bh7lKy7gKmLqCXUJtHZxYV5r8wqMrWyeu7QvB8mkwMJuiNSqLtAcWZuM06WeerES0EZNFi+CdlfV+ssmsGUXl8lprdnyBRh0y6FCCqMnrBTq+Tsspn54QfC3nPUZKXPiED6BwOFuwuq7GWSifxEdKMF+Csy8dtlh+IcAWxCniWm/9npM3Bomk8fkBeezGE6obGG4xFtMMYEu9NBGgzF/UVMRVc3LnJKAzlubxqTfqSJNyC3qhTycdHN0Du6E0nTM9WzqSDkOmsvP6Iw/Vr1b/NRRpaRh5pY7ZQvRR1G4ZIIP4fik6KX9iJp80EnbZbS9N8VuLmGU1enbUsMvV30Brg=="
Date: Fri, 26 Jun 2020 10:16:04 GMT
Content-Type: application/ld+json; profile="https://www.w3.org/ns/activitystreams"; charset=utf-8
Content-Length: 1218
Host: localhost2:7890
Connection: Keep-Alive
Accept-Encoding: gzip
User-Agent: okhttp/3.2.0

{"cc":["http://smithereen.local:8080/users/1/followers"],"actor":"http://smithereen.local:8080/users/1","signature":{"creator":"http://smithereen.local:8080/users/1#main-key","created":"2020-06-26T10:16:04Z","type":"RsaSignature2017","signatureValue":"FflQcL2S99CFCdSd22bOz0S2pZ59fsODQA4XRBz4Fxo1pwOWciP3WZUnfpumMFzTnHs96VTeg8d7yzW36mYkITkaMyul4touUiE31X5WRd5lpRTQbU7qKlsyJ4ScF5jrhW9v8o5QhmSixV9dB4Dqypy7xVPUj2aTbhXZHNdv3kNDjyimgWRHYKUTpwU7n17zRatGe+TmhX2j/pnngKsU9eTbY/hmbGRxr8GZe8nUlV3cruQhaxTW7MB4+1+EeZRfPo7T6O1drnYDxqpshS9N25SRXJHpofEUQX/CLHn0yFt6gZhftYyhEvxk9duXR49VFen75OqS6c8jSmfDs6xvfg=="},"id":"http://smithereen.local:8080/posts/111/activityCreate","published":"2020-06-26T10:16:04Z","to":["https://www.w3.org/ns/activitystreams#Public"],"type":"Create","@context":["https://www.w3.org/ns/activitystreams",{"sensitive":"as:sensitive"}],"object":{"cc":["http://smithereen.local:8080/users/1/followers"],"id":"http://smithereen.local:8080/posts/111","attributedTo":"http://smithereen.local:8080/users/1","published":"2020-06-26T10:16:04Z","to":["https://www.w3.org/ns/activitystreams#Public"],"sensitive":false,"type":"Note","content":"<p>Test for farhan<\/p>","url":"http://smithereen.local:8080/posts/111"}}

You don’t need LD-signatures now though. You only need HTTP as those are enough to participate in the network.

1 Like

Also, here’s my implementation of HTTP signature in Java: https://github.com/grishka/Smithereen/blob/5122851e6d9e03f831597064d0ca8bb080a6d6f4/src/main/java/smithereen/activitypub/ActivityPub.java#L86-L108

Hope this helps.