diff --git a/package.json b/package.json index e1612a0126..a29b37f216 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "sharkey", - "version": "2025.2.2", + "version": "2025.2.3", "codename": "shonk", "repository": { "type": "git", diff --git a/packages/backend/package.json b/packages/backend/package.json index 277aed4f79..6ee762a8d4 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -80,7 +80,7 @@ "@fastify/static": "8.0.2", "@fastify/view": "10.0.1", "@misskey-dev/sharp-read-bmp": "1.2.0", - "@misskey-dev/summaly": "5.1.0", + "@transfem-org/summaly": "5.2.1", "@nestjs/common": "10.4.7", "@nestjs/core": "10.4.7", "@nestjs/testing": "10.4.7", diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts index cb9b74f6d7..44eb029a35 100644 --- a/packages/backend/src/core/activitypub/ApRendererService.ts +++ b/packages/backend/src/core/activitypub/ApRendererService.ts @@ -496,9 +496,7 @@ export class ApRendererService { const attachment = profile.fields.map(field => ({ type: 'PropertyValue', name: field.name, - value: (field.value.startsWith('http://') || field.value.startsWith('https://')) - ? `${new URL(field.value).href}` - : field.value, + value: this.mfmService.toHtml(mfm.parse(field.value)), })); const emojis = await this.getEmojis(user.emojis); diff --git a/packages/backend/src/server/web/UrlPreviewService.ts b/packages/backend/src/server/web/UrlPreviewService.ts index 19dac1dfb8..b8d7020598 100644 --- a/packages/backend/src/server/web/UrlPreviewService.ts +++ b/packages/backend/src/server/web/UrlPreviewService.ts @@ -4,8 +4,8 @@ */ import { Inject, Injectable } from '@nestjs/common'; -import { summaly } from '@misskey-dev/summaly'; -import { SummalyResult } from '@misskey-dev/summaly/built/summary.js'; +import { summaly } from '@transfem-org/summaly'; +import { SummalyResult } from '@transfem-org/summaly/built/summary.js'; import * as Redis from 'ioredis'; import { DI } from '@/di-symbols.js'; import type { Config } from '@/config.js'; @@ -52,12 +52,10 @@ export class UrlPreviewService { @bindThis private wrap(url?: string | null): string | null { return url != null - ? url.match(/^https?:\/\//) - ? `${this.config.mediaProxy}/preview.webp?${query({ - url, - preview: '1', - })}` - : url + ? `${this.config.mediaProxy}/preview.webp?${query({ + url, + preview: '1', + })}` : null; } diff --git a/packages/frontend-embed/package.json b/packages/frontend-embed/package.json index 163e6096f8..2ee60eaad8 100644 --- a/packages/frontend-embed/package.json +++ b/packages/frontend-embed/package.json @@ -38,7 +38,7 @@ "vue": "3.5.12" }, "devDependencies": { - "@misskey-dev/summaly": "5.1.0", + "@transfem-org/summaly": "5.2.1", "@testing-library/vue": "8.1.0", "@types/estree": "1.0.6", "@types/micromatch": "4.0.9", diff --git a/packages/frontend-shared/js/math.ts b/packages/frontend-shared/js/math.ts new file mode 100644 index 0000000000..528f3b08bf --- /dev/null +++ b/packages/frontend-shared/js/math.ts @@ -0,0 +1,10 @@ +/* + * SPDX-FileCopyrightText: dakkar and other Sharkey contributors + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export function clamp(value: number, min: number, max: number) { + if (value > max) return max; + if (value < min) return min; + return value; +} diff --git a/packages/frontend-shared/js/url.ts b/packages/frontend-shared/js/url.ts index eb830b1eea..ed36704d92 100644 --- a/packages/frontend-shared/js/url.ts +++ b/packages/frontend-shared/js/url.ts @@ -26,3 +26,20 @@ export function extractDomain(url: string) { const match = url.match(/^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?([^:\/\n]+)/im); return match ? match[1] : null; } + +export function maybeMakeRelative(urlStr: string, baseStr: string): string { + try { + const baseObj = new URL(baseStr); + const urlObj = new URL(urlStr); + /* in all places where maybeMakeRelative is used, baseStr is the + * instance's public URL, which can't have path components, so the + * relative URL will always have the whole path from the urlStr + */ + if (urlObj.origin === baseObj.origin) { + return urlObj.pathname + urlObj.search + urlObj.hash; + } + return urlStr; + } catch (error) { + return ''; + } +} diff --git a/packages/frontend/package.json b/packages/frontend/package.json index 528a1aef34..47819cef86 100644 --- a/packages/frontend/package.json +++ b/packages/frontend/package.json @@ -81,7 +81,7 @@ "cypress": "13.15.2" }, "devDependencies": { - "@misskey-dev/summaly": "5.1.0", + "@transfem-org/summaly": "5.2.1", "@storybook/addon-actions": "8.4.4", "@storybook/addon-essentials": "8.4.4", "@storybook/addon-interactions": "8.4.4", diff --git a/packages/frontend/src/components/MkLink.vue b/packages/frontend/src/components/MkLink.vue index 263cd95eb1..ad54e1b00e 100644 --- a/packages/frontend/src/components/MkLink.vue +++ b/packages/frontend/src/components/MkLink.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
- -
+ +
@@ -88,7 +88,7 @@ import { defineAsyncComponent, onDeactivated, onUnmounted, ref, watch } from 'vu import { url as local } from '@@/js/config.js'; import { versatileLang } from '@@/js/intl-const.js'; import * as Misskey from 'misskey-js'; -import type { summaly } from '@misskey-dev/summaly'; +import type { summaly } from '@transfem-org/summaly'; import type MkNoteSimple from '@/components/MkNoteSimple.vue'; import type SkNoteSimple from '@/components/SkNoteSimple.vue'; import { i18n } from '@/i18n.js'; @@ -98,6 +98,7 @@ import MkButton from '@/components/MkButton.vue'; import { transformPlayerUrl } from '@/scripts/player-url-transform.js'; import { defaultStore } from '@/store.js'; import { misskeyApi } from '@/scripts/misskey-api.js'; +import { maybeMakeRelative } from '@@/js/url.js'; const XNoteSimple = defineAsyncComponent(() => defaultStore.state.noteDesign === 'misskey' @@ -126,7 +127,8 @@ const MOBILE_THRESHOLD = 500; const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD); const hidePreview = ref(false); -const self = props.url.startsWith(local); +const maybeRelativeUrl = maybeMakeRelative(props.url, local); +const self = maybeRelativeUrl !== props.url; const attr = self ? 'to' : 'href'; const target = self ? null : '_blank'; const fetching = ref(true); diff --git a/packages/frontend/src/components/MkUserInfo.vue b/packages/frontend/src/components/MkUserInfo.vue index a6bbacacee..7e805dc904 100644 --- a/packages/frontend/src/components/MkUserInfo.vue +++ b/packages/frontend/src/components/MkUserInfo.vue @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only