enigma-bbs/core/webfinger.js

49 lines
1.7 KiB
JavaScript

const { Errors } = require('./enig_error');
const { getAddressedToInfo } = require('./mail_util');
const Message = require('./message');
const { getJson } = require('./http_util');
// deps
exports.queryWebFinger = queryWebFinger;
function queryWebFinger(account, cb) {
// ex: @NuSkooler@toot.community -> https://toot.community/.well-known/webfinger with acct:NuSkooler resource
const addrInfo = getAddressedToInfo(account);
if (
addrInfo.flavor !== Message.AddressFlavor.ActivityPub &&
addrInfo.flavor !== Message.AddressFlavor.Email
) {
return cb(Errors.Invalid(`Cannot WebFinger "${account.remote}"; Missing domain`));
}
const domain = addrInfo.remote.slice(addrInfo.remote.lastIndexOf('@') + 1);
if (!domain) {
return cb(Errors.Invalid(`Cannot WebFinger "${account.remote}"; Missing domain`));
}
const resource = encodeURIComponent(`acct:${account.slice(1)}`); // we need drop the initial '@' prefix
const webFingerUrl = `https://${domain}/.well-known/webfinger?resource=${resource}`;
getJson(webFingerUrl, {}, (err, json, res) => {
if (err) {
return cb(err);
}
if (res.statusCode !== 200) {
// only accept 200
return cb(Errors.DoesNotExist(`Failed to WebFinger URL ${webFingerUrl}`));
}
const contentType = res.headers['content-type'] || '';
if (!contentType.startsWith('application/jrd+json')) {
return cb(
Errors.Invalid(
`Invalid Content-Type for WebFinger URL ${webFingerUrl}: ${contentType}`
)
);
}
return cb(null, json);
});
}