-
Notifications
You must be signed in to change notification settings - Fork 783
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(runtime): support for CSP nonces (#3823)
* wip(compiler/runtime): ability to set nonce on runtime platform This commit adds the ability to set a `nonce` value on the runtime platform object. This also introduces the consumption of this value and setting of the `nonce` attribute for generated `style` tags in `dist-custom-elements`. * wip(compiler/runtime): setNonce behavior for dist target This commit adds the `setNonce` definition to the generated output for the `dist` output target. This also sets the `nonce` attribute on the style tag responsible for invisible pre-hydration styles. * feat(runtime): extra check for nonce on window * chore(): nonce function/declaration code comments This commit adds some comments to the internal and generated helper function code for apply nonce attributes. * test(): test various nonce application functions * chore(): run prettier * fix(): update unit tests * fix(tests): remove platform reference in CSS shim polyfill * fix(tests): update CSS shim unit tests * chore(): remove CSP from IE polyfills CSP nonces aren't supported by IE so there is no reason to add support in the polyfills * chore(): add JSdoc comments * chore(): update `setNonce` JSdoc * feat(runtime): updates nonce fallback to use meta tag instead of window (#3955) * feat(runtime): updates nonce fallback to use meta tag instead of window This commit updates our CSP nonce support logic to allow implementers to leverage a meta tag in the DOM head for setting nonce values during the Stencil runtime rather than pulling the value off of the global window object * fix(): PR feedback * feat(utils): update return type fallback to `undefined` only
- Loading branch information
1 parent
b4b5b22
commit c91ed48
Showing
22 changed files
with
189 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
src/client/polyfills/css-shim/test/load-link-styles.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { addGlobalLink } from '../load-link-styles'; | ||
|
||
describe('loadLinkStyles', () => { | ||
describe('addGlobalLink', () => { | ||
global.fetch = jest.fn().mockResolvedValue({ text: () => '--color: var(--app-color);' }); | ||
|
||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
|
||
it('should create a style tag within the link element parent node', async () => { | ||
const linkElm = document.createElement('link'); | ||
linkElm.setAttribute('rel', 'stylesheet'); | ||
linkElm.setAttribute('href', ''); | ||
|
||
const parentElm = document.createElement('head'); | ||
parentElm.appendChild(linkElm); | ||
|
||
await addGlobalLink(document, [], linkElm); | ||
|
||
expect(parentElm.innerHTML).toEqual('<style data-styles>--color: var(--app-color);</style>'); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,5 +186,6 @@ export { | |
renderVdom, | ||
setAssetPath, | ||
setMode, | ||
setNonce, | ||
setValue, | ||
} from '@runtime'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,6 +43,7 @@ export { | |
setAssetPath, | ||
setErrorHandler, | ||
setMode, | ||
setNonce, | ||
setPlatformHelpers, | ||
State, | ||
Watch, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { plt } from '@platform'; | ||
|
||
/** | ||
* Assigns the given value to the nonce property on the runtime platform object. | ||
* During runtime, this value is used to set the nonce attribute on all dynamically created script and style tags. | ||
* @param nonce The value to be assigned to the platform nonce property. | ||
* @returns void | ||
*/ | ||
export const setNonce = (nonce: string) => (plt.$nonce$ = nonce); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
/** | ||
* Helper method for querying a `meta` tag that contains a nonce value | ||
* out of a DOM's head. | ||
* | ||
* @param doc The DOM containing the `head` to query against | ||
* @returns The content of the meta tag representing the nonce value, or `undefined` if no tag | ||
* exists or the tag has no content. | ||
*/ | ||
export function queryNonceMetaTagContent(doc: Document): string | undefined { | ||
return doc.head?.querySelector('meta[name="csp-nonce"]')?.getAttribute('content') ?? undefined; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { queryNonceMetaTagContent } from '../query-nonce-meta-tag-content'; | ||
|
||
describe('queryNonceMetaTagContent', () => { | ||
it('should return the nonce value if the tag exists', () => { | ||
const meta = document.createElement('meta'); | ||
meta.setAttribute('name', 'csp-nonce'); | ||
meta.setAttribute('content', '1234'); | ||
document.head.appendChild(meta); | ||
|
||
const nonce = queryNonceMetaTagContent(document); | ||
|
||
expect(nonce).toEqual('1234'); | ||
}); | ||
|
||
it('should return `undefined` if the tag does not exist', () => { | ||
const nonce = queryNonceMetaTagContent(document); | ||
|
||
expect(nonce).toEqual(undefined); | ||
}); | ||
|
||
it('should return `undefined` if the document does not have a head element', () => { | ||
const head = document.querySelector('head'); | ||
head.remove(); | ||
|
||
const nonce = queryNonceMetaTagContent(document); | ||
|
||
expect(nonce).toEqual(undefined); | ||
}); | ||
|
||
it('should return `undefined` if the tag has no content', () => { | ||
const meta = document.createElement('meta'); | ||
meta.setAttribute('name', 'csp-nonce'); | ||
document.head.appendChild(meta); | ||
|
||
const nonce = queryNonceMetaTagContent(document); | ||
|
||
expect(nonce).toEqual(undefined); | ||
}); | ||
}); |