From 123c4b395da71aa26721d02c4edc28dcb3ae511a Mon Sep 17 00:00:00 2001 From: xjccc <546534045@qq.com> Date: Wed, 19 Feb 2025 14:25:01 +0800 Subject: [PATCH] feat(nuxt): nuxt link add white list --- packages/nuxt/src/app/components/nuxt-link.ts | 20 ++++++++++++++++++- packages/nuxt/test/nuxt-link.test.ts | 6 ++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/packages/nuxt/src/app/components/nuxt-link.ts b/packages/nuxt/src/app/components/nuxt-link.ts index 309fce5227..62bc961e34 100644 --- a/packages/nuxt/src/app/components/nuxt-link.ts +++ b/packages/nuxt/src/app/components/nuxt-link.ts @@ -100,6 +100,11 @@ export interface NuxtLinkOptions extends * Allows controlling default setting for when to prefetch links. By default, prefetch is triggered only on visibility. */ prefetchOn?: Exclude + /** + * A white list of domain that should be not set noreferrer. + * @example ['nuxt.com', 'nuxtjs.org'] + */ + whiteList?: string[] } /* @__NO_SIDE_EFFECTS__ */ @@ -421,6 +426,19 @@ export function defineNuxtLink (options: NuxtLinkOptions) { // Resolves `target` value const target = props.target || null + function isUrlInWhitelist (url: string, whitelist: string[] = []): boolean { + try { + const urlObj = new URL(url) + return whitelist.some(domain => urlObj.hostname.endsWith(domain)) + } catch (e) { + console.error(e) + return false + } + } + let defaultExternalRel = 'noopener noreferrer' + if (isUrlInWhitelist(href.value, options.whiteList)) { + defaultExternalRel = 'noopener' + } // Resolves `rel` checkPropConflicts(props, 'noRel', 'rel') const rel = firstNonUndefined( @@ -431,7 +449,7 @@ export function defineNuxtLink (options: NuxtLinkOptions) { * A fallback rel of `noopener noreferrer` is applied for external links or links that open in a new tab. * This solves a reverse tabnapping security flaw in browsers pre-2021 as well as improving privacy. */ - (isAbsoluteUrl.value || hasTarget.value) ? 'noopener noreferrer' : '', + (isAbsoluteUrl.value || hasTarget.value) ? defaultExternalRel : '', ) || null // https://router.vuejs.org/api/#custom diff --git a/packages/nuxt/test/nuxt-link.test.ts b/packages/nuxt/test/nuxt-link.test.ts index 057214f3a1..84482a2f38 100644 --- a/packages/nuxt/test/nuxt-link.test.ts +++ b/packages/nuxt/test/nuxt-link.test.ts @@ -211,6 +211,12 @@ describe('nuxt-link:propsOrAttributes', () => { expect(nuxtLink({ to: 'https://nuxtjs.org', rel: '' }, { externalRelAttribute: 'bar' }).props.rel).toBe(null) }) + it('uses set white list', () => { + expect(nuxtLink({ to: 'https://nuxtjs.org' }, { whiteList: ['nuxtjs.org'] }).props.rel).toBe('noopener') + expect(nuxtLink({ to: 'https://nuxt.com' }, { whiteList: ['nuxtjs.org', '.nuxt.com'] }).props.rel).toBe('noopener noreferrer') + expect(nuxtLink({ to: 'https://nuxters.nuxt.com' }, { whiteList: ['nuxtjs.org', '.nuxt.com'] }).props.rel).toBe('noopener') + }) + it('honors `noRel` prop', () => { expect(nuxtLink({ to: 'https://nuxtjs.org', noRel: true }).props.rel).toBe(null) expect(nuxtLink({ to: 'https://nuxtjs.org', noRel: false }).props.rel).toBe('noopener noreferrer')