Skip to content

Commit c8d9376

Browse files
authored
feat: Disable session lock when running in element-desktop (#30643)
* feat: Disable session lock when running in element-desktop * feat: Use Platform abstractions over direct invocation for session lock. * fix: Remove window.electron checks from session lock methods. * docs: Remove extraneous doc comments. * feat: Convert BasePlatform session methods to abstract methods. * fix: Check for PlatformPeg instance in session lock. * fix: Remove async marker from checkSessionLockFree
1 parent ca3060a commit c8d9376

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

src/BasePlatform.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,4 +508,19 @@ export default abstract class BasePlatform {
508508
* Begin update polling, if applicable
509509
*/
510510
public startUpdater(): void {}
511+
512+
/**
513+
* Checks if the current session is lock-free, i.e., no other instance is holding the session lock.
514+
* Platforms that support session locking should override this method.
515+
* @returns {boolean} True if the session is lock-free, false otherwise.
516+
*/
517+
public abstract checkSessionLockFree(): boolean;
518+
/**
519+
* Attempts to acquire a session lock for this instance.
520+
* If another instance is detected, calls the provided callback.
521+
* Platforms that support session locking should override this method.
522+
* @param _onNewInstance Callback to invoke if a new instance is detected.
523+
* @returns {Promise<boolean>} True if the lock was acquired, false otherwise.
524+
*/
525+
public abstract getSessionLock(_onNewInstance: () => Promise<void>): Promise<boolean>;
511526
}

src/components/structures/MatrixChat.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,6 @@ import { NotificationLevel } from "../../stores/notifications/NotificationLevel"
130130
import { type UserTab } from "../views/dialogs/UserTab";
131131
import { shouldSkipSetupEncryption } from "../../utils/crypto/shouldSkipSetupEncryption";
132132
import { Filter } from "../views/dialogs/spotlight/Filter";
133-
import { checkSessionLockFree, getSessionLock } from "../../utils/SessionLock";
134133
import { SessionLockStolenView } from "./auth/SessionLockStolenView";
135134
import { ConfirmSessionLockTheftView } from "./auth/ConfirmSessionLockTheftView";
136135
import { LoginSplashView } from "./auth/LoginSplashView";
@@ -314,7 +313,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
314313
private async initSession(): Promise<void> {
315314
// The Rust Crypto SDK will break if two Element instances try to use the same datastore at once, so
316315
// make sure we are the only Element instance in town (on this browser/domain).
317-
if (!(await getSessionLock(() => this.onSessionLockStolen()))) {
316+
const platform = PlatformPeg.get();
317+
if (platform && !(await platform.getSessionLock(() => this.onSessionLockStolen()))) {
318318
// we failed to get the lock. onSessionLockStolen should already have been called, so nothing left to do.
319319
return;
320320
}
@@ -479,7 +479,8 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
479479
// mounted.
480480
if (!this.sessionLoadStarted) {
481481
this.sessionLoadStarted = true;
482-
if (!checkSessionLockFree()) {
482+
const platform = PlatformPeg.get();
483+
if (platform && !platform.checkSessionLockFree()) {
483484
// another instance holds the lock; confirm its theft before proceeding
484485
setTimeout(() => this.setState({ view: Views.CONFIRM_LOCK_THEFT }), 0);
485486
} else {

src/vector/platform/ElectronPlatform.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,4 +558,12 @@ export default class ElectronPlatform extends BasePlatform {
558558
}
559559
return url;
560560
}
561+
562+
public checkSessionLockFree(): boolean {
563+
return true;
564+
}
565+
566+
public async getSessionLock(_onNewInstance: () => Promise<void>): Promise<boolean> {
567+
return true;
568+
}
561569
}

src/vector/platform/WebPlatform.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import ToastStore from "../../stores/ToastStore.ts";
2222
import GenericToast from "../../components/views/toasts/GenericToast.tsx";
2323
import SdkConfig from "../../SdkConfig.ts";
2424
import type { ActionPayload } from "../../dispatcher/payloads.ts";
25+
import * as SessionLock from "../../utils/SessionLock.ts";
2526

2627
const POKE_RATE_MS = 10 * 60 * 1000; // 10 min
2728

@@ -268,4 +269,12 @@ export default class WebPlatform extends BasePlatform {
268269
public reload(): void {
269270
window.location.reload();
270271
}
272+
273+
public checkSessionLockFree(): boolean {
274+
return SessionLock.checkSessionLockFree();
275+
}
276+
277+
public async getSessionLock(onNewInstance: () => Promise<void>): Promise<boolean> {
278+
return SessionLock.getSessionLock(onNewInstance);
279+
}
271280
}

test/test-utils/platform.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { type MethodLikeKeys, mocked, type MockedObject } from "jest-mock";
1010

1111
import BasePlatform from "../../src/BasePlatform";
1212
import PlatformPeg from "../../src/PlatformPeg";
13+
import * as SessionLock from "../../src/utils/SessionLock";
1314

1415
// doesn't implement abstract
1516
// @ts-ignore
@@ -18,6 +19,14 @@ class MockPlatform extends BasePlatform {
1819
super();
1920
Object.assign(this, platformMocks);
2021
}
22+
23+
public checkSessionLockFree(): boolean {
24+
return SessionLock.checkSessionLockFree();
25+
}
26+
27+
public async getSessionLock(onNewInstance: () => Promise<void>): Promise<boolean> {
28+
return SessionLock.getSessionLock(onNewInstance);
29+
}
2130
}
2231
/**
2332
* Mock Platform Peg

test/unit-tests/components/structures/MatrixChat-test.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,6 +1632,10 @@ describe("<MatrixChat />", () => {
16321632
});
16331633

16341634
describe("Multi-tab lockout", () => {
1635+
beforeEach(() => {
1636+
mockPlatformPeg();
1637+
});
1638+
16351639
afterEach(() => {
16361640
Lifecycle.setSessionLockNotStolen();
16371641
});
@@ -1677,6 +1681,8 @@ describe("<MatrixChat />", () => {
16771681
beforeEach(() => {
16781682
// make sure we start from a clean DOM for each of these tests
16791683
document.body.replaceChildren();
1684+
// use the MockPlatform
1685+
mockPlatformPeg();
16801686
});
16811687

16821688
function simulateSessionLockClaim() {

0 commit comments

Comments
 (0)