]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/blobdiff - server/helpers/webfinger.ts
Instance homepage support (#4007)
[github/Chocobozzz/PeerTube.git] / server / helpers / webfinger.ts
index 9586fa5624b568c1eb2052ef8eec54028bf3f978..33367f651793fd3b053390e929d5f5f411162c9a 100644 (file)
@@ -1,9 +1,10 @@
 import * as WebFinger from 'webfinger.js'
-
-import { isTestInstance } from './core-utils'
-import { isActivityPubUrlValid } from './custom-validators'
 import { WebFingerData } from '../../shared'
-import { fetchRemoteAccountAndCreatePod } from './activitypub'
+import { WEBSERVER } from '../initializers/constants'
+import { ActorModel } from '../models/actor/actor'
+import { MActorFull } from '../types/models'
+import { isTestInstance } from './core-utils'
+import { isActivityPubUrlValid } from './custom-validators/activitypub/misc'
 
 const webfinger = new WebFinger({
   webfist_fallback: false,
@@ -12,33 +13,55 @@ const webfinger = new WebFinger({
   request_timeout: 3000
 })
 
-async function getAccountFromWebfinger (url: string) {
-  const webfingerData: WebFingerData = await webfingerLookup(url)
+async function loadActorUrlOrGetFromWebfinger (uriArg: string) {
+  // Handle strings like @toto@example.com
+  const uri = uriArg.startsWith('@') ? uriArg.slice(1) : uriArg
 
-  if (Array.isArray(webfingerData.links) === false) return undefined
+  const [ name, host ] = uri.split('@')
+  let actor: MActorFull
 
-  const selfLink = webfingerData.links.find(l => l.rel === 'self')
-  if (selfLink === undefined || isActivityPubUrlValid(selfLink.href) === false) return undefined
+  if (!host || host === WEBSERVER.HOST) {
+    actor = await ActorModel.loadLocalByName(name)
+  } else {
+    actor = await ActorModel.loadByNameAndHost(name, host)
+  }
+
+  if (actor) return actor.url
 
-  const { account } = await fetchRemoteAccountAndCreatePod(selfLink.href)
+  return getUrlFromWebfinger(uri)
+}
 
-  return account
+async function getUrlFromWebfinger (uri: string) {
+  const webfingerData: WebFingerData = await webfingerLookup(uri)
+  return getLinkOrThrow(webfingerData)
 }
 
 // ---------------------------------------------------------------------------
 
 export {
-  getAccountFromWebfinger
+  getUrlFromWebfinger,
+  loadActorUrlOrGetFromWebfinger
 }
 
 // ---------------------------------------------------------------------------
 
-function webfingerLookup (url: string) {
+function getLinkOrThrow (webfingerData: WebFingerData) {
+  if (Array.isArray(webfingerData.links) === false) throw new Error('WebFinger links is not an array.')
+
+  const selfLink = webfingerData.links.find(l => l.rel === 'self')
+  if (selfLink === undefined || isActivityPubUrlValid(selfLink.href) === false) {
+    throw new Error('Cannot find self link or href is not a valid URL.')
+  }
+
+  return selfLink.href
+}
+
+function webfingerLookup (nameWithHost: string) {
   return new Promise<WebFingerData>((res, rej) => {
-    webfinger.lookup('nick@silverbucket.net', (err, p) => {
+    webfinger.lookup(nameWithHost, (err, p) => {
       if (err) return rej(err)
 
-      return p
+      return res(p.object)
     })
   })
 }