From 9bf90c97154e576bb62f1dba633ef5397d5d094a Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 19:06:34 +0000 Subject: [PATCH 1/6] Reformat data.json --- src/webring/data.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/webring/data.json b/src/webring/data.json index 1843063..9ed3f2e 100644 --- a/src/webring/data.json +++ b/src/webring/data.json @@ -1,17 +1,17 @@ [ - { - "id": "annie", - "name": "annieversary", - "url": "https://versary.town/" - }, - { - "id": "charlotte", - "name": "charlotte", - "url": "https://char.lt/" - }, - { - "id": "mira", - "name": "mira", - "url": "https://boxin.space/" - } + { + "id": "annie", + "name": "annieversary", + "url": "https://versary.town/" + }, + { + "id": "charlotte", + "name": "charlotte", + "url": "https://char.lt/" + }, + { + "id": "mira", + "name": "mira", + "url": "https://boxin.space/" + } ] From e9f60bf7e7a752e68466d93b5c39d4e928b805df Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 19:07:17 +0000 Subject: [PATCH 2/6] jill --- src/webring/data.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/webring/data.json b/src/webring/data.json index 9ed3f2e..dadd27e 100644 --- a/src/webring/data.json +++ b/src/webring/data.json @@ -13,5 +13,10 @@ "id": "mira", "name": "mira", "url": "https://boxin.space/" + }, + { + "id": "oatmealine", + "name": "oatmealine", + "url": "https://oat.zone" } ] From c32320fec4923412fde784997a25865559647cba Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 20:20:02 +0000 Subject: [PATCH 3/6] Create version 2 of the webring --- src/webring/webring-0.2.0.css | 52 +++++++++++++++++++++++++++++++++ src/webring/webring-0.2.0.js | 54 +++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 src/webring/webring-0.2.0.css create mode 100644 src/webring/webring-0.2.0.js diff --git a/src/webring/webring-0.2.0.css b/src/webring/webring-0.2.0.css new file mode 100644 index 0000000..c21ba71 --- /dev/null +++ b/src/webring/webring-0.2.0.css @@ -0,0 +1,52 @@ +/* Feel free to style the webring however you like! */ + +.lavender-webring-container { + all: unset; + + /* + assuming Linux users will have a preferable sans-serif font set in their browser, + everyone else gets a nice default + */ + font-family: -apple-system, BlinkMacSystemFont, "SF Pro", "Segoe UI", + "Helvetica Neue", sans-serif; + + display: flex; + flex-direction: column; + + background-color: rgb(28, 23, 36); + color: rgb(234, 234, 248); + + padding: 1em; + + text-align: center; + font-size: 1.125rem; +} + +.lavender-webring-description { + margin-block-end: 0.5em; +} + +.lavender-webring-container a { + color: hsl(275, 57%, 68%); + text-decoration: none; + border-bottom: 1px solid hsl(275, 57%, 68%); +} + +.lavender-webring-site-links { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + + list-style: none; + margin: 0; + padding: 0; +} + +.lavender-webring-prev-site a::before { + content: "←"; + margin-inline-end: 1ch; +} + +.lavender-webring-next-site a::after { + content: "→"; + margin-inline-start: 1ch; +} diff --git a/src/webring/webring-0.2.0.js b/src/webring/webring-0.2.0.js new file mode 100644 index 0000000..2a1f817 --- /dev/null +++ b/src/webring/webring-0.2.0.js @@ -0,0 +1,54 @@ +const currentScript = document.currentScript; +const ctx = currentScript.dataset; + +// charlotte's ad-hoc terse javascript framework! +const CSS_PREFIX = "lavender-webring"; +const e = (tag, props = {}, children = []) => { + let element = Object.assign(document.createElement(tag), props); + element.append(...children); + return element; +}; +const t = (text) => document.createTextNode(text); +const c = (className) => ({ className: `${CSS_PREFIX}-${className}` }); +const h = (href) => ({ href }); + +const createDescriptionContent = () => + ctx.description != null + ? [t(ctx.description)] + : [ + t("This site is part of the "), + e("a", h("https://lavender.software"), [t("lavender.software")]), + t(" webring!"), + ]; + +const renderWebring = (currSite, prevSite, nextSite) => { + currentScript.replaceWith( + e("aside", c("container"), [ + e("section", c("description"), createDescriptionContent()), + e("ul", c("site-links"), [ + e("li", c("prev-site"), [e("a", h(prevSite.url), [t(prevSite.name)])]), + e("li", c("curr-site"), [e("a", h(currSite.url), [t(currSite.name)])]), + e("li", c("next-site"), [e("a", h(nextSite.url), [t(nextSite.name)])]), + ]), + ]) + ); +}; + +(async () => { + const data = await fetch("https://lavender.software/webring/data.json").then( + (r) => r.json() + ); + + let thisSiteIdx = data.findIndex((site) => site.id == ctx.siteId); + if (thisSiteIdx === -1) { + throw new Error( + `Could not find site by id '${ctx.siteId}' in the webring!` + ); + } + + let currSite = data[thisSiteIdx]; + let prevSite = data[(thisSiteIdx + data.length - 1) % data.length]; + let nextSite = data[(thisSiteIdx + 1) % data.length]; + + renderWebring(currSite, prevSite, nextSite); +})(); From 1e1fe5b82fc8d8fba1f053b60ac240ecbc453d69 Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 20:22:41 +0000 Subject: [PATCH 4/6] Auto-calculate subresource integrity for webring JS --- Cargo.lock | 63 ++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + build_src/webring.rs | 12 +++++++++ 3 files changed, 76 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index bc81536..fea3309 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -89,6 +89,15 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +[[package]] +name = "base64" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" +dependencies = [ + "byteorder", +] + [[package]] name = "bitflags" version = "1.2.1" @@ -416,6 +425,12 @@ dependencies = [ "libc", ] +[[package]] +name = "hex" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" + [[package]] name = "html5ever" version = "0.25.1" @@ -492,6 +507,7 @@ dependencies = [ "askama", "notify", "siru", + "ssri", ] [[package]] @@ -973,6 +989,18 @@ dependencies = [ "opaque-debug", ] +[[package]] +name = "sha2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69" +dependencies = [ + "block-buffer", + "digest", + "fake-simd", + "opaque-debug", +] + [[package]] name = "shell-words" version = "1.0.0" @@ -1006,6 +1034,21 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f173ac3d1a7e3b28003f40de0b5ce7fe2710f9b9dc3fc38664cebee46b3b6527" +[[package]] +name = "ssri" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9cec0d388f39fbe79d7aa600e8d38053bf97b1bc8d350da7c0ba800d0f423f2" +dependencies = [ + "base64", + "digest", + "hex", + "serde", + "sha-1", + "sha2", + "thiserror", +] + [[package]] name = "static_assertions" version = "1.1.0" @@ -1080,6 +1123,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "time" version = "0.1.44" diff --git a/Cargo.toml b/Cargo.toml index 9162e7c..c8cb7c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,3 +14,4 @@ path = "build_src/main.rs" askama = "0.10.5" notify = "4.0.17" siru = { git = "https://github.com/videogame-hacker/siru.git" } +ssri = "7.0.0" diff --git a/build_src/webring.rs b/build_src/webring.rs index 7088e07..397254b 100644 --- a/build_src/webring.rs +++ b/build_src/webring.rs @@ -1,5 +1,7 @@ use crate::*; +use ssri::{Algorithm, IntegrityOpts}; + pub fn copy_webring(ctx: &BuildContext) -> Result<()> { log_info("Copying webring…"); copy_dir_recursive( @@ -7,5 +9,15 @@ pub fn copy_webring(ctx: &BuildContext) -> Result<()> { ctx.output_dir.join("webring"), )?; + log_info("Calculating webring integrity…"); + let webring_content = ctx.read_bin("webring/webring-0.2.0.js")?; + let integrity = IntegrityOpts::new() + .algorithm(Algorithm::Sha512) + .algorithm(Algorithm::Sha1) + .chain(&webring_content) + .result(); + + ctx.write("webring/webring-0.2.0.js.integ.txt", integrity.to_string())?; + Ok(()) } From e2f4635404acdea5466575802d83c374ea8970c7 Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 20:27:16 +0000 Subject: [PATCH 5/6] The CORS header should cover the entire webring directory --- nginx-site.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-site.conf b/nginx-site.conf index 89a096a..aa49013 100644 --- a/nginx-site.conf +++ b/nginx-site.conf @@ -3,7 +3,7 @@ location / { root /srv/http/lavender.software/; - location = /webring/data.json { + location ^~ /webring/ { add_header Access-Control-Allow-Origin *; } } From a777aea8158ca8aabf0d22ed1f0c20baf51757bc Mon Sep 17 00:00:00 2001 From: videogame hacker Date: Sat, 5 Mar 2022 20:28:54 +0000 Subject: [PATCH 6/6] Revert "The CORS header should cover the entire webring directory" Wait no it shouldn't we're fine --- nginx-site.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nginx-site.conf b/nginx-site.conf index aa49013..89a096a 100644 --- a/nginx-site.conf +++ b/nginx-site.conf @@ -3,7 +3,7 @@ location / { root /srv/http/lavender.software/; - location ^~ /webring/ { + location = /webring/data.json { add_header Access-Control-Allow-Origin *; } }