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

Only send token after verifying the homeserver #1189

Merged
merged 1 commit into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading