Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
22
my-app/node_modules/webpack-subresource-integrity/LICENSE
generated
vendored
Executable file
22
my-app/node_modules/webpack-subresource-integrity/LICENSE
generated
vendored
Executable file
|
@ -0,0 +1,22 @@
|
|||
(The MIT License)
|
||||
|
||||
Copyright (c) 2015-present Waysact Pty Ltd
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
301
my-app/node_modules/webpack-subresource-integrity/README.md
generated
vendored
Executable file
301
my-app/node_modules/webpack-subresource-integrity/README.md
generated
vendored
Executable file
|
@ -0,0 +1,301 @@
|
|||
[![Build Status][tests-badge]][tests-url]
|
||||
[![Coverage Status][coverage-badge]][coverage-url]
|
||||
[![Code Climate][codeclimate-badge]][codeclimate-url]
|
||||
[![License][license-badge]][license-url]
|
||||
|
||||
# webpack-subresource-integrity
|
||||
|
||||
Webpack plugin for enabling Subresource Integrity.
|
||||
|
||||
[Subresource Integrity](http://www.w3.org/TR/SRI/) (SRI) is a security
|
||||
feature that enables browsers to verify that files they fetch (for
|
||||
example, from a CDN) are delivered without unexpected
|
||||
manipulation.
|
||||
|
||||
**Upgrading from version 1.x? [Read the migration guide](https://github.com/waysact/webpack-subresource-integrity/blob/main/MIGRATE-v1-to-v5.md).**
|
||||
|
||||
## Features
|
||||
|
||||
- Optional integration with [html-webpack-plugin](https://github.com/ampedandwired/html-webpack-plugin).
|
||||
- Automatic support for dynamic imports (also known as code splitting.)
|
||||
- Compatible with Webpack 5 (for Webpack versions 1-4 see [1.x branch](https://github.com/waysact/webpack-subresource-integrity/tree/1.x/).)
|
||||
|
||||
## Installation
|
||||
|
||||
```shell
|
||||
yarn add --dev webpack-subresource-integrity
|
||||
```
|
||||
|
||||
```shell
|
||||
npm install webpack-subresource-integrity --save-dev
|
||||
```
|
||||
|
||||
### Recommended Webpack Configuration
|
||||
|
||||
```javascript
|
||||
import { SubresourceIntegrityPlugin } from "webpack-subresource-integrity";
|
||||
// or: const { SubresourceIntegrityPlugin } = require('webpack-subresource-integrity');
|
||||
|
||||
const compiler = webpack({
|
||||
output: {
|
||||
// the following setting is required for SRI to work:
|
||||
crossOriginLoading: "anonymous",
|
||||
},
|
||||
plugins: [new SubresourceIntegrityPlugin()],
|
||||
});
|
||||
```
|
||||
|
||||
### Setting the `integrity` attribute for top-level assets
|
||||
|
||||
For the plugin to take effect it is **essential** that you set the
|
||||
`integrity` attribute for top-level assets (i.e. assets loaded by your
|
||||
HTML pages.)
|
||||
|
||||
#### With HtmlWebpackPlugin
|
||||
|
||||
When html-webpack-plugin is injecting assets into the template (the
|
||||
default), the `integrity` attribute will be set automatically. The
|
||||
`crossorigin` attribute will be set as well, to the value of
|
||||
`output.crossOriginLoading` webpack option. There is nothing else to
|
||||
be done.
|
||||
|
||||
#### With HtmlWebpackPlugin({ inject: false })
|
||||
|
||||
When you use html-webpack-plugin with `inject: false`, you are
|
||||
required to set the `integrity` and `crossorigin` attributes in your
|
||||
template as follows:
|
||||
|
||||
```ejs
|
||||
<% for (let index in htmlWebpackPlugin.files.js) { %>
|
||||
<script
|
||||
src="<%= htmlWebpackPlugin.files.js[index] %>"
|
||||
integrity="<%= htmlWebpackPlugin.files.jsIntegrity[index] %>"
|
||||
crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
|
||||
></script>
|
||||
<% } %>
|
||||
|
||||
<% for (let index in htmlWebpackPlugin.files.css) { %>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="<%= htmlWebpackPlugin.files.css[index] %>"
|
||||
integrity="<%= htmlWebpackPlugin.files.cssIntegrity[index] %>"
|
||||
crossorigin="<%= webpackConfig.output.crossOriginLoading %>"
|
||||
/>
|
||||
<% } %>
|
||||
```
|
||||
|
||||
#### Without HtmlWebpackPlugin
|
||||
|
||||
The correct value for the `integrity` attribute can be retrieved from
|
||||
the `integrity` property of Webpack assets. For example:
|
||||
|
||||
```javascript
|
||||
compiler.plugin("done", (stats) => {
|
||||
const integrityValues = stats
|
||||
.toJson()
|
||||
.assets.map((asset) => [asset.name, asset.integrity]);
|
||||
});
|
||||
```
|
||||
|
||||
Note that when you add the `integrity` attribute on your `link` and
|
||||
`script` tags, you're also required to set the `crossorigin`
|
||||
attribute. It is recommended to set this attribute to the same value
|
||||
as the webpack `output.crossOriginLoading` configuration option.
|
||||
|
||||
### Web Server Configuration
|
||||
|
||||
If your page can be loaded through plain HTTP (as opposed to HTTPS),
|
||||
you must set the `Cache-Control: no-transform` response header or your
|
||||
page will break when assets are loaded through a transforming
|
||||
proxy. [See below](#proxies) for more information.
|
||||
|
||||
When using caching, stale assets will fail to load since they will not pass
|
||||
integrity checks. It is vital that you configure caching correctly in your web
|
||||
server. [See below](#caching) for more information.
|
||||
|
||||
### Options
|
||||
|
||||
#### hashFuncNames
|
||||
|
||||
Default value: `["sha384"]`
|
||||
|
||||
An array of strings, each specifying the name of a hash function to be
|
||||
used for calculating integrity hash values.
|
||||
|
||||
See [SRI: Cryptographic hash functions](http://www.w3.org/TR/SRI/#cryptographic-hash-functions)
|
||||
|
||||
The default is chosen based on the current [suggestion by the
|
||||
W3C](https://www.w3.org/TR/2016/REC-SRI-20160623/#hash-collision-attacks) which
|
||||
reads:
|
||||
|
||||
> At the time of writing, SHA-384 is a good baseline.
|
||||
|
||||
See [here](https://github.com/w3c/webappsec/issues/477) for additional
|
||||
information on why SHA-384 was chosen by the W3C over their initial suggestion,
|
||||
SHA-256.
|
||||
|
||||
As one of the commenters in that discussion points out, "SRI hashes are likely
|
||||
delivered over SSL" which today (2021) is often using SHA-256 so that there is
|
||||
probably little harm in downgrading this to `sha256` instead.
|
||||
|
||||
By using SHA-256 you will save 21 bytes per chunk and perhaps a few CPU cycles,
|
||||
although SHA-384 is actually faster to compute on some hardware. Not that it
|
||||
matters, as the difference is dwarfed by all the other work a browser has to do
|
||||
in order to download and parse a JS or CSS asset.
|
||||
|
||||
You probably want to use `sha512` instead of the default only if you're
|
||||
paranoid. It will cost you an additional 21 bytes per chunk; the CPU overhead is
|
||||
virtually nil because SHA-512 is the same as SHA-384, just not truncated.
|
||||
|
||||
Although you can specify multiple hash functions here, doing so is pointless as
|
||||
long as all mainstream browsers only support the SHA-2 family, which is the case
|
||||
today. Worse, it's detrimental since it adds unnecessary overhead.
|
||||
|
||||
The reason is that as per the spec, only the strongest hash function is used and
|
||||
so eg. `['sha256', 'sha512']` is equivalent to `['sha512']` unless SHA-512 was
|
||||
one day deemed _weaker_ than SHA-256 by user agents, which is an unlikely
|
||||
scenario. As one of the authors of the W3C spec [puts
|
||||
it](https://github.com/mozilla/srihash.org/issues/155#issuecomment-259800503):
|
||||
|
||||
> The support for multiple hashes is in the spec for backward-compatibility once
|
||||
> we introduce new hash algorithms (e.g. SHA3).
|
||||
|
||||
#### enabled
|
||||
|
||||
Default value: `"auto"`
|
||||
|
||||
One of `"auto"`, `true`, or `false`.
|
||||
|
||||
`true` means to enable the plugin and `false` means to disable it.
|
||||
|
||||
`auto` is the default and means to enable the plugin when the [Webpack
|
||||
mode](https://webpack.js.org/configuration/mode/) is `production` or
|
||||
`none` and disable it when it is `development`.
|
||||
|
||||
#### hashLoading
|
||||
|
||||
Default value: `"eager"`
|
||||
|
||||
One of `"eager"` or `"lazy"`
|
||||
|
||||
`"eager""` means that integrity hashes for all assets will be defined in the entry chunk.
|
||||
|
||||
`"lazy"` means that integrity hashes for any given asset will be defined in its direct parents
|
||||
in the chunk graph. This can lead to duplication of hashes across assets, but can significantly
|
||||
reduce the size of your entry chunk(s) if you have a large number of async chunks.
|
||||
|
||||
## Exporting `integrity` values
|
||||
|
||||
You might want to export generated integrity hashes, perhaps for use
|
||||
with SSR. We recommend
|
||||
[webpack-assets-manifest](https://github.com/webdeveric/webpack-assets-manifest)
|
||||
for this purpose. When configured with option `integrity: true` it
|
||||
will include the hashes generated by this plugin in the manifest.
|
||||
|
||||
[Example usage with webpack-assets-manifest](https://github.com/waysact/webpack-subresource-integrity/tree/main/examples/webpack-assets-manifest/).
|
||||
|
||||
## Caveats
|
||||
|
||||
### Caching
|
||||
|
||||
Using SRI presents a potential risk to the availability of your website when
|
||||
HTTP response caching is setup incorrectly. Stale asset versions are always
|
||||
problematic but SRI exacerbates the risk.
|
||||
|
||||
Without SRI, inconsequential changes (such as whitespace-only changes) don't
|
||||
matter, and your website might still look OK when a stale CSS asset is used.
|
||||
Even with a stale JS asset there's a chance your website will still be more or
|
||||
less working as expected.
|
||||
|
||||
With SRI, however, a stale asset will fail hard. This is because the browser
|
||||
won't tell the difference between a version of your asset that has been tampered
|
||||
with and one that is simply outdated: both will fail the integrity check and
|
||||
refuse to load.
|
||||
|
||||
It's therefore imperative that, if you do use caching, you use a robust setup:
|
||||
one where _any_ change in content, no matter how miniscule or inconsequential,
|
||||
will cause the cache to be invalidated.
|
||||
|
||||
With Webpack and long-term caching this means using `[contenthash]` (with
|
||||
`realContentHash`, which is enabled by default in production mode). Using
|
||||
`[contenthash]` with `realContentHash` disabled, or using a different type of
|
||||
hash placeholder (such as `[chunkhash]`) provides weaker guarantees, which is
|
||||
why this plugin will output a warning in these cases. See [issue
|
||||
#162](https://github.com/waysact/webpack-subresource-integrity/issues/162)
|
||||
for more information.
|
||||
|
||||
### Proxies
|
||||
|
||||
By its very nature, SRI can cause your page to break when assets are
|
||||
modified by a proxy. This is because SRI doesn't distinguish between
|
||||
malicious and benevolent modifications: any modification will prevent
|
||||
an asset from being loaded.
|
||||
|
||||
Notably, this issue can arise when your page is loaded through
|
||||
[Chrome Data Saver](https://developer.chrome.com/multidevice/data-compression).
|
||||
|
||||
This is only a problem when your page can be loaded with plain HTTP,
|
||||
since proxies are incapable of modifying encrypted HTTPS responses.
|
||||
|
||||
Presumably, you're looking to use SRI because you're concerned about
|
||||
security and thus your page is only served through HTTPS anyway.
|
||||
However, if you really need to use SRI and HTTP together, you should
|
||||
set the `Cache-Control: no-transform` response header. This will
|
||||
instruct all well-behaved proxies (including Chrome Data Saver) to
|
||||
refrain from modifying the assets.
|
||||
|
||||
### Preloading
|
||||
|
||||
This plugin adds the integrity attribute to `<link rel="preload">`
|
||||
tags, but preloading with SRI doesn't work as expected in current
|
||||
Chrome versions. The resource will be loaded twice, defeating the
|
||||
purpose of preloading. This problem doesn't appear to exist in
|
||||
Firefox or Safari. See [issue
|
||||
#111](https://github.com/waysact/webpack-subresource-integrity/issues/111)
|
||||
for more information.
|
||||
|
||||
### Browser support
|
||||
|
||||
Browser support for SRI is widely implemented. Your page will still
|
||||
work on browsers without support for SRI, but subresources won't be
|
||||
protected from tampering.
|
||||
|
||||
See [Can I use Subresource Integrity?](http://caniuse.com/#feat=subresource-integrity)
|
||||
|
||||
### Hot Reloading
|
||||
|
||||
This plugin can interfere with hot reloading and therefore should be
|
||||
disabled when using tools such as `webpack-dev-server`. This shouldn't
|
||||
be a problem because hot reloading is usually used only in development
|
||||
mode where SRI is not normally needed.
|
||||
|
||||
For testing SRI without setting up a full-blown web server, consider
|
||||
using a tool such as [`http-server`](https://github.com/indexzero/http-server).
|
||||
|
||||
### Safari and Assets that Require Cookies
|
||||
|
||||
As detailed in
|
||||
[Webpack Issue #6972](https://github.com/webpack/webpack/issues/6972),
|
||||
the `crossOrigin` attribute can break loading of assets in certain
|
||||
edge cases due to a bug in Safari. Since SRI requires the
|
||||
`crossOrigin` attribute to be set, you may run into this case even
|
||||
when source URL is same-origin with respect to the asset.
|
||||
|
||||
## Further Reading
|
||||
|
||||
- [MDN: Subresource Integrity](https://developer.mozilla.org/en-US/docs/Web/Security/Subresource_Integrity)
|
||||
|
||||
## License
|
||||
|
||||
Copyright (c) 2015-present Waysact Pty Ltd
|
||||
|
||||
MIT (see [LICENSE](LICENSE))
|
||||
|
||||
[tests-badge]: https://github.com/waysact/webpack-subresource-integrity/actions/workflows/test.yml/badge.svg?branch=main
|
||||
[tests-url]: https://github.com/waysact/webpack-subresource-integrity/actions
|
||||
[coverage-badge]: https://coveralls.io/repos/github/waysact/webpack-subresource-integrity/badge.svg?branch=main
|
||||
[coverage-url]: https://coveralls.io/github/waysact/webpack-subresource-integrity?branch=main
|
||||
[codeclimate-badge]: https://codeclimate.com/github/waysact/webpack-subresource-integrity/badges/gpa.svg
|
||||
[codeclimate-url]: https://codeclimate.com/github/waysact/webpack-subresource-integrity
|
||||
[license-badge]: https://img.shields.io/badge/license-MIT-blue.svg
|
||||
[license-url]: https://raw.githubusercontent.com/waysact/webpack-subresource-integrity/main/LICENSE
|
291
my-app/node_modules/webpack-subresource-integrity/index.js
generated
vendored
Executable file
291
my-app/node_modules/webpack-subresource-integrity/index.js
generated
vendored
Executable file
|
@ -0,0 +1,291 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2015-present, Waysact Pty Ltd
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SubresourceIntegrityPlugin = void 0;
|
||||
const crypto_1 = require("crypto");
|
||||
const webpack_1 = require("webpack");
|
||||
const plugin_1 = require("./plugin");
|
||||
const reporter_1 = require("./reporter");
|
||||
const util_1 = require("./util");
|
||||
const thisPluginName = "webpack-subresource-integrity";
|
||||
// https://www.w3.org/TR/2016/REC-SRI-20160623/#cryptographic-hash-functions
|
||||
const standardHashFuncNames = ["sha256", "sha384", "sha512"];
|
||||
let getHtmlWebpackPluginHooks = null;
|
||||
class AddLazySriRuntimeModule extends webpack_1.RuntimeModule {
|
||||
constructor(sriHashes, chunkName) {
|
||||
super(`webpack-subresource-integrity lazy hashes for direct children of chunk ${chunkName}`);
|
||||
this.sriHashes = sriHashes;
|
||||
}
|
||||
generate() {
|
||||
return webpack_1.Template.asString([
|
||||
`Object.assign(${util_1.sriHashVariableReference}, ${JSON.stringify(this.sriHashes)});`,
|
||||
]);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* The webpack-subresource-integrity plugin.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
class SubresourceIntegrityPlugin {
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
constructor(options = {}) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.setup = (compilation) => {
|
||||
const reporter = new reporter_1.Reporter(compilation, thisPluginName);
|
||||
if (!this.validateOptions(compilation, reporter) ||
|
||||
!this.isEnabled(compilation)) {
|
||||
return;
|
||||
}
|
||||
const plugin = new plugin_1.Plugin(compilation, this.options, reporter);
|
||||
if (typeof compilation.outputOptions.chunkLoading === "string" &&
|
||||
["require", "async-node"].includes(compilation.outputOptions.chunkLoading)) {
|
||||
reporter.warnOnce("This plugin is not useful for non-web targets.");
|
||||
return;
|
||||
}
|
||||
compilation.hooks.beforeRuntimeRequirements.tap(thisPluginName, () => {
|
||||
plugin.beforeRuntimeRequirements();
|
||||
});
|
||||
compilation.hooks.processAssets.tap({
|
||||
name: thisPluginName,
|
||||
stage: compilation.compiler.webpack.Compilation
|
||||
.PROCESS_ASSETS_STAGE_OPTIMIZE_INLINE,
|
||||
}, (records) => {
|
||||
return plugin.processAssets(records);
|
||||
});
|
||||
compilation.hooks.afterProcessAssets.tap(thisPluginName, (records) => {
|
||||
for (const chunk of compilation.chunks.values()) {
|
||||
for (const chunkFile of chunk.files) {
|
||||
if (chunkFile in records &&
|
||||
records[chunkFile].source().includes(util_1.placeholderPrefix)) {
|
||||
reporter.errorOnce(`Asset ${chunkFile} contains unresolved integrity placeholders`);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
compilation.compiler.webpack.optimize.RealContentHashPlugin.getCompilationHooks(compilation).updateHash.tap(thisPluginName, (input, oldHash) => {
|
||||
// FIXME: remove type hack pending https://github.com/webpack/webpack/pull/12642#issuecomment-784744910
|
||||
return plugin.updateHash(input, oldHash);
|
||||
});
|
||||
if (getHtmlWebpackPluginHooks) {
|
||||
getHtmlWebpackPluginHooks(compilation).beforeAssetTagGeneration.tapPromise(thisPluginName, async (pluginArgs) => {
|
||||
plugin.handleHwpPluginArgs(pluginArgs);
|
||||
return pluginArgs;
|
||||
});
|
||||
getHtmlWebpackPluginHooks(compilation).alterAssetTagGroups.tapPromise({
|
||||
name: thisPluginName,
|
||||
stage: 10000,
|
||||
}, async (data) => {
|
||||
plugin.handleHwpBodyTags(data);
|
||||
return data;
|
||||
});
|
||||
}
|
||||
const { mainTemplate } = compilation;
|
||||
mainTemplate.hooks.jsonpScript.tap(thisPluginName, (source) => plugin.addAttribute("script", source));
|
||||
mainTemplate.hooks.linkPreload.tap(thisPluginName, (source) => plugin.addAttribute("link", source));
|
||||
mainTemplate.hooks.localVars.tap(thisPluginName, (source, chunk) => {
|
||||
const allChunks = this.options.hashLoading === "lazy"
|
||||
? plugin.getChildChunksToAddToChunkManifest(chunk)
|
||||
: util_1.findChunks(chunk);
|
||||
const includedChunks = chunk.getChunkMaps(false).hash;
|
||||
if (Object.keys(includedChunks).length > 0) {
|
||||
return compilation.compiler.webpack.Template.asString([
|
||||
source,
|
||||
`${util_1.sriHashVariableReference} = ` +
|
||||
JSON.stringify(util_1.generateSriHashPlaceholders(Array.from(allChunks).filter((depChunk) => depChunk.id !== null &&
|
||||
includedChunks[depChunk.id.toString()]), this.options.hashFuncNames)) +
|
||||
";",
|
||||
]);
|
||||
}
|
||||
return source;
|
||||
});
|
||||
if (this.options.hashLoading === "lazy") {
|
||||
compilation.hooks.additionalChunkRuntimeRequirements.tap(thisPluginName, (chunk) => {
|
||||
var _a;
|
||||
const childChunks = plugin.getChildChunksToAddToChunkManifest(chunk);
|
||||
if (childChunks.size > 0 && !chunk.hasRuntime()) {
|
||||
compilation.addRuntimeModule(chunk, new AddLazySriRuntimeModule(util_1.generateSriHashPlaceholders(childChunks, this.options.hashFuncNames), (_a = chunk.name) !== null && _a !== void 0 ? _a : chunk.id));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.validateOptions = (compilation, reporter) => {
|
||||
if (this.isEnabled(compilation) &&
|
||||
!compilation.compiler.options.output.crossOriginLoading) {
|
||||
reporter.warnOnce('SRI requires a cross-origin policy, defaulting to "anonymous". ' +
|
||||
"Set webpack option output.crossOriginLoading to a value other than false " +
|
||||
"to make this warning go away. " +
|
||||
"See https://w3c.github.io/webappsec-subresource-integrity/#cross-origin-data-leakage");
|
||||
}
|
||||
return (this.validateHashFuncNames(reporter) && this.validateHashLoading(reporter));
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.validateHashFuncNames = (reporter) => {
|
||||
if (!Array.isArray(this.options.hashFuncNames)) {
|
||||
reporter.error("options.hashFuncNames must be an array of hash function names, " +
|
||||
"instead got '" +
|
||||
this.options.hashFuncNames +
|
||||
"'.");
|
||||
return false;
|
||||
}
|
||||
else if (this.options.hashFuncNames.length === 0) {
|
||||
reporter.error("Must specify at least one hash function name.");
|
||||
return false;
|
||||
}
|
||||
else if (!this.options.hashFuncNames.every(this.validateHashFuncName.bind(this, reporter))) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
this.warnStandardHashFunc(reporter);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.validateHashLoading = (reporter) => {
|
||||
const supportedHashLoadingOptions = Object.freeze(["eager", "lazy"]);
|
||||
if (supportedHashLoadingOptions.includes(this.options.hashLoading)) {
|
||||
return true;
|
||||
}
|
||||
const optionsStr = supportedHashLoadingOptions
|
||||
.map((opt) => `'${opt}'`)
|
||||
.join(", ");
|
||||
reporter.error(`options.hashLoading must be one of ${optionsStr}, instead got '${this.options.hashLoading}'`);
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.warnStandardHashFunc = (reporter) => {
|
||||
let foundStandardHashFunc = false;
|
||||
for (let i = 0; i < this.options.hashFuncNames.length; i += 1) {
|
||||
if (standardHashFuncNames.indexOf(this.options.hashFuncNames[i]) >= 0) {
|
||||
foundStandardHashFunc = true;
|
||||
}
|
||||
}
|
||||
if (!foundStandardHashFunc) {
|
||||
reporter.warnOnce("It is recommended that at least one hash function is part of the set " +
|
||||
"for which support is mandated by the specification. " +
|
||||
"These are: " +
|
||||
standardHashFuncNames.join(", ") +
|
||||
". " +
|
||||
"See http://www.w3.org/TR/SRI/#cryptographic-hash-functions for more information.");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.validateHashFuncName = (reporter, hashFuncName) => {
|
||||
if (typeof hashFuncName !== "string" &&
|
||||
!(hashFuncName instanceof String)) {
|
||||
reporter.error("options.hashFuncNames must be an array of hash function names, " +
|
||||
"but contained " +
|
||||
hashFuncName +
|
||||
".");
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
crypto_1.createHash(hashFuncName);
|
||||
}
|
||||
catch (error) {
|
||||
reporter.error("Cannot use hash function '" + hashFuncName + "': " + error.message);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (typeof options !== "object") {
|
||||
throw new Error("webpack-subresource-integrity: argument must be an object");
|
||||
}
|
||||
this.options = {
|
||||
hashFuncNames: ["sha384"],
|
||||
enabled: "auto",
|
||||
hashLoading: "eager",
|
||||
...options,
|
||||
};
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
isEnabled(compilation) {
|
||||
if (this.options.enabled === "auto") {
|
||||
return compilation.options.mode !== "development";
|
||||
}
|
||||
return this.options.enabled;
|
||||
}
|
||||
apply(compiler) {
|
||||
compiler.hooks.beforeCompile.tapPromise(thisPluginName, async () => {
|
||||
try {
|
||||
getHtmlWebpackPluginHooks = (await Promise.resolve().then(() => __importStar(require("html-webpack-plugin"))))
|
||||
.default.getHooks;
|
||||
}
|
||||
catch (e) {
|
||||
if (e.code !== "MODULE_NOT_FOUND") {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
compiler.hooks.afterPlugins.tap(thisPluginName, (compiler) => {
|
||||
compiler.hooks.thisCompilation.tap({
|
||||
name: thisPluginName,
|
||||
stage: -10000,
|
||||
}, (compilation) => {
|
||||
this.setup(compilation);
|
||||
});
|
||||
compiler.hooks.compilation.tap(thisPluginName, (compilation) => {
|
||||
compilation.hooks.statsFactory.tap(thisPluginName, (statsFactory) => {
|
||||
statsFactory.hooks.extract
|
||||
.for("asset")
|
||||
.tap(thisPluginName, (object, asset) => {
|
||||
var _a;
|
||||
const contenthash = (_a = asset.info) === null || _a === void 0 ? void 0 : _a.contenthash;
|
||||
if (contenthash) {
|
||||
const shaHashes = (Array.isArray(contenthash) ? contenthash : [contenthash]).filter((hash) => String(hash).match(/^sha[0-9]+-/));
|
||||
if (shaHashes.length > 0) {
|
||||
object.integrity =
|
||||
shaHashes.join(" ");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
exports.SubresourceIntegrityPlugin = SubresourceIntegrityPlugin;
|
||||
//# sourceMappingURL=index.js.map
|
1
my-app/node_modules/webpack-subresource-integrity/index.js.map
generated
vendored
Executable file
1
my-app/node_modules/webpack-subresource-integrity/index.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
94
my-app/node_modules/webpack-subresource-integrity/package.json
generated
vendored
Executable file
94
my-app/node_modules/webpack-subresource-integrity/package.json
generated
vendored
Executable file
|
@ -0,0 +1,94 @@
|
|||
{
|
||||
"name": "webpack-subresource-integrity",
|
||||
"version": "5.1.0",
|
||||
"description": "Webpack plugin for enabling Subresource Integrity",
|
||||
"author": "Julian Scheid <julian@evergiving.com>",
|
||||
"license": "MIT",
|
||||
"homepage": "https://github.com/waysact/webpack-subresource-integrity/tree/main/webpack-subresource-integrity#readme",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/waysact/webpack-subresource-integrity.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/waysact/webpack-subresource-integrity/issues"
|
||||
},
|
||||
"keywords": [
|
||||
"webpack",
|
||||
"plugin",
|
||||
"sri",
|
||||
"subresource",
|
||||
"integrity",
|
||||
"html-webpack-plugin"
|
||||
],
|
||||
"main": "./index.js",
|
||||
"types": "./webpack-subresource-integrity-public.d.ts",
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
},
|
||||
"dependencies": {
|
||||
"typed-assert": "^1.0.8"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"html-webpack-plugin": ">= 5.0.0-beta.1 < 6",
|
||||
"webpack": "^5.12.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"html-webpack-plugin": {
|
||||
"optional": true
|
||||
}
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/api-extractor": "^7.18.1",
|
||||
"@tsconfig/node12": "^1.0.9",
|
||||
"@types/cross-spawn": "^6.0.2",
|
||||
"@types/jest": "^26.0.24",
|
||||
"@types/json-schema": "^7.0.8",
|
||||
"@types/lodash": "^4.14.171",
|
||||
"@types/node": "^14.17.5",
|
||||
"@types/rimraf": "^3.0.1",
|
||||
"@types/tmp": "^0.2.1",
|
||||
"@typescript-eslint/eslint-plugin": "4.28.2",
|
||||
"@typescript-eslint/parser": "^4.28.2",
|
||||
"cross-spawn": "^7.0.3",
|
||||
"eslint": "^7.30.0",
|
||||
"eslint-config-prettier": "^6.15.0",
|
||||
"eslint-plugin-import": "2.23.4",
|
||||
"eslint-plugin-jest": "^24.3.6",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "^3.4.0",
|
||||
"eslint-plugin-promise": "4.3.1",
|
||||
"eslint-plugin-standard": "4.1.0",
|
||||
"html-webpack-plugin": ">= 5.0.0-beta.1",
|
||||
"jest": "^26.6.3",
|
||||
"lodash": "^4.17.21",
|
||||
"memfs": "^3.2.0",
|
||||
"nyc": "*",
|
||||
"prettier": "^2.3.2",
|
||||
"rimraf": "^3.0.2",
|
||||
"tapable": "^2.2.0",
|
||||
"tmp": "^0.2.1",
|
||||
"tmp-promise": "^3.0.2",
|
||||
"ts-jest": "^26.5.6",
|
||||
"typescript": "^4.3.5",
|
||||
"webpack": "^5.44.0"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "tsc && api-extractor run --local"
|
||||
},
|
||||
"files": [
|
||||
"/index.js",
|
||||
"/index.js.map",
|
||||
"/plugin.js",
|
||||
"/plugin.js.map",
|
||||
"/reporter.js",
|
||||
"/reporter.js.map",
|
||||
"/util.js",
|
||||
"/util.js.map",
|
||||
"/types.js",
|
||||
"/types.js.map",
|
||||
"/webpack-subresource-integrity-public.d.ts",
|
||||
"/tsdoc-metadata.json",
|
||||
"/README.md",
|
||||
"/LICENSE"
|
||||
]
|
||||
}
|
291
my-app/node_modules/webpack-subresource-integrity/plugin.js
generated
vendored
Executable file
291
my-app/node_modules/webpack-subresource-integrity/plugin.js
generated
vendored
Executable file
|
@ -0,0 +1,291 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2015-present, Waysact Pty Ltd
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Plugin = void 0;
|
||||
const path_1 = require("path");
|
||||
const fs_1 = require("fs");
|
||||
const assert = __importStar(require("typed-assert"));
|
||||
const util_1 = require("./util");
|
||||
const assetTypeIntegrityKeys = [
|
||||
["js", "jsIntegrity"],
|
||||
["css", "cssIntegrity"],
|
||||
];
|
||||
class Plugin {
|
||||
constructor(compilation, options, reporter) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.assetIntegrity = new Map();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.inverseAssetIntegrity = new Map();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.hwpPublicPath = null;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.sortedSccChunks = [];
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.chunkManifest = new Map();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.hashByChunkId = new Map();
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.addMissingIntegrityHashes = (assets) => {
|
||||
Object.keys(assets).forEach((assetKey) => {
|
||||
const asset = assets[assetKey];
|
||||
let source;
|
||||
try {
|
||||
source = asset.source();
|
||||
}
|
||||
catch (_) {
|
||||
return;
|
||||
}
|
||||
this.updateAssetIntegrity(assetKey, util_1.computeIntegrity(this.options.hashFuncNames, source));
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.replaceAsset = (compiler, assets, hashByChunkId, chunkFile) => {
|
||||
const oldSource = assets[chunkFile].source();
|
||||
const hashFuncNames = this.options.hashFuncNames;
|
||||
const newAsset = new compiler.webpack.sources.ReplaceSource(assets[chunkFile], chunkFile);
|
||||
Array.from(hashByChunkId.entries()).forEach((idAndHash) => {
|
||||
const magicMarker = util_1.makePlaceholder(hashFuncNames, idAndHash[0]);
|
||||
const magicMarkerPos = oldSource.indexOf(magicMarker);
|
||||
if (magicMarkerPos >= 0) {
|
||||
newAsset.replace(magicMarkerPos, magicMarkerPos + magicMarker.length - 1, idAndHash[1], chunkFile);
|
||||
}
|
||||
});
|
||||
assets[chunkFile] = newAsset;
|
||||
return newAsset;
|
||||
};
|
||||
this.warnAboutLongTermCaching = (assetInfo) => {
|
||||
if ((assetInfo.fullhash ||
|
||||
assetInfo.chunkhash ||
|
||||
assetInfo.modulehash ||
|
||||
assetInfo.contenthash) &&
|
||||
!(assetInfo.contenthash &&
|
||||
this.compilation.compiler.options.optimization.realContentHash)) {
|
||||
this.reporter.warnOnce("Using [hash], [fullhash], [modulehash], or [chunkhash] is dangerous \
|
||||
with SRI. The same is true for [contenthash] when realContentHash is disabled. \
|
||||
Use [contenthash] and ensure realContentHash is enabled. See the README for \
|
||||
more information.");
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.processChunk = (chunk, assets) => {
|
||||
Array.from(util_1.findChunks(chunk))
|
||||
.reverse()
|
||||
.forEach((chunk) => this.processChunkAssets(chunk, assets));
|
||||
};
|
||||
this.processChunkAssets = (childChunk, assets) => {
|
||||
const files = Array.from(childChunk.files);
|
||||
files.forEach((sourcePath) => {
|
||||
if (assets[sourcePath]) {
|
||||
this.warnIfHotUpdate(assets[sourcePath].source());
|
||||
const newAsset = this.replaceAsset(this.compilation.compiler, assets, this.hashByChunkId, sourcePath);
|
||||
const integrity = util_1.computeIntegrity(this.options.hashFuncNames, newAsset.source());
|
||||
if (childChunk.id !== null) {
|
||||
this.hashByChunkId.set(childChunk.id, integrity);
|
||||
}
|
||||
this.updateAssetIntegrity(sourcePath, integrity);
|
||||
this.compilation.updateAsset(sourcePath, (x) => x, (assetInfo) => {
|
||||
if (!assetInfo) {
|
||||
return undefined;
|
||||
}
|
||||
this.warnAboutLongTermCaching(assetInfo);
|
||||
return {
|
||||
...assetInfo,
|
||||
contenthash: Array.isArray(assetInfo.contenthash)
|
||||
? [...new Set([...assetInfo.contenthash, integrity])]
|
||||
: assetInfo.contenthash
|
||||
? [assetInfo.contenthash, integrity]
|
||||
: integrity,
|
||||
};
|
||||
});
|
||||
}
|
||||
else {
|
||||
this.reporter.warnOnce(`No asset found for source path '${sourcePath}', options are ${Object.keys(assets).join(", ")}`);
|
||||
}
|
||||
});
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.addAttribute = (elName, source) => {
|
||||
if (!this.compilation.outputOptions.crossOriginLoading) {
|
||||
this.reporter.errorOnce("webpack option output.crossOriginLoading not set, code splitting will not work!");
|
||||
}
|
||||
return this.compilation.compiler.webpack.Template.asString([
|
||||
source,
|
||||
elName + `.integrity = ${util_1.sriHashVariableReference}[chunkId];`,
|
||||
elName +
|
||||
".crossOrigin = " +
|
||||
JSON.stringify(this.compilation.outputOptions.crossOriginLoading) +
|
||||
";",
|
||||
]);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.processAssets = (assets) => {
|
||||
if (this.options.hashLoading === "lazy") {
|
||||
for (const scc of this.sortedSccChunks) {
|
||||
for (const chunk of scc.nodes) {
|
||||
this.processChunkAssets(chunk, assets);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Array.from(this.compilation.chunks)
|
||||
.filter((chunk) => chunk.hasRuntime())
|
||||
.forEach((chunk) => {
|
||||
this.processChunk(chunk, assets);
|
||||
});
|
||||
}
|
||||
this.addMissingIntegrityHashes(assets);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.hwpAssetPath = (src) => {
|
||||
assert.isNotNull(this.hwpPublicPath);
|
||||
return path_1.relative(this.hwpPublicPath, src);
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.getIntegrityChecksumForAsset = (assets, src) => {
|
||||
if (this.assetIntegrity.has(src)) {
|
||||
return this.assetIntegrity.get(src);
|
||||
}
|
||||
const normalizedSrc = util_1.normalizePath(src);
|
||||
const normalizedKey = Object.keys(assets).find((assetKey) => util_1.normalizePath(assetKey) === normalizedSrc);
|
||||
if (normalizedKey) {
|
||||
return this.assetIntegrity.get(normalizedKey);
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.processTag = (tag) => {
|
||||
if (tag.attributes &&
|
||||
Object.prototype.hasOwnProperty.call(tag.attributes, "integrity")) {
|
||||
return;
|
||||
}
|
||||
const tagSrc = util_1.getTagSrc(tag);
|
||||
if (!tagSrc) {
|
||||
return;
|
||||
}
|
||||
const src = this.hwpAssetPath(tagSrc);
|
||||
tag.attributes.integrity =
|
||||
this.getIntegrityChecksumForAsset(this.compilation.assets, src) ||
|
||||
util_1.computeIntegrity(this.options.hashFuncNames, fs_1.readFileSync(path_1.join(this.compilation.compiler.outputPath, src)));
|
||||
tag.attributes.crossorigin =
|
||||
this.compilation.compiler.options.output.crossOriginLoading ||
|
||||
"anonymous";
|
||||
};
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.beforeRuntimeRequirements = () => {
|
||||
if (this.options.hashLoading === "lazy") {
|
||||
const [sortedSccChunks, chunkManifest] = util_1.getChunkToManifestMap(this.compilation.chunks);
|
||||
this.sortedSccChunks = sortedSccChunks;
|
||||
this.chunkManifest = chunkManifest;
|
||||
}
|
||||
this.hashByChunkId.clear();
|
||||
};
|
||||
this.handleHwpPluginArgs = ({ assets }) => {
|
||||
this.hwpPublicPath = assets.publicPath;
|
||||
assetTypeIntegrityKeys.forEach(([a, b]) => {
|
||||
if (b) {
|
||||
assets[b] = assets[a]
|
||||
.map((filePath) => this.getIntegrityChecksumForAsset(this.compilation.assets, this.hwpAssetPath(filePath)))
|
||||
.filter(util_1.notNil);
|
||||
}
|
||||
});
|
||||
};
|
||||
this.updateHash = (input, oldHash) => {
|
||||
const assetKey = this.inverseAssetIntegrity.get(oldHash);
|
||||
if (assetKey && input.length === 1) {
|
||||
const newIntegrity = util_1.computeIntegrity(this.options.hashFuncNames, input[0]);
|
||||
this.inverseAssetIntegrity.delete(oldHash);
|
||||
this.assetIntegrity.delete(assetKey);
|
||||
this.updateAssetIntegrity(assetKey, newIntegrity);
|
||||
return newIntegrity;
|
||||
}
|
||||
return undefined;
|
||||
};
|
||||
this.handleHwpBodyTags = ({ headTags, bodyTags, }) => {
|
||||
this.addMissingIntegrityHashes(this.compilation.assets);
|
||||
headTags
|
||||
.concat(bodyTags)
|
||||
.forEach((tag) => this.processTag(tag));
|
||||
};
|
||||
this.compilation = compilation;
|
||||
this.options = options;
|
||||
this.reporter = reporter;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
warnIfHotUpdate(source) {
|
||||
if (source.indexOf("webpackHotUpdate") >= 0) {
|
||||
this.reporter.warnOnce("webpack-subresource-integrity may interfere with hot reloading. " +
|
||||
"Consider disabling this plugin in development mode.");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
updateAssetIntegrity(assetKey, integrity) {
|
||||
if (!this.assetIntegrity.has(assetKey)) {
|
||||
this.assetIntegrity.set(assetKey, integrity);
|
||||
this.inverseAssetIntegrity.set(integrity, assetKey);
|
||||
}
|
||||
}
|
||||
getChildChunksToAddToChunkManifest(chunk) {
|
||||
var _a;
|
||||
return (_a = this.chunkManifest.get(chunk)) !== null && _a !== void 0 ? _a : new Set();
|
||||
}
|
||||
}
|
||||
exports.Plugin = Plugin;
|
||||
//# sourceMappingURL=plugin.js.map
|
1
my-app/node_modules/webpack-subresource-integrity/plugin.js.map
generated
vendored
Executable file
1
my-app/node_modules/webpack-subresource-integrity/plugin.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
57
my-app/node_modules/webpack-subresource-integrity/reporter.js
generated
vendored
Executable file
57
my-app/node_modules/webpack-subresource-integrity/reporter.js
generated
vendored
Executable file
|
@ -0,0 +1,57 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2015-present, Waysact Pty Ltd
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Reporter = void 0;
|
||||
class Reporter {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
constructor(compilation, pluginName) {
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
this.emittedMessages = new Set();
|
||||
this.compilation = compilation;
|
||||
this.pluginName = pluginName;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
emitMessage(messages, message) {
|
||||
messages.push(new Error(`${this.pluginName}: ${message}`));
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
emitMessageOnce(messages, message) {
|
||||
if (!this.emittedMessages.has(message)) {
|
||||
this.emittedMessages.add(message);
|
||||
this.emitMessage(messages, message);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
warnOnce(message) {
|
||||
this.emitMessageOnce(this.compilation.warnings, message);
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
errorOnce(message) {
|
||||
this.emitMessageOnce(this.compilation.errors, message);
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
error(message) {
|
||||
this.emitMessage(this.compilation.errors, message);
|
||||
}
|
||||
}
|
||||
exports.Reporter = Reporter;
|
||||
//# sourceMappingURL=reporter.js.map
|
1
my-app/node_modules/webpack-subresource-integrity/reporter.js.map
generated
vendored
Executable file
1
my-app/node_modules/webpack-subresource-integrity/reporter.js.map
generated
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["reporter.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAIH,MAAa,QAAQ;IAgBnB;;OAEG;IACH,YAAmB,WAAwB,EAAE,UAAkB;QAR/D;;WAEG;QACK,oBAAe,GAAgB,IAAI,GAAG,EAAE,CAAC;QAM/C,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,WAAW,CAAC,QAAiB,EAAE,OAAe;QACpD,QAAQ,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,UAAU,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,QAAiB,EAAE,OAAe;QACxD,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE;YACtC,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;SACrC;IACH,CAAC;IAED;;OAEG;IACI,QAAQ,CAAC,OAAe;QAC7B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED;;OAEG;IACI,SAAS,CAAC,OAAe;QAC9B,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,OAAe;QAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrD,CAAC;CACF;AA7DD,4BA6DC"}
|
11
my-app/node_modules/webpack-subresource-integrity/tsdoc-metadata.json
generated
vendored
Executable file
11
my-app/node_modules/webpack-subresource-integrity/tsdoc-metadata.json
generated
vendored
Executable file
|
@ -0,0 +1,11 @@
|
|||
// This file is read by tools that parse documentation comments conforming to the TSDoc standard.
|
||||
// It should be published with your NPM package. It should not be tracked by Git.
|
||||
{
|
||||
"tsdocVersion": "0.12",
|
||||
"toolPackages": [
|
||||
{
|
||||
"packageName": "@microsoft/api-extractor",
|
||||
"packageVersion": "7.18.1"
|
||||
}
|
||||
]
|
||||
}
|
3
my-app/node_modules/webpack-subresource-integrity/types.js
generated
vendored
Executable file
3
my-app/node_modules/webpack-subresource-integrity/types.js
generated
vendored
Executable file
|
@ -0,0 +1,3 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=types.js.map
|
1
my-app/node_modules/webpack-subresource-integrity/types.js.map
generated
vendored
Executable file
1
my-app/node_modules/webpack-subresource-integrity/types.js.map
generated
vendored
Executable file
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"types.js","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":""}
|
326
my-app/node_modules/webpack-subresource-integrity/util.js
generated
vendored
Executable file
326
my-app/node_modules/webpack-subresource-integrity/util.js
generated
vendored
Executable file
|
@ -0,0 +1,326 @@
|
|||
"use strict";
|
||||
/**
|
||||
* Copyright (c) 2015-present, Waysact Pty Ltd
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getChunkToManifestMap = exports.buildTopologicallySortedChunkGraph = exports.generateSriHashPlaceholders = exports.notNil = exports.findChunks = exports.makePlaceholder = exports.computeIntegrity = exports.placeholderPrefix = exports.normalizePath = exports.getTagSrc = exports.assert = exports.sriHashVariableReference = void 0;
|
||||
const crypto_1 = require("crypto");
|
||||
const path_1 = require("path");
|
||||
exports.sriHashVariableReference = "__webpack_require__.sriHashes";
|
||||
function assert(value, message) {
|
||||
if (!value) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
exports.assert = assert;
|
||||
function getTagSrc(tag) {
|
||||
if (!["script", "link"].includes(tag.tagName) || !tag.attributes) {
|
||||
return undefined;
|
||||
}
|
||||
if (typeof tag.attributes.href === "string") {
|
||||
return tag.attributes.href;
|
||||
}
|
||||
if (typeof tag.attributes.src === "string") {
|
||||
return tag.attributes.src;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
exports.getTagSrc = getTagSrc;
|
||||
const normalizePath = (p) => p.replace(/\?.*$/, "").split(path_1.sep).join("/");
|
||||
exports.normalizePath = normalizePath;
|
||||
exports.placeholderPrefix = "*-*-*-CHUNK-SRI-HASH-";
|
||||
const computeIntegrity = (hashFuncNames, source) => {
|
||||
const result = hashFuncNames
|
||||
.map((hashFuncName) => hashFuncName +
|
||||
"-" +
|
||||
crypto_1.createHash(hashFuncName)
|
||||
.update(typeof source === "string" ? Buffer.from(source, "utf-8") : source)
|
||||
.digest("base64"))
|
||||
.join(" ");
|
||||
return result;
|
||||
};
|
||||
exports.computeIntegrity = computeIntegrity;
|
||||
const makePlaceholder = (hashFuncNames, id) => {
|
||||
const placeholder = `${exports.placeholderPrefix}${id}`;
|
||||
const filler = exports.computeIntegrity(hashFuncNames, placeholder);
|
||||
return exports.placeholderPrefix + filler.substring(exports.placeholderPrefix.length);
|
||||
};
|
||||
exports.makePlaceholder = makePlaceholder;
|
||||
function findChunks(chunk) {
|
||||
const allChunks = new Set();
|
||||
const groupsVisited = new Set();
|
||||
function addIfNotExist(set, item) {
|
||||
if (set.has(item))
|
||||
return true;
|
||||
set.add(item);
|
||||
return false;
|
||||
}
|
||||
(function recurseChunk(childChunk) {
|
||||
function recurseGroup(group) {
|
||||
if (addIfNotExist(groupsVisited, group.id))
|
||||
return;
|
||||
group.chunks.forEach(recurseChunk);
|
||||
group.childrenIterable.forEach(recurseGroup);
|
||||
}
|
||||
if (addIfNotExist(allChunks, childChunk))
|
||||
return;
|
||||
Array.from(childChunk.groupsIterable).forEach(recurseGroup);
|
||||
})(chunk);
|
||||
return allChunks;
|
||||
}
|
||||
exports.findChunks = findChunks;
|
||||
function notNil(value) {
|
||||
return value !== null && value !== undefined;
|
||||
}
|
||||
exports.notNil = notNil;
|
||||
function generateSriHashPlaceholders(chunks, hashFuncNames) {
|
||||
return Array.from(chunks).reduce((sriHashes, depChunk) => {
|
||||
if (depChunk.id) {
|
||||
sriHashes[depChunk.id] = exports.makePlaceholder(hashFuncNames, depChunk.id);
|
||||
}
|
||||
return sriHashes;
|
||||
}, {});
|
||||
}
|
||||
exports.generateSriHashPlaceholders = generateSriHashPlaceholders;
|
||||
function* intersect(sets) {
|
||||
const { value: initialSet } = sets[Symbol.iterator]().next();
|
||||
if (!initialSet) {
|
||||
return;
|
||||
}
|
||||
initialSetLoop: for (const item of initialSet) {
|
||||
for (const set of sets) {
|
||||
if (!set.has(item)) {
|
||||
continue initialSetLoop;
|
||||
}
|
||||
}
|
||||
yield item;
|
||||
}
|
||||
}
|
||||
function* map(items, fn) {
|
||||
for (const item of items) {
|
||||
yield fn(item);
|
||||
}
|
||||
}
|
||||
function* flatMap(collections, fn) {
|
||||
for (const item of collections) {
|
||||
for (const result of fn(item)) {
|
||||
yield result;
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Tarjan's strongly connected components algorithm
|
||||
* https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm
|
||||
*/
|
||||
function createDAGfromGraph({ vertices, edges, }) {
|
||||
var _a;
|
||||
let index = 0;
|
||||
const stack = [];
|
||||
const vertexMetadata = new Map(map(vertices, (vertex) => [vertex, {}]));
|
||||
const stronglyConnectedComponents = new Set();
|
||||
function strongConnect(vertex) {
|
||||
var _a, _b;
|
||||
// Set the depth index for v to the smallest unused index
|
||||
const vertexData = vertexMetadata.get(vertex);
|
||||
assert(vertexData, "Vertex metadata missing");
|
||||
vertexData.index = index;
|
||||
vertexData.lowlink = index;
|
||||
index++;
|
||||
stack.push(vertex);
|
||||
vertexData.onstack = true;
|
||||
for (const child of (_a = edges.get(vertex)) !== null && _a !== void 0 ? _a : []) {
|
||||
const childData = vertexMetadata.get(child);
|
||||
assert(childData, "Child vertex metadata missing");
|
||||
if (childData.index === undefined) {
|
||||
// Child has not yet been visited; recurse on it
|
||||
strongConnect(child);
|
||||
vertexData.lowlink = Math.min(vertexData.lowlink, (_b = childData.lowlink) !== null && _b !== void 0 ? _b : Infinity);
|
||||
}
|
||||
else if (childData.onstack) {
|
||||
// Child is in stack and hence in the current SCC
|
||||
// If child is not on stack, then (vertex, child) is an edge pointing to an SCC already found and must be ignored
|
||||
// Note: The next line may look odd - but is correct.
|
||||
// It says childData.index not childData.lowlink; that is deliberate and from the original paper
|
||||
vertexData.lowlink = Math.min(vertexData.lowlink, childData.index);
|
||||
}
|
||||
}
|
||||
// If vertex is a root node, pop the stack and generate an SCC
|
||||
if (vertexData.index === vertexData.lowlink) {
|
||||
const newStronglyConnectedComponent = { nodes: new Set() };
|
||||
let currentNode;
|
||||
do {
|
||||
currentNode = stack.pop();
|
||||
assert(currentNode, "Working stack was empty");
|
||||
const metadata = vertexMetadata.get(currentNode);
|
||||
assert(metadata, "All nodes on stack should have metadata");
|
||||
metadata.onstack = false;
|
||||
newStronglyConnectedComponent.nodes.add(currentNode);
|
||||
} while (currentNode !== vertex);
|
||||
stronglyConnectedComponents.add(newStronglyConnectedComponent);
|
||||
}
|
||||
}
|
||||
for (const vertex of vertices) {
|
||||
const data = vertexMetadata.get(vertex);
|
||||
assert(data, "Vertex metadata not found");
|
||||
if (data.index === undefined) {
|
||||
strongConnect(vertex);
|
||||
}
|
||||
}
|
||||
// Now that all SCCs have been identified, rebuild the graph
|
||||
const vertexToSCCMap = new Map();
|
||||
const sccEdges = new Map();
|
||||
for (const scc of stronglyConnectedComponents) {
|
||||
for (const vertex of scc.nodes) {
|
||||
vertexToSCCMap.set(vertex, scc);
|
||||
}
|
||||
}
|
||||
for (const scc of stronglyConnectedComponents) {
|
||||
const childSCCNodes = new Set();
|
||||
for (const vertex of scc.nodes) {
|
||||
for (const childVertex of (_a = edges.get(vertex)) !== null && _a !== void 0 ? _a : []) {
|
||||
const childScc = vertexToSCCMap.get(childVertex);
|
||||
if (childScc && childScc !== scc) {
|
||||
childSCCNodes.add(childScc);
|
||||
}
|
||||
}
|
||||
}
|
||||
sccEdges.set(scc, childSCCNodes);
|
||||
}
|
||||
return { vertices: stronglyConnectedComponents, edges: sccEdges };
|
||||
}
|
||||
// This implementation assumes a directed acyclic graph (such as one produced by createDAGfromGraph),
|
||||
// and does not attempt to detect cycles
|
||||
function topologicalSort({ vertices, edges }) {
|
||||
const sortedItems = [];
|
||||
const seenNodes = new Set();
|
||||
function visit(node) {
|
||||
var _a;
|
||||
if (seenNodes.has(node)) {
|
||||
return;
|
||||
}
|
||||
seenNodes.add(node);
|
||||
for (const child of (_a = edges.get(node)) !== null && _a !== void 0 ? _a : []) {
|
||||
visit(child);
|
||||
}
|
||||
sortedItems.push(node);
|
||||
}
|
||||
for (const vertex of vertices) {
|
||||
visit(vertex);
|
||||
}
|
||||
return sortedItems;
|
||||
}
|
||||
function buildTopologicallySortedChunkGraph(chunks) {
|
||||
var _a;
|
||||
const vertices = new Set();
|
||||
const edges = new Map();
|
||||
// Chunks should have *all* chunks, not simply entry chunks
|
||||
for (const vertex of chunks) {
|
||||
if (vertices.has(vertex)) {
|
||||
continue;
|
||||
}
|
||||
vertices.add(vertex);
|
||||
edges.set(vertex, new Set());
|
||||
for (const vertexGroup of vertex.groupsIterable) {
|
||||
for (const childGroup of vertexGroup.childrenIterable) {
|
||||
for (const childChunk of childGroup.chunks) {
|
||||
(_a = edges.get(vertex)) === null || _a === void 0 ? void 0 : _a.add(childChunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const dag = createDAGfromGraph({ vertices, edges });
|
||||
const sortedVertices = topologicalSort(dag);
|
||||
const chunkToSccMap = new Map(flatMap(dag.vertices, (scc) => map(scc.nodes, (chunk) => [chunk, scc])));
|
||||
return [sortedVertices, dag, chunkToSccMap];
|
||||
}
|
||||
exports.buildTopologicallySortedChunkGraph = buildTopologicallySortedChunkGraph;
|
||||
function getChunkToManifestMap(chunks) {
|
||||
var _a;
|
||||
const [sortedVertices, , chunkToSccMap] = buildTopologicallySortedChunkGraph(chunks);
|
||||
// This map tracks which hashes a chunk group has in its manifest and the intersection
|
||||
// of all its parents (and intersection of all their parents, etc.)
|
||||
// This is meant as a guarantee that the hash for a given chunk is handled by a chunk group
|
||||
// or its parents regardless of the tree traversal used from the roots
|
||||
const hashesByChunkGroupAndParents = new Map();
|
||||
// A map of what child chunks a given chunk should contain hashes for
|
||||
const chunkManifest = new Map();
|
||||
function intersectSets(setsToIntersect) {
|
||||
return new Set(intersect(setsToIntersect));
|
||||
}
|
||||
function findIntersectionOfParentSets(chunk) {
|
||||
var _a;
|
||||
const setsToIntersect = [];
|
||||
for (const group of chunk.groupsIterable) {
|
||||
for (const parent of group.parentsIterable) {
|
||||
setsToIntersect.push((_a = hashesByChunkGroupAndParents.get(parent)) !== null && _a !== void 0 ? _a : new Set());
|
||||
}
|
||||
}
|
||||
return intersectSets(setsToIntersect);
|
||||
}
|
||||
function getChildChunksToAddToChunkManifest(chunk) {
|
||||
var _a;
|
||||
const childChunks = new Set();
|
||||
const chunkSCC = chunkToSccMap.get(chunk);
|
||||
for (const chunkGroup of chunk.groupsIterable) {
|
||||
if (chunkGroup.chunks[chunkGroup.chunks.length - 1] !== chunk) {
|
||||
// Only add sri hashes for one chunk per chunk group,
|
||||
// where the last chunk in the group is the primary chunk
|
||||
continue;
|
||||
}
|
||||
for (const childGroup of chunkGroup.childrenIterable) {
|
||||
for (const childChunk of childGroup.chunks) {
|
||||
const childChunkSCC = chunkToSccMap.get(childChunk);
|
||||
if (childChunkSCC === chunkSCC) {
|
||||
// Don't include your own SCC.
|
||||
// Your parent will have the hashes for your SCC siblings
|
||||
continue;
|
||||
}
|
||||
for (const childChunkSccNode of (_a = childChunkSCC === null || childChunkSCC === void 0 ? void 0 : childChunkSCC.nodes) !== null && _a !== void 0 ? _a : []) {
|
||||
childChunks.add(childChunkSccNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const parentManifest = findIntersectionOfParentSets(chunk);
|
||||
for (const manifestEntry of parentManifest) {
|
||||
childChunks.delete(manifestEntry);
|
||||
}
|
||||
return childChunks;
|
||||
}
|
||||
// We want to walk from the root nodes down to the leaves
|
||||
for (let i = sortedVertices.length - 1; i >= 0; i--) {
|
||||
const scc = sortedVertices[i];
|
||||
for (const chunk of scc.nodes) {
|
||||
const manifest = getChildChunksToAddToChunkManifest(chunk);
|
||||
const combinedParentManifest = findIntersectionOfParentSets(chunk);
|
||||
for (const chunk of manifest) {
|
||||
if (combinedParentManifest.has(chunk)) {
|
||||
manifest.delete(chunk);
|
||||
}
|
||||
else {
|
||||
combinedParentManifest.add(chunk);
|
||||
}
|
||||
}
|
||||
chunkManifest.set(chunk, manifest);
|
||||
for (const group of chunk.groupsIterable) {
|
||||
// Get intersection of all parent manifests
|
||||
const groupCombinedManifest = intersectSets(map(group.parentsIterable, (parent) => { var _a; return (_a = hashesByChunkGroupAndParents.get(parent)) !== null && _a !== void 0 ? _a : new Set(); }));
|
||||
// Add this chunk's manifest
|
||||
for (const chunk of manifest) {
|
||||
groupCombinedManifest.add(chunk);
|
||||
}
|
||||
// Add any existing manifests part of the group
|
||||
for (const chunk of (_a = hashesByChunkGroupAndParents.get(group)) !== null && _a !== void 0 ? _a : new Set()) {
|
||||
groupCombinedManifest.add(chunk);
|
||||
}
|
||||
hashesByChunkGroupAndParents.set(group, groupCombinedManifest);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [sortedVertices, chunkManifest];
|
||||
}
|
||||
exports.getChunkToManifestMap = getChunkToManifestMap;
|
||||
//# sourceMappingURL=util.js.map
|
1
my-app/node_modules/webpack-subresource-integrity/util.js.map
generated
vendored
Executable file
1
my-app/node_modules/webpack-subresource-integrity/util.js.map
generated
vendored
Executable file
File diff suppressed because one or more lines are too long
35
my-app/node_modules/webpack-subresource-integrity/webpack-subresource-integrity-public.d.ts
generated
vendored
Executable file
35
my-app/node_modules/webpack-subresource-integrity/webpack-subresource-integrity-public.d.ts
generated
vendored
Executable file
|
@ -0,0 +1,35 @@
|
|||
import type { Compiler } from 'webpack';
|
||||
|
||||
/**
|
||||
* The webpack-subresource-integrity plugin.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
export declare class SubresourceIntegrityPlugin {
|
||||
private readonly options;
|
||||
/**
|
||||
* Create a new instance.
|
||||
*
|
||||
* @public
|
||||
*/
|
||||
constructor(options?: SubresourceIntegrityPluginOptions);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
apply(compiler: Compiler): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* @public
|
||||
*/
|
||||
export declare interface SubresourceIntegrityPluginOptions {
|
||||
readonly hashFuncNames?: [string, ...string[]];
|
||||
readonly enabled?: "auto" | true | false;
|
||||
readonly hashLoading?: "eager" | "lazy";
|
||||
}
|
||||
|
||||
export { }
|
Loading…
Add table
Add a link
Reference in a new issue