import { escape_html_attr } from '../../../utils/escape.js';
import { base64, sha256 } from './crypto.js';
const array = new Uint8Array(16);
function generate_nonce() {
crypto.getRandomValues(array);
return base64(array);
}
const quoted = new Set([
'self',
'unsafe-eval',
'unsafe-hashes',
'unsafe-inline',
'none',
'strict-dynamic',
'report-sample',
'wasm-unsafe-eval',
'script'
]);
const crypto_pattern = /^(nonce|sha\d\d\d)-/;
// CSP and CSP Report Only are extremely similar with a few caveats
// the easiest/DRYest way to express this is with some private encapsulation
class BaseProvider {
/** @type {boolean} */
#use_hashes;
/** @type {boolean} */
#script_needs_csp;
/** @type {boolean} */
#style_needs_csp;
/** @type {import('types').CspDirectives} */
#directives;
/** @type {import('types').Csp.Source[]} */
#script_src;
/** @type {import('types').Csp.Source[]} */
#script_src_elem;
/** @type {import('types').Csp.Source[]} */
#style_src;
/** @type {import('types').Csp.Source[]} */
#style_src_attr;
/** @type {import('types').Csp.Source[]} */
#style_src_elem;
/** @type {string} */
#nonce;
/**
* @param {boolean} use_hashes
* @param {import('types').CspDirectives} directives
* @param {string} nonce
*/
constructor(use_hashes, directives, nonce) {
this.#use_hashes = use_hashes;
this.#directives = __SVELTEKIT_DEV__ ? { ...directives } : directives; // clone in dev so we can safely mutate
const d = this.#directives;
this.#script_src = [];
this.#script_src_elem = [];
this.#style_src = [];
this.#style_src_attr = [];
this.#style_src_elem = [];
const effective_script_src = d['script-src'] || d['default-src'];
const script_src_elem = d['script-src-elem'];
const effective_style_src = d['style-src'] || d['default-src'];
const style_src_attr = d['style-src-attr'];
const style_src_elem = d['style-src-elem'];
if (__SVELTEKIT_DEV__) {
// remove strict-dynamic in dev...
// TODO reinstate this if we can figure out how to make strict-dynamic work
// if (d['default-src']) {
// d['default-src'] = d['default-src'].filter((name) => name !== 'strict-dynamic');
// if (d['default-src'].length === 0) delete d['default-src'];
// }
// if (d['script-src']) {
// d['script-src'] = d['script-src'].filter((name) => name !== 'strict-dynamic');
// if (d['script-src'].length === 0) delete d['script-src'];
// }
// ...and add unsafe-inline so we can inject