Skip to content

Data structures for E2EE push keys#2193

Merged
gnprice merged 17 commits intozulip:mainfrom
gnprice:pr-e2een-keys
Mar 9, 2026
Merged

Data structures for E2EE push keys#2193
gnprice merged 17 commits intozulip:mainfrom
gnprice:pr-e2een-keys

Conversation

@gnprice
Copy link
Copy Markdown
Member

@gnprice gnprice commented Mar 3, 2026

Toward #1764. Stacked atop #2181.

This PR adds a table PushKeys, and substores PushKeyStore and GlobalPushKeyStore, to manage remembering our encryption keys for end-to-end-encrypted push notifications #1764.

@gnprice gnprice requested a review from chrisbobbe March 3, 2026 05:53
@gnprice gnprice added the maintainer review PR ready for review by Zulip maintainers label Mar 3, 2026
@gnprice
Copy link
Copy Markdown
Member Author

gnprice commented Mar 3, 2026

This is ready for review. But like #2181, it won't be ready for merge until #2158 is complete, excluding data from backups.

@gnprice gnprice marked this pull request as draft March 3, 2026 05:55
Copy link
Copy Markdown
Collaborator

@chrisbobbe chrisbobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great! Just one nit below, otherwise LGTM.

Comment on lines +70 to +74
Future<PushKey> doInsertPushKey(PushKeysCompanion data);

Future<void> doUpdatePushKey(int pushKeyId, PushKeysCompanion data);

Future<void> doRemovePushKey(int pushKeyId);
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could add dartdocs for these, like the global-settings methods above

@gnprice
Copy link
Copy Markdown
Member Author

gnprice commented Mar 4, 2026

Thanks! Revision pushed.

@gnprice gnprice force-pushed the pr-e2een-keys branch 2 times, most recently from 3c87713 to 07d1f40 Compare March 8, 2026 20:59
@chrisbobbe
Copy link
Copy Markdown
Collaborator

LGTM!

gnprice added 17 commits March 9, 2026 14:59
In particular, updating the generated code for `build_runner` first
and `drift` later goes a bit smoother: if going in the other order,
one has to make a temporary commit in between in order to reassure
the `build_runner` suite it won't clobber the output of `drift`.
Initially when adding the deviceId column, I'd forgotten that this
bit of code existed and needed updating.  The result was some
confused debugging, as the column remained stubbornly null in the
tests' data no matter how I initially tried to give it a value.

To prevent that happening again, I wrote up a somewhat ridiculous
(but effective) check, involving a switch in a loop, to remind us
to update this code:
  zulip#2181 (comment)
Then I filed a feature request in Drift upstream for a way to
automate this away entirely.

From that thread, here's a workaround to automate this construction
today.  It's a bit more complex than ideal, but much nicer than the
manual code we had.
This should make it significantly less tedious to add and test
further migrations that just add columns to this table.
As a bonus, we add coverage for several migrations that are boring
enough that they previously hadn't been worth the tedium.  Now they
only add one line each to the test, plus a one-line comment to
match the list up.
This will let us keep things clean as we add additional fields whose
values get generated by the client rather than set by the user or
the server.
This diff is mostly indentation; try `git diff -b` to read it.

All these existing tests are for the legacy pre-E2EE notification
subsystem, so have them explicitly use a pre-E2EE feature level.

As we start implementing the new system and adding logic that
conditions on the E2EE notifications feature, we'll add corresponding
tests here that use a current feature level.
I think we won't end up ever making the change this suggested,
and that's fine.  Discussion here:
  zulip#2181 (comment)

On the other hand it would be good to register the token proactively
for all accounts, not just the current one, in case it's changed.
Filed that as its own issue, zulip#2197.
This comment is from the very early prototype of this app, and
refers to a data structure from the legacy app.

 * The push token wound up on NotificationService, in a
   ValueNotifier of its own.

 * Two other fields on the legacy app's GlobalSessionState are
   `orientation` and `isOnline`, both referring to state of the
   device, for which Flutter has better APIs than putting the data
   on the app's global state object.

 * The remaining field is `isHydrated`, which is false only when the
   legacy app hasn't yet loaded data from its database.  That
   effectively means that none of the data in most of the rest of
   the store can be trusted, because it's all just bogus initial
   values that the various Redux substates start with.  In the new
   app, we eliminate that whole problem architecturally: there is no
   GlobalStore until we have non-bogus data to put into it.
This line was getting a bit long to read.
@gnprice
Copy link
Copy Markdown
Member Author

gnprice commented Mar 9, 2026

Thanks for the reviews! Merging, since #2160 is in.

@gnprice gnprice merged commit 0cacaf4 into zulip:main Mar 9, 2026
2 checks passed
@gnprice gnprice deleted the pr-e2een-keys branch March 9, 2026 23:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

maintainer review PR ready for review by Zulip maintainers

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants