webfinger.ts 2.0 KB

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