Skip to content
This repository has been archived by the owner on Jun 13, 2024. It is now read-only.

2 Errors in different projects #9

Open
reinerBa opened this issue Feb 26, 2022 · 4 comments
Open

2 Errors in different projects #9

reinerBa opened this issue Feb 26, 2022 · 4 comments

Comments

@reinerBa
Copy link

I tried to use the plugin in advanced projects. In the first one i could build but not load the js file, the console in the browser says:

Failed to find a valid digest in the 'integrity' attribute for resource 'http://127.0.0.1:8080/assets/index.5ef158b2.js' with computed SHA-384 integrity 'R2XRnrxjTxiLu4w3LeNCg3zSZFIf5fEeglzI0AA2xNBPtbT/YWKerFOhMXIzoJtb'. The resource has been blocked

This is the generated script tag where the error comes from:

<script type="module" crossorigin="" src="/assets/index.5ef158b2.js" integrity="sha384-Wl6kxwptiSC61eBxreLUI/hA1RPxBgf9W0fV77HpwvX2mrFJkZBzRUVEprF0TWHz"></script>
<link rel="modulepreload" href="/assets/vendor.821c7442.js"> 

Why is there no integrity attribute on the generated vendor js file?

In my secound project it wasn't able to run the "npm run build" command successfully. No matter how much assets i deleted from my index.html. The console wrote me everytime:

rendering chunks (2)...[vite:build-html] Cannot read properties of undefined (reading 'code') error during build:
TypeError: Cannot read properties of undefined (reading 'code')
at calculateIntegrityHashes (file:///.../node_modules/@small-tech/vite-plugin-sri/index.js:46:31)

For both projects i used the vue3 vite template. I don't know whats wrong there.

@reinerBa
Copy link
Author

reinerBa commented Feb 26, 2022

The webpack pendant uses .digest("base64") https://github.com/waysact/webpack-subresource-integrity/blob/ad9265e2db2635abb4b75ff00f0f0dd6ecb14dff/webpack-subresource-integrity/util.ts#L54

instead of .digest().toString('base64') in the index.js here.
The api suggests to use an encoding property in digest https://nodejs.org/api/crypto.html#hashdigestencoding
Maybe that is a reason?

@sean-hill
Copy link

I'm encountering this same issue while building with AWS Amplify 😭

@sean-hill
Copy link

sean-hill commented Jul 15, 2022

Looks like this happens when you have link or script tags importing from your public folder like this:

<link href="/css/global.css" rel="stylesheet" />
<script src="/js/storage.js" type="application/javascript"></script>

Those files aren't included in the context.bundle variable that vite provides.

@sean-hill
Copy link

@aral I tried to create a PR, but I don't have write access, here is a small change to the index.js file that fixed the issue for me:

////////////////////////////////////////////////////////////////////////////////
//
// @small-tech/vite-plugin-sri
//
// Subresource integrity (SRI) plugin for Vite (https://vitejs.dev/)
//
// Adds subresource integrity hashes to script and stylesheet
// imports from your index.html file at build time.
//
// If you’re looking for a generic Rollup plugin that does the same thing,
// see rollup-plugin-sri by Jonas Kruckenberg that this one was inspired by:
// https://github.com/JonasKruckenberg/rollup-plugin-sri
//
// Like this? Fund us!
// https://small-tech.org/fund-us
//
// Copyright ⓒ 2021-present Aral Balkan, Small Technology Foundation
// License: ISC.
//
////////////////////////////////////////////////////////////////////////////////

import { createHash } from 'crypto'
import cheerio from 'cheerio'
import fetch from 'node-fetch'

export default function sri () {
  return {
    name: 'vite-plugin-sri',
    enforce: 'post',
    apply: 'build',

    async transformIndexHtml(html, context) {
      const bundle = context.bundle

      const calculateIntegrityHashes = async (element) => {
        let source
        let attributeName = element.attribs.src ? 'src' : 'href'
        const resourcePath = element.attribs[attributeName]
        if (resourcePath.startsWith('http')) {
          // Load remote source from URL.
          source = await (await fetch(resourcePath)).buffer()
        } else {
          // Load local source from bundle.
          const resourcePathWithoutLeadingSlash = element.attribs[attributeName].slice(1)
          const bundleItem = bundle[resourcePathWithoutLeadingSlash]
          source = bundleItem && (bundleItem.code || bundleItem.source)
        }

        if (source) {
          element.attribs.integrity = `sha384-${createHash('sha384').update(source).digest().toString('base64')}`
        }
      }

      const $ = cheerio.load(html)
      $.prototype.asyncForEach = async function (callback) {
        for (let index = 0; index < this.length; index++) {
          await callback(this[index], index, this);
        }
      }

      // Implement SRI for scripts and stylesheets.
      const scripts = $('script').filter('[src]')
      const stylesheets = $('link[rel=stylesheet]').filter('[href]')

      await scripts.asyncForEach(calculateIntegrityHashes)
      await stylesheets.asyncForEach(calculateIntegrityHashes)

      return $.html()
    }
  }
}

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

No branches or pull requests

2 participants