From 139a273e6e722073aded9ffcb3a58bc8c7ca5d55 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator <kainoa@t1c.dev> Date: Sun, 16 Jul 2023 21:03:38 -0700 Subject: [PATCH] refactor: :recycle: export verifyLink, use ReGeX to validate --- .../queue/processors/system/verify-links.ts | 36 ++++++------------- .../src/server/api/endpoints/i/update.ts | 14 +------- packages/backend/src/services/fetch-rel-me.ts | 19 +++++++++- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/packages/backend/src/queue/processors/system/verify-links.ts b/packages/backend/src/queue/processors/system/verify-links.ts index 71362b1f63..3ddda9baf4 100644 --- a/packages/backend/src/queue/processors/system/verify-links.ts +++ b/packages/backend/src/queue/processors/system/verify-links.ts @@ -3,7 +3,7 @@ import type Bull from "bull"; import { UserProfiles } from "@/models/index.js"; import { Not } from "typeorm"; import { queueLogger } from "../../logger.js"; -import { getRelMeLinks } from "@/services/fetch-rel-me.js"; +import { verifyLink } from "@/services/fetch-rel-me.js"; import config from "@/config/index.js"; const logger = queueLogger.createSubLogger("verify-links"); @@ -19,36 +19,22 @@ export async function verifyLinks( userHost: "", }); for (const user of usersToVerify) { - const fields = user.fields - .filter( - (x) => - typeof x.name === "string" && - x.name !== "" && - typeof x.value === "string" && - x.value !== "" && - x.value.startsWith("http") - ) - .map(async (x) => { - const relMeLinks = await getRelMeLinks(x.value); - const verified = relMeLinks.some((link) => - link.includes(`${config.host}/@${user.user?.host}`), - ); - return { - name: x.name, - value: x.value, - verified: verified, - }; - }); - if (fields.length > 0) { - const fieldsFinal = await Promise.all(fields); + for (const field of user.fields) { + if (!field || field.name === "" || field.value === "") { + continue; + } + if (field.value.startsWith("http") && user.user?.username) { + field.verified = await verifyLink(field.value, user.user.username); + } + } + if (user.fields.length > 0) { try { await UserProfiles.update(user.userId, { - fields: fieldsFinal, + fields: user.fields, }); } catch (e) { logger.error(`Failed to update user ${user.userId} ${e}`); done(e); - break; } } } diff --git a/packages/backend/src/server/api/endpoints/i/update.ts b/packages/backend/src/server/api/endpoints/i/update.ts index d1d2f672df..6d3bde2b8d 100644 --- a/packages/backend/src/server/api/endpoints/i/update.ts +++ b/packages/backend/src/server/api/endpoints/i/update.ts @@ -12,7 +12,7 @@ import type { UserProfile } from "@/models/entities/user-profile.js"; import { notificationTypes } from "@/types.js"; import { normalizeForSearch } from "@/misc/normalize-for-search.js"; import { langmap } from "@/misc/langmap.js"; -import { getRelMeLinks } from "@/services/fetch-rel-me.js"; +import { verifyLink } from "@/services/fetch-rel-me.js"; import { ApiError } from "../../error.js"; import config from "@/config/index.js"; import define from "../../define.js"; @@ -149,17 +149,6 @@ export const paramDef = { }, } as const; -async function verifyLink(link: string, username: string): Promise<boolean> { - let verified = false; - if (link.startsWith("http")) { - const relMeLinks = await getRelMeLinks(link); - verified = relMeLinks.some((href) => - href.includes(`${config.host}/@${username}`), - ); - } - return verified; -} - export default define(meta, paramDef, async (ps, _user, token) => { const user = await Users.findOneByOrFail({ id: _user.id }); const isSecure = token == null; @@ -261,7 +250,6 @@ export default define(meta, paramDef, async (ps, _user, token) => { if (ps.fields) { for (const field of ps.fields) { if (!field || field.name === "" || field.value === "") { - ps.fields.remove(field); continue; } if (typeof field.name !== "string" || field.name === "") { diff --git a/packages/backend/src/services/fetch-rel-me.ts b/packages/backend/src/services/fetch-rel-me.ts index f6422c22ac..9e1d8f9b6f 100644 --- a/packages/backend/src/services/fetch-rel-me.ts +++ b/packages/backend/src/services/fetch-rel-me.ts @@ -1,7 +1,8 @@ import { getHtml } from "@/misc/fetch.js"; import { JSDOM } from "jsdom"; +import config from "@/config"; -export async function getRelMeLinks(url: string): Promise<string[]> { +async function getRelMeLinks(url: string): Promise<string[]> { try { const html = await getHtml(url); const dom = new JSDOM(html); @@ -14,3 +15,19 @@ export async function getRelMeLinks(url: string): Promise<string[]> { return []; } } + +export async function verifyLink(link: string, username: string): Promise<boolean> { + let verified = false; + if (link.startsWith("http")) { + const relMeLinks = await getRelMeLinks(link); + verified = relMeLinks.some((href) => + new RegExp( + `^https?:\/\/${config.host.replace( + /[.*+\-?^${}()|[\]\\]/g, + "\\$&", + )}\/@${username.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&")}$`, + ).test(href), + ); + } + return verified; +}