-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Handle cross-signing keys missing locally and/or from secret storage #31367
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Handle cross-signing keys missing locally and/or from secret storage #31367
Conversation
If cross-signing keys are missing both locally and in 4S, show a new toast saying that identity needs resetting, rather than saying that the device needs to be verified.
- move enum from SetupEncryptionToast to DeviceListener - DeviceListener has public method to get device state - DeviceListener emits events to update device state
brings RecoveryPanelOutOfSync in line with SetupEncryptionToast behaviour
rather than using its own logic
kaylendog
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some linting hints from Sonar, plus a few suggestions. Looks fine, otherwise!
src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx
Outdated
Show resolved
Hide resolved
src/components/views/settings/tabs/user/EncryptionUserSettingsTab.tsx
Outdated
Show resolved
Hide resolved
Co-authored-by: Skye Elliot <[email protected]>
fb83e3e to
edc4d81
Compare
kaylendog
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wonderful, I think this is fine now!
| /** | ||
| * The state of the device and the user's account. | ||
| */ | ||
| export enum DeviceState { | ||
| /** | ||
| * The device is in a good state. | ||
| */ | ||
| OK = "ok", | ||
| /** | ||
| * The user needs to set up recovery. | ||
| */ | ||
| SET_UP_RECOVERY = "set_up_recovery", | ||
| /** | ||
| * The device is not verified. | ||
| */ | ||
| VERIFY_THIS_SESSION = "verify_this_session", | ||
| /** | ||
| * Key storage is out of sync (keys are missing locally, from recovery, or both). | ||
| */ | ||
| KEY_STORAGE_OUT_OF_SYNC = "key_storage_out_of_sync", | ||
| /** | ||
| * Key storage is not enabled, and has not been marked as purposely disabled. | ||
| */ | ||
| TURN_ON_KEY_STORAGE = "turn_on_key_storage", | ||
| /** | ||
| * The user's identity needs resetting, due to missing keys. | ||
| */ | ||
| IDENTITY_NEEDS_RESET = "identity_needs_reset", | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use string union? It allows more flexibility
| await deviceListener.whilePaused(async () => { | ||
| await accessSecretStorage(async () => { | ||
| // Reset backup if needed. | ||
| if (needsBackupReset) { | ||
| await resetKeyBackupAndWait(crypto); | ||
| } else if (await matrixClient.isKeyBackupKeyStored()) { | ||
| await crypto.loadSessionBackupPrivateKeyFromSecretStorage(); | ||
| } | ||
| }); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is happening if this promises are rejected?
| return render( | ||
| <MatrixClientContext.Provider value={MatrixClientPeg.safeGet()}> | ||
| <RecoveryPanelOutOfSync onFinish={onFinish} onForgotRecoveryKey={onForgotRecoveryKey} /> | ||
| </MatrixClientContext.Provider>, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| return render( | |
| <MatrixClientContext.Provider value={MatrixClientPeg.safeGet()}> | |
| <RecoveryPanelOutOfSync onFinish={onFinish} onForgotRecoveryKey={onForgotRecoveryKey} /> | |
| </MatrixClientContext.Provider>, | |
| ); | |
| return render(<RecoveryPanelOutOfSync onFinish={onFinish} onForgotRecoveryKey={onForgotRecoveryKey} />, withClientContextRenderOptions(matrixClient)); |
| describe("<RecoveyPanelOutOfSync />", () => { | ||
| function renderComponent(onFinish = jest.fn(), onForgotRecoveryKey = jest.fn()) { | ||
| return render(<RecoveryPanelOutOfSync onFinish={onFinish} onForgotRecoveryKey={onForgotRecoveryKey} />); | ||
| stubClient(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid using MatrixClientPeg.safeGet(), prefer to create the matrix client and put it an a context
| stubClient(); | |
| createTestClient(); |
| .mockImplementation(async (func = async (): Promise<void> => {}) => { | ||
| return await func(); | ||
| }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we really need to call the function in mockImplementation? Or returning a promise for accessSecretStorage is enough?
| .mockImplementation(async (func = async (): Promise<void> => {}) => { | |
| return await func(); | |
| }); | |
| .mockResolvedValue(undefined) |
| } | ||
|
|
||
| afterEach(() => { | ||
| jest.restoreAllMocks(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| jest.restoreAllMocks(); | |
| jest.clearAllMocks() |
|
|
||
| const user = userEvent.setup(); | ||
| mocked(accessSecretStorage) | ||
| .mockClear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With jest.clearAllMocks() in afteEach, this not necessary
| expect(accessSecretStorage).toHaveBeenCalled(); | ||
| expect(onFinish).toHaveBeenCalled(); | ||
|
|
||
| expect(MatrixClientPeg.safeGet().getCrypto()!.resetKeyBackup).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto matrix client
| return this.deviceState; | ||
| } | ||
|
|
||
| private async setDeviceState(newState: DeviceState, logSpan: LogSpan): Promise<void> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
missing tsdoc
Fixes #31187 and parts of #30438
Best to review this commit-by-commit
Checklist
public/exportedsymbols have accurate TSDoc documentation.