diff --git a/config.json b/config.json new file mode 100644 index 0000000..7ade5ab --- /dev/null +++ b/config.json @@ -0,0 +1,4 @@ +{ + "DOMAIN" : "767b16bb.ngrok.io", + "PORT" : 3000 +} \ No newline at end of file diff --git a/index.js b/index.js new file mode 100644 index 0000000..6bb4498 --- /dev/null +++ b/index.js @@ -0,0 +1,18 @@ +const config = require('./config'); +const server = require('./server'); +const express = require('express'); +const app = express(); +const http = require('http'); + +app.set('domain', config.DOMAIN); +app.set('port', process.env.PORT || config.PORT || 3000); +app.set('port-https', process.env.PORT_HTTPS || 8443); + +app.get('/', (req, res) => res.send('Hello World!')); +app.get('/u/:name', server.get_user); +app.get('/.well-known/webfinger', server.get_webfinger); +app.get('/inbox', (req, res) => res.send('Here lies the inbox')); + +http.createServer(app).listen(app.get('port'), function(){ + console.log('Express server listening on port ' + app.get('port')); +}); diff --git a/package.json b/package.json index d06f622..177504a 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,12 @@ "name": "scuttlebutt_to_ap", "version": "1.0.0", "dependencies": { - "ssb-client": "latest", + "express": "latest", + "node-fetch": "latest", "pull-stream": "latest", + "ssb-client": "latest", + "ssb-friends": "latest", "stream-to-pull-stream": "latest", - "node-fetch": "latest" + "http": "latest" } } diff --git a/bridge.js b/save_to_ssb.js similarity index 97% rename from bridge.js rename to save_to_ssb.js index a917f77..271da1a 100644 --- a/bridge.js +++ b/save_to_ssb.js @@ -89,7 +89,7 @@ async function get_last_by_activity_id(id) { */ let last = null; - + let out = new Promise((resolve, reject) => { ssbClient((err, sbot) => { pull( @@ -157,13 +157,13 @@ function add_ssb_message(type, id, actor, summary, object, origin = null, target let actor_id = actor.id; delete actor.id; let actor_promise = createBlobObject(actor_type, actor_id, actor); - + let object_type = object.type; delete object.type; let object_id = object.id; delete object.id; let object_promise = createBlobObject(object_type, object_id, object); - + Promise.all([actor_promise, object_promise]).then(([actor_blob, object_blob]) => { ssbClient((err, sbot) => { if (err) throw err; @@ -196,7 +196,7 @@ function add_ssb_message(type, id, actor, summary, object, origin = null, target sbot.close(); }); }) - + } async function get_json_from_blob(blob_id){ @@ -266,9 +266,9 @@ async function restore_ssb_message(id){ return await out; } -exports.bridge = { +module.exports = { save : (message) => { - if (message.@context === "https://www.w3.org/ns/activitystreams") { + if (message["@context"] === "https://www.w3.org/ns/activitystreams") { //todo: should be @context add_ssb_message( message.type, @@ -284,9 +284,5 @@ exports.bridge = { throw ("Invalid message context."); } }, - restore: (id) => { - let p = restore_ssb_message(id); - - return p; - } -}; + restore: restore_ssb_message +}; \ No newline at end of file diff --git a/server.js b/server.js new file mode 100644 index 0000000..085d45f --- /dev/null +++ b/server.js @@ -0,0 +1,122 @@ +const config = require('./config'); +const ssbClient = require('ssb-client'); +const pull = require('pull-stream'); + +DOMAIN = config.DOMAIN; + +async function check_if_in_friends(name){ + let result = false; + let out = new Promise((resolve, reject) => { + ssbClient((err, sbot) => { + if (err) reject(err); + + pull( + sbot.friends.createFriendStream(), + pull.collect((err, array) => { + array.forEach(function (actor) { + let short_actor = (actor.substr(1)); + if (short_actor === name) { + result = true; + } + }); + sbot.close(); + resolve(result); + }) + ); + }); + }); + return await out; +} + +function get_webfinger(req, res) { + let resource = req.query.resource; + if (!resource || !resource.includes('acct:')) { + return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.'); + } + else { + let name = resource.replace('acct:',''); + name = name.substr(0,name.indexOf('@')); + + // This might help with webfinger detection + // let encoded_name = encodeURIComponent(name); + + let p = check_if_in_friends(name); + + p.then((result) => { + if (result) { + res.json( + { + 'subject': `acct:${name}@${DOMAIN}`, + links: [ + { + rel: 'self', + type: 'application/activitypub+json', + href: `https://${DOMAIN}/u/${name}` + } + ], + } + ); + } else { + return res.status(404).send(`No record found for ${name}.`); + } + }).catch((err) => { + return res.status(500).send(`An error occured: ${err}.`); + }) + } +} + +function get_user(req, res){ + let name = req.params.name; + if (!name) { + return res.status(400).send('Bad request.'); + } + else { + + // This might help with webfinger detection + // let encoded_name = encodeURIComponent(name); + + let p = check_if_in_friends(name); + + p.then((result) => { + if (result) { + + res.json( + { + '@context': [ + 'https://www.w3.org/ns/activitystreams', + 'https://w3id.org/security/v1' + ], + + id: `https://${DOMAIN}/u/${name}`, + type: 'Person', + preferredUsername: 'TESTPERSON PLS CHANGE', //todo: read from latest about message + inbox: `https://${DOMAIN}/u/${name}/inbox`, + + publicKey: { + id: `https://${DOMAIN}/u/${name}#main-key`, + owner: `https://${DOMAIN}/u/${name}`, + publicKeyPem: '-----BEGIN PUBLIC KEY-----\n' + + 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsT4MEtffaV0uFr9jgSnx\n' + + 'kb1+MMd1/jGYBugJ4jkHc9rvQRJLA2C8O2LbrdNb/00TRHh0pkR7AJW7DWMhIF/P\n' + + 'WmsHcdouAUhovAVO+4yrRK5fMA96JP6k2YwqJK+yjK4SMm9iwvcdBlrkZif0KWvA\n' + + 'Qf4eU24n64NSEdVu48cgZwMvQeYKaAtf2LIhXYOE4pA16C05z3BAar+9m2e1yZMG\n' + + '+JzhoywmpqlrB+XK55wjAIhvwVGgOMtUg5FbHU5sH7wZv7H945t40x7HjNCBxU6d\n' + + 'yrF7Bl6nMg+ifT5a6SzPSJ0f3g99AyfMVL5fnhSodjpsnjohfIsx9Vzd4oO1JhDx\n' + + 'SwIDAQAB\n' + + '-----END PUBLIC KEY-----' + } + } + ); + }else { + return res.status(404).send(`No record found for ${name}.`); + } + }).catch((err) => { + return res.status(500).send(`An error occured: ${err}.`); + }) + } +} + +module.exports = { + get_user, + get_webfinger +}; \ No newline at end of file