vite-plugin-html-security
Version:
vite plugin for html security
91 lines (90 loc) • 4 kB
JavaScript
;
var __webpack_require__ = {};
(()=>{
__webpack_require__.d = (exports1, definition)=>{
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
enumerable: true,
get: definition[key]
});
};
})();
(()=>{
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
})();
(()=>{
__webpack_require__.r = function(exports1) {
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
value: 'Module'
});
Object.defineProperty(exports1, '__esModule', {
value: true
});
};
})();
var __webpack_exports__ = {};
__webpack_require__.r(__webpack_exports__);
__webpack_require__.d(__webpack_exports__, {
default: ()=>src
});
const external_crypto_namespaceObject = require("crypto");
const external_fs_namespaceObject = require("fs");
const external_path_namespaceObject = require("path");
const external_lodash_namespaceObject = require("lodash");
const sriAssetsMap = [];
const integrityAttrValueShaKey = "integrityAttrValueSha";
function getSRIHash(filePath) {
try {
const fileContent = (0, external_fs_namespaceObject.readFileSync)(filePath);
const hash = (0, external_crypto_namespaceObject.createHash)("sha384");
hash.update(fileContent);
return `sha384-${hash.digest("base64")}`;
} catch (e) {
return null;
}
}
function src(options) {
const config = (0, external_lodash_namespaceObject.merge)({
outputDir: "dist"
}, options);
return {
name: "vite-plugin-sri",
apply: "build",
enforce: "post",
closeBundle () {
sriAssetsMap.forEach((item)=>{
const htmlPath = (0, external_path_namespaceObject.join)(process.cwd(), config.outputDir, item.path);
const sriHash = getSRIHash(/node_modules/.test(item.filePath) ? (0, external_path_namespaceObject.join)(process.cwd(), "node_modules", item.filePath.replace(/.*?node_modules/, "")) : item.filePath);
let newHtml = (0, external_fs_namespaceObject.readFileSync)(htmlPath, "utf-8");
if (sriHash) newHtml = newHtml.replace(item.match, (0, external_lodash_namespaceObject.template)(item.matchTag)({
[integrityAttrValueShaKey]: sriHash
}));
(0, external_fs_namespaceObject.writeFileSync)(htmlPath, newHtml);
});
},
transformIndexHtml: {
enforce: "post",
transform (html, { bundle, path }) {
if (!bundle) return html;
const newHtml = html.replace(/<(link|script) ([^>]*?)(href|src)=("([^"]+)"|'([^']+)')([^>]*?)>/g, (match, tag, before, attr, quoteWrappedUrl, url1, url2)=>{
const url = (url1 || url2 || "").replace(/^(\.|\/)+/, "");
const asset = Object.values(bundle).find((b)=>b.fileName === url);
const filePath = (0, external_path_namespaceObject.join)(process.cwd(), config.outputDir, url);
sriAssetsMap.push({
filePath,
asset: !!asset,
path,
match,
matchTag: `<${tag} ${before}${attr}=${quoteWrappedUrl} integrity="<%=${integrityAttrValueShaKey}%>" crossorigin="anonymous"${match.endsWith("/>") ? "/" : ""}>`
});
return match;
});
return newHtml;
}
}
};
}
var __webpack_export_target__ = exports;
for(var __webpack_i__ in __webpack_exports__)__webpack_export_target__[__webpack_i__] = __webpack_exports__[__webpack_i__];
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
value: true
});