Skip to content
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

#565 Provide optional SRI hash when displaying embed code #730

Draft
wants to merge 11 commits into
base: development
Choose a base branch
from

Conversation

raLaaaa
Copy link
Contributor

@raLaaaa raLaaaa commented Jul 28, 2022

Hey, first draft for the implementation of an optional SRI hash for the script tag.

image

The last required step is not working yet (by that I mean pulling the embedding script into the auditorium build file stage to generate the hash). Hopefully I can finalize everything on the weekend and already add your feedback / improvements.

@hendr-ik if you want I'll also update the UI towards a using a simple checkbox.

@@ -13,6 +13,7 @@ var buffer = require('vinyl-buffer')
var gap = require('gulp-append-prepend')
var Readable = require('stream').Readable
var linguasFile = require('linguas-file')
var CryptoJS = require('crypto-js')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As this is now exclusively running on the server, can we use the stdlib crypto module and not add a dependency?

@raLaaaa raLaaaa marked this pull request as draft July 28, 2022 08:13
const snippetWithSRI = `<script async src="${window.location.origin}/script.js" data-account-id="${model.account.accountId}" integrity="sha256-${process.env.SCRIPT_INTEGRITY_HASH}"></script>`
const [useSnippetWithSRI, setActive] = useState(false);
let embeddedSnipped = useSnippetWithSRI ? snippetWithSRI : snippet;
let buttonText = useSnippetWithSRI ? 'Hide integrity hash' : 'Show with integrity hash';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As Offen is translated into multiple languages, all copy needs to be localized properly. Doing this is relatively easy: a global __ function is available in all modules that you can wrap a string in, marking as "to be localized":

__('Hide integrity hash')

@@ -59,17 +70,22 @@ const EmbedCode = (props) => {
<Paragraph class='ma0 mb3'>
{__('In case you are serving multiple domains from your Offen instance, please double check that the domain in this snippet matches the target account.')}
</Paragraph>
<div class="flex items-end">
<div class="w-100 tr bb b--light-gray">
<button onClick={toggleScriptDisplay} class='pointer w-100 w-auto-ns fw1 f7 tc bn dib br1 ph2 pv1 black bg-black-10'><span class={classnames('ml2', 'dib', 'label-toggle', 'label-toggle', !useSnippetWithSRI? null : 'label-toggle--rotate')}></span> {buttonText}</button>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With classnames you don't need to add ternary statements yourself, instead you can have the library conditionally apply classnames:

classnames('a', 'b' {'label-toggle--rotate': useSnippetWithSRI })

@lgtm-com
Copy link

lgtm-com bot commented Jul 29, 2022

This pull request introduces 1 alert when merging ac23ced into c7aed87 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

@raLaaaa
Copy link
Contributor Author

raLaaaa commented Jul 29, 2022

@m90 thank you for your feedback.
I hopefully tackled most of the stuff in the latest commits.


Most importantly I changed towards the crypto library from node.
How ever copying the index.js from the script folder only worked for when running the script stage before the auditorium stage. Otherwise the file can not be found. ac23ced

Docker will figure out that the auditorium stage now depends on the script stage and wait for it to build.

Is there a special trick to invoke this behavior you mentioned?


Also: currently the generated sha-256 hash always differs from the browser enforced integrity hash.
I assume that is because the browser generates the hash from a minified version (?) whereas I'm currently calculating the hash from the clear text script file. I'm working on that.

Furthermore my formatter seems to differ a bit from yours. Which one do you use?

@m90
Copy link
Member

m90 commented Jul 29, 2022

Furthermore my formatter seems to differ a bit from yours. Which one do you use?

The entire repo uses standard at version 14

"standard": "^14.3.1",
- it would be much appreciated if you could use this so the diff noise is as low as possible. Right now, it's a bit hard to tell which changes are formatting, and which ones are feature related.

You can check whether standard likes your changes by running the tests locally:

docker-compose run auditorium npm t

Is there a special trick to invoke this behavior you mentioned?

Not really a trick. If you look at the compiler stage of the build Dockerfile, you can see how it copies in the artifacts generated by the script stage here:

COPY --from=script /code/script/dist /go/src/github.com/offen/offen/server/public/static

You can now do the same in the auditorium stage, copying these files to the location expected by the Gulpfile.

WORKDIR /code/deps
RUN npm ci
COPY ./script /code/script
COPY ./auditorium /code/auditorium
COPY --from=script ./code/script/index.js /code/auditorium/script/index.js
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This copies the entrypoint file when instead we need to copy the bundled versions. See my comment on how to do this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this invoke the behavior we need?

COPY --from=script /code/script/dist/index.js /script/script.js

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a bundle created per locale (the script logs user facing messages in some cases which are localized) so we need t copy the entire dist directory and then pick the correct one in the build for auditorium.

See:

offen/script/gulpfile.js

Lines 43 to 44 in c7aed87

var dest = './dist/' + locale + '/'
var scriptTask = makeScriptTask(dest, locale)
and

offen/script/gulpfile.js

Lines 76 to 84 in c7aed87

return b
.plugin('tinyify')
.bundle()
.pipe(source('script.js'))
.pipe(buffer())
.pipe(gap.prependText('*/'))
.pipe(gap.prependFile('./../banner.txt'))
.pipe(gap.prependText('/**'))
.pipe(gulp.dest(dest))

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To not bother you with more questions I'll need some time to work me through the build process. To be honest it is a lot magic for me right now.

I'm not quite sure how gulp works together with the dockerfile.build furthermore my overall gulp knowledge is very limited.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have questions while doing so, don't worry about bothering me. In any case, take your time. Thanks.

docker-compose.yml Outdated Show resolved Hide resolved
@lgtm-com
Copy link

lgtm-com bot commented Aug 1, 2022

This pull request introduces 1 alert when merging 4d37805 into c7aed87 - view on LGTM.com

new alerts:

  • 1 for Unused variable, import, function or class

return true
},
transform: transforms.map(function (transform) {
if (transform === '@offen/l10nify' || (Array.isArray(transform) && transform[0] === '@offen/l10nify')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be good if you could undo these formatting only changes as well even if standard is ok with them. It'll be easier to understand what changed if we don't have the additional noise in the diff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants