Demonstrating the Feathers error when mounting a service at root

parent 80141f1e
......@@ -81,79 +81,6 @@ app.get('/followers', function (req, res, next) {
res.send({})
})
app.all('/', function (req, res, next) {
res.format({
'text/html': function () {
res.send('<h1>Hello, world</h1>')
},
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"': function () {
console.log('🎭 Actor request')
// Set correct content type.
const contentType = 'application/activity+json; charset=utf-8'
res.set('Content-Type', contentType)
console.log(` ↳ Content-Type: application/activity+json`)
// WebFinger support is not a requirement in the ActivityPub spec
// but it is required for federation with Mastodon.
// https://github.com/tootsuite/mastodon/issues/4906#issuecomment-328844846
console.log(` ↳ Link: acct:person@${localDomain} → https://${localDomain}/ (for application/activity+json)'`)
res.set('Link', `<https://${localDomain}/.well-known/webfinger?resource=acct%3Aperson%40${localDomain}>; rel="lrdd"; type="application/xrd+xml", <https://${localDomain}/>; rel="alternate"; type="application/activity+json"`)
// The structure of this reponse is modelled on the Mastodon response
// to an Actor request. This full response should not be necessary
// to successfully interoperate with Mastodon. According to the same
// issue thread, above, the only requirements according to Eugen are
// the presence of an inbox endpoint and a link header pointing to
// the WebFinger endpoint (and the implementation of the webfinger
// endpoint itself.)
console.log(' ↳ Returning ActivityStream object.\n')
const sampleActorActivityStreamObject = JSON.parse(`{
"@context": [
"https://www.w3.org/ns/activitystreams"
],
"type": "Person",
"id": "https://${localDomain}/",
"following": "https://${localDomain}/following",
"followers": "https://${localDomain}/followers",
"inbox": "https://${localDomain}/inbox",
"outbox": "https://${localDomain}/outbox",
"preferredUsername": "person",
"name": "Aral Balkan",
"summary": "Just a guy.",
"url": "https://${localDomain}/",
"icon": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://ar.al/images/aral-432.jpg"
},
"image": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://ar.al/images/aral-432.jpg"
},
"endpoints": {
"sharedInbox": "https://${localDomain}/inbox"
},
"publicKey": {
"owner": "https://${localDomain}/",
"id": "https://${localDomain}/publickey",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8NY/rAs24sgBWrTFiE0ovxSbv9ekts8NM109W6WM3s30SpAAmK/dPVzmMLeZxrsHaJVOFOCuSe2X2vVHUkYySMDokdIUWfHfGf+hpied8QPVJopoZq8cv3zz6HC8j7RFUaQYQMYi5JpdF7z9y0ZpI8bvRxWH2TPchJQe0uDk8Jvdlcqm/FfQIC6rQyLgLnX2/kRs0e7TeYTmMlXvtbmUqbtBd9FHIA0Kz9xyPm310N2E0Ca/pbDRYEylw5roRN1FI3teov3dR3Jxoy02iwHTeI9FOUF4K/MaS+ebZGjlI7ArJa4zHQ0gqslFlNLbi+4KdOI6CQKyjBZqRNBGlXBD8QIDAQAB-----END PUBLIC KEY-----"
}
}
`)
res.send(sampleActorActivityStreamObject)
}
})
})
// Set up Plugins and providers
app.configure(express.rest())
app.configure(socketio())
......@@ -165,6 +92,100 @@ app.configure(services)
// Set up event channels (see channels.js)
app.configure(channels)
// Define a service-specific middlware for the root route
// so we can render a basic HTML message if called from a browser
// and pass ActivityPub requests to the actual handler.
function indexPage (req, res, next) {
res.format({
'text/html': function () {
res.send('<h1>Hello, world</h1>')
},
'application/ld+json; profile="https://www.w3.org/ns/activitystreams"': next
})
}
// Set the headers for the Actor request.
function actorHeaders (req, res, next) {
console.log('🎭 Actor request: setting headers')
// Set correct content type.
const contentType = 'application/activity+json; charset=utf-8'
res.set('Content-Type', contentType)
console.log(` ↳ Content-Type: application/activity+json`)
// WebFinger support is not a requirement in the ActivityPub spec
// but it is required for federation with Mastodon.
// https://github.com/tootsuite/mastodon/issues/4906#issuecomment-328844846
console.log(` ↳ Link: acct:person@${localDomain} → https://${localDomain}/ (for application/activity+json)'`)
res.set('Link', `<https://${localDomain}/.well-known/webfinger?resource=acct%3Aperson%40${localDomain}>; rel="lrdd"; type="application/xrd+xml", <https://${localDomain}/>; rel="alternate"; type="application/activity+json"`)
}
const actorService = {
get (id, params) {
console.log('🎭 Actor request')
// The structure of this reponse is modelled on the Mastodon response
// to an Actor request. This full response should not be necessary
// to successfully interoperate with Mastodon. According to the same
// issue thread, above, the only requirements according to Eugen are
// the presence of an inbox endpoint and a link header pointing to
// the WebFinger endpoint (and the implementation of the webfinger
// endpoint itself.)
console.log(' ↳ Returning ActivityStream object.\n')
const sampleActorActivityStreamObject = JSON.parse(`{
"@context": [
"https://www.w3.org/ns/activitystreams"
],
"type": "Person",
"id": "https://${localDomain}/",
"following": "https://${localDomain}/following",
"followers": "https://${localDomain}/followers",
"inbox": "https://${localDomain}/inbox",
"outbox": "https://${localDomain}/outbox",
"preferredUsername": "person",
"name": "Aral Balkan",
"summary": "Just a guy.",
"url": "https://${localDomain}/",
"icon": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://ar.al/images/aral-432.jpg"
},
"image": {
"type": "Image",
"mediaType": "image/jpeg",
"url": "https://ar.al/images/aral-432.jpg"
},
"endpoints": {
"sharedInbox": "https://${localDomain}/inbox"
},
"publicKey": {
"owner": "https://${localDomain}/",
"id": "https://${localDomain}/publickey",
"publicKeyPem": "-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8NY/rAs24sgBWrTFiE0ovxSbv9ekts8NM109W6WM3s30SpAAmK/dPVzmMLeZxrsHaJVOFOCuSe2X2vVHUkYySMDokdIUWfHfGf+hpied8QPVJopoZq8cv3zz6HC8j7RFUaQYQMYi5JpdF7z9y0ZpI8bvRxWH2TPchJQe0uDk8Jvdlcqm/FfQIC6rQyLgLnX2/kRs0e7TeYTmMlXvtbmUqbtBd9FHIA0Kz9xyPm310N2E0Ca/pbDRYEylw5roRN1FI3teov3dR3Jxoy02iwHTeI9FOUF4K/MaS+ebZGjlI7ArJa4zHQ0gqslFlNLbi+4KdOI6CQKyjBZqRNBGlXBD8QIDAQAB-----END PUBLIC KEY-----"
}
}
`)
return sampleActorActivityStreamObject
}
}
// NOTE: Feathers will not let you define a route at root so the following
// will not work. We either have to fall back to Express for this or to
// remove this limitation in Feathers if we’re going to use it.
// Define root as a Feathers service. Initially, try to render an HTML
// index page if that’s content type requested. Otherwise, delegate to the
// actor service endpoint for ActivityPub.
app.use('/', indexPage, actorHeaders, actorService)
// Define inbox as a Feathers service.
app.use('inbox', {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment