Skip to content

Commit

Permalink
Merge pull request #1189 from element-hq/midhun/auth-media/token
Browse files Browse the repository at this point in the history
Only send token after verifying the homeserver
  • Loading branch information
MidhunSureshR authored Oct 21, 2024
2 parents d3e3d5a + f7a6a26 commit 49263a7
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 21 deletions.
11 changes: 8 additions & 3 deletions src/matrix/Client.js
Original file line number Diff line number Diff line change
Expand Up @@ -290,8 +290,11 @@ export class Client {
serverVersions: lastVersionsResponse.versions,
});

// Let the serviceWorkerHandler know of this access-token
this._platform.updateService.setAccessToken(sessionInfo.accessToken);
// Let the serviceWorkerHandler know of this access-token and homeserver
this._platform.updateService.updateAuthData({
accessToken: sessionInfo.accessToken,
homeserver: sessionInfo.homeServer,
});

this._session = new Session({
storage: this._storage,
Expand Down Expand Up @@ -382,7 +385,9 @@ export class Client {
throw Error("No session loaded, cannot update access token");
}
this._session.updateAccessToken(token);
await this._platform.updateService.setAccessToken(token);
this._platform.updateService.updateAuthData({
accessToken: token,
});
await this._platform.sessionInfoStorage.updateAccessToken(this._sessionId, token);
}

Expand Down
19 changes: 12 additions & 7 deletions src/platform/web/dom/ServiceWorkerHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,24 @@ export class ServiceWorkerHandler {
this._currentController = null;
this._sessionInfoStorage = sessionInfoStorage;
this.haltRequests = false;
this._accessToken = null;
this._authData = {};
}

setNavigation(navigation) {
this._navigation = navigation;
}

/**
* Set the access-token to be used within the service worker.
* @param token An access-token
* Set the access-token and homeserver to be used within the service worker.
* @param auth An object with accessToken and homeserver
*/
setAccessToken(token) {
this._accessToken = token;
updateAuthData(auth) {
if (!auth.accessToken && !auth.homeserver) {
throw new Error(
"updateAuthData argument must contain accessToken, homeserver or both!"
);
}
this._authData = { ...this._authData, ...auth };
}

registerAndStart(path) {
Expand Down Expand Up @@ -96,10 +101,10 @@ export class ServiceWorkerHandler {
event.source.postMessage({ replyTo: data.id });
} else if (data.type === "openRoom") {
this._navigation.push("room", data.payload.roomId);
} else if (data.type === "getAccessToken") {
} else if (data.type === "getAuthInfo") {
event.source.postMessage({
replyTo: data.id,
payload: this._accessToken,
payload: this._authData,
});
}
}
Expand Down
36 changes: 25 additions & 11 deletions src/platform/web/sw.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,39 @@ async function handleRequest({ request, clientId }) {
}

// Add access token for authenticated media endpoints
if (request.url.includes("_matrix/client/v1/media")) {
const headers = new Headers(request.headers);
const pathNameStartsWithMediaPrefix =
url.pathname.indexOf("/_matrix/client/v1/media") === 0;
if (pathNameStartsWithMediaPrefix) {
const client = await self.clients.get(clientId);
const accessToken = await sendAndWaitForReply(
const { accessToken, homeserver } = await sendAndWaitForReply(
client,
"getAccessToken",
"getAuthInfo",
{}
);
if (!accessToken) {
throw new Error(
"Token returned from getAccessToken message in sw.js is null"
"Token returned from getAuthInfo message in sw.js is null!"
);
}
headers.set("authorization", `Bearer ${accessToken}`);
request = new Request(request, {
mode: "cors",
credentials: "omit",
headers,
});
if (!homeserver) {
throw new Error(
"homeserver returned from getAuthInfo message in sw.js is null!"
);
}
// Is this request actually going to the homeserver?
const isRequestForHomeserver =
new URL(homeserver).origin === url.origin;
if (isRequestForHomeserver) {
// Only add the access-token if we know that this request
// is going to the homeserver.
const headers = new Headers(request.headers);
headers.set("authorization", `Bearer ${accessToken}`);
request = new Request(request, {
mode: "cors",
credentials: "omit",
headers,
});
}
}

let response = await readCache(request);
Expand Down

0 comments on commit 49263a7

Please sign in to comment.