diff options
| author | Marie <github@yuugi.dev> | 2024-10-04 02:31:22 +0200 |
|---|---|---|
| committer | Marie <github@yuugi.dev> | 2024-10-04 02:31:22 +0200 |
| commit | d5b372f7a92e3892addb306fc6b62b169e2bfc41 (patch) | |
| tree | b17986d43be7213a56cefa8ccd7db05f472311c7 /packages/frontend/src/scripts | |
| parent | merge: Feat: Implement "Show Below Avatar" for Avatar Decorations (!645) (diff) | |
| download | sharkey-d5b372f7a92e3892addb306fc6b62b169e2bfc41.tar.gz sharkey-d5b372f7a92e3892addb306fc6b62b169e2bfc41.tar.bz2 sharkey-d5b372f7a92e3892addb306fc6b62b169e2bfc41.zip | |
upd&merge: Merge Cherrypick/MisskeyIO's external url popup, delete old popup warning and modify script to handle undefined domains
Diffstat (limited to 'packages/frontend/src/scripts')
| -rw-r--r-- | packages/frontend/src/scripts/warning-external-website.ts | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/packages/frontend/src/scripts/warning-external-website.ts b/packages/frontend/src/scripts/warning-external-website.ts new file mode 100644 index 0000000000..c0050112ce --- /dev/null +++ b/packages/frontend/src/scripts/warning-external-website.ts @@ -0,0 +1,48 @@ +/* + * SPDX-FileCopyrightText: syuilo and misskey-project + * SPDX-License-Identifier: AGPL-3.0-only + */ + +import { instance } from '@/instance.js'; +import { defaultStore } from '@/store.js'; +import * as os from '@/os.js'; +import MkUrlWarningDialog from '@/components/MkUrlWarningDialog.vue'; + +const extractDomain = /^(https?:\/\/|\/\/)?([^@/\s]+@)?(www\.)?([^:/\s]+)/i; +const isRegExp = /^\/(.+)\/(.*)$/; + +export async function warningExternalWebsite(url: string) { + const domain = extractDomain.exec(url)?.[4]; + + if (!domain) return false; + + const isTrustedByInstance = instance.trustedLinkUrlPatterns.some(expression => { + const r = isRegExp.exec(expression); + + if (r) { + return new RegExp(r[1], r[2]).test(url); + } else if (expression.includes(' ')) return expression.split(' ').every(keyword => url.includes(keyword)); + else return domain.endsWith(expression); + }); + + const isTrustedByUser = defaultStore.reactiveState.trustedDomains.value.includes(domain); + + if (!isTrustedByInstance && !isTrustedByUser) { + const confirm = await new Promise<{ canceled: boolean }>(resolve => { + const { dispose } = os.popup(MkUrlWarningDialog, { + url, + }, { + done: result => { + resolve(result ? result : { canceled: true }); + }, + closed: () => dispose(), + }); + }); + + if (confirm.canceled) return false; + + window.open(url, '_blank', 'nofollow noopener popup=false'); + } + + return true; +} |