Skip to content

Releases: michaelsanford/Mortimer

v1.1.1

Choose a tag to compare

@github-actions github-actions released this 07 Aug 16:36
30a68dd

Loonie · patch release

A security and CI maintenance release. No user-facing behaviour changes — all calculations, storage, and UI are identical to v1.1.0.

Security

Four transitive dependencies carrying high-severity advisories are now pinned to patched releases. All four reached the project through a single devDependency, @cyclonedx/cyclonedx-npm (the SBOM generator), and none of them were ever part of the shipped browser bundle — no deployed version of Mortimer was exposed.

Package Advisory Pinned to
brace-expansion DoS via unbounded expansion length / intermediate arrays (bypassing the CVE-2026-14257 mitigation) 2.1.4
fast-uri GHSA-7p8r-x3mc-p8w7 3.1.5
ip-address GHSA-mwp4-54f8-5fhr — SSRF / trust-boundary bypass, plus two moderates 10.4.0
js-yaml Quadratic CPU consumption in !!omap resolution (CVE-2026-59870 not backported) 4.3.1

Each pin is the minimum patched release inside the existing major version, so no consumer in the dependency chain sees a breaking change.

One moderate advisory is also resolved: postcss moves to 8.5.26, clearing GHSA-fxqj-rqcc-2cmp — an incomplete fix of GHSA-6g55-p6wh-862q where an attacker-controlled sourceMappingURL could read arbitrary .map files when from is unset.

npm audit reports 0 high or critical findings, down from 3 high. A single moderate remains (tar, GHSA-r292-9mhp-454m), below the pipeline's high gate.

Fixed

  • Vulnerability scan results now reach GitHub code scanning. The SBOM & Vulnerability Scan job had never successfully uploaded its SARIF report. Grype derives each result's physicalLocation.artifactLocation from the scan source's file paths, and a CycloneDX SBOM from cyclonedx-npm records none, so every upload was rejected with locationFromSarifResult: expected artifact location. The gate was correctly failing builds, but the findings were only ever visible in raw job logs. A new normalization step anchors location-less results to package-lock.json before upload.

  • Qodana no longer fails on Dependabot pull requests. Dependabot-triggered pull_request runs read from the Dependabot secret store, so QODANA_TOKEN resolved empty and the scan exited 1 on its license check before analysing anything. The job is now skipped for that actor; pushes to main and the weekly scheduled scan still cover the full tree.

What's Changed

Toolchain also advanced since v1.1.0: TypeScript 7, @types/node 26, cyclonedx-npm 6, Vite 8.1.5, oxlint 1.75, Vitest 4.1.10. Runtime dependencies moved only within patch/minor — React 19.2.8, lucide-react 1.25.

Verifying this release

Artifacts are signed keylessly with cosign via GitHub OIDC, and carry build provenance attestations.

# Verify the signature bundle
cosign verify-blob mortimer-v1.1.1.zip \
  --bundle mortimer-v1.1.1.zip.bundle \
  --certificate-identity-regexp '^https://github\.com/michaelsanford/Mortimer/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

# Verify build provenance
gh attestation verify mortimer-v1.1.1.zip --repo michaelsanford/Mortimer

A CycloneDX SBOM for this release is attached as mortimer-v1.1.1-sbom.json.

Full changelog: v1.1.0...v1.1.1

v1.1.0

Choose a tag to compare

@github-actions github-actions released this 21 Jul 21:38
8f32a34

What's Changed

Full Changelog: v1.0.0...v1.1.0

v1.0.0

Choose a tag to compare

@github-actions github-actions released this 10 Jul 19:48
0f9ac95

Mortimer v1.0.0 — "Loonie" 🪙

First Full Release 🎉 💰

The definitive first production release of Mortimer, a privacy-first Progressive Web App for simulating mortgage paydowns, comparing renewal and refinancing offers, and planning home equity borrowing — built specifically for Canadian mortgages.

Every calculation runs 100% in your browser. No backend, no analytics, no cookies — your financial data never leaves your device.

✨ Highlights

📊 Dashboard

An at-a-glance view of your mortgage profile: remaining balance, interest paid to date, overall progress paid off, and time saved from extra payments.

💸 Paydown Simulator

Model lump-sum payments, double-up schedules, and payment increases, then watch your amortization shorten in real time. Includes an outcome zone, household-income and estimated-net-income context, delta rows, and the ability to pull offers directly from the Rates Comparer.

🔁 Rates Comparer

Compare renewal and refinancing scenarios side-by-side, including IRD and three-month interest penalty models, break-even analysis, a comparison charts dashboard, and estimated remaining amortization at term end. Export scenarios as calendar reminders (ICS) or a printable report.

🏠 Reno & HELOC Planner

Estimate available home equity under Canadian regulatory caps (80% LTV total / 65% HELOC limit), reorder renovation projects, and plan financing with an editable checklist.

📈 Variable-Rate Stress Testing

Stress-test variable-rate scenarios, view break-even charts, and calculate your trigger rate.

🍁 Canadian Mortgage Math

Correct semi-annual compounding for fixed rates and monthly compounding for variable rates, across every payment frequency:

  • Monthly, semi-monthly
  • Bi-weekly (regular & accelerated)
  • Weekly (regular & accelerated)

🔐 Privacy & Security

  • Fully client-side — data stored only in browser localStorage
  • Optional passcode lock with AES-GCM encryption and PBKDF2 key derivation (100,000 iterations)
  • WebAuthn biometric unlock layered on top of your PIN
  • Automatic session inactivity auto-lock
  • Export / import profiles; one-click clear-all-data
  • PIPEDA and Loi 25 (Quebec) compliant

🌐 Localization & UX

  • Bilingual English / French interface with locale-aware number and currency formatting
  • System theme matching (light / dark)
  • Guided onboarding tour
  • Full offline support via service worker, with an in-app update banner
  • Debounced autosave with visual status indicators
  • Installable as a PWA with a fixed mobile bottom-nav

🛠️ Tech Stack

React 19 + TypeScript 6 · Vite 8 · Chart.js · Lucide icons · Oxlint

✅ Quality & Supply Chain

  • Vitest test suite with V8 coverage reporting in CI
  • Qodana static analysis
  • CycloneDX SBOM generation with Grype vulnerability scanning (high/critical CVEs fail the build)
  • Content Security Policy and security headers

Full documentation: see the README · Versioning scheme: VERSIONING.md

Released under the MIT License.

What's Changed

  • feat(pwa): full offline support and update banner by @michaelsanford in #7
  • fix(deploy): split upload and deploy into separate jobs to prevent duplicate pages artifact by @michaelsanford in #8
  • fix(sw): use unambiguous placeholder so swVersionPlugin replaces code not comment by @michaelsanford in #10
  • feat(paydown): outcome zone, double-up slider, taller chart, household income by @michaelsanford in #11
  • Add qodana CI checks by @qodana-cloud[bot] in #12
  • fix(qodana): resolve reported static analysis warnings by @michaelsanford in #13
  • chore(git): ignore Qodana SARIF reports and organize README badges by @michaelsanford in #14
  • feat(comparer): improve renewal comparison table and add charts dashboard by @michaelsanford in #15
  • test(comparer): add component integration tests and resolve linter warnings by @michaelsanford in #16
  • fix(comparer): resolve qodana findings for redundant conditionals and duplicate test code by @michaelsanford in #17
  • Add code coverage (Vitest V8) and remediate 0% components by @michaelsanford in #18
  • CI health: fix flaky async tests + bump deprecated action versions by @michaelsanford in #19
  • feat(paydown): connect simulator to rates comparer offers by @michaelsanford in #20
  • feat(ux): implement system theme matching, onboarding tour, and HELOC project reordering by @michaelsanford in #21
  • feat(modeling): implement variable rate stress testing, break-even chart, dual ICS exports, and print report action by @michaelsanford in #22
  • feat(security): implement webauthn biometric unlock, settings, and session inactivity auto-lock by @michaelsanford in #23
  • fix: lint error, qodana trigger, stress test slider placement by @michaelsanford in #24
  • fix: resolve Qodana code quality findings by @michaelsanford in #25
  • fix(simulator): paydown simulator fixes, renaming, delta and estimated net income rows by @michaelsanford in #26
  • feat(locale): add locale-aware inputs and formatted numeric displays by @michaelsanford in #27

New Contributors

  • @qodana-cloud[bot] made their first contribution in #12

Full Changelog: v0.1.0...v1.0.0

v0.6.0 - Half-Dollar

v0.6.0 - Half-Dollar Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Jul 17:35
0b05bae

What's Changed

  • feat(ux): implement system theme matching, onboarding tour, and HELOC project reordering by @michaelsanford in #21
  • feat(modeling): implement variable rate stress testing, break-even chart, dual ICS exports, and print report action by @michaelsanford in #22
  • feat(security): implement webauthn biometric unlock, settings, and session inactivity auto-lock by @michaelsanford in #23
  • fix: lint error, qodana trigger, stress test slider placement by @michaelsanford in #24
  • fix: resolve Qodana code quality findings by @michaelsanford in #25

Full Changelog: v0.5.0...v0.6.0

v0.5.0 - Shinplaster

v0.5.0 - Shinplaster Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 06 Jul 00:19
2f9f629

What's Changed

Full Changelog: v0.4.0...v0.5.0

v0.4.0 - Quarter

v0.4.0 - Quarter Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 05 Jul 03:43
7a4daa4

What's Changed

  • Add qodana CI checks by @qodana-cloud[bot] in #12
  • fix(qodana): resolve reported static analysis warnings by @michaelsanford in #13
  • chore(git): ignore Qodana SARIF reports and organize README badges by @michaelsanford in #14
  • feat(comparer): improve renewal comparison table and add charts dashboard by @michaelsanford in #15
  • test(comparer): add component integration tests and resolve linter warnings by @michaelsanford in #16
  • fix(comparer): resolve qodana findings for redundant conditionals and duplicate test code by @michaelsanford in #17

New Contributors

  • @qodana-cloud[bot] made their first contribution in #12

Full Changelog: v0.3.0...v0.4.0

v0.3.0 - Dime

v0.3.0 - Dime Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 04 Jul 01:32
e1161ca

What's Changed

  • feat(paydown): outcome zone, double-up slider, taller chart, household income by @michaelsanford in #11

Full Changelog: v0.2.0...v0.3.0

v0.2.0 - Nickel

v0.2.0 - Nickel Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Jul 20:22
32b5639

What's Changed

  • feat(pwa): full offline support and update banner by @michaelsanford in #7
  • fix(deploy): split upload and deploy into separate jobs to prevent duplicate pages artifact by @michaelsanford in #8
  • fix(sw): use unambiguous placeholder so swVersionPlugin replaces code not comment by @michaelsanford in #10

Full Changelog: v0.1.0...v0.2.0

v0.1.0 - "Penny"

v0.1.0 - "Penny" Pre-release
Pre-release

Choose a tag to compare

@github-actions github-actions released this 03 Jul 19:26
f98b71b

Mortimer v0.1.0 — Penny 🪙

The humble first coin. Now phased out, but historically iconic — and so begins Mortimer.

We're excited to ship the very first public release of Mortimer, a privacy-first Progressive Web App for Canadian mortgage planning. Every calculation runs entirely in your browser — no data ever leaves your device.


✨ What's in this release

Core App

Mortimer launches with four fully-featured tools tailored to the nuances of the Canadian mortgage market:

  • Dashboard — an at-a-glance summary of your mortgage profile: remaining balance, interest paid to date, and time saved through accelerated payments.
  • Paydown Simulator — model lump-sum payments, double-up schedules, and payment increases to see exactly how much amortization time each strategy saves.
  • Rates Comparer — compare renewal offers and refinancing scenarios side-by-side, including IRD and three-month interest penalties.
  • Reno & HELOC Planner — estimate available home equity and plan renovation financing through a HELOC.
  • Settings & Privacy — export and import profiles, enable optional passcode encryption via Web Crypto API key derivation, and clear all local data.

All mortgage math uses semi-annual compounding (Canada's statutory standard) and supports all common payment frequencies: monthly, semi-monthly, bi-weekly (regular and accelerated), and weekly (regular and accelerated).

Internationalization

Mortimer ships with support for 7 languages out of the box, including English and French (Canada's two official languages) plus the top non-official community languages in Canada:

Language Locale
English en
French fr
Arabic ar
Punjabi pa
Spanish es
Chinese (Simplified) zh
Chinese (Traditional, HK) zh-HK

The language picker UI has been redesigned for clarity and ease of use.

Privacy & Compliance

  • 100% client-side — no backend, no analytics, no cookies
  • Optional passcode lock with Web Crypto key derivation
  • PIPEDA and Loi 25 (Quebec) compliant
  • Data stored only in browser localStorage

Supply Chain Security

Mortimer's CI pipeline generates a CycloneDX 1.6 SBOM on every run, published as a build artifact, and scans it automatically for known vulnerabilities using Grype. The deploy workflow is gated on a clean CI run, so no build with a failing vulnerability scan can reach production.


🔧 Infrastructure

  • CI pipeline with SBOM generation and vulnerability gate
  • GitHub Pages deployment, gated on CI success
  • Automated release workflow with version-stamped footer

What's Changed

PR Change
#1 Add CycloneDX SBOM generation and Grype vulnerability gate
#2 Gate Deploy workflow on a successful CI run
#3 Unbounded number inputs and aligned dropdown caret
#4 Add top 5 Canadian non-official languages and redesigned language picker
#5 Standard release and deploy workflow with footer version stamp
#6 Add VERSIONING.md — currency-themed release codename convention

Full Changelog: https://github.com/michaelsanford/Mortimer/commits/v0.1.0