49 lines
1.7 KiB
JavaScript
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);
|
|
});
|
|
}
|