Compare commits

...

10 Commits

Author SHA1 Message Date
David Baker
3d65d5b261 Merge pull request #1249 from vector-im/dbkr/update_lk_urls
Update livekit service URLs if they fail
2023-07-12 17:38:54 +01:00
David Baker
3d885597ae Use merged js-sdk commit 2023-07-12 17:32:19 +01:00
David Baker
04781ab3a4 Merge branch '042-hotfix' into dbkr/update_lk_urls 2023-07-12 17:28:11 +01:00
David Baker
89d42cde7b Update JWT service URL 2023-07-12 17:27:44 +01:00
David Baker
02f6416741 Bump js-sdk 2023-07-12 17:21:47 +01:00
David Baker
73e1ce547d Fix other FocusInfo / livekit service URL instances 2023-07-12 17:20:02 +01:00
David Baker
587973fb9b Bump js-sdk 2023-07-12 17:12:14 +01:00
David Baker
bb68e63f54 Update js-sdk 2023-07-12 17:06:07 +01:00
David Baker
4fe6ac6b2d Update livekit service URLs if they fail
Requires https://github.com/matrix-org/matrix-js-sdk/pull/3598
Fixes https://github.com/vector-im/element-call/issues/1190
Fixes https://github.com/matrix-org/matrix-hosted/issues/8021
2023-07-12 17:06:00 +01:00
David Baker
c11259d2aa Spell SFU correctly 2023-07-12 17:05:37 +01:00
8 changed files with 117 additions and 57 deletions

View File

@@ -6,7 +6,7 @@
}
},
"livekit": {
"livekit_service_url": "https://livekit.element.dev"
"livekit_service_url": "https://livekit-jwt.call.element.dev"
},
"posthog": {
"api_key": "phc_rXGHx9vDmyEvyRxPziYtdVIv0ahEv8A9uLWFcCi1WcU",

View File

@@ -57,7 +57,7 @@
"i18next-http-backend": "^1.4.4",
"livekit-client": "1.12.0",
"lodash": "^4.17.21",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#9ba44b96202e36d8bd6fbcff3222b7c70fc371d7",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#b698217445318f453e0b1086364a33113eaa85d9",
"matrix-widget-api": "^1.3.1",
"mermaid": "^8.13.8",
"normalize.css": "^8.0.1",

View File

@@ -139,13 +139,6 @@ export const ClientProvider: FC<Props> = ({ children }) => {
session;
const livekit = Config.get().livekit;
const foci = livekit
? [
{
livekitServiceUrl: livekit.livekit_service_url,
},
]
: undefined;
try {
return {
@@ -156,7 +149,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
userId: user_id,
deviceId: device_id,
fallbackICEServerAllowed: fallbackICEServerAllowed,
foci,
livekitServiceURL: livekit?.livekit_service_url,
},
true
),
@@ -173,7 +166,7 @@ export const ClientProvider: FC<Props> = ({ children }) => {
userId: user_id,
deviceId: device_id,
fallbackICEServerAllowed: fallbackICEServerAllowed,
foci,
livekitServiceURL: livekit?.livekit_service_url,
},
false // Don't need the crypto store just to log out
);

View File

@@ -22,6 +22,7 @@ import {
useState,
} from "react";
import { logger } from "matrix-js-sdk/src/logger";
import { GroupCall } from "matrix-js-sdk";
import {
OpenIDClientParts,
@@ -32,7 +33,7 @@ import { ErrorView, LoadingView } from "../FullScreenView";
interface Props {
client: OpenIDClientParts;
livekitServiceURL: string;
groupCall: GroupCall;
roomName: string;
children: ReactNode;
}
@@ -41,12 +42,7 @@ const SFUConfigContext = createContext<SFUConfig>(undefined);
export const useSFUConfig = () => useContext(SFUConfigContext);
export function OpenIDLoader({
client,
livekitServiceURL,
roomName,
children,
}: Props) {
export function OpenIDLoader({ client, groupCall, roomName, children }: Props) {
const [state, setState] = useState<
SFUConfigLoading | SFUConfigLoaded | SFUConfigFailed
>({ kind: "loading" });
@@ -56,7 +52,7 @@ export function OpenIDLoader({
try {
const result = await getSFUConfigWithOpenID(
client,
livekitServiceURL,
groupCall,
roomName
);
setState({ kind: "loaded", sfuConfig: result });
@@ -65,7 +61,7 @@ export function OpenIDLoader({
setState({ kind: "failed", error: e });
}
})();
}, [client, livekitServiceURL, roomName]);
}, [client, groupCall, roomName]);
switch (state.kind) {
case "loading":

View File

@@ -14,9 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import { MatrixClient } from "matrix-js-sdk";
import { GroupCall, IOpenIDToken, MatrixClient } from "matrix-js-sdk";
import { logger } from "matrix-js-sdk/src/logger";
import { Config } from "../config/Config";
export interface SFUConfig {
url: string;
jwt: string;
@@ -30,25 +32,84 @@ export type OpenIDClientParts = Pick<
export async function getSFUConfigWithOpenID(
client: OpenIDClientParts,
livekitServiceURL: string,
groupCall: GroupCall,
roomName: string
): Promise<SFUConfig> {
const openIdToken = await client.getOpenIdToken();
logger.debug("Got openID token", openIdToken);
const res = await fetch(livekitServiceURL + "/sfu/get", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
room: roomName,
openid_token: openIdToken,
device_id: client.getDeviceId(),
}),
});
if (!res.ok) {
throw new Error("SFO Config fetch failed with status code " + res.status);
// if the call has a livekit service URL, try it.
if (groupCall.livekitServiceURL) {
try {
logger.info(`Trying to get JWT from ${groupCall.livekitServiceURL}...`);
const sfuConfig = await getLiveKitJWT(
client,
groupCall.livekitServiceURL,
roomName,
openIdToken
);
return sfuConfig;
} catch (e) {
logger.warn(
`Failed to get JWT from group call's configured URL of ${groupCall.livekitServiceURL}.`,
e
);
}
}
// otherwise, try our configured one and, if it works, update the call's service URL in the state event
// NB. This wuill update it for everyone so we may end up with multiple clients updating this when they
// join at similar times, but we don't have a huge number of options here.
const urlFromConf = Config.get().livekit.livekit_service_url;
logger.info(`Trying livekit service URL from our config: ${urlFromConf}...`);
try {
const sfuConfig = await getLiveKitJWT(
client,
urlFromConf,
roomName,
openIdToken
);
logger.info(`Updating call livekit service URL with: ${urlFromConf}...`);
try {
await groupCall.updateLivekitServiceURL(urlFromConf);
} catch (e) {
logger.warn(
`Failed to update call livekit service URL: continuing anyway.`
);
}
return sfuConfig;
} catch (e) {
logger.error("Failed to get JWT from URL defined in Config.", e);
throw e;
}
}
async function getLiveKitJWT(
client: OpenIDClientParts,
livekitServiceURL: string,
roomName: string,
openIDToken: IOpenIDToken
): Promise<SFUConfig> {
try {
const res = await fetch(livekitServiceURL + "/sfu/get", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
room: roomName,
openid_token: openIDToken,
device_id: client.getDeviceId(),
}),
});
if (!res.ok) {
throw new Error("SFU Config fetch failed with status code " + res.status);
}
return await res.json();
} catch (e) {
throw new Error("SFU Config fetch failed with exception " + e);
}
return await res.json();
}

View File

@@ -36,7 +36,6 @@ import { UserChoices } from "../livekit/useLiveKit";
import { findDeviceByName } from "../media-utils";
import { OpenIDLoader } from "../livekit/OpenIDLoader";
import { ActiveCall } from "./InCallView";
import { Config } from "../config/Config";
declare global {
interface Window {
@@ -220,20 +219,13 @@ export function GroupCallView({
undefined
);
const livekitServiceURL =
groupCall.foci[0]?.livekitServiceUrl ??
Config.get().livekit.livekit_service_url;
if (!livekitServiceURL) {
return <ErrorView error={new Error("No livekit_service_url defined")} />;
}
if (error) {
return <ErrorView error={error} />;
} else if (state === GroupCallState.Entered && userChoices) {
return (
<OpenIDLoader
client={client}
livekitServiceURL={livekitServiceURL}
groupCall={groupCall}
roomName={`${groupCall.room.roomId}-${groupCall.groupCallId}`}
>
<ActiveCall

View File

@@ -164,7 +164,7 @@ export const widget: WidgetHelpers | null = (() => {
// message so that we can use the widget API in less racy mode, but we need to change
// element-web to use waitForIFrameLoad=false. Once that change has rolled out,
// we can just start the client after we've fetched the config.
foci: [],
livekitServiceURL: undefined,
}
);
@@ -178,9 +178,7 @@ export const widget: WidgetHelpers | null = (() => {
// Now we've fetched the config, be evil and use the getter to inject the focus
// into the client (see above XXX).
if (focus) {
client.getFoci().push({
livekitServiceUrl: livekit.livekit_service_url,
});
client.setLivekitServiceURL(livekit.livekit_service_url);
}
await client.startClient();
resolve(client);

View File

@@ -2186,10 +2186,10 @@
"@react-hook/latest" "^1.0.3"
clsx "^1.2.1"
"@matrix-org/matrix-sdk-crypto-js@^0.1.0-alpha.10":
version "0.1.0-alpha.10"
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.0-alpha.10.tgz#b6a6395cffd3197ae2e0a88f4eeae8b315571fd2"
integrity sha512-8V2NKuzGOFzEZeZVgF2is7gmuopdRbMZ064tzPDE0vN34iX6s3O8A4oxIT7SA3qtymwm3t1yEvTnT+0gfbmh4g==
"@matrix-org/matrix-sdk-crypto-js@^0.1.1":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-js/-/matrix-sdk-crypto-js-0.1.3.tgz#19981e7613d3673d07c885a98d39276b5fe74ef0"
integrity sha512-RcRlE3wcMnE5ijACHIHmhXFogEEJdIcb/CbJ4rK1PCMduQ4yvxycVpMxwh7aKxFNitZbHZLCK7TfRzUpzjU2tw==
"@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz":
version "3.2.14"
@@ -6399,6 +6399,11 @@ crypto-browserify@^3.11.0:
randombytes "^2.0.0"
randomfill "^1.0.3"
crypto-js@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf"
integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==
css-blank-pseudo@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561"
@@ -10613,6 +10618,11 @@ junk@^3.1.0:
resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1"
integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==
jwt-decode@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/jwt-decode/-/jwt-decode-3.1.2.tgz#3fb319f3675a2df0c2895c8f5e9fa4b67b04ed59"
integrity sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A==
khroma@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/khroma/-/khroma-1.4.1.tgz#ad6a5b6a972befc5112ce5129887a1a83af2c003"
@@ -10972,18 +10982,20 @@ matrix-events-sdk@0.0.1:
resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd"
integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA==
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#9ba44b96202e36d8bd6fbcff3222b7c70fc371d7":
version "26.0.1"
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/9ba44b96202e36d8bd6fbcff3222b7c70fc371d7"
"matrix-js-sdk@github:matrix-org/matrix-js-sdk#b698217445318f453e0b1086364a33113eaa85d9":
version "26.2.0"
resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/b698217445318f453e0b1086364a33113eaa85d9"
dependencies:
"@babel/runtime" "^7.12.5"
"@matrix-org/matrix-sdk-crypto-js" "^0.1.0-alpha.10"
"@matrix-org/matrix-sdk-crypto-js" "^0.1.1"
another-json "^0.2.0"
bs58 "^5.0.0"
content-type "^1.0.4"
jwt-decode "^3.1.2"
loglevel "^1.7.1"
matrix-events-sdk "0.0.1"
matrix-widget-api "^1.3.1"
oidc-client-ts "^2.2.4"
p-retry "4"
sdp-transform "^2.14.1"
unhomoglyph "^1.0.6"
@@ -11670,6 +11682,14 @@ objectorarray@^1.0.5:
resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5"
integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==
oidc-client-ts@^2.2.4:
version "2.2.4"
resolved "https://registry.yarnpkg.com/oidc-client-ts/-/oidc-client-ts-2.2.4.tgz#7d86b5efe2248f3637a6f3a0ee1af86764aea125"
integrity sha512-nOZwIomju+AmXObl5Oq5PjrES/qTt8bLsENJCIydVgi9TEWk7SCkOU6X3RNkY7yfySRM1OJJvDKdREZdmnDT2g==
dependencies:
crypto-js "^4.1.1"
jwt-decode "^3.1.2"
on-finished@2.4.1:
version "2.4.1"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"