Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit d473b4a

Browse files
author
Kerry
authored
Device manager - confirm sign out of other sessions (PSG-921) (#9487)
* change testid attribute for dialog buttons to rtl friendly * add confirm dialog for signing out sessions * cleanup commented * update cypress tets * clear modals before test * missing modal in jest tests on ci only
1 parent 37e613b commit d473b4a

File tree

9 files changed

+174
-84
lines changed

9 files changed

+174
-84
lines changed

cypress/e2e/settings/device-management.spec.ts

+3
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ describe("Device manager", () => {
7878
cy.get('.mx_FilteredDeviceList_list .mx_FilteredDeviceList_listItem .mx_Checkbox').last().click();
7979
// sign out from list selection action buttons
8080
cy.get('[data-testid="sign-out-selection-cta"]').click();
81+
cy.get('[data-testid="dialog-primary-button"]').click();
8182
// list updated after sign out
8283
cy.get('.mx_FilteredDeviceList_list').find('.mx_FilteredDeviceList_listItem').should('have.length', 1);
8384
// security recommendation count updated
@@ -106,6 +107,8 @@ describe("Device manager", () => {
106107
// sign out using the device details sign out
107108
cy.get('[data-testid="device-detail-sign-out-cta"]').click();
108109
});
110+
// confirm the signout
111+
cy.get('[data-testid="dialog-primary-button"]').click();
109112

110113
// no other sessions or security recommendations sections when only one session
111114
cy.contains('Other sessions').should('not.exist');

src/components/views/elements/DialogButtons.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export default class DialogButtons extends React.Component<IProps> {
8282
cancelButton = <button
8383
// important: the default type is 'submit' and this button comes before the
8484
// primary in the DOM so will get form submissions unless we make it not a submit.
85-
data-test-id="dialog-cancel-button"
85+
data-testid="dialog-cancel-button"
8686
type="button"
8787
onClick={this.onCancelClick}
8888
className={this.props.cancelButtonClass}
@@ -104,7 +104,7 @@ export default class DialogButtons extends React.Component<IProps> {
104104
{ cancelButton }
105105
{ this.props.children }
106106
<button type={this.props.primaryIsSubmit ? 'submit' : 'button'}
107-
data-test-id="dialog-primary-button"
107+
data-testid="dialog-primary-button"
108108
className={primaryButtonClassName}
109109
onClick={this.props.onPrimaryButtonClick}
110110
autoFocus={this.props.focus}

src/components/views/settings/tabs/user/SessionManagerTab.tsx

+24
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,25 @@ import LoginWithQRSection from '../../devices/LoginWithQRSection';
3636
import LoginWithQR, { Mode } from '../../../auth/LoginWithQR';
3737
import SettingsStore from '../../../../../settings/SettingsStore';
3838
import { useAsyncMemo } from '../../../../../hooks/useAsyncMemo';
39+
import QuestionDialog from '../../../dialogs/QuestionDialog';
40+
41+
const confirmSignOut = async (sessionsToSignOutCount: number): Promise<boolean> => {
42+
const { finished } = Modal.createDialog(QuestionDialog, {
43+
title: _t("Sign out"),
44+
description: (
45+
<div>
46+
<p>{ _t("Are you sure you want to sign out of %(count)s sessions?", {
47+
count: sessionsToSignOutCount,
48+
}) }</p>
49+
</div>
50+
),
51+
cancelButton: _t('Cancel'),
52+
button: _t("Sign out"),
53+
});
54+
const [confirmed] = await finished;
55+
56+
return confirmed;
57+
};
3958

4059
const useSignOut = (
4160
matrixClient: MatrixClient,
@@ -61,6 +80,11 @@ const useSignOut = (
6180
if (!deviceIds.length) {
6281
return;
6382
}
83+
const userConfirmedSignout = await confirmSignOut(deviceIds.length);
84+
if (!userConfirmedSignout) {
85+
return;
86+
}
87+
6488
try {
6589
setSigningOutDeviceIds([...signingOutDeviceIds, ...deviceIds]);
6690
await deleteDevicesWithInteractiveAuth(

src/i18n/strings/en_EN.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -1596,6 +1596,9 @@
15961596
"Sessions": "Sessions",
15971597
"Where you're signed in": "Where you're signed in",
15981598
"Manage your signed-in devices below. A device's name is visible to people you communicate with.": "Manage your signed-in devices below. A device's name is visible to people you communicate with.",
1599+
"Sign out": "Sign out",
1600+
"Are you sure you want to sign out of %(count)s sessions?|other": "Are you sure you want to sign out of %(count)s sessions?",
1601+
"Are you sure you want to sign out of %(count)s sessions?|one": "Are you sure you want to sign out of %(count)s session?",
15991602
"Other sessions": "Other sessions",
16001603
"For best security, verify your sessions and sign out from any session that you don't recognize or use anymore.": "For best security, verify your sessions and sign out from any session that you don't recognize or use anymore.",
16011604
"Sidebar": "Sidebar",
@@ -1732,7 +1735,6 @@
17321735
"Please enter verification code sent via text.": "Please enter verification code sent via text.",
17331736
"Verification code": "Verification code",
17341737
"Discovery options will appear once you have added a phone number above.": "Discovery options will appear once you have added a phone number above.",
1735-
"Sign out": "Sign out",
17361738
"Sign out all other sessions": "Sign out all other sessions",
17371739
"Current session": "Current session",
17381740
"Confirm logging out these devices by using Single Sign On to prove your identity.|other": "Confirm logging out these devices by using Single Sign On to prove your identity.",

test/components/views/dialogs/AccessSecretStorageDialog-test.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { mount, ReactWrapper } from 'enzyme';
2020
import { act } from 'react-dom/test-utils';
2121
import { IPassphraseInfo } from 'matrix-js-sdk/src/crypto/api';
2222

23-
import { findByTestId, getMockClientWithEventEmitter, unmockClientPeg } from '../../../test-utils';
23+
import { findByAttr, getMockClientWithEventEmitter, unmockClientPeg } from '../../../test-utils';
2424
import { findById, flushPromises } from '../../../test-utils';
2525
import AccessSecretStorageDialog from "../../../../src/components/views/dialogs/security/AccessSecretStorageDialog";
2626

@@ -91,7 +91,7 @@ describe("AccessSecretStorageDialog", () => {
9191
wrapper.setProps({});
9292
});
9393

94-
const submitButton = findByTestId(wrapper, 'dialog-primary-button').at(0);
94+
const submitButton = findByAttr('data-testid')(wrapper, 'dialog-primary-button').at(0);
9595
// submit button is enabled when key is valid
9696
expect(submitButton.props().disabled).toBeFalsy();
9797
expect(wrapper.find('.mx_AccessSecretStorageDialog_recoveryKeyFeedback').text()).toEqual('Looks good!');
@@ -112,7 +112,7 @@ describe("AccessSecretStorageDialog", () => {
112112
// @ts-ignore private
113113
await wrapper.instance().validateRecoveryKey();
114114

115-
const submitButton = findByTestId(wrapper, 'dialog-primary-button').at(0);
115+
const submitButton = findByAttr('data-testid')(wrapper, 'dialog-primary-button').at(0);
116116
// submit button is disabled when recovery key is invalid
117117
expect(submitButton.props().disabled).toBeTruthy();
118118
expect(

test/components/views/dialogs/ExportDialog-test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ describe('<ExportDialog />', () => {
6565
const getAttachmentsCheckbox = (component) => component.find('input[id="include-attachments"]');
6666
const getMessageCountInput = (component) => component.find('input[id="message-count"]');
6767
const getExportFormatInput = (component, format) => component.find(`input[id="exportFormat-${format}"]`);
68-
const getPrimaryButton = (component) => component.find('[data-test-id="dialog-primary-button"]');
69-
const getSecondaryButton = (component) => component.find('[data-test-id="dialog-cancel-button"]');
68+
const getPrimaryButton = (component) => component.find('[data-testid="dialog-primary-button"]');
69+
const getSecondaryButton = (component) => component.find('[data-testid="dialog-cancel-button"]');
7070

7171
const submitForm = async (component) => act(async () => {
7272
getPrimaryButton(component).simulate('click');

test/components/views/dialogs/__snapshots__/ChangelogDialog-test.tsx.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,14 @@ exports[`<ChangelogDialog /> should fetch github proxy url for each repo with ol
111111
class="mx_Dialog_buttons_row"
112112
>
113113
<button
114-
data-test-id="dialog-cancel-button"
114+
data-testid="dialog-cancel-button"
115115
type="button"
116116
>
117117
Cancel
118118
</button>
119119
<button
120120
class="mx_Dialog_primary"
121-
data-test-id="dialog-primary-button"
121+
data-testid="dialog-primary-button"
122122
type="button"
123123
>
124124
Update

test/components/views/dialogs/__snapshots__/ExportDialog-test.tsx.snap

+20-20
Original file line numberDiff line numberDiff line change
@@ -249,14 +249,14 @@ Array [
249249
class="mx_Dialog_buttons_row"
250250
>
251251
<button
252-
data-test-id="dialog-cancel-button"
252+
data-testid="dialog-cancel-button"
253253
type="button"
254254
>
255255
Cancel
256256
</button>
257257
<button
258258
class="mx_Dialog_primary"
259-
data-test-id="dialog-primary-button"
259+
data-testid="dialog-primary-button"
260260
type="button"
261261
>
262262
Export
@@ -474,14 +474,14 @@ Array [
474474
class="mx_Dialog_buttons_row"
475475
>
476476
<button
477-
data-test-id="dialog-cancel-button"
477+
data-testid="dialog-cancel-button"
478478
type="button"
479479
>
480480
Cancel
481481
</button>
482482
<button
483483
class="mx_Dialog_primary"
484-
data-test-id="dialog-primary-button"
484+
data-testid="dialog-primary-button"
485485
type="button"
486486
>
487487
Export
@@ -827,7 +827,7 @@ Array [
827827
className="mx_Dialog_buttons_row"
828828
>
829829
<button
830-
data-test-id="dialog-cancel-button"
830+
data-testid="dialog-cancel-button"
831831
disabled={false}
832832
onClick={[Function]}
833833
type="button"
@@ -836,7 +836,7 @@ Array [
836836
</button>
837837
<button
838838
className="mx_Dialog_primary"
839-
data-test-id="dialog-primary-button"
839+
data-testid="dialog-primary-button"
840840
onClick={[Function]}
841841
type="button"
842842
>
@@ -1102,14 +1102,14 @@ Array [
11021102
class="mx_Dialog_buttons_row"
11031103
>
11041104
<button
1105-
data-test-id="dialog-cancel-button"
1105+
data-testid="dialog-cancel-button"
11061106
type="button"
11071107
>
11081108
Cancel
11091109
</button>
11101110
<button
11111111
class="mx_Dialog_primary"
1112-
data-test-id="dialog-primary-button"
1112+
data-testid="dialog-primary-button"
11131113
type="button"
11141114
>
11151115
Export
@@ -1327,14 +1327,14 @@ Array [
13271327
class="mx_Dialog_buttons_row"
13281328
>
13291329
<button
1330-
data-test-id="dialog-cancel-button"
1330+
data-testid="dialog-cancel-button"
13311331
type="button"
13321332
>
13331333
Cancel
13341334
</button>
13351335
<button
13361336
class="mx_Dialog_primary"
1337-
data-test-id="dialog-primary-button"
1337+
data-testid="dialog-primary-button"
13381338
type="button"
13391339
>
13401340
Export
@@ -1680,7 +1680,7 @@ Array [
16801680
className="mx_Dialog_buttons_row"
16811681
>
16821682
<button
1683-
data-test-id="dialog-cancel-button"
1683+
data-testid="dialog-cancel-button"
16841684
disabled={false}
16851685
onClick={[Function]}
16861686
type="button"
@@ -1689,7 +1689,7 @@ Array [
16891689
</button>
16901690
<button
16911691
className="mx_Dialog_primary"
1692-
data-test-id="dialog-primary-button"
1692+
data-testid="dialog-primary-button"
16931693
onClick={[Function]}
16941694
type="button"
16951695
>
@@ -1942,14 +1942,14 @@ Array [
19421942
class="mx_Dialog_buttons_row"
19431943
>
19441944
<button
1945-
data-test-id="dialog-cancel-button"
1945+
data-testid="dialog-cancel-button"
19461946
type="button"
19471947
>
19481948
Cancel
19491949
</button>
19501950
<button
19511951
class="mx_Dialog_primary"
1952-
data-test-id="dialog-primary-button"
1952+
data-testid="dialog-primary-button"
19531953
type="button"
19541954
>
19551955
Export
@@ -2167,14 +2167,14 @@ Array [
21672167
class="mx_Dialog_buttons_row"
21682168
>
21692169
<button
2170-
data-test-id="dialog-cancel-button"
2170+
data-testid="dialog-cancel-button"
21712171
type="button"
21722172
>
21732173
Cancel
21742174
</button>
21752175
<button
21762176
class="mx_Dialog_primary"
2177-
data-test-id="dialog-primary-button"
2177+
data-testid="dialog-primary-button"
21782178
type="button"
21792179
>
21802180
Export
@@ -2520,7 +2520,7 @@ Array [
25202520
className="mx_Dialog_buttons_row"
25212521
>
25222522
<button
2523-
data-test-id="dialog-cancel-button"
2523+
data-testid="dialog-cancel-button"
25242524
disabled={false}
25252525
onClick={[Function]}
25262526
type="button"
@@ -2529,7 +2529,7 @@ Array [
25292529
</button>
25302530
<button
25312531
className="mx_Dialog_primary"
2532-
data-test-id="dialog-primary-button"
2532+
data-testid="dialog-primary-button"
25332533
onClick={[Function]}
25342534
type="button"
25352535
>
@@ -2873,7 +2873,7 @@ Array [
28732873
className="mx_Dialog_buttons_row"
28742874
>
28752875
<button
2876-
data-test-id="dialog-cancel-button"
2876+
data-testid="dialog-cancel-button"
28772877
disabled={false}
28782878
onClick={[Function]}
28792879
type="button"
@@ -2882,7 +2882,7 @@ Array [
28822882
</button>
28832883
<button
28842884
className="mx_Dialog_primary"
2885-
data-test-id="dialog-primary-button"
2885+
data-testid="dialog-primary-button"
28862886
onClick={[Function]}
28872887
type="button"
28882888
>

0 commit comments

Comments
 (0)