Skip to content

Commit

Permalink
Only apply metadata manifest credentials for preview deployment (#64940)
Browse files Browse the repository at this point in the history
### What

Follow up for #62873
Only apply credentials in metadata manifest tag for preview deployment

### Why

When the CORS header is "\*" and if you're including credentials in
request it will block by browser. For manifest's case, if it's fetching
from a publich CDN with responsing the CORS header "\*" and mismatching
with the current website domain it will get blocked. Previously we
introduced that change mostly for vercel deployment auth protection, now
we're going to check if it's preview deployment and also the same
origin, if yes then we'll include credentails for manifest request

Closes NEXT-3208
  • Loading branch information
huozhi authored Apr 30, 2024
1 parent 029d1da commit ecbf537
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
13 changes: 12 additions & 1 deletion packages/next/src/lib/metadata/generate/basic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type { ViewportLayout } from '../types/extra-types'
import React from 'react'
import { Meta, MetaFilter, MultiMeta } from './meta'
import { ViewportMetaKeys } from '../constants'
import { getOrigin } from './utils'

// convert viewport object to string for viewport meta tag
function resolveViewportLayout(viewport: Viewport) {
Expand Down Expand Up @@ -45,6 +46,10 @@ export function ViewportMeta({ viewport }: { viewport: ResolvedViewport }) {
}

export function BasicMeta({ metadata }: { metadata: ResolvedMetadata }) {
const manifestOrigin = metadata.manifest
? getOrigin(metadata.manifest)
: undefined

return MetaFilter([
<meta charSet="utf-8" />,
metadata.title !== null && metadata.title.absolute ? (
Expand All @@ -64,7 +69,13 @@ export function BasicMeta({ metadata }: { metadata: ResolvedMetadata }) {
<link
rel="manifest"
href={metadata.manifest.toString()}
crossOrigin="use-credentials"
// If it's same origin, and it's a preview deployment,
// including credentials for manifest request.
crossOrigin={
!manifestOrigin && process.env.VERCEL_ENV === 'preview'
? 'use-credentials'
: undefined
}
/>
) : null,
Meta({ name: 'generator', content: metadata.generator }),
Expand Down
13 changes: 12 additions & 1 deletion packages/next/src/lib/metadata/generate/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,15 @@ function resolveAsArrayOrUndefined<T>(
return resolveArray(value) as any
}

export { resolveAsArrayOrUndefined, resolveArray }
function getOrigin(url: string | URL): string | undefined {
let origin = undefined
if (typeof url === 'string') {
try {
url = new URL(url)
origin = url.origin
} catch {}
}
return origin
}

export { resolveAsArrayOrUndefined, resolveArray, getOrigin }
4 changes: 2 additions & 2 deletions test/e2e/app-dir/metadata/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ describe('app dir - metadata', () => {
// Manifest link should have crossOrigin attribute
await matchDom('link', 'rel="manifest"', {
href: '/api/manifest',
crossOrigin: 'use-credentials',
crossOrigin: isNextDeploy ? 'use-credentials' : null,
})

await matchDom('meta', 'name="theme-color"', {
Expand Down Expand Up @@ -263,7 +263,7 @@ describe('app dir - metadata', () => {
// Manifest link should have crossOrigin attribute
await matchDom('link', 'rel="manifest"', {
href: '/api/manifest',
crossOrigin: 'use-credentials',
crossOrigin: isNextDeploy ? 'use-credentials' : null,
})
})

Expand Down

0 comments on commit ecbf537

Please sign in to comment.