Webfinger detection now works and incoming Activities are saved to the ssb log.
This commit is contained in:
parent
939d242996
commit
ea8cbb43c3
5 changed files with 117 additions and 39 deletions
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"DOMAIN" : "",
|
"DOMAIN": "",
|
||||||
"PORT" : 3000
|
"PORT": 3000
|
||||||
}
|
}
|
13
index.js
13
index.js
|
@ -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'));
|
||||||
});
|
});
|
||||||
|
|
|
@ -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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,16 @@ const pull = require('pull-stream');
|
||||||
|
|
||||||
const allowed_message_types = [ //valid activitypub message types
|
const allowed_message_types = [ //valid activitypub message types
|
||||||
'create',
|
'create',
|
||||||
'update',
|
'update',
|
||||||
'delete',
|
'delete',
|
||||||
'follow',
|
'follow',
|
||||||
'update',
|
'update',
|
||||||
'reject',
|
'reject',
|
||||||
'add',
|
'add',
|
||||||
'remove',
|
'remove',
|
||||||
'like',
|
'like',
|
||||||
'announce',
|
'announce',
|
||||||
'undo'
|
'undo'
|
||||||
];
|
];
|
||||||
|
|
||||||
async function createBlobObject(type, objectId, otherData) {
|
async function createBlobObject(type, objectId, otherData) {
|
||||||
|
@ -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,
|
||||||
|
|
96
server.js
96
server.js
|
@ -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,
|
||||||
};
|
};
|
Loading…
Reference in a new issue