From 1c5bf48fcc2dc944b629234f454b3844226d2b55 Mon Sep 17 00:00:00 2001 From: mei23 Date: Mon, 25 Dec 2023 02:25:53 +0900 Subject: [PATCH] cleanup url --- built/general.js | 11 ++++++----- built/utils/cleanup-url.d.ts | 7 +++++++ built/utils/cleanup-url.js | 26 ++++++++++++++++++++++++++ src/general.ts | 11 ++++++----- src/utils/cleanup-url.ts | 18 ++++++++++++++++++ 5 files changed, 63 insertions(+), 10 deletions(-) create mode 100644 built/utils/cleanup-url.d.ts create mode 100644 built/utils/cleanup-url.js create mode 100644 src/utils/cleanup-url.ts diff --git a/built/general.js b/built/general.js index 8d8d5d10..18c9c092 100644 --- a/built/general.js +++ b/built/general.js @@ -12,6 +12,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); const cleanup_title_1 = require("./utils/cleanup-title"); const decode_entities_1 = require("./utils/decode-entities"); const got_1 = require("./utils/got"); +const cleanup_url_1 = require("./utils/cleanup-url"); exports.default = (url, lang = null) => __awaiter(void 0, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6; if (lang && !lang.match(/^[\w-]+(\s*,\s*[\w-]+)*$/)) @@ -23,9 +24,9 @@ exports.default = (url, lang = null) => __awaiter(void 0, void 0, void 0, functi let title = (_e = (_d = (_c = (_b = $('meta[name="twitter:title"]').attr('content')) !== null && _b !== void 0 ? _b : $('meta[property="twitter:title"]').attr('content')) !== null && _c !== void 0 ? _c : $('meta[property="og:title"]').attr('content')) !== null && _d !== void 0 ? _d : $('title').text()) !== null && _e !== void 0 ? _e : null; title = (0, decode_entities_1.decodeEntities)(title, 300); let image = (_l = (_k = (_j = (_h = (_g = (_f = $('meta[name="twitter:image"]').attr('content')) !== null && _f !== void 0 ? _f : $('meta[property="twitter:image"]').attr('content')) !== null && _g !== void 0 ? _g : $('meta[property="og:image"]').attr('content')) !== null && _h !== void 0 ? _h : $('link[rel="image_src"]').attr('href')) !== null && _j !== void 0 ? _j : $('link[rel="apple-touch-icon"]').attr('href')) !== null && _k !== void 0 ? _k : $('link[rel="apple-touch-icon image_src"]').attr('href')) !== null && _l !== void 0 ? _l : null; - image = image ? new URL(image, landingUrl.href).href : null; - let playerUrl = (_r = (_q = (_p = (_o = (_m = (twitterCard !== 'summary_large_image' && $('meta[name="twitter:player"]').attr('content'))) !== null && _m !== void 0 ? _m : (twitterCard !== 'summary_large_image' && $('meta[property="twitter:player"]').attr('content'))) !== null && _o !== void 0 ? _o : $('meta[property="og:video"]').attr('content')) !== null && _p !== void 0 ? _p : $('meta[property="og:video:secure_url"]').attr('content')) !== null && _q !== void 0 ? _q : $('meta[property="og:video:url"]').attr('content')) !== null && _r !== void 0 ? _r : null; - playerUrl = playerUrl ? new URL(playerUrl, landingUrl.href).href : null; + image = (0, cleanup_url_1.cleanupUrl)(image, landingUrl.href); + let playerUrl = (_r = (_q = (_p = (_o = (_m = (twitterCard !== 'summary_large_image' ? $('meta[name="twitter:player"]').attr('content') : null)) !== null && _m !== void 0 ? _m : (twitterCard !== 'summary_large_image' ? $('meta[property="twitter:player"]').attr('content') : null)) !== null && _o !== void 0 ? _o : $('meta[property="og:video"]').attr('content')) !== null && _p !== void 0 ? _p : $('meta[property="og:video:secure_url"]').attr('content')) !== null && _q !== void 0 ? _q : $('meta[property="og:video:url"]').attr('content')) !== null && _r !== void 0 ? _r : null; + playerUrl = (0, cleanup_url_1.cleanupUrl)(playerUrl, landingUrl.href); const playerWidth = parseInt((_u = (_t = (_s = $('meta[name="twitter:player:width"]').attr('content')) !== null && _s !== void 0 ? _s : $('meta[property="twitter:player:width"]').attr('content')) !== null && _t !== void 0 ? _t : $('meta[property="og:video:width"]').attr('content')) !== null && _u !== void 0 ? _u : ''); const playerHeight = parseInt((_x = (_w = (_v = $('meta[name="twitter:player:height"]').attr('content')) !== null && _v !== void 0 ? _v : $('meta[property="twitter:player:height"]').attr('content')) !== null && _w !== void 0 ? _w : $('meta[property="og:video:height"]').attr('content')) !== null && _x !== void 0 ? _x : ''); let description = (_1 = (_0 = (_z = (_y = $('meta[name="twitter:description"]').attr('content')) !== null && _y !== void 0 ? _y : $('meta[property="twitter:description"]').attr('content')) !== null && _z !== void 0 ? _z : $('meta[property="og:description"]').attr('content')) !== null && _0 !== void 0 ? _0 : $('meta[name="description"]').attr('content')) !== null && _1 !== void 0 ? _1 : null; @@ -35,8 +36,8 @@ exports.default = (url, lang = null) => __awaiter(void 0, void 0, void 0, functi } let siteName = (_4 = (_3 = (_2 = $('meta[property="og:site_name"]').attr('content')) !== null && _2 !== void 0 ? _2 : $('meta[name="application-name"]').attr('content')) !== null && _3 !== void 0 ? _3 : landingUrl.hostname) !== null && _4 !== void 0 ? _4 : null; siteName = (0, decode_entities_1.decodeEntities)(siteName, 300); - const favicon = (_6 = (_5 = $('link[rel="shortcut icon"]').attr('href')) !== null && _5 !== void 0 ? _5 : $('link[rel="icon"]').attr('href')) !== null && _6 !== void 0 ? _6 : '/favicon.ico'; - const icon = favicon ? new URL(favicon, landingUrl.href).href : null; + const favicon = (_6 = (_5 = $('link[rel="shortcut icon"]').attr('href')) !== null && _5 !== void 0 ? _5 : $('link[rel="icon"]').attr('href')) !== null && _6 !== void 0 ? _6 : null; + const icon = (0, cleanup_url_1.cleanupUrl)(favicon, landingUrl.href); const sensitive = $('.tweet').attr('data-possibly-sensitive') === 'true'; // Clean up the title title = (0, cleanup_title_1.default)(title, siteName); diff --git a/built/utils/cleanup-url.d.ts b/built/utils/cleanup-url.d.ts new file mode 100644 index 00000000..c72f6fe3 --- /dev/null +++ b/built/utils/cleanup-url.d.ts @@ -0,0 +1,7 @@ +/** + * To absolute and sanitize URL + * @param url URL (absolute or relative) + * @param base Base URL + * @returns absolute URL + */ +export declare function cleanupUrl(url: string | null, base: string): string | null; diff --git a/built/utils/cleanup-url.js b/built/utils/cleanup-url.js new file mode 100644 index 00000000..db7faf6e --- /dev/null +++ b/built/utils/cleanup-url.js @@ -0,0 +1,26 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.cleanupUrl = void 0; +/** + * To absolute and sanitize URL + * @param url URL (absolute or relative) + * @param base Base URL + * @returns absolute URL + */ +function cleanupUrl(url, base) { + if (url == null) + return null; + try { + const u = new URL(url, base); + if (u.protocol === 'https:') + return u.href; + if (u.protocol === 'http:') + return u.href; + // dataはこないということに + } + catch (_a) { + return null; + } + return null; +} +exports.cleanupUrl = cleanupUrl; diff --git a/src/general.ts b/src/general.ts index 833ba465..c50bdcc1 100644 --- a/src/general.ts +++ b/src/general.ts @@ -2,6 +2,7 @@ import cleanupTitle from './utils/cleanup-title'; import { decodeEntities } from './utils/decode-entities'; import { SummalyEx } from './summaly'; import { scpaping } from './utils/got'; +import { cleanupUrl } from './utils/cleanup-url'; export default async (url: URL, lang: string | null = null): Promise => { if (lang && !lang.match(/^[\w-]+(\s*,\s*[\w-]+)*$/)) lang = null; @@ -31,17 +32,17 @@ export default async (url: URL, lang: string | null = null): Promise $('link[rel="apple-touch-icon image_src"]').attr('href') ?? null; - image = image ? new URL(image, landingUrl.href).href : null; + image = cleanupUrl(image, landingUrl.href); let playerUrl = - (twitterCard !== 'summary_large_image' && $('meta[name="twitter:player"]').attr('content')) ?? - (twitterCard !== 'summary_large_image' && $('meta[property="twitter:player"]').attr('content')) ?? + (twitterCard !== 'summary_large_image' ? $('meta[name="twitter:player"]').attr('content') : null) ?? + (twitterCard !== 'summary_large_image' ? $('meta[property="twitter:player"]').attr('content') : null) ?? $('meta[property="og:video"]').attr('content') ?? $('meta[property="og:video:secure_url"]').attr('content') ?? $('meta[property="og:video:url"]').attr('content') ?? null; - playerUrl = playerUrl ? new URL(playerUrl, landingUrl.href).href : null; + playerUrl = cleanupUrl(playerUrl, landingUrl.href); const playerWidth = parseInt( $('meta[name="twitter:player:width"]').attr('content') ?? @@ -81,7 +82,7 @@ export default async (url: URL, lang: string | null = null): Promise $('link[rel="icon"]').attr('href') ?? null; - const icon = favicon ? new URL(favicon, landingUrl.href).href : null; + const icon = cleanupUrl(favicon, landingUrl.href); const sensitive = $('.tweet').attr('data-possibly-sensitive') === 'true'; diff --git a/src/utils/cleanup-url.ts b/src/utils/cleanup-url.ts new file mode 100644 index 00000000..01a01560 --- /dev/null +++ b/src/utils/cleanup-url.ts @@ -0,0 +1,18 @@ +/** + * To absolute and sanitize URL + * @param url URL (absolute or relative) + * @param base Base URL + * @returns absolute URL + */ +export function cleanupUrl(url: string | null, base: string): string | null { + if (url == null) return null; + try { + const u = new URL(url, base); + if (u.protocol === 'https:') return u.href; + if (u.protocol === 'http:') return u.href; + // dataはこないということに + } catch { + return null; + } + return null; +}