social-butterfly
Version:
Incorporate federated social network protocols easily. Used with Hello, world federated blog.
232 lines (218 loc) • 6.16 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _url_factory = require("./util/url_factory");
var _react = require("react");
var _server = require("react-dom/server");
var _default = options => async (req, res) => {
const user = await options.getLocalUser(req.query.resource, req);
if (!user) {
return res.sendStatus(404);
}
if (req.query.format !== 'xml') {
return sendWebfingerAsJson(req, res, user);
}
res.type('application/xrd+xml');
res.send(`<?xml version='1.0' encoding='UTF-8'?>` + (0, _server.renderToString)( /*#__PURE__*/React.createElement(WebFinger, {
req: req,
user: user
})));
};
exports.default = _default;
function sendWebfingerAsJson(req, res, user) {
const accountInfo = getAccountInfo(req, user);
const logo = (0, _url_factory.buildUrl)({
req,
pathname: user.logo || user.favicon
});
const json = {
subject: accountInfo.account,
aliases: [user.url],
links: [{
rel: 'http://schemas.google.com/g/2010#updates-from',
type: 'application/atom+xml',
href: accountInfo.feedUrl
}, {
rel: 'http://webfinger.net/rel/profile-page',
type: 'text/html',
href: user.url
}, {
rel: 'http://webfinger.net/rel/avatar',
type: 'image/jpeg',
href: logo
}, {
rel: 'salmon',
href: accountInfo.salmonUrl
}, {
rel: 'http://salmon-protocol.org/ns/salmon-replies',
href: accountInfo.salmonUrl
}, {
rel: 'http://salmon-protocol.org/ns/salmon-mention',
href: accountInfo.salmonUrl
}, {
rel: 'http://ostatus.org/schema/1.0/subscribe',
href: accountInfo.followUrl
}, {
rel: 'webmention',
href: accountInfo.webmentionUrl
}, {
rel: 'magic-public-key',
href: `data:application/magic-public-key,${user.magic_key}`
}, {
rel: 'describedby',
type: 'application/rdf+xml',
href: accountInfo.foafUrl
}, {
rel: 'describedby',
type: 'application/json',
href: accountInfo.webfingerUrl
}, {
rel: 'http://microformats.org/profile/hcard',
type: 'text/html',
href: user.url
}, {
rel: 'self',
type: 'application/activity+json',
href: accountInfo.actorUrl
}]
};
return res.json(json);
}
function getAccountInfo(req, user) {
const {
username,
magic_key,
url
} = user;
const resource = url;
const account = `acct:${username}@${req.get('host')}`;
const actorUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/activitypub/actor',
searchParams: {
resource
}
});
const feedUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/feed',
searchParams: {
resource
}
});
const foafUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/foaf',
searchParams: {
resource
}
});
const followUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/follow',
searchParams: {
resource
}
});
const salmonUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/salmon',
searchParams: {
resource
}
});
const webfingerUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/webfinger',
searchParams: {
resource
}
});
const webmentionUrl = (0, _url_factory.buildUrl)({
req,
pathname: '/api/social/webmention',
searchParams: {
resource
}
});
return {
account,
actorUrl,
feedUrl,
foafUrl,
followUrl,
salmonUrl,
webfingerUrl,
webmentionUrl
};
}
function WebFinger({
req,
user
}) {
const accountInfo = getAccountInfo(req, user);
const logo = (0, _url_factory.buildUrl)({
req,
pathname: user.logo || user.favicon
});
return /*#__PURE__*/React.createElement(XML.XRD, {
xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"
}, /*#__PURE__*/React.createElement(XML.Subject, null, accountInfo.account), /*#__PURE__*/React.createElement(XML.Alias, null, user.url), /*#__PURE__*/React.createElement(XML.Link, {
rel: "describedby",
href: accountInfo.foafUrl,
type: "application/rdf+xml"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "describedby",
href: accountInfo.webfingerUrl,
type: "application/xrd+xml"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "salmon",
href: accountInfo.salmonUrl
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://salmon-protocol.org/ns/salmon-replies",
href: accountInfo.salmonUrl
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://salmon-protocol.org/ns/salmon-mention",
href: accountInfo.salmonUrl
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "magic-public-key",
href: `data:application/magic-public-key,${user.magic_key}`
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "webmention",
href: accountInfo.webmentionUrl
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://webfinger.net/rel/profile-page",
href: user.url,
type: "text/html"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://webfinger.net/rel/avatar",
href: logo,
type: "image/jpeg"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://schemas.google.com/g/2010#updates-from",
href: accountInfo.feedUrl,
type: "application/atom+xml"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://ostatus.org/schema/1.0/subscribe",
href: accountInfo.followUrl
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "http://microformats.org/profile/hcard",
href: user.url,
type: "text/html"
}), /*#__PURE__*/React.createElement(XML.Link, {
rel: "self",
href: accountInfo.actorUrl,
type: "application/activity+json"
}));
}
const createElementFactory = type => p => {
const {
children,
...props
} = p;
return /*#__PURE__*/(0, _react.createElement)(type, props, children);
};
const XML = {};
['XRD', 'Link', 'Subject', 'Alias'].forEach(type => XML[type] = createElementFactory(type));