diff --git a/index.html b/index.html
index 603b61b..7df17a8 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,8 @@
Hellō Quickstart
-
+
+
+
+
+
+
+
+
+
+
+ `
+ }
+
+ get nosociallinks() {
+ return this.getAttribute("nosociallinks")
+ }
+
+ static get observedAttributes() {
+ return ["nosociallinks"]
+ }
+
+ connectedCallback() {
+ if (window.location.host === "www.hello.coop") {
+ const fromHelloRef = this.shadow.getElementById("from-hello")
+ fromHelloRef.style.display = "none"
+ if (window.innerWidth < 968) {
+ const footerRef = this.shadow.getElementById("wc-footer")
+ footerRef.style.height = "4rem"
+ }
+ }
+ }
+
+ attributeChangedCallback(name, oldValue, newValue) {
+ if (name === "nosociallinks") {
+ const footerRef = this.shadow.getElementById("wc-footer")
+ footerRef.style.height = "3rem"
+ footerRef.style.padding = "0"
+ const footerContainerRef = this.shadow.getElementById(
+ "wc-footer-content-container"
+ )
+ footerContainerRef.style.justifyContent = "center"
+ const socialLinksRef = this.shadow.getElementById("social-links")
+ socialLinksRef.style.display = "none"
+ const fromHello = this.shadow.getElementById("from-hello")
+ fromHello.style.display = "none"
+ const linksRef = this.shadow.getElementById("links")
+ linksRef.style.width = "100%"
+ linksRef.style.justifyContent = "center"
+ }
+ }
+ }
+
+ customElements.define("wc-footer", Footer)
\ No newline at end of file
diff --git a/public/assets/quickstart-glob.js b/public/assets/quickstart-glob.js
new file mode 100644
index 0000000..6415852
--- /dev/null
+++ b/public/assets/quickstart-glob.js
@@ -0,0 +1,12 @@
+/**
+ * If browser back button was used, flush cache
+ * This ensures that user will always see an accurate, up-to-date view based on their state
+ * https://stackoverflow.com/questions/8788802/prevent-safari-loading-from-cache-when-back-button-is-clicked
+ */
+(function () {
+ window.onpageshow = function (event) {
+ if (event.persisted) {
+ window.location.reload();
+ }
+ };
+})();
\ No newline at end of file
diff --git a/sri.js b/sri.js
new file mode 100644
index 0000000..065bb32
--- /dev/null
+++ b/sri.js
@@ -0,0 +1,71 @@
+//Based on https://github.com/vitejs/vite/discussions/11043#discussioncomment-4233645 and rollup-sri-plugin
+//These is discussion around making this fn native to vite: https://github.com/vitejs/vite/issues/2377
+
+import * as cheerio from 'cheerio';
+import { createHash } from 'crypto';
+import fs from 'fs';
+import fetch from 'node-fetch';
+
+const invalidHashAlgorithms = ['sha1', 'md5'];
+
+export default function subresourceIntegrity(options) {
+ const selectors = options?.selectors || ['script', 'link[rel=stylesheet]'];
+ const hashAlgorithms = options?.algorithms || ['sha384'];
+ const crossorigin = options?.crossorigin || 'anonymous';
+ const publicPath = options?.publicPath ?? '';
+ let active = options?.active ?? true;
+
+ return {
+ name: 'subresource-integrity',
+ buildStart() {
+ hashAlgorithms
+ .filter((alg) => invalidHashAlgorithms.includes(alg.toLowerCase()))
+ .forEach((alg) => this.warn(`Insecure hashing algorithm "${alg}" will be rejected by browsers!`));
+ },
+ async closeBundle() {
+ if (!active) return;
+
+ const buildDir = 'S3'; //TBD get this from vite config
+ for(const file of ['/index.html']) { //TBD get these from vite config
+ let content = fs.readFileSync(buildDir + file);
+ const $ = cheerio.load(content);
+ const elements = $(selectors.join()).get();
+
+ for (const el of elements) {
+ const integrityAlreadyHardCoded = $(el).attr('integrity');
+ if (integrityAlreadyHardCoded) continue;
+ // const url = ($(el).attr('href') || $(el).attr('src'))?.replace(publicPath, '');
+ const url = $(el).attr('src')?.replace(publicPath, ''); //only generate hash for script src
+ if (!url) continue;
+
+ let buf;
+ if (fs.existsSync(buildDir + '/' + url)) {
+ //@ts-ignore
+ buf = Buffer.from(fs.readFileSync(buildDir + '/' + url));
+ } else if (url.startsWith('http')) {
+ buf = await (await fetch(url)).buffer();
+ } else {
+ this.warn(`could not resolve resource "${url}"!`);
+ continue;
+ }
+
+ const hashes = hashAlgorithms.map((algorithm) => generateIdentity(buf, algorithm));
+
+ $(el).attr('integrity', hashes.join(' '));
+ $(el).attr('crossorigin', crossorigin);
+ }
+
+ fs.writeFileSync(buildDir + file, $.html());
+ }
+ },
+ };
+}
+
+function generateIdentity(source, alg) {
+ const hash = createHash(alg).update(source).digest().toString('base64');
+ return `${alg.toLowerCase()}-${hash}`;
+}
+
+function isHtmlAsset(obj) {
+ return obj.fileName.endsWith('.html') && obj.type === 'asset';
+}
\ No newline at end of file
diff --git a/vite.config.js b/vite.config.js
index 91d6ca5..11c5469 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -1,9 +1,16 @@
import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
+import sri from './sri.js';
// https://vitejs.dev/config/
export default defineConfig({
- plugins: [svelte()],
+ plugins: [
+ svelte(),
+ {
+ enforce: "post",
+ ...sri({ publicPath: "/" })
+ }
+ ],
build: {
outDir: 'S3',
emptyOutDir: true