UNPKG

vite-plugin-csp

Version:

Create CSP meta tags and header configs from all sources in the final Vite html

21 lines (20 loc) 8.96 kB
var ye=Object.defineProperty,Pe=Object.defineProperties;var he=Object.getOwnPropertyDescriptors;var Z=Object.getOwnPropertySymbols;var ge=Object.prototype.hasOwnProperty,me=Object.prototype.propertyIsEnumerable;var M=(s,t,e)=>t in s?ye(s,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):s[t]=e,h=(s,t)=>{for(var e in t||(t={}))ge.call(t,e)&&M(s,e,t[e]);if(Z)for(var e of Z(t))me.call(t,e)&&M(s,e,t[e]);return s},ee=(s,t)=>Pe(s,he(t));import L from"path";import{CspDirectives as fe}from"csp-typed-directives";import te from"path";import{mkdirSync as Ce,writeFileSync as be}from"fs";var x=(s,t,e)=>{Ce(s.srvConfDir,{recursive:!0});let r=te.resolve(te.join(s.srvConfDir,t));be(r,e)},T=(s,t=" ")=>s.split(` `).map((e,r)=>e&&r?t+e:e).join(` `);var se=s=>Object.entries(s).map(([t,e])=>`header ${t} "${e}" `).join(""),w={Caddyfile:"Caddyfile",Caddyfile_HeadersOnly:"headers.caddyfile"},re={Caddyfile:({ctx:s,parsedHeaders:t,outFile:e=w.Caddyfile})=>{let r=` {$SITE_ADDRESS} root * dist ${T(se(t)," ")} file_server `;return x(s,e,r)},Caddyfile_HeadersOnly:({ctx:s,parsedHeaders:t,outFile:e=w.Caddyfile_HeadersOnly})=>x(s,e,se(t))};var ne=s=>Object.entries(s).map(([t,e])=>`add_header ${t} "${e}"; `).join(""),J={Nginx:"nginx.conf",Nginx_HeadersOnly:"nginx-headers.conf"},oe={Nginx:({ctx:s,parsedHeaders:t,outFile:e=J.Nginx})=>{let r=` server { listen 443 80; index index.html Index.html; ${T(ne(t))} location / { try_files $uri /index.html $uri/ / =404; } } `;return x(s,e,r)},Nginx_HeadersOnly:({ctx:s,parsedHeaders:t,outFile:e=J.Nginx_HeadersOnly})=>x(s,e,ne(t))};var ie=s=>{let t=JSON.parse(JSON.stringify(s));for(let e in t){let r=t[e];t[e]=[r]}return t},$={CaddyJSON:"caddy.json",CaddyJSON_HeadersOnly:"caddy-headers.json"},ce={CaddyJSON:({ctx:s,parsedHeaders:t,outFile:e=$.CaddyJSON})=>{let r=ie(t),f={listen:[":443"],routes:[{match:[{host:["localhost"]}],handle:[{handler:"file_server",root:"/var/www"},{handler:"headers",response:{set:r}}]}]};return x(s,e,JSON.stringify(f,null,2))},CaddyJSON_HeadersOnly:({ctx:s,parsedHeaders:t,outFile:e=$.CaddyJSON_HeadersOnly})=>x(s,e,JSON.stringify({handler:"headers",response:{set:ie(t)}},null,2))};var V=h(h(h({},re),oe),ce),Je=h(h(h({},w),J),$);import{createFilter as ue}from"@rollup/pluginutils";import*as pe from"cheerio";import{createHash as xe}from"crypto";import Y from"path";import{ValidHashes as Ye,ValidCrypto as He}from"csp-typed-directives";var ae=He,C={enabled:!0,inject:!0,injectReporting:!1,onDev:"permissive",policy:{"base-uri":"self","object-src":"none","script-src":["unsafe-inline","self","unsafe-eval"],"style-src":["unsafe-inline","self","unsafe-eval"]},hashingMethod:"sha384",hashEnabled:{"script-src":!0,"style-src":!0,"script-src-attr":!0,"style-src-attr":!0},nonceEnabled:{"script-src":!1,"style-src":!1},processFn:void 0,referrerHeaderOverride:void 0,sendReportsTo:void 0,reportSubset:void 0,mapHtmlFiles:void 0,debugPlugin:!1,srvConfDir:".server_config"};import*as N from"css-tree";var le=(s,t)=>s[0]===t&&s[s.length-1]===t,Fe=s=>s.slice(1,s.length-1),U=s=>{let t=N.parse(s);return N.findAll(t,function(r,f,g){return r.type==="Atrule"&&r.name==="import"}).map(r=>{var f;if(r!==null&&typeof r=="object"&&r.type==="Atrule"&&((f=r==null?void 0:r.prelude)==null?void 0:f.type)==="AtrulePrelude"){let g=N.toPlainObject(r==null?void 0:r.prelude);if(g.type==="AtrulePrelude"&&g.children.length)return g.children.map(l=>{var p;if(l.type==="Url"&&((p=l==null?void 0:l.value)==null?void 0:p.type)==="String"&&l.value.value)return l.value.value}).filter(l=>typeof l=="string")}}).filter(r=>Array.isArray(r)).flat().map(r=>le(r,"'")||le(r,'"')?Fe(r):r)};function I(s,t){let e=xe(s);return e.update(t),`${s}-${e.digest("base64")}`}function de(s,t,e,r){let f=pe.load(s),g={scriptSrcHashes:new Set,styleSrcHashes:new Set,scriptAttrHashes:new Set,styleAttrHashes:new Set},_=p=>ae.some(o=>o===(p==null?void 0:p.slice(0,6))),l=(p,o)=>{_(p)&&g[o].add(p)};if(f("script").each(function(p,o){var c,u,P,b,v,O,R;if(Object.keys(o.attribs).length&&((u=(c=o.attribs)==null?void 0:c.src)==null?void 0:u.length)){let S=Y.resolve((P=o.attribs)==null?void 0:P.src);t.has(S)&&l((b=t.get(S))==null?void 0:b[r],"scriptSrcHashes")}if(((O=(v=o.childNodes)==null?void 0:v[0])==null?void 0:O.type)==="text"){let S=f.text([(R=o.childNodes)==null?void 0:R[0]]);S.length&&l(I(r,S),"scriptSrcHashes")}}),f("style").each(function(p,o){var c,u,P;if(((u=(c=o.childNodes)==null?void 0:c[0])==null?void 0:u.type)==="text"){let b=f.text([(P=o.childNodes)==null?void 0:P[0]]);b.length&&(U(b).forEach(O=>{var R;if(O.length){let S=Y.resolve(O);t.has(S)&&l((R=t.get(S))==null?void 0:R[r],"styleSrcHashes")}}),l(I(r,b),"styleSrcHashes"))}}),f("link").each(function(p,o){var c,u,P,b,v;if(Object.keys(o.attribs).length&&((c=o.attribs)==null?void 0:c.rel)==="stylesheet"&&((P=(u=o.attribs)==null?void 0:u.href)==null?void 0:P.length)){let O=Y.resolve((b=o.attribs)==null?void 0:b.href);t.has(O)&&l((v=t.get(O))==null?void 0:v[r],"styleSrcHashes")}}),e["style-src-attr"]&&f("[style]").each((p,o)=>{var c;(c=o.attribs)!=null&&c.style.length&&l(I(r,o.attribs.style),"styleAttrHashes")}),e["script-src-attr"]){let p=o=>o.startsWith("on");f("*").filter((o,c)=>Object.keys(c.attribs).some(p)).each((o,c)=>{Object.keys(c.attribs).filter(p).forEach(u=>{let P=c.attribs[u];P!=null&&P.length&&l(I(r,P),"scriptAttrHashes")})})}return{"script-src-attr":g.scriptAttrHashes,"style-src-attr":g.styleAttrHashes,"script-src":g.scriptSrcHashes,"style-src":g.styleSrcHashes}}var q=class{constructor(t,e){this.tag=t,this.attrs=e}},z=class extends q{constructor(){super(...arguments);this.injectTo="head"}};function Oe(...s){var Q;let{p:t,o:e}={0:{o:C,p:C.policy},1:{o:s[0],p:((Q=s[0])==null?void 0:Q.policy)||C.policy},2:{o:s[1],p:s[0]}}[s.length];if(!(typeof e.enabled=="boolean"?e.enabled:C.enabled))return;let f=typeof e.inject=="boolean"?e.inject:C.inject,g=typeof e.injectReporting=="boolean"?e.injectReporting:C.injectReporting,_=typeof e.onDev=="string"?e.onDev:C.onDev;function l(n){let a=Array.isArray(n)?new fe(...n):new fe(n);return typeof e.referrerHeaderOverride=="string"&&(a.ReferrerHeader=e.referrerHeaderOverride),typeof e.sendReportsTo=="object"&&(a.ReportTo=e.sendReportsTo),typeof e.reportSubset=="object"&&(a.ReportOnly=e.reportSubset),a.checkReportTo(),a}let p=l(t),o={};if(!!e.mapHtmlFiles&&Object.keys(e.mapHtmlFiles).length)for(let n in e.mapHtmlFiles){let a=e.mapHtmlFiles[n];a!==null&&typeof a=="object"&&(o[n]=l(a))}let c=e.hashingMethod||C.hashingMethod,u=h(h({},C.hashEnabled),e==null?void 0:e.hashEnabled),P=h(h({},C.nonceEnabled),e==null?void 0:e.nonceEnabled),b=e.srvConfDir||C.srvConfDir,v=(Array.isArray(e.processFn)?e.processFn:e.processFn?[e.processFn]:[]).map(n=>{var a,D,k;if(typeof n=="string"&&typeof((a=V)==null?void 0:a[n])=="function")return(y,m)=>{var i,H;return(H=(i=V)==null?void 0:i[n])==null?void 0:H.call(i,{ctx:y,parsedHeaders:m,processor:n})};if(typeof n=="object"&&((D=n==null?void 0:n.processor)==null?void 0:D.length)&&typeof((k=V)==null?void 0:k[n.processor])=="function")return(y,m)=>{var i,H;return(H=(i=V)==null?void 0:i[n.processor])==null?void 0:H.call(i,ee(h({},n),{ctx:y,parsedHeaders:m}))};if(typeof n=="function")return async(y,m)=>{let i=await n(y,m);typeof i=="object"&&typeof(i==null?void 0:i.name)=="string"&&typeof(i==null?void 0:i.content)=="string"&&x(y,i.name,i.content)}}).filter(n=>typeof n=="function");async function O(n,a){for(let D of v)await D(n,a)}let R=ue("**.js"),S=ue("**.css"),A=new Map,G=new Set,W={},K={name:"vite-plugin-csp",enforce:"post",apply:()=>!0,configResolved(n){W.command=n==null?void 0:n.command},async transform(n,a){if(W.command==="build"||_==="full"){let D=R(a),k=S(a);D&&u["script-src"]?A.set(a,{fileType:"script",[c]:I(c,n)}):k&&u["style-src"]&&(U(n).forEach(m=>{let i="";try{i=L.resolve(m)}catch{return}i&&G.add(i)}),A.set(a,{fileType:"style",[c]:I(c,n)}))}return null},async transformIndexHtml(n,{path:a,filename:D}){let k=de(n,A,u,c),y=p,m=o;if(!!m&&Object.keys(m).length){let d=a?L.resolve(a,D):L.resolve(D);for(let F of Object.keys(m))L.resolve(F)===d&&(y=m[F])}function i(d){let F=y.CSP[d];return Array.isArray(F)||(typeof F<"u"?y.CSP[d]=[F]:y.CSP[d]=[]),y.CSP[d]}let H=d=>!u[d]||i(d).push(...k[d]);H("script-src"),H("script-src-attr"),H("style-src"),H("style-src-attr"),G.forEach(d=>{if(A.has(d)){let F=A.get(d);if(F){let B=new Set(y.CSP["style-src"]);B.add(F[c]),y.CSP["style-src"]=Array.from(B)}}});let X=y.getHeaders();if(await O({path:a,htmlFileName:D,builtinProcessorFns:V,srvConfDir:b},X),f)return Object.entries(X).filter(([d])=>g||!d.includes("Report")).map(([d,F])=>new z("meta",{"http-equiv":d,content:F}))}};return e.debugPlugin&&Object.defineProperty(K,"debugProperties",{value:{inject:f,onDev:_,policy:p,hashingMethod:c,hashEnabled:u,nonceEnabled:P,processFns:v,idMap:A,validatedMappedPolicies:o,config:W}}),K}var Se=Oe,Ft=Se;export{Se as ViteCspPlugin,Ft as default}; //# sourceMappingURL=index.js.map