webfinger.ts 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import * as WebFinger from 'webfinger.js'
  2. import { WebFingerData } from '../../shared'
  3. import { ActorModel } from '../models/activitypub/actor'
  4. import { isTestInstance } from './core-utils'
  5. import { isActivityPubUrlValid } from './custom-validators/activitypub/misc'
  6. import { WEBSERVER } from '../initializers/constants'
  7. const webfinger = new WebFinger({
  8. webfist_fallback: false,
  9. tls_only: isTestInstance(),
  10. uri_fallback: false,
  11. request_timeout: 3000
  12. })
  13. async function loadActorUrlOrGetFromWebfinger (uriArg: string) {
  14. // Handle strings like @toto@example.com
  15. const uri = uriArg.startsWith('@') ? uriArg.slice(1) : uriArg
  16. const [ name, host ] = uri.split('@')
  17. let actor: ActorModel
  18. if (!host || host === WEBSERVER.HOST) {
  19. actor = await ActorModel.loadLocalByName(name)
  20. } else {
  21. actor = await ActorModel.loadByNameAndHost(name, host)
  22. }
  23. if (actor) return actor.url
  24. return getUrlFromWebfinger(uri)
  25. }
  26. async function getUrlFromWebfinger (uri: string) {
  27. const webfingerData: WebFingerData = await webfingerLookup(uri)
  28. return getLinkOrThrow(webfingerData)
  29. }
  30. // ---------------------------------------------------------------------------
  31. export {
  32. getUrlFromWebfinger,
  33. loadActorUrlOrGetFromWebfinger
  34. }
  35. // ---------------------------------------------------------------------------
  36. function getLinkOrThrow (webfingerData: WebFingerData) {
  37. if (Array.isArray(webfingerData.links) === false) throw new Error('WebFinger links is not an array.')
  38. const selfLink = webfingerData.links.find(l => l.rel === 'self')
  39. if (selfLink === undefined || isActivityPubUrlValid(selfLink.href) === false) {
  40. throw new Error('Cannot find self link or href is not a valid URL.')
  41. }
  42. return selfLink.href
  43. }
  44. function webfingerLookup (nameWithHost: string) {
  45. return new Promise<WebFingerData>((res, rej) => {
  46. webfinger.lookup(nameWithHost, (err, p) => {
  47. if (err) return rej(err)
  48. return res(p.object)
  49. })
  50. })
  51. }