Amp-script hash not found or incorrect

So my error message is as follows

amp-script Script hash not found or incorrect for amp-script[script="hello-world"].js. 
You must include <meta 
name="amp-script-src" 
content="sha384-6FlT3Nsv_toaZHleLVjcNK4SLgMUAzs02tV7EQBsyC35AUB7twCU-QCQ_aE_bMiC"
>

Currently I am generating hash using following method

{{ $built := resources.Get "js/auth/sign-up.js" | resources.Fingerprint "sha384" }}
{{<meta name="amp-script-src" content={{$built.Data.Integrity}}>}}

Officially amp-script hash is generated as per documentation as follows

const crypto = require('crypto');
const hash = crypto.createHash('sha384');

function generateCSPHash(script) {
  const data = hash.update(script, 'utf-8');
  return (
    'sha384-' +
    data
      .digest('base64')
      .replace(/=/g, '')
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
  );
}

The current workaround is copy hash from error message and paste into public and it works. But problem is

  • I cannot do this for 100’s of files
  • I currently Use CI-CD workflow to deploy website so each time hash would be different and I can’t copy paste from error message.

How do I create hash with Hugo as per amp-script documentation with CI-CD workflow in mind.

Untested, but this would be my attempt.

  • look at generateCSPHash and follow the instructions in that function and hack together your own solution
  • sha384- is a string
  • data is the crypted string, that can be done with hmac - the documentation does not include sha384, but that might be an oversight, @bep?) if not then open an issue in Hugos repo to add this functionality
  • digest(base64) can be achieved with base64
  • replace can be achieved with replacere (re for regexp)

something along the lines of

sha384-{{ data) | hmac 'sha384' | base64 | replace something something }}

And if you have too much time you could compare the hashes that amp-script expects and the ones you deliver. I wonder what the difference is. An sha hash should always be identical for identical content… Maybe it’s the utf-8 charset that is the difference and you have a non-latin characterset on your site.

Edit: forgot the sha string at the beginning of the string

And maybe, just maybe, you are minifying the resulting JavaScript files AFTER Hugo is done creating them. Don’t. Do not touch any JS file after Hugo is done with them. Because the hash at that point is the hash to be used. If you use for instance Netlify and minify the files over there again the hash changes. I had that once in my olden days.

Just to be clear the data in

sha384-{{ data) | hmac 'sha384' | base64 | replace something something }}

or script

function generateCSPHash(script) {
  const data = hash.update(script, 'utf-8');
  .....
}

that is basically {{$data := (resources.Get "js/auth/sign-up.js").Content }} correct??
Not actual file?
That leads me to similar question. amp-script supports remote URL and local element
but when I do local element as per documentation as follows

<script id="hello-world" type="text/plain" target="amp-script">
    {{ safeJS (resources.Get "js/auth/sign-up.js").Content }}
</script>

Then my output is as follows

<script id="hello-world" type="text/plain" target="amp-script">
     console.log(&#39;test&#39;)
</script>

After that local JS element cannot execuite because of special characters.
How do I fix that?

:wink:

Have a look at all the “safe” functions in Hugo. Go to the doc, type safe in the search on top. There is one for everything. The content is encoded with safe encoding %something, because you print it out in an HTML context.

This brings us back to the first issue: Is your javascript file UTF-8? If not, then the hashed string is probably different from the one amp-script creates/expects.

Changing safeJS to safeHTML did fix that issue.

Is your javascript file UTF-8?

Yes its UTF-8. As per VS Code bottom right corner thing.

Now I am getting following error

error calling hmac: hmac: sha384 is not a supported hash function

Also secret KEY is required for using hmac and I am not supposed to use Key as per documentation.

I also tried sha and I get following error

function "sha384" not defined

That’s the part where I said “if not then open an issue in Hugos repo to add this functionality” :wink: It does not exist yet, but it needs to be added, because it’s a valid method today.