Vendor ical.js instead of loading it from unpkg.com
The upcoming events table pulled its ICS parser straight from a CDN with
`import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js"`. That sends
every visitor of the start page to unpkg.com, which hands their IP address and
user agent to a third party before any of our own code runs. The URL is not
even pinned to a version, so whatever ical.js publishes next is executed on our
site without anybody looking at it, and the start page silently breaks when the
CDN is unreachable.
Check the parser into `assets/js/vendor/` and let Hugo bundle it. This is what
`js.Build` is for: it runs the esbuild that is built into Hugo, so it resolves
the import at build time and needs no node_modules and no extra tooling in the
build environment. The result is minified and fingerprinted like the other
scripts of the site, and the script tag carries a subresource integrity hash.
Since the bundle now has a content hash in its name, its URL cannot be written
by hand in the markdown any more. Move the table and the script tag into an
`upcoming` shortcode, which is the same pattern `calendar.html` already uses,
and move `upcoming.js` from `static/` to `assets/` so Hugo can process it.
The vendored file is the unminified `dist/ical.js` of the pinned release: it
carries the MPL-2.0 header and is the source form of what we ship, and Hugo
minifies it for delivery anyway. `assets/js/vendor/README.md` records the
version, where it came from and how to update it.
The built bundle renders the same table as before, checked against
https://berlin.ccc.de/calendars/all.ics.
Fixes: c28f04c6e8 ("switch to ics files; make calendars work; fix some minor issues")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
parent
028ffe098b
commit
3d2231d7ec
6 changed files with 9760 additions and 6 deletions
|
|
@ -30,13 +30,16 @@ This is the website of the CCCB.
|
||||||
Every change you make on the project will be reflected in your browser as long as `hugo serve` is running.
|
Every change you make on the project will be reflected in your browser as long as `hugo serve` is running.
|
||||||
|
|
||||||
The *"Nächste Veranstaltungen"* table on the home page and the calendar under `/verein/calendar/` are rendered in the
|
The *"Nächste Veranstaltungen"* table on the home page and the calendar under `/verein/calendar/` are rendered in the
|
||||||
browser by `static/js/upcoming.js` and `assets/js/calendar.js`. Both fetch `/calendars/all.ics`, which is **not**
|
browser by `assets/js/upcoming.js` and `assets/js/calendar.js`. Both fetch `/calendars/all.ics`, which is **not**
|
||||||
generated by Hugo and is not part of this repo — it is published separately on the web server. Locally those two
|
generated by Hugo and is not part of this repo — it is published separately on the web server. Locally those two
|
||||||
tables therefore stay empty; check them on the [staging site](https://staging.berlin.ccc.de/) instead.
|
tables therefore stay empty; check them on the [staging site](https://staging.berlin.ccc.de/) instead.
|
||||||
|
|
||||||
Hugo does generate an `.ics` feed per section (for example `/veranstaltungen/index.ics`) from the `dtstart`, `dtend`
|
Hugo does generate an `.ics` feed per section (for example `/veranstaltungen/index.ics`) from the `dtstart`, `dtend`
|
||||||
and `rrule` front matter of the pages in `content/veranstaltungen/`, using the `.ics` templates under `layouts/`.
|
and `rrule` front matter of the pages in `content/veranstaltungen/`, using the `.ics` templates under `layouts/`.
|
||||||
|
|
||||||
|
The site must not make the browser load anything from an external server, so third party JavaScript is checked into
|
||||||
|
`assets/js/vendor/` and bundled in by Hugo instead of being pulled from a CDN. See the README there before updating it.
|
||||||
|
|
||||||
To build the site for upload, run:
|
To build the site for upload, run:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import ICAL from "https://unpkg.com/ical.js/dist/ical.min.js";
|
import ICAL from "./vendor/ical.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the URL of an event.
|
* Read the URL of an event.
|
||||||
19
assets/js/vendor/README.md
vendored
Normal file
19
assets/js/vendor/README.md
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# Vendored JavaScript
|
||||||
|
|
||||||
|
Third party code is checked in here instead of being loaded from a CDN, so that the website does not make the visitor's
|
||||||
|
browser fetch anything from an external server.
|
||||||
|
|
||||||
|
Hugo bundles and minifies these files into the scripts that reference them, so the unminified source is checked in.
|
||||||
|
|
||||||
|
## ical.js
|
||||||
|
|
||||||
|
- Version: 2.2.1
|
||||||
|
- Source: <https://unpkg.com/ical.js@2.2.1/dist/ical.js>
|
||||||
|
- Upstream: <https://github.com/kewisch/ical.js>
|
||||||
|
- License: MPL-2.0 (see the header of `ical.js`)
|
||||||
|
|
||||||
|
To update, download the `dist/ical.js` of the wanted release and replace the file, keeping the version above in sync:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
curl -o assets/js/vendor/ical.js https://unpkg.com/ical.js@<version>/dist/ical.js
|
||||||
|
```
|
||||||
9732
assets/js/vendor/ical.js
vendored
Normal file
9732
assets/js/vendor/ical.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -25,9 +25,6 @@ description: "Startseite CCCB mit Kurzkalender"
|
||||||
|
|
||||||
### Nächste Veranstaltungen
|
### Nächste Veranstaltungen
|
||||||
|
|
||||||
<table id="upcoming" class="table table-condensed">
|
{{< upcoming >}}
|
||||||
</table>
|
|
||||||
|
|
||||||
Weitere Termine findest du im [Veranstaltungskalender](/verein/calendar/).
|
Weitere Termine findest du im [Veranstaltungskalender](/verein/calendar/).
|
||||||
|
|
||||||
<script type="module" src="/js/upcoming.js"></script>
|
|
||||||
|
|
|
||||||
3
layouts/shortcodes/upcoming.html
Normal file
3
layouts/shortcodes/upcoming.html
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
{{- $js := resources.Get "js/upcoming.js" | js.Build (dict "minify" true "format" "esm" "target" "es2020") | fingerprint -}}
|
||||||
|
<table id="upcoming" class="table table-condensed"></table>
|
||||||
|
<script type="module" src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}"></script>
|
||||||
Loading…
Reference in a new issue