Skip to content

Commit

Permalink
enhance(frontend): 외부 사이트로 이동할 때 경고 표시 (MisskeyIO/misskey#558)
Browse files Browse the repository at this point in the history
  • Loading branch information
noridev committed Oct 2, 2024
2 parents a4fa297 + c2fae88 commit a44d9fc
Show file tree
Hide file tree
Showing 19 changed files with 321 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_CHERRYPICK.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Misskey의 전체 변경 사항을 확인하려면, [CHANGELOG.md#2024xx](CHANGE
- Enhance: 리액션 수신 범위에 따라 리액션 버튼의 툴팁 내용이 변경됨
- Enhance: 설정 페이지 개선
- 일반 설정에 있던 설정 중 디자인과 관련된 설정을 모양으로 옮겼습니다.
- Enhance: 외부 사이트로 이동할 때 경고 표시 (MisskeyIO/misskey#558)
- Fix: 환경설정 백업 시 일부 설정이 누락되어 백업될 수 있음

---
Expand Down
7 changes: 7 additions & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,9 @@ additionalPermissionsForFlash: "Allow to add permission to Play"
thisFlashRequiresTheFollowingPermissions: "This Play requires the following permissions"
doYouWantToAllowThisPlayToAccessYourAccount: "Do you want to allow this Play to access your account?"
translateProfile: "Translate profile"
trustedLinkUrlPatterns: "Link to external site warning exclusion list"
trustedLinkUrlPatternsDescription: "Separate with spaces for an AND condition or with line breaks for an OR condition. Using surrounding keywords with slashes will turn them into a regular expression. If you write only the domain name, it will be a backward match."
open: "Open"
_nsfwOpenBehavior:
click: "Click to open"
doubleClick: "Double click to open"
Expand Down Expand Up @@ -3008,3 +3011,7 @@ _imageCompressionMode:
noResizeCompress: "Compression without resize"
resizeCompressLossy: "Resize and lossy compression"
noResizeCompressLossy: "Lossy compression without resize"
_externalNavigationWarning:
title: "Navigate to an external site"
description: "Leave {host} and go to an external site"
trustThisDomain: "Trust this domain on this device in the future"
26 changes: 26 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5653,6 +5653,18 @@ export interface Locale extends ILocale {
* プロフィールを翻訳する
*/
"translateProfile": string;
/**
* 外部サイトへのリンク警告 除外リスト
*/
"trustedLinkUrlPatterns": string;
/**
* スペースで区切るとAND指定になり、改行で区切るとOR指定になります。スラッシュで囲むと正規表現になります。ドメイン名だけ書くと後方一致になります。
*/
"trustedLinkUrlPatternsDescription": string;
/**
* 開く
*/
"open": string;
"_nsfwOpenBehavior": {
/**
* タップして開く
Expand Down Expand Up @@ -11764,6 +11776,20 @@ export interface Locale extends ILocale {
*/
"noResizeCompressLossy": string;
};
"_externalNavigationWarning": {
/**
* 外部サイトに移動します
*/
"title": string;
/**
* {host}を離れて外部サイトに移動します
*/
"description": ParameterizedString<"host">;
/**
* このデバイスで今後このドメインを信頼する
*/
"trustThisDomain": string;
};
}
declare const locales: {
[lang: string]: Locale;
Expand Down
8 changes: 8 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1407,6 +1407,9 @@ additionalPermissionsForFlash: "Playへの追加許可"
thisFlashRequiresTheFollowingPermissions: "このPlayは以下の権限を要求しています"
doYouWantToAllowThisPlayToAccessYourAccount: "このPlayによるアカウントへのアクセスを許可しますか?"
translateProfile: "プロフィールを翻訳する"
trustedLinkUrlPatterns: "外部サイトへのリンク警告 除外リスト"
trustedLinkUrlPatternsDescription: "スペースで区切るとAND指定になり、改行で区切るとOR指定になります。スラッシュで囲むと正規表現になります。ドメイン名だけ書くと後方一致になります。"
open: "開く"

_nsfwOpenBehavior:
click: "タップして開く"
Expand Down Expand Up @@ -3131,3 +3134,8 @@ _imageCompressionMode:
noResizeCompress: "縮小せず再圧縮する"
resizeCompressLossy: "縮小して非可逆圧縮する"
noResizeCompressLossy: "縮小せず非可逆圧縮する"

_externalNavigationWarning:
title: "外部サイトに移動します"
description: "{host}を離れて外部サイトに移動します"
trustThisDomain: "このデバイスで今後このドメインを信頼する"
7 changes: 7 additions & 0 deletions locales/ko-KR.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1406,6 +1406,9 @@ additionalPermissionsForFlash: "Play에 대한 추가 권한"
thisFlashRequiresTheFollowingPermissions: "이 Play는 다음 권한을 요구해요"
doYouWantToAllowThisPlayToAccessYourAccount: "이 Play가 계정에 접근하도록 허용할까요?"
translateProfile: "프로필 번역하기"
trustedLinkUrlPatterns: "외부 사이트 링크 경고 제외 목록"
trustedLinkUrlPatternsDescription: "공백으로 구분하는 경우 AND, 줄바꿈으로 구분하는 경우 OR로 지정할 수 있어요. 슬래시로 둘러싸면 정규 표현식이 돼요. 도메인만 쓰면 후방 탐색으로 작동해요."
open: "열기"
_nsfwOpenBehavior:
click: "탭하여 열기"
doubleClick: "두 번 탭하여 열기"
Expand Down Expand Up @@ -3039,3 +3042,7 @@ _imageCompressionMode:
noResizeCompress: "해상도를 축소하지 않고 압축"
resizeCompressLossy: "해상도 축소 및 손실 압축"
noResizeCompressLossy: "해상도를 축소하지 않고 손실 압축"
_externalNavigationWarning:
title: "외부 사이트로 이동할까요?"
description: "{host}을(를) 떠나 외부 사이트로 이동하려고 해요"
trustThisDomain: "이 장치에서 앞으로 이 도메인을 신뢰할게요"
16 changes: 16 additions & 0 deletions packages/backend/migration/1711008460816-external-website-warn.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/

export class ExternalWebsiteWarn1711008460816 {
name = 'ExternalWebsiteWarn1711008460816'

async up(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" ADD "trustedLinkUrlPatterns" character varying(3072) array NOT NULL DEFAULT '{}'`);
}

async down(queryRunner) {
await queryRunner.query(`ALTER TABLE "meta" DROP COLUMN "trustedLinkUrlPatterns"`);
}
}
1 change: 1 addition & 0 deletions packages/backend/src/core/entities/MetaEntityService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ export class MetaEntityService {
imageUrl: ad.imageUrl,
dayOfWeek: ad.dayOfWeek,
})),
trustedLinkUrlPatterns: instance.trustedLinkUrlPatterns,
notesPerOneAd: instance.notesPerOneAd,
enableEmail: instance.enableEmail,
enableServiceWorker: instance.enableServiceWorker,
Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/models/Meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,14 @@ export class MiMeta {
})
public urlPreviewRequireContentLength: boolean;

@Column('varchar', {
length: 3072,
array: true,
default: '{}',
comment: 'An array of URL strings or regex that can be used to omit warnings about redirects to external sites. Separate them with spaces to specify AND, and enclose them with slashes to specify regular expressions. Each item is regarded as an OR.',
})
public trustedLinkUrlPatterns: string[];

@Column('varchar', {
length: 1024,
nullable: true,
Expand Down
8 changes: 8 additions & 0 deletions packages/backend/src/models/json-schema/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,14 @@ export const packedMetaLiteSchema = {
},
},
},
trustedLinkUrlPatterns: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
notesPerOneAd: {
type: 'number',
optional: false, nullable: false,
Expand Down
9 changes: 9 additions & 0 deletions packages/backend/src/server/api/endpoints/admin/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -583,6 +583,14 @@ export const meta = {
type: 'string',
optional: true, nullable: true,
},
trustedLinkUrlPatterns: {
type: 'array',
optional: false, nullable: false,
items: {
type: 'string',
optional: false, nullable: false,
},
},
},
},
} as const;
Expand Down Expand Up @@ -748,6 +756,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
enableReceivePrerelease: instance.enableReceivePrerelease,
skipVersion: instance.skipVersion,
skipCherryPickVersion: instance.skipCherryPickVersion,
trustedLinkUrlPatterns: instance.trustedLinkUrlPatterns,
};
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@ export const paramDef = {
enableReceivePrerelease: { type: 'boolean' },
skipVersion: { type: 'boolean' },
skipCherryPickVersion: { type: 'string', nullable: true },
trustedLinkUrlPatterns: {
type: 'array', nullable: true, items: {
type: 'string',
},
},
},
required: [],
} as const;
Expand Down Expand Up @@ -782,6 +787,10 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
set.skipCherryPickVersion = ps.skipCherryPickVersion;
}

if (Array.isArray(ps.trustedLinkUrlPatterns)) {
set.trustedLinkUrlPatterns = ps.trustedLinkUrlPatterns.filter(Boolean);
}

const before = await this.metaService.fetch(true);

await this.metaService.update(set);
Expand Down
3 changes: 3 additions & 0 deletions packages/cherrypick-js/src/autogen/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5319,6 +5319,7 @@ export type components = {
imageUrl: string;
dayOfWeek: number;
}[];
trustedLinkUrlPatterns: string[];
/** @default 0 */
notesPerOneAd: number;
enableEmail: boolean;
Expand Down Expand Up @@ -5511,6 +5512,7 @@ export type operations = {
perUserListTimelineCacheMax: number;
enableReactionsBuffering: boolean;
notesPerOneAd: number;
trustedLinkUrlPatterns: string[];
backgroundImageUrl: string | null;
deeplAuthKey: string | null;
deeplIsPro: boolean;
Expand Down Expand Up @@ -10232,6 +10234,7 @@ export type operations = {
mediaSilencedHosts?: string[] | null;
/** @description [Deprecated] Use "urlPreviewSummaryProxyUrl" instead. */
summalyProxy?: string | null;
trustedLinkUrlPatterns?: string[] | null;
urlPreviewEnabled?: boolean;
urlPreviewTimeout?: number;
urlPreviewMaximumContentLength?: number;
Expand Down
5 changes: 3 additions & 2 deletions packages/frontend/src/components/MkLink.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:is="self ? 'MkA' : 'a'" ref="el" style="word-break: break-all;" class="_link" :[attr]="self ? url.substring(local.length) : url" :rel="rel ?? 'nofollow noopener'" :target="target"
:behavior="props.navigationBehavior"
:title="url"
@click.stop
@click.stop="(ev: MouseEvent) => warningExternalWebsite(ev, props.url)"
>
<slot></slot>
<i v-if="target === '_blank'" class="ti ti-external-link" :class="$style.icon"></i>
Expand All @@ -22,6 +22,7 @@ import { useTooltip } from '@/scripts/use-tooltip.js';
import * as os from '@/os.js';
import { isEnabledUrlPreview } from '@/instance.js';
import { MkABehavior } from '@/components/global/MkA.vue';
import { warningExternalWebsite } from '@/scripts/warning-external-website.js';

const props = withDefaults(defineProps<{
url: string;
Expand All @@ -32,7 +33,7 @@ const props = withDefaults(defineProps<{

const self = props.url.startsWith(local);
const attr = self ? 'to' : 'href';
const target = self ? null : '_blank';
const target = self ? undefined : '_blank';

const el = ref<HTMLElement | { $el: HTMLElement }>();

Expand Down
5 changes: 3 additions & 2 deletions packages/frontend/src/components/MkUrlPreview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
</template>
<div v-else>
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substring(local.length) : url" rel="nofollow noopener" :target="target" :title="url" @click.stop>
<div v-if="thumbnail && !sensitive" :class="$style.thumbnail" :style="defaultStore.state.dataSaver.urlPreview ? '' : `background-image: url('${thumbnail}')`">
<component :is="self ? 'MkA' : 'a'" :class="[$style.link, { [$style.compact]: compact }]" :[attr]="self ? url.substring(local.length) : url" rel="nofollow noopener" :target="target" :title="url" @click.stop="(ev: MouseEvent) => warningExternalWebsite(ev, url)">
<div v-if="thumbnail && !sensitive" :class="[$style.thumbnail, { [$style.thumbnailBlur]: sensitive }]" :style="defaultStore.state.dataSaver.urlPreview ? '' : `background-image: url('${thumbnail}')`">
</div>
<article :class="$style.body">
<header :class="$style.header">
Expand Down Expand Up @@ -93,6 +93,7 @@ import { deviceKind } from '@/scripts/device-kind.js';
import MkButton from '@/components/MkButton.vue';
import { transformPlayerUrl } from '@/scripts/player-url-transform.js';
import { defaultStore } from '@/store.js';
import { warningExternalWebsite } from '@/scripts/warning-external-website.js';

type SummalyResult = Awaited<ReturnType<typeof summaly>>;

Expand Down
Loading

0 comments on commit a44d9fc

Please sign in to comment.