This repository has been archived by the owner on Sep 11, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 827
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
194 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
/* | ||
Copyright 2023 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
import { HomeserverInstance } from "../../plugins/utils/homeserver"; | ||
import { UserCredentials } from "../../support/login"; | ||
import { doTokenRegistration } from "./utils"; | ||
|
||
describe("Soft logout", () => { | ||
let homeserver: HomeserverInstance; | ||
|
||
beforeEach(() => { | ||
cy.task("startOAuthServer") | ||
.then((oAuthServerPort: number) => { | ||
return cy.startHomeserver({ template: "default", oAuthServerPort }); | ||
}) | ||
.then((data) => { | ||
homeserver = data; | ||
}); | ||
}); | ||
|
||
afterEach(() => { | ||
cy.stopHomeserver(homeserver); | ||
}); | ||
|
||
describe("with password user", () => { | ||
let testUserCreds: UserCredentials; | ||
|
||
beforeEach(() => { | ||
cy.initTestUser(homeserver, "Alice").then((creds) => { | ||
testUserCreds = creds; | ||
}); | ||
}); | ||
|
||
it("shows the soft-logout page when a request fails, and allows a re-login", () => { | ||
interceptRequestsWithSoftLogout(); | ||
cy.findByText("You're signed out"); | ||
cy.findByPlaceholderText("Password").type(testUserCreds.password).type("{enter}"); | ||
|
||
// back to the welcome page | ||
cy.url().should("contain", "/#/home", { timeout: 30000 }); | ||
cy.findByRole("heading", { name: "Welcome Alice" }); | ||
}); | ||
|
||
it("still shows the soft-logout page when the page is reloaded after a soft-logout", () => { | ||
interceptRequestsWithSoftLogout(); | ||
cy.findByText("You're signed out"); | ||
cy.reload(); | ||
cy.findByText("You're signed out"); | ||
}); | ||
}); | ||
|
||
describe("with SSO user", () => { | ||
beforeEach(() => { | ||
doTokenRegistration(homeserver.baseUrl); | ||
|
||
// Eventually, we should end up at the home screen. | ||
cy.url().should("contain", "/#/home", { timeout: 30000 }); | ||
cy.findByRole("heading", { name: "Welcome Alice" }); | ||
}); | ||
|
||
it("shows the soft-logout page when a request fails, and allows a re-login", () => { | ||
// there is a bug in Element which means this only actually works if there is an app reload between | ||
// the token login and the soft-logout: https://github.com/vector-im/element-web/issues/25957 | ||
cy.reload(); | ||
cy.findByRole("heading", { name: "Welcome Alice" }); | ||
|
||
interceptRequestsWithSoftLogout(); | ||
|
||
cy.findByText("You're signed out"); | ||
cy.findByRole("button", { name: "Continue with OAuth test" }).click(); | ||
|
||
// click the submit button | ||
cy.findByRole("button", { name: "Submit" }).click(); | ||
|
||
// Synapse prompts us to grant permission to Element | ||
cy.findByRole("heading", { name: "Continue to your account" }); | ||
cy.findByRole("link", { name: "Continue" }).click(); | ||
|
||
// back to the welcome page | ||
cy.url().should("contain", "/#/home", { timeout: 30000 }); | ||
cy.findByRole("heading", { name: "Welcome Alice" }); | ||
}); | ||
}); | ||
}); | ||
|
||
/** | ||
* Intercept calls to /sync and have them fail with a soft-logout | ||
* | ||
* Any further requests to /sync with the same access token are blocked. | ||
*/ | ||
function interceptRequestsWithSoftLogout(): void { | ||
let expiredAccessToken: string | null = null; | ||
cy.intercept( | ||
{ | ||
pathname: "/_matrix/client/*/sync", | ||
}, | ||
(req) => { | ||
const accessToken = req.headers["authorization"] as string; | ||
|
||
// on the first request, record the access token | ||
if (!expiredAccessToken) { | ||
console.log(`Soft-logout on access token ${accessToken}`); | ||
expiredAccessToken = accessToken; | ||
} | ||
|
||
// now, if the access token on this request matches the expired one, block it | ||
if (expiredAccessToken && accessToken === expiredAccessToken) { | ||
console.log(`Intercepting request with soft-logged-out access token`); | ||
req.reply({ | ||
statusCode: 401, | ||
body: { | ||
errcode: "M_UNKNOWN_TOKEN", | ||
error: "Soft logout", | ||
soft_logout: true, | ||
}, | ||
}); | ||
return; | ||
} | ||
|
||
// otherwise, pass through as normal | ||
req.continue(); | ||
}, | ||
); | ||
|
||
// do something to make the active /sync return: create a new room | ||
cy.getClient().then((client) => { | ||
// don't wait for this to complete: it probably won't, because of the broken sync | ||
return client.createRoom({}); | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
/* | ||
Copyright 2023 The Matrix.org Foundation C.I.C. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
*/ | ||
|
||
/** Visit the login page, choose to log in with "OAuth test", register a new account, and redirect back to Element | ||
*/ | ||
export function doTokenRegistration(homeserverUrl: string) { | ||
cy.visit("/#/login"); | ||
|
||
cy.findByRole("button", { name: "Edit" }).click(); | ||
cy.findByRole("textbox", { name: "Other homeserver" }).type(homeserverUrl); | ||
cy.findByRole("button", { name: "Continue" }).click(); | ||
// wait for the dialog to go away | ||
cy.get(".mx_ServerPickerDialog").should("not.exist"); | ||
|
||
// click on "Continue with OAuth test" | ||
cy.findByRole("button", { name: "Continue with OAuth test" }).click(); | ||
|
||
// wait for the Test OAuth Page to load | ||
cy.findByText("Test OAuth page"); | ||
|
||
// click the submit button | ||
cy.findByRole("button", { name: "Submit" }).click(); | ||
|
||
// Synapse prompts us to pick a user ID | ||
cy.findByRole("heading", { name: "Create your account" }); | ||
cy.findByRole("textbox", { name: "Username (required)" }).type("alice"); | ||
|
||
// wait for username validation to start, and complete | ||
cy.wait(50); | ||
cy.get("#field-username-output").should("have.value", ""); | ||
cy.findByRole("button", { name: "Continue" }).click(); | ||
|
||
// Synapse prompts us to grant permission to Element | ||
cy.findByRole("heading", { name: "Continue to your account" }); | ||
cy.findByRole("link", { name: "Continue" }).click(); | ||
} |