Saving an event wrote it in the user's zone, so a title change moved a
New York meeting to Europe/Berlin. The form now shows and saves the
times on the event's own clock, with a time zone field ("Time zone: New
York", or a "Time zone" link when it is yours), and the popover shows
"10:00–11:00 New York (16:00–17:00 your time)". The form asks for the
date and time right after the title and for the description last.
Participant answers read in plain words ("Not answered yet"), the
untitled preview is translated, and the quick editor grows to fit long
calendar names.
Changed assertions: rsvp-buttons.test expects the plain status key, and
event-modal-organizer.test expects an unchanged save to keep the event's
New York zone instead of rewriting it into the user's.
With two accounts signed in, Calendar showed only the active one's
calendars. Now, as in the Pro interface, the sidebar lists each
account's calendars under its name, each with its own checkbox, ticked
by default, and the grid shows the ticked ones together. Creating,
editing, moving, deleting and answering an event of the other account
go through that account; tasks of all accounts are listed and change in
their own account.
- a calendar one account sees as shared and the other owns shows once
- a load or push that names one account keeps the merged list
- an event made in the other account's calendar no longer takes the id
of the active account's event with the same raw id
- a change to an event the store no longer holds still goes to the
account its id names
The tasks view filtered tasks by the grid's calendar selection, which
never holds a task-only list such as "To-do". Those tasks never showed
while the sidebar counted them, and a task moved into To-do vanished on
save. The tasks view now has its own task lists in the sidebar, ticked
by default, and the grid's selection is left alone.
- tasks are on by default; an "off" the user never chose turns on, one
they chose stays
- new tasks go to the first task-only list
- "Add a task…" reads a date at the end of the title (tomorrow, Friday,
12.11.) into the due date and shows it as a chip first
- the task status says "Not started" and "In progress"
filterTasksForList now takes the unticked task lists instead of the
selected calendars, so task-plugin-surfaces passes the unticked list and
task-list-dates no longer passes selectedCalendarIds.
The review found the store key readable from a copy of the disk. The
desktop app only added its OS layer with the lock on, the record from
before a lock stayed in LevelDB and opened the mail with no PIN, any
frame could unwrap the PIN record and guess at it, a lock left the key
in the renderer's memory, and a store waiting after a refused login went
to whoever signed in next under the same username@host.
- The desktop app wraps the store key with safeStorage, lock or no lock.
A record without the layer gets it at its next open. A refusal is said
out loud, and only a computer with no key store goes without, which
settings say. So do they for a browser, which has no such layer.
- A record that gained layers, and every record after a changed PIN, asks
for a new key: `sqlite3_backup` into a new file under a new key while
the store keeps working, one write to the record, then the old file
goes. A changed PIN makes a new lock key, since the old PIN's record
stays on disk too. The passkey and OS unlock go with the old key.
- `wrap` and `unwrap` come through `claim()`, and the key under the PIN
takes a secret from main, one counted trip per guess.
- A lock on the desktop ends the renderer rather than reload in it.
- A sign-in compares the waiting store's JMAP account and server first,
and wipes on a mismatch. The account id keeps its form: every store,
setting and server record of an account is keyed by it.
- The 30 days also run in an app that stays open.
Changes an existing assertion: turning the lock off now keeps the
safeStorage layer, by decision, so that test expects it to stay.
The shell now takes a message's signed attributes where it took a digest,
so a page can't get a login or TLS digest signed. A quiet option lets a
plugin answer from what's allowed, for anything the user didn't ask for.
An admin's install no longer covers the certificates on someone's own
computer: a managed plugin gets `keystore` when that person says yes, also
when an update adds it, and it's forgotten once everyone has signed out.
Changed test assertions: the fixture plugin needs a grant now, as managed
alone is no longer enough, and the bridge gets an options argument.
A wipe by name took any username and server with no session behind it. It
now needs a sealed cookie the account got while it was signed in, since a
dropped account has no session cookie left. The old wipe test asserted that
a name alone was enough, which is the behaviour being removed.