-
Notifications
You must be signed in to change notification settings - Fork 121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(injectBaseStylesheet): address style injection issue #605
Conversation
Bug Fixes
Chore
ContributorsCommit-Lint commandsYou can trigger Commit-Lint actions by commenting on this PR:
|
05e3d9b
to
8869e0c
Compare
src/js/injectBaseStylesheet.js
Outdated
const styleTag = allHeadElements.item(allHeadElements.length - 1); | ||
styleTag.innerHTML = styleEl.innerHTML + styleTag.innerHTML; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will definitely work in the context of the local demo since the last child element happens to be a <style>
element, but I don't think we can assume that will be the case for all of our users. We should prepend a completely separate <style>
element into the list of allHeadElements
to ensure we don't accidentally cause any errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const styleTag = allHeadElements.item(allHeadElements.length - 1); | |
styleTag.innerHTML = styleEl.innerHTML + styleTag.innerHTML; | |
const styleTag = allHeadElements.item(allHeadElements.length - 1); | |
styleTag.outerHTML = styleEl.outerHTML + styleTag.outerHTML; |
I don't know if this is the correct way to do this... but it works 🤷
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to clear up that this works well for other configurations and resolve the comments before merging, but otherwise LGTM.
src/js/injectBaseStylesheet.js
Outdated
@@ -63,5 +63,6 @@ export default function injectBaseStylesheet() { | |||
const head = document.head; | |||
|
|||
const allHeadElements = head.getElementsByTagName("*"); | |||
allHeadElements.innerHTML = styleEl + allHeadElements.innerHTML; | |||
const styleTag = allHeadElements.item(allHeadElements.length - 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const styleTag = allHeadElements.item(allHeadElements.length - 1); | |
const styleTag = allHeadElements.item(0); |
We want to select the first element, not the last one (afaik)
8869e0c
to
9bbb838
Compare
Made use of the Tested locally on |
Hey @luqven we actually can't use |
🤦🏼 right my bad. Ugh really wanted to avoid magic numbers or |
9bbb838
to
b9360fc
Compare
index.html
Outdated
<!-- If CSP style policies, ensure SHA, nonce, or unsafe-inline are enabled --> | ||
<meta http-equiv="Accept-CH" content="DPR, Width, Viewport-Width"> | ||
<meta | ||
http-equiv="Content-Security-Policy" | ||
content="style-src 'self' 'sha256-W+PadZMOYbQi3EzR/NC+KcPx3bNLCz0OtfWwp+LK9b4=' 'sha256-OdI56ZW769BKGaLghLr3uZVaaWfqyRwyccMiu8gXf0w=' 'sha256-W+PadZMOYbQi3EzR/NC+KcPx3bNLCz0OtfWwp+LK9b4=' 'sha256-cG/+JJX3ZZs6snnMipxMnaYWATXBcyQw3vFWJF1zmAM='" | ||
/> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unfortunately this is the only way I successfully got around the CSP violation issues. We had to generate a SHA value for the style tags that violated the policy and add them to the csp. We also had to add self
as an src to avoid the library's inline styles from getting blocked as well.
This will have to be done by an end user as well. Ie, they'll have to implement some combination of the recommended options for style-src
that allows our script and or styles to be set.
We could host the stylesheets in question on a CDN, but that seems like overkill when the user can do the above.
After looking into this some more, I don't think there's a better way to solve the CSP issues. The user would have to modify their CSPs to accommodate for Drift's behavior. edit: to be clear, this would mean some combination of creating a hash of the script and or style tags, allowing |
144e71f
to
08b5538
Compare
Fix a bug where getElementByTagName() was attempting to access an attr, .innerHTML, that was not defined. Instead, create and inject a new style tag as a child to the head.
Add styles hash to csp to avoid it getting blocked by browser
Apols for all the force pushes, forgot there was 1 outstanding PR before this one 😬 |
@all-contributors add @luqven for maintenance |
I've put up a pull request to add @luqven! 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All good if the discussion is resolved.
// prepend them to the document head's first child | ||
const head = document.head; | ||
const allHeadElements = head.getElementsByTagName("*"); | ||
allHeadElements.innerHTML = styleEl + allHeadElements.innerHTML; | ||
const firstItem = allHeadElements.item(0); | ||
firstItem.outerHTML = styleEl.outerHTML + firstItem.outerHTML; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't get around the CSP violation anyway, is it cleaner to go back to using .insertBefore()
rather than this method? i.e. reverting the changes introduced here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good point. I do think this read easier that way..
It might then be better to close this PR altogether and create two new ones:
- rolling back that change and then
- adding the CSP to
index.html
as an example / check for handling those issues.
I'll discuss w/ @sherwinski offline and circle back.
After chatting I think it's best to close and split this PR into two. Will make sure to reference this discussion so context isn't lost. |
Description
Fix a bug where
getElementByTagName()
was attempting to access an attribute,.innerHTML
, that was not defined.Instead updates stylesheet by using the
.item()
method forHTMLCollections
to then access.innerHTML
.Checklist
Bug Fix
fix(<area>): fixed bug #issue-number
Steps to Test
Clone the repo,
npm run build
, and open/index.html
in your default browser.Related issue: [e.g. #603 ]
Code:
Discussion
In future, Cypress testing (or the like) integration is recommended to catch this type of bugs. Hard to detect without browser testing.