github ulsklyc/yuvomi v2.56.0

one hour ago

Added

  • Reminders can be delivered by email. Households without a native app fell back to keeping a
    browser tab open: reminders reached Web Push, Gotify, ntfy or a webhook, and nothing else (#944).
    Email is now a fourth channel type next to those three, configured the same way under
    Settings → Personal → Notifications.

    It deliberately brings no credentials of its own. The SMTP access already configured for password
    resets and invitations is the one it uses, so a mail server is set up once and not once per
    channel - a second copy would only be a second place to forget when the server changes. A channel
    therefore holds just a recipient address; a second recipient is a second channel, which keeps each
    one separately switchable and separately testable. Who gets a reminder is still decided by the
    channel's scope, exactly as for the other providers.

    Two details are worth knowing. Web Push splits a reminder across title and body, but an inbox
    shows only the subject line, so the mail puts both there - "Calendar: Dentist" rather than
    "Calendar". And the link back into the app needs BASE_URL; without it the mail arrives without a
    link rather than with a dead one. The provider list marks email as not ready while SMTP is
    unconfigured, so the settings page says so before a test send fails.

    A note for anyone tracking health data: an email channel carries reminder contents in the subject
    line, medication names included, and subject lines stay readable in transit and permanently in the
    recipient's mailbox. docs/PRIVACY-FOR-SELFHOSTERS.md covers what that means.

  • A shopping list can be sent to whoever is doing the run. The second half of #944. An entry in
    the list's overflow menu mails its open items to one household member, grouped by aisle in the same
    order the screen shows them.

    It sends a snapshot, not an access route - no link, no token, nothing that outlives the message.
    A read-only share URL was the other obvious shape and was deliberately not built: it would have
    been the first unauthenticated view of household data in Yuvomi, and a leaked link stays leaked.
    Someone who needs the list continuously is a household member and already has the app. Because a
    snapshot goes stale the moment someone at home ticks an item off, the mail says which moment it
    captured rather than pretending to be live.

    The recipient is picked from the household, and only members with an address on their contact
    appear - the same source password reset mails use. The address is never taken from the request:
    accepting one would make the instance an open mail relay for anyone with a login. Sending to
    yourself works too, which is the "get the list onto my phone" case, and then the mail skips the
    "X sent you this list" line.

    Needs SMTP configured. Three refusals are told apart rather than collapsed into one failure: the
    member has no address, SMTP is not set up, or nothing on the list is still open.

    Only actual household members can be picked, and that is narrower than "has an account". Housekeeping
    staff and shared-expense guests both have logins and both have a contact with an address on it -
    guests especially are external people who are blocked from every other part of the app. The rule that
    decides this is written once and used by both the picker and the send route, so the two cannot drift
    apart. An address field holding a list rather than one address makes that member unreachable instead
    of reaching everyone on it.

Fixed

  • The settings page works offline again. Its shell loads dirty-guard.js - the part that asks
    before you discard unsaved edits - and that file was never in the service worker's precache list.
    Online nobody noticed, because the network filled the gap. Offline the import failed and took the
    whole settings shell with it. The file is precached now.

    The date picker was missing the same way, and it is loaded by the router itself - so a first
    offline visit could get the HTML fallback instead of the module, on every page with a date field.

    The reason both went unnoticed is the more useful half. A guard does check that every module
    reachable from a precached one is itself precached, and it stayed green throughout: it read only
    imports written as from '/absolute/path'. The settings shell writes from './dirty-guard.js'
    and the router writes import '/components/datepicker.js' - a relative specifier and a
    side-effect import, both loaded by the browser exactly like any other. The guard now resolves both
    forms, which is how these were found in the first place.

Don't miss a new yuvomi release

NewReleases is sending notifications on new releases.