mirror of
https://github.com/CringeStudios/element-desktop.git
synced 2025-01-18 23:44:59 +01:00
Merge commit from fork
* Check url with homeserver * Move check to where access-token is added * Do IPC comm sparingly Before, the code would fetch the hs for every request. Since this needs the whole event-handler dance, it's best we do it only for the requests that match the media endpoints. Also added some try..catch since we create URL objects that could potentially throw * Check origin instead of just hostname
This commit is contained in:
parent
60d28ca3d8
commit
2d6e087fb0
@ -33,39 +33,74 @@ async function getAccessToken(window: BrowserWindow): Promise<string | undefined
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the homeserver url
|
||||||
|
* This requires asking the renderer process for the homeserver url.
|
||||||
|
*/
|
||||||
|
async function getHomeserverUrl(window: BrowserWindow): Promise<string> {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
ipcMain.once("homeserverUrl", (_, homeserver) => {
|
||||||
|
resolve(homeserver);
|
||||||
|
});
|
||||||
|
window.webContents.send("homeserverUrl"); // ping now that the listener exists
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function setupMediaAuth(window: BrowserWindow): void {
|
export function setupMediaAuth(window: BrowserWindow): void {
|
||||||
session.defaultSession.webRequest.onBeforeRequest(async (req, callback) => {
|
session.defaultSession.webRequest.onBeforeRequest(async (req, callback) => {
|
||||||
// This handler emulates the element-web service worker, where URLs are rewritten late in the request
|
// This handler emulates the element-web service worker, where URLs are rewritten late in the request
|
||||||
// for backwards compatibility. As authenticated media becomes more prevalent, this should be replaced
|
// for backwards compatibility. As authenticated media becomes more prevalent, this should be replaced
|
||||||
// by the app using authenticated URLs from the outset.
|
// by the app using authenticated URLs from the outset.
|
||||||
let url = req.url;
|
try {
|
||||||
if (!url.includes("/_matrix/media/v3/download") && !url.includes("/_matrix/media/v3/thumbnail")) {
|
const url = new URL(req.url);
|
||||||
return callback({}); // not a URL we care about
|
if (
|
||||||
}
|
!url.pathname.startsWith("/_matrix/media/v3/download") &&
|
||||||
|
!url.pathname.startsWith("/_matrix/media/v3/thumbnail")
|
||||||
|
) {
|
||||||
|
return callback({}); // not a URL we care about
|
||||||
|
}
|
||||||
|
|
||||||
const supportedVersions = await getSupportedVersions(window);
|
const supportedVersions = await getSupportedVersions(window);
|
||||||
// We have to check that the access token is truthy otherwise we'd be intercepting pre-login media request too,
|
// We have to check that the access token is truthy otherwise we'd be intercepting pre-login media request too,
|
||||||
// e.g. those required for SSO button icons.
|
// e.g. those required for SSO button icons.
|
||||||
const accessToken = await getAccessToken(window);
|
const accessToken = await getAccessToken(window);
|
||||||
if (supportedVersions.includes("v1.11") && accessToken) {
|
if (supportedVersions.includes("v1.11") && accessToken) {
|
||||||
url = url.replace(/\/media\/v3\/(.*)\//, "/client/v1/media/$1/");
|
url.href = url.href.replace(/\/media\/v3\/(.*)\//, "/client/v1/media/$1/");
|
||||||
return callback({ redirectURL: url });
|
return callback({ redirectURL: url.toString() });
|
||||||
} else {
|
} else {
|
||||||
return callback({}); // no support == no modification
|
return callback({}); // no support == no modification
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
session.defaultSession.webRequest.onBeforeSendHeaders(async (req, callback) => {
|
session.defaultSession.webRequest.onBeforeSendHeaders(async (req, callback) => {
|
||||||
if (!req.url.includes("/_matrix/client/v1/media")) {
|
try {
|
||||||
return callback({}); // invoke unmodified
|
const url = new URL(req.url);
|
||||||
}
|
if (!url.pathname.startsWith("/_matrix/client/v1/media")) {
|
||||||
|
return callback({}); // invoke unmodified
|
||||||
|
}
|
||||||
|
|
||||||
// Only add authorization header to authenticated media URLs. This emulates the service worker
|
// Is this request actually going to the homeserver?
|
||||||
// behaviour in element-web.
|
// We don't combine this check with the one above on purpose.
|
||||||
const accessToken = await getAccessToken(window);
|
// We're fetching the homeserver url through IPC and should do so
|
||||||
// `accessToken` can be falsy, but if we're trying to download media without authentication
|
// as sparingly as possible.
|
||||||
// then we should expect failure anyway.
|
const homeserver = await getHomeserverUrl(window);
|
||||||
const headers = { ...req.requestHeaders, Authorization: `Bearer ${accessToken}` };
|
const isRequestToHomeServer = homeserver && url.origin === new URL(homeserver).origin;
|
||||||
return callback({ requestHeaders: headers });
|
if (!isRequestToHomeServer) {
|
||||||
|
return callback({}); // invoke unmodified
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only add authorization header to authenticated media URLs. This emulates the service worker
|
||||||
|
// behaviour in element-web.
|
||||||
|
const accessToken = await getAccessToken(window);
|
||||||
|
// `accessToken` can be falsy, but if we're trying to download media without authentication
|
||||||
|
// then we should expect failure anyway.
|
||||||
|
const headers = { ...req.requestHeaders, Authorization: `Bearer ${accessToken}` };
|
||||||
|
return callback({ requestHeaders: headers });
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ const CHANNELS = [
|
|||||||
"userDownloadAction",
|
"userDownloadAction",
|
||||||
"openDesktopCapturerSourcePicker",
|
"openDesktopCapturerSourcePicker",
|
||||||
"userAccessToken",
|
"userAccessToken",
|
||||||
|
"homeserverUrl",
|
||||||
"serverSupportedVersions",
|
"serverSupportedVersions",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user