Webfinger detection now works and incoming Activities are saved to the ssb log.

This commit is contained in:
Daniel Mowitz 2019-09-24 15:08:03 +02:00
parent 939d242996
commit ea8cbb43c3
5 changed files with 117 additions and 39 deletions

View file

@ -1,4 +1,4 @@
{ {
"DOMAIN" : "", "DOMAIN": "",
"PORT" : 3000 "PORT": 3000
} }

View file

@ -2,8 +2,16 @@ const config = require('./config');
const server = require('./server'); const server = require('./server');
const express = require('express'); const express = require('express');
const app = express(); const app = express();
const bodyParser = require('body-parser');
const http = require('http'); const http = require('http');
var options = { //todo: maybe be more specific here
type: "application/*"
};
app.use(bodyParser.raw(options));
app.use(bodyParser.urlencoded({extended: true}));
app.set('domain', config.DOMAIN); app.set('domain', config.DOMAIN);
app.set('port', process.env.PORT || config.PORT || 3000); app.set('port', process.env.PORT || config.PORT || 3000);
app.set('port-https', process.env.PORT_HTTPS || 8443); app.set('port-https', process.env.PORT_HTTPS || 8443);
@ -12,7 +20,10 @@ app.get('/', (req, res) => res.send('Hello World!'));
app.get('/u/:name', server.get_user); app.get('/u/:name', server.get_user);
app.get('/.well-known/webfinger', server.get_webfinger); app.get('/.well-known/webfinger', server.get_webfinger);
app.get('/inbox', (req, res) => res.send('Here lies the inbox')); app.get('/inbox', (req, res) => res.send('Here lies the inbox'));
app.get('/users', server.get_users);
http.createServer(app).listen(app.get('port'), function(){ app.post('/inbox', server.post_inbox);
http.createServer(app).listen(app.get('port'), function () {
console.log('Express server listening on port ' + app.get('port')); console.log('Express server listening on port ' + app.get('port'));
}); });

View file

@ -3,11 +3,12 @@
"version": "1.0.0", "version": "1.0.0",
"dependencies": { "dependencies": {
"express": "latest", "express": "latest",
"http": "latest",
"node-fetch": "latest", "node-fetch": "latest",
"pull-stream": "latest", "pull-stream": "latest",
"ssb-client": "latest", "ssb-client": "latest",
"ssb-friends": "latest", "ssb-friends": "latest",
"stream-to-pull-stream": "latest", "stream-to-pull-stream": "latest",
"http": "latest" "body-parser": "latest"
} }
} }

View file

@ -99,16 +99,16 @@ async function get_last_by_activity_id(id) {
if (err) reject(err); if (err) reject(err);
for (let i in array) { for (let i in array) {
if (array[i].value.content.type.length > 3 && if (array[i].value.content.type.length > 3 &&
array[i].value.content.type.substr(0,3) === 'ap-' && array[i].value.content.type.substr(0, 3) === 'ap-' &&
allowed_message_types.indexOf(array[i].value.content.type.substr(3)) >= 0) { allowed_message_types.indexOf(array[i].value.content.type.substr(3)) >= 0) {
if (array[i].value.content.id === id) { if (array[i].value.content.id === id) {
last = array[i]; last = array[i];
} }
} }
} }
if (last){ if (last) {
resolve(last); resolve(last);
}else { } else {
reject('no activity found'); reject('no activity found');
} }
@ -199,7 +199,7 @@ function add_ssb_message(type, id, actor, summary, object, origin = null, target
} }
async function get_json_from_blob(blob_id){ async function get_json_from_blob(blob_id) {
/* /*
* Gets the Object with the specified id from the * Gets the Object with the specified id from the
@ -225,7 +225,7 @@ async function get_json_from_blob(blob_id){
return await out; return await out;
} }
async function restore_ssb_message(id){ async function restore_ssb_message(id) {
/* /*
* Gets the Message with the specified id from the * Gets the Message with the specified id from the
@ -246,12 +246,12 @@ async function restore_ssb_message(id){
msg.type = msg.type.substr(3); msg.type = msg.type.substr(3);
delete msg.actor.otherData; delete msg.actor.otherData;
for (let key in actor_data){ for (let key in actor_data) {
msg.actor[key] = actor_data[key]; msg.actor[key] = actor_data[key];
} }
delete msg.object.otherData; delete msg.object.otherData;
for (let key in object_data){ for (let key in object_data) {
msg.object[key] = object_data[key]; msg.object[key] = object_data[key];
} }
@ -267,8 +267,8 @@ async function restore_ssb_message(id){
} }
module.exports = { module.exports = {
save : (message) => { save: (message) => {
if (message["@context"] === "https://www.w3.org/ns/activitystreams") { //todo: should be @context if (message["@context"] === "https://www.w3.org/ns/activitystreams") {
add_ssb_message( add_ssb_message(
message.type, message.type,

View file

@ -1,11 +1,29 @@
const config = require('./config'); const config = require('./config');
const ssbClient = require('ssb-client'); const ssbClient = require('ssb-client');
const pull = require('pull-stream'); const pull = require('pull-stream');
const ssb_bridge = require('./save_to_ssb');
DOMAIN = config.DOMAIN; DOMAIN = config.DOMAIN;
async function check_if_in_friends(name){ let chars_to_encode = "_!*'();:@&=+$,/?#[]"; // basically anything covered by %-encoding plus underscore
function encode_webfinger_name(name) {
for (let i in chars_to_encode) {
name = name.replace(chars_to_encode[i], "_" + chars_to_encode[i].charCodeAt(0).toString(16) + "_");
}
return name;
}
function decode_webfinger_name(name) {
for (let i in chars_to_encode) {
name = name.replace("_" + chars_to_encode[i].charCodeAt(0).toString(16) + "_", chars_to_encode[i]);
}
return name
}
async function check_if_in_friends(name) {
let result = false; let result = false;
name = decode_webfinger_name(name);
let out = new Promise((resolve, reject) => { let out = new Promise((resolve, reject) => {
ssbClient((err, sbot) => { ssbClient((err, sbot) => {
if (err) reject(err); if (err) reject(err);
@ -28,14 +46,31 @@ async function check_if_in_friends(name){
return await out; return await out;
} }
async function get_friends() {
let out = new Promise((resolve, reject) => {
ssbClient((err, sbot) => {
if (err) reject(err);
pull(
sbot.friends.createFriendStream(),
pull.collect((err, array) => {
sbot.close();
resolve(array);
})
);
});
});
return await out;
}
function get_webfinger(req, res) { function get_webfinger(req, res) {
let resource = req.query.resource; let resource = req.query.resource;
if (!resource || !resource.includes('acct:')) { 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.'); return res.status(400).send('Bad request. Please make sure "acct:USER@DOMAIN" is what you are sending as the "resource" query parameter.');
} } else {
else { let name = resource.replace('acct:', '');
let name = resource.replace('acct:',''); name = name.substr(0, name.indexOf('@'));
name = name.substr(0,name.indexOf('@')); let encoded_name = encodeURIComponent(name);
let p = check_if_in_friends(name + "=.ed25519"); let p = check_if_in_friends(name + "=.ed25519");
@ -43,18 +78,18 @@ function get_webfinger(req, res) {
if (result) { if (result) {
res.json( res.json(
{ {
'subject': `acct:${name}@${DOMAIN}`, 'subject': `acct:${encoded_name}@${DOMAIN}`,
links: [ links: [
{ {
rel: 'self', rel: 'self',
type: 'application/activity+json', type: 'application/activity+json',
href: `https://${DOMAIN}/u/${name}` href: `https://${DOMAIN}/u/${encoded_name}`
} }
], ],
} }
); );
} else { } else {
return res.status(404).send(`No record found for ${name}.`); return res.status(404).send(`No record found for ${encoded_name}.`);
} }
}).catch((err) => { }).catch((err) => {
return res.status(500).send(`An error occured: ${err}.`); return res.status(500).send(`An error occured: ${err}.`);
@ -62,12 +97,11 @@ function get_webfinger(req, res) {
} }
} }
function get_user(req, res){ function get_user(req, res) {
let name = req.params.name; let name = req.params.name;
if (!name) { if (!name) {
return res.status(400).send('Bad request.'); return res.status(400).send('Bad request.');
} } else {
else {
let p = check_if_in_friends(name + "=.ed25519"); let p = check_if_in_friends(name + "=.ed25519");
@ -83,8 +117,9 @@ function get_user(req, res){
id: `https://${DOMAIN}/u/${name}`, id: `https://${DOMAIN}/u/${name}`,
type: 'Person', type: 'Person',
preferredUsername: 'TESTPERSON PLS CHANGE', //todo: read from latest about message preferredUsername: 'TESTPERSON', //todo: read from latest about message
inbox: `https://${DOMAIN}/u/${name}/inbox`, // inbox: `https://${DOMAIN}/u/${name}/inbox`,
inbox: `https://${DOMAIN}/inbox`,
publicKey: { publicKey: {
id: `https://${DOMAIN}/u/${name}#main-key`, id: `https://${DOMAIN}/u/${name}#main-key`,
@ -101,7 +136,7 @@ function get_user(req, res){
} }
} }
); );
}else { } else {
return res.status(404).send(`No record found for ${name}.`); return res.status(404).send(`No record found for ${name}.`);
} }
}).catch((err) => { }).catch((err) => {
@ -110,7 +145,38 @@ function get_user(req, res){
} }
} }
function get_users(req, res) {
let p = get_friends();
p.then((result) => {
if (result) {
let out = {};
for (let i in result) {
out[i] = encode_webfinger_name(result[i].substr(1).replace("=.ed25519", ""));
}
res.json(out);
} else {
return res.status(404).send(`No record found for ${name}.`);
}
}).catch((err) => {
return res.status(500).send(`An error occured: ${err}.`);
})
}
function post_inbox(req, res) {
console.log("Saved activity to ssb log.");
try {
let in_activity = JSON.parse(req.body.toString());
ssb_bridge.save(in_activity);
} catch (e) {
}
return res.status(200).send('ayy\n');
}
module.exports = { module.exports = {
get_user, get_user,
get_webfinger get_webfinger,
get_users,
post_inbox,
}; };