Skip to content

Releases: Maxren2/ebbwell

v0.7.1 — Voice input detects the spoken language

Choose a tag to compare

@Maxren2 Maxren2 released this 29 Sep 17:06

Voice input understands the language you speak

  • Language detection. Whisper used to be told to expect the interface language, so French spoken with an English interface came out as English words and only the numbers were kept. Ebbwell now detects which of its languages is spoken (English, French, German, Arabic; the interface language wins near ties) and transcribes and reads the sentence in that language. It is still about 2 seconds after Stop on a laptop.
  • More everyday French in Quick entry, such as "petites règles", "mal de ventre", "mal aux seins", "règles très abondantes" and "rapport sexuel non protégé". Singular and plural now match either way ("crampe" / "crampes").

Upgrade: change the image to ghcr.io/maxren2/ebbwell:0.7.1. There is no configuration change, and the voice model already on your devices is kept.

v0.7.0 — Voice input with Whisper on the device

Choose a tag to compare

@Maxren2 Maxren2 released this 29 Sep 15:06

Voice input with Whisper, on the device (#2)

  • Settings → Voice input is a choice per device: Keyboard dictation (as before) or Whisper on this device.
  • With Whisper, Quick entry gets a Speak button. Say the day ("36.52, light bleeding, no cramps, headache, tired"), tap Stop, and the form fills in. What was heard is shown so you can correct it.
  • Speech is recognised in the browser (OpenAI's Whisper, run with ONNX Runtime WebAssembly in a background worker). The audio and the text never leave the device.
  • The model is downloaded once from your own Ebbwell server (never from the internet), only by signed-in users, and kept in the browser. Settings can download it ahead of time (on Wi-Fi) or remove it.

Configuration:

  • VOICE_MODEL=base (default, ~79 MB, more accurate, especially in Arabic), tiny (~43 MB, faster on old phones) or off. Both models are in the image, which is about 140 MB larger.
  • The microphone needs HTTPS.
  • New or changed security headers: Cross-Origin-Embedder-Policy: require-corp (lets the recogniser use several threads), 'wasm-unsafe-eval' in the CSP (WebAssembly only, not JavaScript eval), Permissions-Policy: microphone=(self). If your reverse proxy rewrites security headers, keep these.

Upgrade: change the image to ghcr.io/maxren2/ebbwell:0.7.0. No configuration change is needed. Voice input stays on the keyboard until someone picks Whisper in Settings.

See docs/DEPLOY.md § 13.

v0.6.0 — Partner-only accounts, quick entry, feedback

Choose a tag to compare

@Maxren2 Maxren2 released this 29 Sep 12:35

Partner-only accounts, quick entry and feedback

  • Follow a partner's cycle without tracking your own (#5). After accepting an invite, someone who hasn't logged anything is asked: Only follow {name}'s cycle or Also track my own cycle. In follow-only mode the app shows the shared cycle and Settings, and only the partner reminder is sent. Switch at any time in Settings; nothing is deleted.
  • Quick entry (#2). Type or dictate one sentence, like "36.52 at 6:45, light bleeding, no cramps, headache, tired", and the day's form fills in. It works in English, French, German and Arabic. Dictation uses your keyboard's microphone; Ebbwell reads the text in the browser only, and nothing is saved until you tap Save.
  • Report a bug / Suggest a feature in Settings (#1). They open the GitHub issue forms with only the app version and device type filled in. FEEDBACK_URL points them elsewhere (https) or off hides them. About now shows the version.

Also: buttons that are links (such as Export) use the normal text colour.

Upgrade: change the image to ghcr.io/maxren2/ebbwell:0.6.0. There is no required configuration change; FEEDBACK_URL is optional. Existing users keep the full app.

If your partner signs in through Authentik with OIDC_ALLOWED_GROUPS set, add them to that group.

v0.5.1 — Bug fixes

Choose a tag to compare

@Maxren2 Maxren2 released this 29 Sep 12:11

Bug fixes:

  • Signing out works immediately on Android. Tapping Sign out seemed to do nothing until the page was refreshed: Chrome held the response while it cleared the site data. The sign-out response no longer asks it to. The session cookie is still cleared, and API responses were never cached.
  • The tab bar stays at the bottom on iPhone (#4). After a system dialog or the keyboard, the bottom bar could start scrolling with the page in the installed app. The content now scrolls on its own and the tab bar is part of the layout.
  • Partner invites survive sign-in (#5). A partner who opened the invite link while signed out landed on an empty tracker after signing in. The invitation now reopens automatically.

Upgrade: change the image to ghcr.io/maxren2/ebbwell:0.5.1. There is no configuration change.

v0.5.0 — Languages

Choose a tag to compare

@Maxren2 Maxren2 released this 28 Sep 09:37

Languages: English, French, German and Arabic

  • Per-user choice in Settings → Units & defaults → Language. The default, Device language, follows the phone or browser.
  • Everything is translated: every screen, dates and month names, the server-rendered sign-in pages (password, two-factor, recovery codes, signed out) and the reminder notifications.
  • Arabic is laid out right-to-left. The temperature chart and PIN keypad keep their usual orientation, and dates use Western digits so they match what you type.
  • Adding a language: copy shared/i18n/en.ts. The compiler refuses a translation with missing or extra keys.

Also changed:

  • POST /api/account/password now returns a reason code with its error. The English message is still there.
  • /signed-out.html is now rendered by the server.

Upgrade: change the image to ghcr.io/maxren2/ebbwell:0.5.0. There is no configuration change. Existing users start on Device language.

The Arabic translation would benefit from a review by a native speaker. Corrections are welcome in shared/i18n/ar.ts.

Ebbwell 0.4.0 — two-factor authentication

Choose a tag to compare

@Maxren2 Maxren2 released this 28 Sep 06:28

Two-factor authentication for local accounts

  • Standard authenticator apps (TOTP, RFC 6238): Aegis, 2FAS, Google/Microsoft Authenticator, 1Password… Set it up in Settings → Account by scanning a QR code or typing the key.
  • 10 single-use recovery codes, shown once. You can create new ones later with your password plus a current code.
  • Sign-in: after the password, a code prompt (a recovery code works too). A code can't be reused, and wrong codes count toward the account lockout.
  • Policy: LOCAL_2FA=optional|required. With required, every local user must set it up right after their password before using the app. Recommended if you use LOCAL_LOGIN=everywhere.
  • Storage: the secret and recovery codes are encrypted at rest and covered by key rotation.
  • Lost phone and recovery codes: an administrator can use Reset two-factor, or run docker exec <container> node server/cli.ts disable-2fa <user>.

Single sign-on users keep using their identity provider's MFA (e.g. Authentik).

Image: ghcr.io/maxren2/ebbwell:0.4.0. See docs/DEPLOY.md §2.

Ebbwell 0.3.0 — local accounts

Choose a tag to compare

@Maxren2 Maxren2 released this 28 Sep 06:15

Local accounts with a network-restricted sign-in policy

Single sign-on (OpenID Connect) is now optional. You can also use local accounts (username + password), and you decide where passwords are accepted with LOCAL_LOGIN:

LOCAL_LOGIN Password sign-in
disabled (default) nowhere, single sign-on only
local-network only from LOCAL_NETWORKS, never through the public domain
everywhere anywhere (not recommended)
  • Fails closed. The connecting address and every forwarded client address must be local; any public or unparseable address means "outside". Passwords are never accepted over plain HTTP from outside.
  • No password form where passwords aren't allowed. The public domain goes straight to single sign-on.
  • Administration: create accounts with one-time temporary passwords (forced change at first sign-in), reset passwords, grant admin rights (also via OIDC_ADMIN_GROUPS), disable or delete accounts. The last admin can't be removed, and admins never see cycle data. A connection diagnostic shows how Ebbwell classifies your current connection.
  • Hardening: per-account lockout (10 failures → 15 min), per-device rate limit, login CSRF protection, timing-safe handling of unknown usernames.
  • Setup and recovery: bootstrap admin via ADMIN_USERNAME / ADMIN_PASSWORD. Recovery CLI: docker exec <container> node server/cli.ts reset-password <user>.
  • Plain-HTTP LAN access (http://nas-ip:port) works with a separate non-Secure session cookie.

Upgrade note: existing AUTH_MODE=oidc configurations keep working unchanged.

Image: ghcr.io/maxren2/ebbwell:0.3.0. See docs/DEPLOY.md §2.

Ebbwell 0.2.0

Choose a tag to compare

@Maxren2 Maxren2 released this 27 Sep 21:43

First public release.

Tracking and predictions

  • Daily log: bleeding, basal temperature (with disturbances), cervical mucus (Sensiplan categories), cervix, LH/pregnancy tests, sex, symptoms, mood, notes
  • Personal cycle statistics and FIGO 2018 regularity checks
  • Predictions with ranges and confidence levels; late-period detection
  • Ovulation confirmation: Sensiplan temperature rule (both exceptions), mucus peak, double check, LH
  • Opt-in Sensiplan evaluation (5-day / minus-8 rules)

New in this release

  • Reminders (Web Push): morning temperature, evening check-in, period coming, fertile window, partner's period. Discreet wording by default.
  • App lock: server-enforced PIN plus Face ID / Touch ID / fingerprint (WebAuthn), auto-lock, lockout after 5 wrong attempts. A PIN reset needs a fresh OIDC login.
  • Partner sharing: single-use invite link, read-only view with owner-chosen scopes. Notes and intimate data are never shared.

Security

  • OIDC login with PKCE (Authentik, Authelia, Keycloak, …)
  • AES-256-GCM encryption at rest, with key rotation
  • Strict CSP, CSRF protection, rate limiting, audit log
  • Daily encrypted backups

Image: ghcr.io/maxren2/ebbwell:0.2.0. See docs/DEPLOY.md.