Skip to content
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

MSC3575 (Sliding Sync) add well-known proxy support #12307

Merged
merged 108 commits into from
Apr 30, 2024
Merged
Show file tree
Hide file tree
Changes from 106 commits
Commits
Show all changes
108 commits
Select commit Hold shift + click to select a range
9d73b7c
Initial commit
EdGeraghty Mar 4, 2024
876f59c
Remove commented code
EdGeraghty Mar 5, 2024
c65b22b
Change function to reflect it's proxy not native support
EdGeraghty Mar 5, 2024
e99ef75
Re-add check for servers with native support
EdGeraghty Mar 5, 2024
6adac18
Add native support check back in
EdGeraghty Mar 5, 2024
065e255
Re-add endpoint health check function
EdGeraghty Mar 5, 2024
1345379
Use inbuilt `getWellKnown` function
EdGeraghty Mar 8, 2024
7736582
Change the error message to the correct function
EdGeraghty Mar 8, 2024
4f2c1f2
Stop storing the proxyurl in the settings for now
EdGeraghty Mar 8, 2024
cb78747
Make the logger messages more useful
EdGeraghty Mar 8, 2024
10095b6
Start moving the checking logic directly into the controller
EdGeraghty Mar 10, 2024
5ef62f3
Add missing import
EdGeraghty Mar 10, 2024
0ac51af
Get the client rather than passing it in to the functions
EdGeraghty Mar 10, 2024
bc73cd8
remove invalid `function` keyword
EdGeraghty Mar 10, 2024
1118135
Fix imports
EdGeraghty Mar 10, 2024
8185c08
Our new functions are private
EdGeraghty Mar 10, 2024
e782249
Change our proxy check function to return a boolean
EdGeraghty Mar 10, 2024
2fdab77
Make `nativeSlidingSyncSupport` also return boolean, add in health check
EdGeraghty Mar 10, 2024
0a87ebc
Disable the sliding sync option if the server doesn't support
EdGeraghty Mar 10, 2024
740a28f
Only enable the setting if it passes (again)
EdGeraghty Mar 10, 2024
a034550
Update our comments to better match what's going on
EdGeraghty Mar 10, 2024
24424e6
Remove unused dialog
EdGeraghty Mar 10, 2024
dfd4ced
Add a well-known check on start-up, if sliding sync has been enabled
EdGeraghty Mar 10, 2024
be0e4d3
Check against the correct endpoint...
EdGeraghty Mar 10, 2024
dbbdc8a
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Mar 13, 2024
43e3341
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Mar 16, 2024
b3ebb8a
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Mar 19, 2024
f43cd19
Extract baseUrl as we'll reuse it
EdGeraghty Apr 8, 2024
2e4f110
Make the logs differentiate between the types of proxy
EdGeraghty Apr 8, 2024
c32ea33
Grab the client well-known directly for use
EdGeraghty Apr 8, 2024
9d831b1
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 8, 2024
16522ae
Add myself to the copyright assignation
EdGeraghty Apr 8, 2024
f4f8463
Only return `true` if it's actually there
EdGeraghty Apr 8, 2024
0417265
Correct the `proxySlidingSyncSupport` function comment to match the code
EdGeraghty Apr 8, 2024
d9199e4
Correct the `nativeSlidingSyncSupport`function comment to match the code
EdGeraghty Apr 8, 2024
229b8d8
Another comment/functionality paring
EdGeraghty Apr 8, 2024
672b003
Remove duplicated types from the doc
EdGeraghty Apr 10, 2024
7cdab7b
Move await to the previous line
EdGeraghty Apr 10, 2024
2f45ddb
use `waitForClientWellKnown` to avoid a race condition with the request
EdGeraghty Apr 10, 2024
23b026f
Move getting the client out of the `if`, use `waitForClientWellKnown`
EdGeraghty Apr 10, 2024
e1d28ec
Remove `beforeChange` override
EdGeraghty Apr 10, 2024
5f7b513
Move proxy setup logic into `SlidingSyncManager`
EdGeraghty Apr 10, 2024
c80a00b
Swap `configure` to private, we call it from `setup` which handles proxy
EdGeraghty Apr 10, 2024
ef1da4a
Promises are always `true`
EdGeraghty Apr 10, 2024
71e5d60
use `timeoutSignal`
EdGeraghty Apr 10, 2024
e150b05
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 10, 2024
2095501
Change message when there's no server support
EdGeraghty Apr 10, 2024
629d5bb
Refactor `slidingSyncHealthCheck`
EdGeraghty Apr 10, 2024
8edc6c1
Refactor `nativeSlidingSyncSupport` with try/catch
EdGeraghty Apr 10, 2024
bca3aa2
Change comment to hotlink
EdGeraghty Apr 10, 2024
9d735cf
Try and make the toggle disabled when there's no endpoint
EdGeraghty Apr 10, 2024
9bae69d
Move the if statement outside the refactored fn to avoid an await
EdGeraghty Apr 11, 2024
eb60521
Revert "Swap `configure` to private, we call it from `setup` which ha…
EdGeraghty Apr 11, 2024
9defa25
Remove unused import
EdGeraghty Apr 11, 2024
3b1e87e
Further refactor `slidingSyncHealthCheck`
EdGeraghty Apr 11, 2024
0aa46c3
Make `proxySlidingSyncSupport` log on success
EdGeraghty Apr 11, 2024
8397e2e
Clarify log message for proxy being up
EdGeraghty Apr 11, 2024
98674c5
Move the logic into SlidingSyncManager
EdGeraghty Apr 12, 2024
c75ed4c
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 12, 2024
7ddec2b
Obviously this isn't a return so don't overwrite with false!
EdGeraghty Apr 12, 2024
cfc48bb
Remove outdated comment
EdGeraghty Apr 12, 2024
a09b1b2
No need to pass in the client
EdGeraghty Apr 12, 2024
aab3e51
Activating SS should probably be info level logs
EdGeraghty Apr 12, 2024
40ca313
If we've not enabled sliding sync, push the logs down a bit
EdGeraghty Apr 12, 2024
efeb2ae
Update i18n error message
EdGeraghty Apr 12, 2024
51660ff
Remove unused i18n strings
EdGeraghty Apr 12, 2024
2b41e0c
Correct log message
EdGeraghty Apr 12, 2024
90f96e6
Prettier
EdGeraghty Apr 12, 2024
90b9876
Remove many of the log messages
EdGeraghty Apr 12, 2024
7bc854e
Short out of `checkSupport` if it's `true`
EdGeraghty Apr 13, 2024
1a342d6
Add the endpoint back into the log when we're enabling it
EdGeraghty Apr 13, 2024
79b45b7
Note in the comment that `feature_sliding_sync_proxy_url` is legacy
EdGeraghty Apr 13, 2024
7b4d4f2
Expand the well-known liveness check log
EdGeraghty Apr 13, 2024
99c10f6
No need to stall the client waiting for sliding sync support
EdGeraghty Apr 15, 2024
77d41c1
`AutoDiscovery.findClientConfig` throws if the baseUrl is blank
EdGeraghty Apr 15, 2024
d7d2f8b
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 16, 2024
ac4de59
Fix `getProxyFromWellKnown` (?)
EdGeraghty Apr 16, 2024
9cd4ac4
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 16, 2024
a0e2f63
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 17, 2024
9fe4e9a
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 19, 2024
f99dc79
Add missing semicolon
EdGeraghty Apr 19, 2024
0b04649
Pass our `MatrixClient` through instead of trying to grab it
EdGeraghty Apr 19, 2024
0eee348
Add missing return in function comment
EdGeraghty Apr 19, 2024
061041b
Actually pass through our Client, not the Peg object
EdGeraghty Apr 19, 2024
2ea8e47
Remove SonarCube smell complaint
EdGeraghty Apr 25, 2024
6682690
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 25, 2024
490092c
Neew to make our other two methods public to test
EdGeraghty Apr 27, 2024
fcca43f
First passing test
EdGeraghty Apr 27, 2024
c1670f4
Two more tests, this time on `checkSupport`
EdGeraghty Apr 27, 2024
9d20b46
Merge branch 'edg/msc3575-native-support' of https://github.com/EdGer…
EdGeraghty Apr 27, 2024
9178ab4
Reset our `serverSupportsSlidingSync` between tests
EdGeraghty Apr 27, 2024
3785b89
Check the static member is being set
EdGeraghty Apr 27, 2024
ac18bdb
Move the static assignation down to the relevant tests
EdGeraghty Apr 27, 2024
4637b3d
Pull getProxyFromWellKnown mocking up
EdGeraghty Apr 27, 2024
15ac5b0
Check we /haven't/ shorted out
EdGeraghty Apr 27, 2024
db5a374
Move our spy up so we can reuse it
EdGeraghty Apr 27, 2024
a98552c
Check spidering is being called
EdGeraghty Apr 27, 2024
298cb8f
Test the proxy is declared
EdGeraghty Apr 27, 2024
f840249
Test entered manually
EdGeraghty Apr 27, 2024
4494079
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 29, 2024
58f0d90
Sorry, linter
EdGeraghty Apr 29, 2024
27830f8
Merge branch 'edg/msc3575-native-support' of github.com:EdGeraghty/ma…
EdGeraghty Apr 29, 2024
e01fa3d
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 29, 2024
0a00a29
I guess these strings are wrong?
EdGeraghty Apr 29, 2024
48b361a
Merge branch 'edg/msc3575-native-support' of github.com:EdGeraghty/ma…
EdGeraghty Apr 29, 2024
2e1bb20
Merge branch 'develop' into edg/msc3575-native-support
t3chguy Apr 30, 2024
0288e89
Replace any with string
EdGeraghty Apr 30, 2024
3cbc39a
Merge branch 'develop' into edg/msc3575-native-support
EdGeraghty Apr 30, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions src/MatrixClientPeg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,17 +273,9 @@ class MatrixClientPegClass implements IMatrixClientPeg {
opts.threadSupport = true;

if (SettingsStore.getValue("feature_sliding_sync")) {
const proxyUrl = SettingsStore.getValue("feature_sliding_sync_proxy_url");
if (proxyUrl) {
logger.log("Activating sliding sync using proxy at ", proxyUrl);
} else {
logger.log("Activating sliding sync");
}
opts.slidingSync = SlidingSyncManager.instance.configure(
this.matrixClient,
proxyUrl || this.matrixClient.baseUrl,
);
SlidingSyncManager.instance.startSpidering(100, 50); // 100 rooms at a time, 50ms apart
opts.slidingSync = await SlidingSyncManager.instance.setup(this.matrixClient);
} else {
SlidingSyncManager.instance.checkSupport(this.matrixClient);
}

// Connect the matrix client to the dispatcher and setting handlers
Expand Down
94 changes: 93 additions & 1 deletion src/SlidingSyncManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ limitations under the License.
* list ops)
*/

import { MatrixClient, EventType } from "matrix-js-sdk/src/matrix";
import { MatrixClient, EventType, AutoDiscovery, Method, timeoutSignal } from "matrix-js-sdk/src/matrix";
import {
MSC3575Filter,
MSC3575List,
Expand All @@ -56,6 +56,9 @@ import {
import { logger } from "matrix-js-sdk/src/logger";
import { defer, sleep } from "matrix-js-sdk/src/utils";

import SettingsStore from "./settings/SettingsStore";
import SlidingSyncController from "./settings/controllers/SlidingSyncController";

// how long to long poll for
const SLIDING_SYNC_TIMEOUT_MS = 20 * 1000;

Expand Down Expand Up @@ -323,4 +326,93 @@ export class SlidingSyncManager {
firstTime = false;
}
}

/**
* Set up the Sliding Sync instance; configures the end point and starts spidering.
* The sliding sync endpoint is derived the following way:
* 1. The user-defined sliding sync proxy URL (legacy, for backwards compatibility)
* 2. The client `well-known` sliding sync proxy URL [declared at the unstable prefix](https://github.com/matrix-org/matrix-spec-proposals/blob/kegan/sync-v3/proposals/3575-sync.md#unstable-prefix)
* 3. The homeserver base url (for native server support)
* @param client The MatrixClient to use
* @returns A working Sliding Sync or undefined
*/
public async setup(client: MatrixClient): Promise<SlidingSync | undefined> {
const baseUrl = client.baseUrl;
const proxyUrl = SettingsStore.getValue("feature_sliding_sync_proxy_url");
const wellKnownProxyUrl = await this.getProxyFromWellKnown(client);

const slidingSyncEndpoint = proxyUrl || wellKnownProxyUrl || baseUrl;

this.configure(client, slidingSyncEndpoint);
logger.info("Sliding sync activated at", slidingSyncEndpoint);
this.startSpidering(100, 50); // 100 rooms at a time, 50ms apart

return this.slidingSync;
}

/**
* Get the sliding sync proxy URL from the client well known
* @param client The MatrixClient to use
* @return The proxy url
*/
public async getProxyFromWellKnown(client: MatrixClient): Promise<string | undefined> {
let proxyUrl: any;
EdGeraghty marked this conversation as resolved.
Show resolved Hide resolved

try {
const clientWellKnown = await AutoDiscovery.findClientConfig(client.baseUrl);
proxyUrl = clientWellKnown?.["org.matrix.msc3575.proxy"]?.url;
} catch (e) {
// client.baseUrl is invalid, `AutoDiscovery.findClientConfig` has thrown
}

if (proxyUrl != undefined) {
logger.log("getProxyFromWellKnown: client well-known declares sliding sync proxy at", proxyUrl);
}
return proxyUrl;
}

/**
* Check if the server "natively" supports sliding sync (at the unstable endpoint).
* @param client The MatrixClient to use
* @return Whether the "native" (unstable) endpoint is up
*/
public async nativeSlidingSyncSupport(client: MatrixClient): Promise<boolean> {
try {
await client.http.authedRequest<void>(Method.Post, "/sync", undefined, undefined, {
localTimeoutMs: 10 * 1000, // 10s
prefix: "/_matrix/client/unstable/org.matrix.msc3575",
});
Comment on lines +381 to +384
Copy link
Member

Choose a reason for hiding this comment

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

this is unsafe. It will cause the Sliding Sync proxy to start polling with our access token, which means that the SS proxy will receive our to-device messages, causing decryption errors.

} catch (e) {
return false; // 404, M_UNRECOGNIZED
}

logger.log("nativeSlidingSyncSupport: sliding sync endpoint is up");
return true; // 200, OK
}

/**
* Check whether our homeserver has sliding sync support, that the endpoint is up, and
* is a sliding sync endpoint.
*
* Sets static member `SlidingSyncController.serverSupportsSlidingSync`
* @param client The MatrixClient to use
*/
public async checkSupport(client: MatrixClient): Promise<void> {
if (await this.nativeSlidingSyncSupport(client)) {
SlidingSyncController.serverSupportsSlidingSync = true;
return;
}

const proxyUrl = await this.getProxyFromWellKnown(client);
if (proxyUrl != undefined) {
const response = await fetch(proxyUrl + "/client/server.json", {
method: Method.Get,
signal: timeoutSignal(10 * 1000), // 10s
});
if (response.status === 200) {
logger.log("checkSupport: well-known sliding sync proxy is up at", proxyUrl);
SlidingSyncController.serverSupportsSlidingSync = true;
}
}
}
}
142 changes: 0 additions & 142 deletions src/components/views/dialogs/SlidingSyncOptionsDialog.tsx

This file was deleted.

9 changes: 1 addition & 8 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1452,16 +1452,9 @@
"rust_crypto_optin_warning": "Switching to the Rust cryptography requires a migration process that may take several minutes. To disable you will need to log out and back in; use with caution!",
"rust_crypto_requires_logout": "Once enabled, Rust cryptography can only be disabled by logging out and in again",
"sliding_sync": "Sliding Sync mode",
"sliding_sync_checking": "Checking…",
"sliding_sync_configuration": "Sliding Sync configuration",
"sliding_sync_description": "Under active development, cannot be disabled.",
"sliding_sync_disable_warning": "To disable you will need to log out and back in, use with caution!",
"sliding_sync_disabled_notice": "Log out and back in to disable",
"sliding_sync_proxy_url_label": "Proxy URL",
"sliding_sync_proxy_url_optional_label": "Proxy URL (optional)",
"sliding_sync_server_no_support": "Your server lacks native support",
"sliding_sync_server_specify_proxy": "Your server lacks native support, you must specify a proxy",
"sliding_sync_server_support": "Your server has native support",
"sliding_sync_server_no_support": "Your server lacks support",
"under_active_development": "Under active development.",
"unrealiable_e2e": "Unreliable in encrypted rooms",
"video_rooms": "Video rooms",
Expand Down
2 changes: 1 addition & 1 deletion src/settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ export const SETTINGS: { [setting: string]: ISetting } = {
controller: new SlidingSyncController(),
},
"feature_sliding_sync_proxy_url": {
// This is not a distinct feature, it is a setting for feature_sliding_sync above
// This is not a distinct feature, it is a legacy setting for feature_sliding_sync above
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS_WITH_CONFIG,
default: "",
},
Expand Down
13 changes: 5 additions & 8 deletions src/settings/controllers/SlidingSyncController.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/*
Copyright 2022 The Matrix.org Foundation C.I.C.
Copyright 2024 Ed Geraghty <ed@geraghty.family>

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -16,18 +17,11 @@ limitations under the License.

import SettingController from "./SettingController";
import PlatformPeg from "../../PlatformPeg";
import { SettingLevel } from "../SettingLevel";
import { SlidingSyncOptionsDialog } from "../../components/views/dialogs/SlidingSyncOptionsDialog";
import Modal from "../../Modal";
import SettingsStore from "../SettingsStore";
import { _t } from "../../languageHandler";

export default class SlidingSyncController extends SettingController {
public async beforeChange(level: SettingLevel, roomId: string, newValue: any): Promise<boolean> {
const { finished } = Modal.createDialog(SlidingSyncOptionsDialog);
const [value] = await finished;
return newValue === value; // abort the operation if we're already in the state the user chose via modal
}
public static serverSupportsSlidingSync: boolean;

public async onChange(): Promise<void> {
PlatformPeg.get()?.reload();
Expand All @@ -38,6 +32,9 @@ export default class SlidingSyncController extends SettingController {
if (SettingsStore.getValue("feature_sliding_sync")) {
return _t("labs|sliding_sync_disabled_notice");
}
if (!SlidingSyncController.serverSupportsSlidingSync) {
return _t("labs|sliding_sync_server_no_support");
}

return false;
}
Expand Down
Loading
Loading