Tags give the ability to mark specific points in history as being important
-
v2.1.2
protected97f23394 · ·v2.1.2 A weather lens for the week, and themes you can write yourself. The thermometer button in the toolbar lays an hourly forecast over the calendar: a temperature wash per hour, rain bars scaled by amount and faded by how likely the rain is, a high and low per day in the header, and DWD severe-weather warnings on a row of their own. The calendar recedes underneath while the lens is up and comes straight back when it closes. The day view is the same component with one column, so it gets the lens too. Nothing is fetched or drawn until you press the button, and the lens starts closed on every load. It is something you reach for, not a mode you leave the calendar in, so settings hold only the configuration: a location and a source. The forecast is fetched by the server rather than the page. The app's own CSP is connect-src 'self', so the page could not reach a weather host in any case, and this way your coordinates never leave your instance. Operators who would rather not depend on a public endpoint can point WEATHER_BRIGHTSKY_URL at their own Bright Sky. The data is DWD's, published under CC BY and GeoNutzV, and the credit rides on the grid while the lens is up. Alongside it, two changes to theming. Blacksite is a third built-in theme: carbon ground, one red accent, squared corners and monospace type, with destructive actions pushed off the accent so Delete still reads as Delete. And there is now a Custom theme, which is a layer rather than a blank page. Pick which built-in theme to start from, override individual colour tokens, and add up to 16 KiB of your own CSS on top. It is stored on your account rather than the device, so it follows you everywhere you sign in. If a stylesheet ever leaves the app unusable, open it with ?safemode=1 to load without it; the editor still works, so you can fix the rule or reset. Android: versionCode 8.
-
v2.1.1
protected28671a13 · ·v2.1.1 The APK no longer carries Google's encrypted dependency-metadata block. Android's build tools embed that blob into every signed APK by default: the app's dependency list, encrypted with a Google public key and readable only by Google. This app is not distributed through Google Play, so it was never anything but dead weight, and F-Droid refuses an APK that carries one. Removing it is what lets the official F-Droid build ship this exact signed APK instead of a differently signed rebuild. F-Droid builds the app from source on its own infrastructure, compares the result against this release byte for byte, and distributes this file when the two match. The GitLab release, the project's own F-Droid repository and the official F-Droid repository are therefore one signing key, and moving between them is an ordinary upgrade rather than an uninstall that would take your calendar with it. No functional changes.
-
v2.1.0
protected1c0da59d · ·hypercal 2.1.0 A new name, a from-source build, and a server that is markedly harder to attack. **`WEBAUTHN_ORIGIN` is now required in production.** A server started with `NODE_ENV=production` and no `WEBAUTHN_ORIGIN` refuses to boot. Set it to the public origin people reach the instance on, scheme included — e.g. `https://calendar.example.com`. It is not a convenience setting: without it a passkey assertion is checked against the caller's own `Origin` header, which is a check that can only pass. `WEBAUTHN_RP_ID` remains optional and defaults to that origin's hostname. `AUTH_DEV_AUTOLOGIN=1` together with `NODE_ENV=production` is now fatal rather than a warning — it treats every session-less request as a seeded admin, which is a complete authentication bypass. The Playwright suites run as the new `NODE_ENV=e2e`, which is production behaviour in every respect that matters and tolerates the bypass the harness needs. Nothing else needs attention. The schema migrates itself and the Android package identifiers are unchanged, so this is an ordinary in-place update. The name is shorter everywhere a person reads it — launcher, PWA manifest, browser tab, F-Droid listing — with a new icon and a refreshed set of screenshots. `dev.hypercalendar.app` is untouched, and so is the CalDAV realm string: clients cache credentials against (host, realm), so renaming it would make every configured device re-prompt for its app password in exchange for a name nobody ever sees. The SQLite engine the on-device backend runs on is now compiled from source during the build — emscripten, in CI — instead of arriving as the prebuilt `.wasm` inside `@sqlite.org/sqlite-wasm`. F-Droid builds every APK from source on their own infrastructure and their scanner rejects a prebuilt binary outright, so this is what makes a from-source build possible at all. Doing it in our pipeline too, rather than only inside the F-Droid recipe, is the point: the published APK and the one F-Droid builds now run the same engine, and the standalone test suite exercises it on every tag instead of leaving it a path only their reviewer discovers is broken. - **Per-username login throttling.** The existing per-IP limiter cannot help with the case that actually matters for a password: many hosts making a few attempts each against one account, which stays under every per-IP ceiling indefinitely. Failures are now counted against the account itself, wherever they come from. It is a throttle and not a lockout — each failure past a small free allowance imposes a doubling delay, so knowing a family member's username is not a way to lock them out of their own calendar. Failed CalDAV Basic auth feeds the same counter. - **Origin checking on state-changing `/api` requests.** `SameSite=Lax` cookies already stop a cross-site POST, but Lax treats sibling subdomains as same-site, so an untrusted neighbour under the same registrable domain was not covered. Requests carrying an `Origin` must now match this instance's; requests with no `Origin` are unaffected, because they did not come from a browser being tricked. `CSRF_ALLOWED_ORIGINS` adds deliberate extras. - **Passkey sign-in no longer skips 2FA when it proves only possession.** User verification is requested as "preferred", so an authenticator that performs none still returns a valid assertion. For an account that has deliberately enabled TOTP, that assertion now falls through to the same second step the password flow uses. - **A real Content-Security-Policy for the SPA shell.** The one inline script — the pre-paint theme read — is allowed by a hash computed at startup from the file the server is about to serve, rather than by `'unsafe-inline'` or by a constant that drifts the next time someone edits the shell. - **SSRF hardening** on the outbound fetches behind ICS subscriptions and remote CalDAV links, with the same guard shimmed into the on-device backend. - **Signing out wipes the device.** The offline event cache, the pending write queue, the conflict list and the service worker's cached `/api/events` responses are all cleared, so the next account on a shared device starts clean. - **A leaner, pinned container.** Base images are pinned by digest, and the native build toolchain `better-sqlite3` needs is confined to a build stage instead of shipping to production. `docker-compose.yml` is now a hardened reference deployment — read-only root filesystem, no new privileges. The security model, security policy, deployment and self-hosting pages have all been reworked around the above, including what the optional per-calendar encryption does and does not defend against.
-
-
v2.0.2
protected9e1f2289 · ·hyper-calendar 2.0.2 The app now has a name, a face, and a way to talk back. Android and F-Droid * The app is called **Hyper-Calendar** everywhere a person reads it — launcher, PWA manifest, browser tab and the F-Droid listing. Package identifiers are unchanged, so this is an ordinary in-place update. * A real launcher icon. Every density shipped Capacitor's scaffolding artwork until now, as did all eleven splash screens. The mark is rendered from SVG sources in assets/ via 'npm run icons'. * Reminder notifications get their own status-bar icon. capacitor.config.ts had always named an ic_stat_icon resource that did not exist, so they fell back to a generic system glyph. The F-Droid listing shows images at last 'fdroid update' reads per-app images from fdroid/repo/<applicationId>/<locale>/, and nothing ever put them there — so the app page had no screenshots, no banner, and only whatever icon could be scraped from the APK. It now carries an icon, a feature graphic and four screenshots, generated from the running app by 'npm run screenshots'. About and feedback, in the app * Account menu -> About: version, build, deployment mode, licence and links. Until now there was nowhere in the app to read the version the issue tracker keeps asking reporters for. * Account menu -> Send feedback: describe what happened and it composes a report with the version, deployment mode, platform, browser, locale, timezone and window size already filled in, then opens a prefilled GitLab issue. Nothing is sent by the app — the diagnostics are shown and editable first, and the issue is public. Documentation The site is the single source of truth: the repository's markdown is now short pointers to it, and the site itself finally shows the product. This is the first release whose APK is built and signed by CI rather than uploaded by hand. Getting there took two fixes to that job: it died of SIGPIPE after accepting the SDK licences, and then needed a JDK 21 image, which Capacitor 8 requires and Debian 12 cannot provide.
-
v2.0.1
protected130ef4f2 · ·hyper-calendar 2.0.1 Corrected reverse-proxy documentation; APK re-signed with a new release key (CN=hyper-calendar). Not upgradeable in place from 2.0.0.
-
v2.0.0
protectedcbff2609 · ·hyper-calendar 2.0.0 First published release. Renamed from weekcal. Docker image: registry.gitlab.com/kreuz-com-group/hyper-calendar:2.0.0 APK: dev.hypercalendar.app versionCode 2