diff options
Diffstat (limited to 'src/services/fetch-nodeinfo.ts')
| -rw-r--r-- | src/services/fetch-nodeinfo.ts | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/services/fetch-nodeinfo.ts b/src/services/fetch-nodeinfo.ts new file mode 100644 index 0000000000..e5d652a6b3 --- /dev/null +++ b/src/services/fetch-nodeinfo.ts @@ -0,0 +1,91 @@ +import * as request from 'request-promise-native'; +import { Instance } from '../models/entities/instance'; +import { Instances } from '../models'; +import config from '../config'; +import { getNodeinfoLock } from '../misc/app-lock'; +import Logger from '../services/logger'; + +export const logger = new Logger('nodeinfo', 'cyan'); + +export async function fetchNodeinfo(instance: Instance) { + const unlock = await getNodeinfoLock(instance.host); + + const _instance = await Instances.findOne({ host: instance.host }); + const now = Date.now(); + if (_instance && _instance.infoUpdatedAt && (now - _instance.infoUpdatedAt.getTime() < 1000 * 60 * 60 * 24)) { + unlock(); + return; + } + + logger.info(`Fetching nodeinfo of ${instance.host} ...`); + + try { + const wellknown = await request({ + url: 'https://' + instance.host + '/.well-known/nodeinfo', + proxy: config.proxy, + timeout: 1000 * 10, + forever: true, + headers: { + 'User-Agent': config.userAgent, + Accept: 'application/json, */*' + }, + json: true + }).catch(e => { + if (e.statusCode === 404) { + throw 'No nodeinfo provided'; + } else { + throw e.statusCode || e.message; + } + }); + + if (wellknown.links == null || !Array.isArray(wellknown.links)) { + throw 'No wellknown links'; + } + + const links = wellknown.links as any[]; + + const lnik1_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0'); + const lnik2_0 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0'); + const lnik2_1 = links.find(link => link.rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1'); + const link = lnik2_1 || lnik2_0 || lnik1_0; + + if (link == null) { + throw 'No nodeinfo link provided'; + } + + const info = await request({ + url: link.href, + proxy: config.proxy, + timeout: 1000 * 10, + forever: true, + headers: { + 'User-Agent': config.userAgent, + Accept: 'application/json, */*' + }, + json: true + }).catch(e => { + throw e.statusCode || e.message; + }); + + await Instances.update(instance.id, { + infoUpdatedAt: new Date(), + softwareName: info.software.name.toLowerCase(), + softwareVersion: info.software.version, + openRegistrations: info.openRegistrations, + name: info.metadata ? (info.metadata.nodeName || info.metadata.name || null) : null, + description: info.metadata ? (info.metadata.nodeDescription || info.metadata.description || null) : null, + maintainerName: info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.name || null) : null : null, + maintainerEmail: info.metadata ? info.metadata.maintainer ? (info.metadata.maintainer.email || null) : null : null, + }); + + logger.succ(`Successfuly fetched nodeinfo of ${instance.host}`); + } catch (e) { + logger.error(`Failed to fetch nodeinfo of ${instance.host}: ${e}`); + + await Instances.update(instance.id, { + infoUpdatedAt: new Date(), + }); + } finally { + unlock(); + } +} |