Skip to content

Commit a3b41c1

Browse files
authored
Merge pull request #982 from cherry-pick
cherry picked from upstream
2 parents 969c5e3 + fe90cc7 commit a3b41c1

File tree

12 files changed

+66
-28
lines changed

12 files changed

+66
-28
lines changed

packages/backend/src/server/web/UrlPreviewService.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ export class UrlPreviewService {
3737
@bindThis
3838
private wrap(url?: string | null): string | null {
3939
if (!url) return null;
40-
if (!RegExp(/^https?:\/\//).exec(url)) return url;
4140

4241
return appendQuery(
4342
`${this.config.mediaProxy}/preview/${encodeURIComponent(omitHttps(url))}`,

packages/frontend/src/components/MkLink.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
99
ref="el"
1010
style="word-break: break-all;"
1111
class="_link"
12-
:[attr]="self ? url.substring(local.length) : url"
12+
:[attr]="maybeRelativeUrl"
1313
:rel="rel ?? 'nofollow noopener'"
1414
:target="target"
1515
:behavior="props.navigationBehavior"
@@ -28,7 +28,8 @@ import { useTooltip } from '@/scripts/use-tooltip.js';
2828
import { warningExternalWebsite } from '@/scripts/warning-external-website.js';
2929
import * as os from '@/os.js';
3030
import { isEnabledUrlPreview } from '@/instance.js';
31-
import { MkABehavior } from '@/components/global/MkA.vue';
31+
import type { MkABehavior } from '@/components/global/MkA.vue';
32+
import { maybeMakeRelative } from '@/scripts/url.js';
3233
3334
const props = withDefaults(defineProps<{
3435
url: string;
@@ -39,7 +40,8 @@ const props = withDefaults(defineProps<{
3940
hideIcon: false,
4041
});
4142
42-
const self = props.url.startsWith(local);
43+
const maybeRelativeUrl = maybeMakeRelative(props.url, local);
44+
const self = maybeRelativeUrl !== props.url;
4345
const attr = self ? 'to' : 'href';
4446
const target = self ? null : '_blank';
4547

packages/frontend/src/components/MkUrlPreview.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ SPDX-License-Identifier: AGPL-3.0-only
4747
<component
4848
:is="self ? 'MkA' : 'a'"
4949
:class="[$style.link, { [$style.compact]: compact }]"
50-
:[attr]="self ? url.substring(local.length) : url"
50+
:[attr]="maybeRelativeUrl"
5151
rel="nofollow noopener"
5252
:target="target"
5353
:title="url"
5454
@click="(ev: MouseEvent) => warningExternalWebsite(ev, url)"
5555
>
56-
<div v-if="thumbnail" :class="[$style.thumbnail, { [$style.thumbnailBlur]: sensitive }]" :style="defaultStore.state.dataSaver.urlPreview ? '' : `background-image: url('${thumbnail}')`">
56+
<div v-if="thumbnail" :class="[$style.thumbnail, { [$style.thumbnailBlur]: sensitive }]" :style="defaultStore.state.dataSaver.urlPreview ? '' : { backgroundImage: `url('${thumbnail}')` }">
5757
</div>
5858
<article :class="$style.body">
5959
<header :class="$style.header">
@@ -101,6 +101,7 @@ import MkButton from '@/components/MkButton.vue';
101101
import { versatileLang } from '@/scripts/intl-const.js';
102102
import { defaultStore } from '@/store.js';
103103
import { warningExternalWebsite } from '@/scripts/warning-external-website.js';
104+
import { maybeMakeRelative } from '@/scripts/url.js';
104105
105106
type SummalyResult = Awaited<ReturnType<typeof summaly>>;
106107
@@ -118,7 +119,8 @@ const props = withDefaults(defineProps<{
118119
const MOBILE_THRESHOLD = 500;
119120
const isMobile = ref(deviceKind === 'smartphone' || window.innerWidth <= MOBILE_THRESHOLD);
120121
121-
const self = props.url.startsWith(local);
122+
const maybeRelativeUrl = maybeMakeRelative(props.url, local);
123+
const self = maybeRelativeUrl !== props.url;
122124
const attr = self ? 'to' : 'href';
123125
const target = self ? null : '_blank';
124126
const fetching = ref(true);

packages/frontend/src/components/MkUserInfo.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
55

66
<template>
77
<div class="_panel" :class="$style.root">
8-
<div :class="$style.banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''"></div>
8+
<div :class="$style.banner" :style="user.bannerUrl ? { backgroundImage: `url(${user.bannerUrl})` } : ''"></div>
99
<MkAvatar :class="$style.avatar" :user="user" indicator/>
1010
<div :class="$style.title">
1111
<MkA :class="$style.name" :to="userPage(user)"><MkUserName :user="user" :nowrap="false"/></MkA>

packages/frontend/src/components/MkUserPopup.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ SPDX-License-Identifier: AGPL-3.0-only
1313
>
1414
<div v-if="showing" :class="$style.root" class="_popup _shadow" :style="{ zIndex, top: top + 'px', left: left + 'px' }" @mouseover="() => { emit('mouseover'); }" @mouseleave="() => { emit('mouseleave'); }">
1515
<div v-if="user != null">
16-
<div :class="$style.banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''">
16+
<div :class="$style.banner" :style="user.bannerUrl ? { backgroundImage: `url(${user.bannerUrl})` } : ''">
1717
<span v-if="$i && $i.id != user.id && user.isFollowed" :class="$style.followed">{{ i18n.ts.followsYou }}</span>
1818
</div>
1919
<svg viewBox="0 0 128 128" :class="$style.avatarBack">

packages/frontend/src/components/MkUserSetupDialog.User.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only
55

66
<template>
77
<div v-adaptive-bg class="_panel" style="position: relative;">
8-
<div :class="$style.banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''"></div>
8+
<div :class="$style.banner" :style="user.bannerUrl ? { backgroundImage: `url(${user.bannerUrl})` } : ''"></div>
99
<MkAvatar :class="$style.avatar" :user="user" indicator/>
1010
<div :class="$style.title">
1111
<div :class="$style.name"><MkUserName :user="user" :nowrap="false"/></div>

packages/frontend/src/components/global/MkUrl.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ SPDX-License-Identifier: AGPL-3.0-only
99
ref="el"
1010
:class="$style.root"
1111
class="_link"
12-
:[attr]="self ? props.url.substring(local.length) : props.url"
12+
:[attr]="maybeRelativeUrl"
1313
:rel="rel ?? 'nofollow noopener'"
1414
:target="target"
1515
:behavior="props.navigationBehavior"
@@ -40,7 +40,8 @@ import { useTooltip } from '@/scripts/use-tooltip.js';
4040
import { safeURIDecode } from '@/scripts/safe-uri-decode.js';
4141
import { warningExternalWebsite } from '@/scripts/warning-external-website.js';
4242
import { isEnabledUrlPreview } from '@/instance.js';
43-
import { MkABehavior } from '@/components/global/MkA.vue';
43+
import type { MkABehavior } from '@/components/global/MkA.vue';
44+
import { maybeMakeRelative } from '@/scripts/url.js';
4445
4546
const props = withDefaults(defineProps<{
4647
url: string;
@@ -51,7 +52,8 @@ const props = withDefaults(defineProps<{
5152
showUrlPreview: true,
5253
});
5354
54-
const self = props.url.startsWith(local);
55+
const maybeRelativeUrl = maybeMakeRelative(props.url, local);
56+
const self = maybeRelativeUrl !== props.url;
5557
const url = new URL(props.url);
5658
if (!['http:', 'https:'].includes(url.protocol)) throw new Error('invalid url');
5759
const el = ref();

packages/frontend/src/scripts/aiscript/api.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,9 @@ export function createAiScriptEnv(opts) {
5151
}),
5252
'Mk:api': values.FN_NATIVE(async ([ep, param, token]) => {
5353
utils.assertString(ep);
54-
if (ep.value.includes('://')) throw new Error('invalid endpoint');
54+
if (ep.value.includes('://') || ep.value.includes('..')) {
55+
throw new Error('invalid endpoint');
56+
}
5557
if (token) {
5658
utils.assertString(token);
5759
// バグがあればundefinedもあり得るため念のため

packages/frontend/src/scripts/collapsed.ts

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,30 @@
66
import * as Misskey from 'misskey-js';
77

88
export function shouldCollapsed(note: Misskey.entities.Note, urls: string[]): boolean {
9-
const collapsed = note.cw == null && note.text != null && (
10-
(note.text.includes('$[x2')) ||
11-
(note.text.includes('$[x3')) ||
12-
(note.text.includes('$[x4')) ||
13-
(note.text.includes('$[scale')) ||
14-
(note.text.split('\n').length > 9) ||
15-
(note.text.length > 500) ||
16-
(note.files.length >= 5) ||
17-
(urls.length >= 4)
18-
);
9+
if (note.cw != null) {
10+
return false;
11+
}
1912

20-
return collapsed;
13+
if (note.text != null) {
14+
if (
15+
note.text.includes('$[x2') ||
16+
note.text.includes('$[x3') ||
17+
note.text.includes('$[x4') ||
18+
note.text.includes('$[scale') ||
19+
note.text.split('\n').length > 9 ||
20+
note.text.length > 500
21+
) {
22+
return true;
23+
}
24+
}
25+
26+
if (urls.length >= 4) {
27+
return true;
28+
}
29+
30+
if (note.files != null && note.files.length >= 5) {
31+
return true;
32+
}
33+
34+
return false;
2135
}

packages/frontend/src/scripts/url.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,20 @@ export function omitHttps(url: string): string {
2727
if (url.startsWith('https%3A%2F%2F')) return url.slice(14);
2828
return url;
2929
}
30+
31+
export function maybeMakeRelative(urlStr: string, baseStr: string): string {
32+
try {
33+
const baseObj = new URL(baseStr);
34+
const urlObj = new URL(urlStr);
35+
/* in all places where maybeMakeRelative is used, baseStr is the
36+
* instance's public URL, which can't have path components, so the
37+
* relative URL will always have the whole path from the urlStr
38+
*/
39+
if (urlObj.origin === baseObj.origin) {
40+
return urlObj.pathname + urlObj.search + urlObj.hash;
41+
}
42+
return urlStr;
43+
} catch {
44+
return '';
45+
}
46+
}

packages/frontend/src/widgets/WidgetPhotos.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ SPDX-License-Identifier: AGPL-3.0-only
1414
<div
1515
v-for="(image, i) in images" :key="i"
1616
:class="$style.img"
17-
:style="`background-image: url(${thumbnail(image)})`"
17+
:style="{ backgroundImage: `url(${thumbnail(image)})` }"
1818
></div>
1919
</div>
2020
</div>

packages/frontend/src/widgets/server-metric/cpu-mem.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ SPDX-License-Identifier: AGPL-3.0-only
3434
<rect
3535
x="-2" y="-2"
3636
:width="viewBoxX + 4" :height="viewBoxY + 4"
37-
:style="`stroke: none; fill: url(#${ cpuGradientId }); mask: url(#${ cpuMaskId })`"
37+
:style="{ stroke: 'none', fill: `url(#${ cpuGradientId })`, mask: `url(#${ cpuMaskId })` }"
3838
/>
3939
<text x="1" y="5">CPU <tspan>{{ cpuP }}%</tspan></text>
4040
</svg>
@@ -67,7 +67,7 @@ SPDX-License-Identifier: AGPL-3.0-only
6767
<rect
6868
x="-2" y="-2"
6969
:width="viewBoxX + 4" :height="viewBoxY + 4"
70-
:style="`stroke: none; fill: url(#${ memGradientId }); mask: url(#${ memMaskId })`"
70+
:style="{ stroke: 'none', fill: `url(#${ memGradientId })`, mask: `url(#${ memMaskId })` }"
7171
/>
7272
<text x="1" y="5">MEM <tspan>{{ memP }}%</tspan></text>
7373
</svg>

0 commit comments

Comments
 (0)