From 30172b92e62eba16e1d8a51babd83ad5b76a81ec Mon Sep 17 00:00:00 2001
From: syuilo <syuilotan@yahoo.co.jp>
Date: Wed, 10 Apr 2019 15:07:21 +0900
Subject: [PATCH] =?UTF-8?q?WebFinger=E3=83=AA=E3=82=AF=E3=82=A8=E3=82=B9?=
 =?UTF-8?q?=E3=83=88=E3=81=A7=20Proxy,=20Keep-Alive=20=E3=81=AA=E3=81=A9?=
 =?UTF-8?q?=E3=82=92=E3=82=B5=E3=83=9D=E3=83=BC=E3=83=88=20#4658?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Co-Authored-By: MeiMei <mei23@users.noreply.github.com>
---
 package.json                 |  1 -
 src/@types/webfinger.js.d.ts | 65 ------------------------------------
 src/remote/resolve-user.ts   |  4 +--
 src/remote/webfinger.ts      | 42 +++++++++++++++++------
 4 files changed, 34 insertions(+), 78 deletions(-)
 delete mode 100644 src/@types/webfinger.js.d.ts

diff --git a/package.json b/package.json
index 9e696d19d..acff5efaf 100644
--- a/package.json
+++ b/package.json
@@ -258,7 +258,6 @@
 		"vuex": "3.1.0",
 		"vuex-persistedstate": "2.5.4",
 		"web-push": "3.3.3",
-		"webfinger.js": "2.7.0",
 		"webpack": "4.28.4",
 		"webpack-cli": "3.2.3",
 		"websocket": "1.0.28",
diff --git a/src/@types/webfinger.js.d.ts b/src/@types/webfinger.js.d.ts
deleted file mode 100644
index 3556c4577..000000000
--- a/src/@types/webfinger.js.d.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-declare module 'webfinger.js' {
-	interface IWebFingerConstructorConfig {
-		tls_only?: boolean;
-		webfist_fallback?: boolean;
-		uri_fallback?: boolean;
-		request_timeout?: number;
-	}
-
-	type JRDProperties = { [type: string]: string };
-
-	interface IJRDLink {
-		rel: string;
-		type?: string;
-		href?: string;
-		template?: string;
-		titles?: { [lang: string]: string };
-		properties?: JRDProperties;
-	}
-
-	interface IJRD {
-		subject?: string;
-		expires?: Date;
-		aliases?: string[];
-		properties?: JRDProperties;
-		links?: IJRDLink[];
-	}
-
-	interface IIDXLinks {
-		'avatar': IJRDLink[];
-		'remotestorage': IJRDLink[];
-		'blog': IJRDLink[];
-		'vcard': IJRDLink[];
-		'updates': IJRDLink[];
-		'share': IJRDLink[];
-		'profile': IJRDLink[];
-		'webfist': IJRDLink[];
-		'camlistore': IJRDLink[];
-		[type: string]: IJRDLink[];
-	}
-
-	interface IIDXProperties {
-		'name': string;
-		[type: string]: string;
-	}
-
-	interface IIDX {
-		links: IIDXLinks;
-		properties: IIDXProperties;
-	}
-
-	interface ILookupCallbackResult {
-		object: IJRD;
-		json: string;
-		idx: IIDX;
-	}
-
-	type LookupCallback = (err: Error | string, result?: ILookupCallbackResult) => void;
-
-	export class WebFinger {
-		constructor(config?: IWebFingerConstructorConfig);
-
-		public lookup(address: string, cb: LookupCallback): NodeJS.Timeout;
-		public lookupLink(address: string, rel: string, cb: IJRDLink): void;
-	}
-}
diff --git a/src/remote/resolve-user.ts b/src/remote/resolve-user.ts
index e6a11bc0d..6a8ce45c9 100644
--- a/src/remote/resolve-user.ts
+++ b/src/remote/resolve-user.ts
@@ -73,8 +73,8 @@ export async function resolveUser(username: string, host: string, option?: any,
 async function resolveSelf(acctLower: string) {
 	logger.info(`WebFinger for ${chalk.yellow(acctLower)}`);
 	const finger = await webFinger(acctLower).catch(e => {
-		logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${e.message} (${e.status})`);
-		throw e;
+		logger.error(`Failed to WebFinger for ${chalk.yellow(acctLower)}: ${ e.statusCode || e.message }`);
+		throw new Error(`Failed to WebFinger for ${acctLower}: ${ e.statusCode || e.message }`);
 	});
 	const self = finger.links.find(link => link.rel && link.rel.toLowerCase() === 'self');
 	if (!self) {
diff --git a/src/remote/webfinger.ts b/src/remote/webfinger.ts
index 1229dbaf9..67535e37d 100644
--- a/src/remote/webfinger.ts
+++ b/src/remote/webfinger.ts
@@ -1,6 +1,7 @@
-import { WebFinger } from 'webfinger.js';
-
-const webFinger = new WebFinger({ });
+import config from '../config';
+import * as request from 'request-promise-native';
+import { URL } from 'url';
+import { query as urlQuery } from '../prelude/url';
 
 type ILink = {
 	href: string;
@@ -12,12 +13,33 @@ type IWebFinger = {
 	subject: string;
 };
 
-export default async function resolve(query: any): Promise<IWebFinger> {
-	return await new Promise((res, rej) => webFinger.lookup(query, (error: Error | string, result: any) => {
-		if (error) {
-			return rej(error);
-		}
+export default async function(query: string): Promise<IWebFinger> {
+	const url = genUrl(query);
 
-		res(result.object);
-	})) as IWebFinger;
+	return await request({
+		url,
+		proxy: config.proxy,
+		timeout: 10 * 1000,
+		forever: true,
+		headers: {
+			'User-Agent': config.userAgent,
+			Accept: 'application/jrd+json, application/json'
+		},
+		json: true
+	});
+}
+
+function genUrl(query: string) {
+	if (query.match(/^https?:\/\//)) {
+		const u = new URL(query);
+		return `${u.protocol}//${u.hostname}/.well-known/webfinger?` + urlQuery({ resource: query });
+	}
+
+	const m = query.match(/^([^@]+)@(.*)/);
+	if (m) {
+		const hostname = m[2];
+		return `https://${hostname}/.well-known/webfinger?` + urlQuery({ resource: `acct:${query}` });
+	}
+
+	throw new Error(`Invalied query (${query})`);
 }