From 1abe3a8d983e3bfdd30040016c9968eac25e751f Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 11:49:56 +0200 Subject: [PATCH 01/11] display inactive status on device tile --- res/css/components/views/settings/devices/_DeviceTile.pcss | 7 +++++++ src/components/views/settings/devices/DeviceTile.tsx | 1 + .../devices/__snapshots__/DeviceTile-test.tsx.snap | 2 ++ 3 files changed, 10 insertions(+) diff --git a/res/css/components/views/settings/devices/_DeviceTile.pcss b/res/css/components/views/settings/devices/_DeviceTile.pcss index d89fd9c76eb..0418d941023 100644 --- a/res/css/components/views/settings/devices/_DeviceTile.pcss +++ b/res/css/components/views/settings/devices/_DeviceTile.pcss @@ -38,9 +38,16 @@ limitations under the License. vertical-align: middle; } +.mx_DeviceTile_inactiveIcon { + height: 12px; + margin-right: $spacing-4; +} + .mx_DeviceTile_actions { display: grid; grid-gap: $spacing-8; grid-auto-flow: column; margin-left: $spacing-8; } + + diff --git a/src/components/views/settings/devices/DeviceTile.tsx b/src/components/views/settings/devices/DeviceTile.tsx index 68c355316ee..86910337cdf 100644 --- a/src/components/views/settings/devices/DeviceTile.tsx +++ b/src/components/views/settings/devices/DeviceTile.tsx @@ -24,6 +24,7 @@ import { Alignment } from "../../elements/Tooltip"; import Heading from "../../typography/Heading"; import { INACTIVE_DEVICE_AGE_MS, isDeviceInactive } from "./filter"; import { DeviceWithVerification } from "./useOwnDevices"; + export interface DeviceTileProps { device: DeviceWithVerification; children?: React.ReactNode; diff --git a/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap index cafd47a8a74..0013306aedf 100644 --- a/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[` Last activity renders with inactive notice when last activity was more than 90 days ago 1`] = `"Inactive for 90+ days (Dec 4, 2021)"`; + exports[` renders a device with no metadata 1`] = `
Date: Thu, 11 Aug 2022 13:01:31 +0200 Subject: [PATCH 02/11] unify DeviceSecurityVariation type, add correct icon to inactive ui --- res/css/components/views/settings/devices/_DeviceTile.pcss | 7 ------- src/components/views/settings/devices/DeviceTile.tsx | 1 - .../devices/__snapshots__/DeviceTile-test.tsx.snap | 2 -- 3 files changed, 10 deletions(-) diff --git a/res/css/components/views/settings/devices/_DeviceTile.pcss b/res/css/components/views/settings/devices/_DeviceTile.pcss index 0418d941023..d89fd9c76eb 100644 --- a/res/css/components/views/settings/devices/_DeviceTile.pcss +++ b/res/css/components/views/settings/devices/_DeviceTile.pcss @@ -38,16 +38,9 @@ limitations under the License. vertical-align: middle; } -.mx_DeviceTile_inactiveIcon { - height: 12px; - margin-right: $spacing-4; -} - .mx_DeviceTile_actions { display: grid; grid-gap: $spacing-8; grid-auto-flow: column; margin-left: $spacing-8; } - - diff --git a/src/components/views/settings/devices/DeviceTile.tsx b/src/components/views/settings/devices/DeviceTile.tsx index 86910337cdf..68c355316ee 100644 --- a/src/components/views/settings/devices/DeviceTile.tsx +++ b/src/components/views/settings/devices/DeviceTile.tsx @@ -24,7 +24,6 @@ import { Alignment } from "../../elements/Tooltip"; import Heading from "../../typography/Heading"; import { INACTIVE_DEVICE_AGE_MS, isDeviceInactive } from "./filter"; import { DeviceWithVerification } from "./useOwnDevices"; - export interface DeviceTileProps { device: DeviceWithVerification; children?: React.ReactNode; diff --git a/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap index 0013306aedf..cafd47a8a74 100644 --- a/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/DeviceTile-test.tsx.snap @@ -1,7 +1,5 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[` Last activity renders with inactive notice when last activity was more than 90 days ago 1`] = `"Inactive for 90+ days (Dec 4, 2021)"`; - exports[` renders a device with no metadata 1`] = `
Date: Thu, 11 Aug 2022 13:28:43 +0200 Subject: [PATCH 03/11] move types into type file --- .../views/settings/devices/DeviceTile.tsx | 2 +- .../settings/devices/FilteredDeviceList.tsx | 2 +- .../views/settings/devices/filter.ts | 2 +- .../views/settings/devices/types.ts | 20 +++++++++++++++++++ .../views/settings/devices/useOwnDevices.ts | 5 ++--- 5 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 src/components/views/settings/devices/types.ts diff --git a/src/components/views/settings/devices/DeviceTile.tsx b/src/components/views/settings/devices/DeviceTile.tsx index 68c355316ee..3b553ac4019 100644 --- a/src/components/views/settings/devices/DeviceTile.tsx +++ b/src/components/views/settings/devices/DeviceTile.tsx @@ -23,7 +23,7 @@ import TooltipTarget from "../../elements/TooltipTarget"; import { Alignment } from "../../elements/Tooltip"; import Heading from "../../typography/Heading"; import { INACTIVE_DEVICE_AGE_MS, isDeviceInactive } from "./filter"; -import { DeviceWithVerification } from "./useOwnDevices"; +import { DeviceWithVerification } from "./types"; export interface DeviceTileProps { device: DeviceWithVerification; children?: React.ReactNode; diff --git a/src/components/views/settings/devices/FilteredDeviceList.tsx b/src/components/views/settings/devices/FilteredDeviceList.tsx index 5920d671324..116066d78f6 100644 --- a/src/components/views/settings/devices/FilteredDeviceList.tsx +++ b/src/components/views/settings/devices/FilteredDeviceList.tsx @@ -18,7 +18,7 @@ import React from 'react'; import DeviceTile from './DeviceTile'; import { filterDevicesBySecurityRecommendation } from './filter'; -import { DevicesDictionary, DeviceWithVerification } from './useOwnDevices'; +import { DevicesDictionary, DeviceWithVerification } from './types'; interface Props { devices: DevicesDictionary; diff --git a/src/components/views/settings/devices/filter.ts b/src/components/views/settings/devices/filter.ts index 82bd9e59059..f690d39b3a7 100644 --- a/src/components/views/settings/devices/filter.ts +++ b/src/components/views/settings/devices/filter.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DeviceWithVerification } from "./useOwnDevices"; +import { DeviceWithVerification } from "./types"; export enum DeviceSecurityVariation { Verified = 'Verified', diff --git a/src/components/views/settings/devices/types.ts b/src/components/views/settings/devices/types.ts new file mode 100644 index 00000000000..f5e04052208 --- /dev/null +++ b/src/components/views/settings/devices/types.ts @@ -0,0 +1,20 @@ +/* +Copyright 2022 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 { IMyDevice } from "matrix-js-sdk/src/matrix"; + +export type DeviceWithVerification = IMyDevice & { isVerified: boolean | null }; +export type DevicesDictionary = Record; diff --git a/src/components/views/settings/devices/useOwnDevices.ts b/src/components/views/settings/devices/useOwnDevices.ts index f48d35acdd9..0247a2788a9 100644 --- a/src/components/views/settings/devices/useOwnDevices.ts +++ b/src/components/views/settings/devices/useOwnDevices.ts @@ -20,8 +20,7 @@ import { CrossSigningInfo } from "matrix-js-sdk/src/crypto/CrossSigning"; import { logger } from "matrix-js-sdk/src/logger"; import MatrixClientContext from "../../../../contexts/MatrixClientContext"; - -export type DeviceWithVerification = IMyDevice & { isVerified: boolean | null }; +import { DevicesDictionary, DeviceWithVerification } from "./types"; const isDeviceVerified = ( matrixClient: MatrixClient, @@ -56,11 +55,11 @@ const fetchDevicesWithVerification = async (matrixClient: MatrixClient): Promise return devicesDict; }; + export enum OwnDevicesError { Unsupported = 'Unsupported', Default = 'Default', } -export type DevicesDictionary = Record; type DevicesState = { devices: DevicesDictionary; currentDeviceId: string; From ba372a0ce4423be1bc244859ea528db00b710048 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 13:32:24 +0200 Subject: [PATCH 04/11] move DeviceSecurityVariation into types --- .../views/settings/devices/DeviceSecurityCard.tsx | 2 +- src/components/views/settings/devices/filter.ts | 8 +------- src/components/views/settings/devices/types.ts | 6 ++++++ src/components/views/settings/devices/useOwnDevices.ts | 2 +- .../views/settings/tabs/user/SessionManagerTab.tsx | 2 +- .../views/settings/devices/DeviceSecurityCard-test.tsx | 2 +- test/components/views/settings/devices/filter-test.ts | 4 +++- 7 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/components/views/settings/devices/DeviceSecurityCard.tsx b/src/components/views/settings/devices/DeviceSecurityCard.tsx index d71409cb4fb..01fe4888821 100644 --- a/src/components/views/settings/devices/DeviceSecurityCard.tsx +++ b/src/components/views/settings/devices/DeviceSecurityCard.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { Icon as VerifiedIcon } from '../../../../../res/img/e2e/verified.svg'; import { Icon as UnverifiedIcon } from '../../../../../res/img/e2e/warning.svg'; import { Icon as InactiveIcon } from '../../../../../res/img/element-icons/settings/inactive.svg'; -import { DeviceSecurityVariation } from './filter'; +import { DeviceSecurityVariation } from './types'; interface Props { variation: DeviceSecurityVariation; heading: string; diff --git a/src/components/views/settings/devices/filter.ts b/src/components/views/settings/devices/filter.ts index f690d39b3a7..302c66969bd 100644 --- a/src/components/views/settings/devices/filter.ts +++ b/src/components/views/settings/devices/filter.ts @@ -14,13 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { DeviceWithVerification } from "./types"; - -export enum DeviceSecurityVariation { - Verified = 'Verified', - Unverified = 'Unverified', - Inactive = 'Inactive', -} +import { DeviceWithVerification, DeviceSecurityVariation } from "./types"; type DeviceFilterCondition = (device: DeviceWithVerification) => boolean; diff --git a/src/components/views/settings/devices/types.ts b/src/components/views/settings/devices/types.ts index f5e04052208..1f3328c09ef 100644 --- a/src/components/views/settings/devices/types.ts +++ b/src/components/views/settings/devices/types.ts @@ -18,3 +18,9 @@ import { IMyDevice } from "matrix-js-sdk/src/matrix"; export type DeviceWithVerification = IMyDevice & { isVerified: boolean | null }; export type DevicesDictionary = Record; + +export enum DeviceSecurityVariation { + Verified = 'Verified', + Unverified = 'Unverified', + Inactive = 'Inactive', +} diff --git a/src/components/views/settings/devices/useOwnDevices.ts b/src/components/views/settings/devices/useOwnDevices.ts index 0247a2788a9..ec5ee1ca189 100644 --- a/src/components/views/settings/devices/useOwnDevices.ts +++ b/src/components/views/settings/devices/useOwnDevices.ts @@ -20,7 +20,7 @@ import { CrossSigningInfo } from "matrix-js-sdk/src/crypto/CrossSigning"; import { logger } from "matrix-js-sdk/src/logger"; import MatrixClientContext from "../../../../contexts/MatrixClientContext"; -import { DevicesDictionary, DeviceWithVerification } from "./types"; +import { DevicesDictionary } from "./types"; const isDeviceVerified = ( matrixClient: MatrixClient, diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index ebda5ebe827..ce788db403d 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -23,7 +23,7 @@ import DeviceTile from '../../devices/DeviceTile'; import DeviceSecurityCard from '../../devices/DeviceSecurityCard'; import SettingsSubsection from '../../shared/SettingsSubsection'; import FilteredDeviceList from '../../devices/FilteredDeviceList'; -import { DeviceSecurityVariation } from '../../devices/filter'; +import { DeviceSecurityVariation } from '../../devices/types'; import SettingsTab from '../SettingsTab'; const SessionManagerTab: React.FC = () => { diff --git a/test/components/views/settings/devices/DeviceSecurityCard-test.tsx b/test/components/views/settings/devices/DeviceSecurityCard-test.tsx index 89fb9931b1f..43bf025eba3 100644 --- a/test/components/views/settings/devices/DeviceSecurityCard-test.tsx +++ b/test/components/views/settings/devices/DeviceSecurityCard-test.tsx @@ -18,7 +18,7 @@ import { render } from '@testing-library/react'; import React from 'react'; import DeviceSecurityCard from '../../../../../src/components/views/settings/devices/DeviceSecurityCard'; -import { DeviceSecurityVariation } from '../../../../../src/components/views/settings/devices/filter'; +import { DeviceSecurityVariation } from '../../../../../src/components/views/settings/devices/types'; describe('', () => { const defaultProps = { diff --git a/test/components/views/settings/devices/filter-test.ts b/test/components/views/settings/devices/filter-test.ts index 073efc79cd5..f46b8838ca7 100644 --- a/test/components/views/settings/devices/filter-test.ts +++ b/test/components/views/settings/devices/filter-test.ts @@ -15,9 +15,11 @@ limitations under the License. */ import { - DeviceSecurityVariation, filterDevicesBySecurityRecommendation, } from "../../../../../src/components/views/settings/devices/filter"; +import { + DeviceSecurityVariation, +} from "../../../../../src/components/views/settings/devices/types"; const MS_DAY = 86400000; describe('filterDevicesBySecurityRecommendation()', () => { From 2baa206627ad6157d4a9b8c85fe5bbee5f7336a2 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 13:57:08 +0200 Subject: [PATCH 05/11] add security recommendations section --- .../devices/_SecurityRecommendations.pcss | 4 + .../devices/SecurityRecommendations.tsx | 78 +++++++++++++++++++ .../views/settings/devices/filter.ts | 3 +- .../settings/tabs/user/SessionManagerTab.tsx | 2 + src/i18n/strings/en_EN.json | 6 ++ .../devices/SecurityRecommendations-test.tsx | 16 ++++ 6 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 res/css/components/views/settings/devices/_SecurityRecommendations.pcss create mode 100644 src/components/views/settings/devices/SecurityRecommendations.tsx create mode 100644 test/components/views/settings/devices/SecurityRecommendations-test.tsx diff --git a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss new file mode 100644 index 00000000000..c5ed2015feb --- /dev/null +++ b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss @@ -0,0 +1,4 @@ + +.mx_SecurityRecommendations { + +} diff --git a/src/components/views/settings/devices/SecurityRecommendations.tsx b/src/components/views/settings/devices/SecurityRecommendations.tsx new file mode 100644 index 00000000000..2f9206f498a --- /dev/null +++ b/src/components/views/settings/devices/SecurityRecommendations.tsx @@ -0,0 +1,78 @@ +/* +Copyright 2022 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 React from 'react'; +import { _t } from '../../../../languageHandler'; +import SettingsSubsection from '../shared/SettingsSubsection'; +import DeviceSecurityCard from './DeviceSecurityCard'; +import { filterDevicesBySecurityRecommendation, INACTIVE_DEVICE_AGE_MS } from './filter'; + +import { DevicesDictionary, DeviceSecurityVariation } from './types'; + +interface Props { + devices: DevicesDictionary; +} +const MS_DAY = 24 * 60 * 60 * 1000; + +const SecurityRecommendations: React.FC = ({ devices }) => { + const devicesArray = Object.values(devices); + + const unverifiedDevicesCount = filterDevicesBySecurityRecommendation( + devicesArray, + [DeviceSecurityVariation.Unverified], + ).length; + const inactiveDevicesCount = filterDevicesBySecurityRecommendation( + devicesArray, + [DeviceSecurityVariation.Inactive], + ).length; + + if (!(unverifiedDevicesCount | inactiveDevicesCount)) { + return null; + } + + const inactiveAgeDays = INACTIVE_DEVICE_AGE_MS / MS_DAY; + + return + { + !!unverifiedDevicesCount && + + } + { + !!inactiveDevicesCount && + + } + +}; + +export default SecurityRecommendations; diff --git a/src/components/views/settings/devices/filter.ts b/src/components/views/settings/devices/filter.ts index 302c66969bd..54d18bcea08 100644 --- a/src/components/views/settings/devices/filter.ts +++ b/src/components/views/settings/devices/filter.ts @@ -18,7 +18,8 @@ import { DeviceWithVerification, DeviceSecurityVariation } from "./types"; type DeviceFilterCondition = (device: DeviceWithVerification) => boolean; -export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days +// export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days +export const INACTIVE_DEVICE_AGE_MS = 7.776e+9 / 90; // 90 days export const isDeviceInactive: DeviceFilterCondition = device => !!device.last_seen_ts && device.last_seen_ts < Date.now() - INACTIVE_DEVICE_AGE_MS; diff --git a/src/components/views/settings/tabs/user/SessionManagerTab.tsx b/src/components/views/settings/tabs/user/SessionManagerTab.tsx index ce788db403d..a7201e360aa 100644 --- a/src/components/views/settings/tabs/user/SessionManagerTab.tsx +++ b/src/components/views/settings/tabs/user/SessionManagerTab.tsx @@ -24,6 +24,7 @@ import DeviceSecurityCard from '../../devices/DeviceSecurityCard'; import SettingsSubsection from '../../shared/SettingsSubsection'; import FilteredDeviceList from '../../devices/FilteredDeviceList'; import { DeviceSecurityVariation } from '../../devices/types'; +import SecurityRecommendations from '../../devices/SecurityRecommendations'; import SettingsTab from '../SettingsTab'; const SessionManagerTab: React.FC = () => { @@ -43,6 +44,7 @@ const SessionManagerTab: React.FC = () => { }; return + ', () => { + const defaultProps = {}; + const getComponent = (props = {}) => + mount(); + + it('renders', () => { + const component = getComponent(); + expect(component).toBeTruthy(); + }); +}); From 311865f02b0d0aa80fe23423f5fba3f181a297d4 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 21:49:43 +0200 Subject: [PATCH 06/11] add view all stubbed buttons --- .../devices/_SecurityRecommendations.pcss | 4 -- .../devices/SecurityRecommendations.tsx | 46 ++++++++++++++----- src/i18n/strings/en_EN.json | 1 + 3 files changed, 35 insertions(+), 16 deletions(-) delete mode 100644 res/css/components/views/settings/devices/_SecurityRecommendations.pcss diff --git a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss deleted file mode 100644 index c5ed2015feb..00000000000 --- a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss +++ /dev/null @@ -1,4 +0,0 @@ - -.mx_SecurityRecommendations { - -} diff --git a/src/components/views/settings/devices/SecurityRecommendations.tsx b/src/components/views/settings/devices/SecurityRecommendations.tsx index 2f9206f498a..7d234362268 100644 --- a/src/components/views/settings/devices/SecurityRecommendations.tsx +++ b/src/components/views/settings/devices/SecurityRecommendations.tsx @@ -15,11 +15,12 @@ limitations under the License. */ import React from 'react'; + import { _t } from '../../../../languageHandler'; +import AccessibleButton from '../../elements/AccessibleButton'; import SettingsSubsection from '../shared/SettingsSubsection'; import DeviceSecurityCard from './DeviceSecurityCard'; import { filterDevicesBySecurityRecommendation, INACTIVE_DEVICE_AGE_MS } from './filter'; - import { DevicesDictionary, DeviceSecurityVariation } from './types'; interface Props { @@ -45,6 +46,9 @@ const SecurityRecommendations: React.FC = ({ devices }) => { const inactiveAgeDays = INACTIVE_DEVICE_AGE_MS / MS_DAY; + // TODO(kerrya) stubbed until PSG-640/652 + const noop = () => {}; + return = ({ devices }) => { heading={_t('Unverified sessions')} description={_t( `Verify your sessions for enhanced secure messaging` + - ` or sign out from those you don't recognize or use anymore.` + ` or sign out from those you don't recognize or use anymore.`, )} - /> + > + + { _t('View all') + ` (${unverifiedDevicesCount})` } + + } { !!inactiveDevicesCount && - + <> + { !!unverifiedDevicesCount &&
} + + + { _t('View all') + ` (${inactiveDevicesCount})` } + + + } - + ; }; export default SecurityRecommendations; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index cba9264fffe..8459bda18d5 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1710,6 +1710,7 @@ "Improve your account security by following these recommendations": "Improve your account security by following these recommendations", "Unverified sessions": "Unverified sessions", "Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore.": "Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore.", + "View all": "View all", "Inactive sessions": "Inactive sessions", "Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore": "Consider signing out from old sessions (%(inactiveAgeDays)s days or older) you don't use anymore", "Unable to remove contact information": "Unable to remove contact information", From 1fcb3bbcbe7f4a5a14bdb379ffacfc845f64ded0 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 21:50:00 +0200 Subject: [PATCH 07/11] undeo debug --- src/components/views/settings/devices/filter.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/settings/devices/filter.ts b/src/components/views/settings/devices/filter.ts index 54d18bcea08..0b12bff64cb 100644 --- a/src/components/views/settings/devices/filter.ts +++ b/src/components/views/settings/devices/filter.ts @@ -19,7 +19,7 @@ import { DeviceWithVerification, DeviceSecurityVariation } from "./types"; type DeviceFilterCondition = (device: DeviceWithVerification) => boolean; // export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days -export const INACTIVE_DEVICE_AGE_MS = 7.776e+9 / 90; // 90 days +export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days export const isDeviceInactive: DeviceFilterCondition = device => !!device.last_seen_ts && device.last_seen_ts < Date.now() - INACTIVE_DEVICE_AGE_MS; From 1281724dfb2e6ea57f72d59f6012adccaeedda5a Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Thu, 11 Aug 2022 22:00:40 +0200 Subject: [PATCH 08/11] test security recs --- .../devices/SecurityRecommendations-test.tsx | 68 ++++- .../SecurityRecommendations-test.tsx.snap | 274 ++++++++++++++++++ 2 files changed, 336 insertions(+), 6 deletions(-) create mode 100644 test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap diff --git a/test/components/views/settings/devices/SecurityRecommendations-test.tsx b/test/components/views/settings/devices/SecurityRecommendations-test.tsx index 820592674f5..13f028539a8 100644 --- a/test/components/views/settings/devices/SecurityRecommendations-test.tsx +++ b/test/components/views/settings/devices/SecurityRecommendations-test.tsx @@ -1,16 +1,72 @@ +/* +Copyright 2022 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 React from 'react'; -import { mount } from 'enzyme'; +import { render } from '@testing-library/react'; import SecurityRecommendations from '../../../../../src/components/views/settings/devices/SecurityRecommendations'; +const MS_DAY = 86400000; describe('', () => { - const defaultProps = {}; + const unverifiedNoMetadata = { device_id: 'unverified-no-metadata', isVerified: false }; + const verifiedNoMetadata = { device_id: 'verified-no-metadata', isVerified: true }; + const hundredDaysOld = { device_id: '100-days-old', isVerified: true, last_seen_ts: Date.now() - (MS_DAY * 100) }; + const hundredDaysOldUnverified = { + device_id: 'unverified-100-days-old', + isVerified: false, + last_seen_ts: Date.now() - (MS_DAY * 100), + }; + + const defaultProps = { + devices: {}, + }; const getComponent = (props = {}) => - mount(); + (); + + it('renders null when no devices', () => { + const { container } = render(getComponent()); + expect(container.firstChild).toBeNull(); + }); + + it('renders unverified devices section when user has unverified devices', () => { + const devices = { + [unverifiedNoMetadata.device_id]: unverifiedNoMetadata, + [verifiedNoMetadata.device_id]: verifiedNoMetadata, + [hundredDaysOldUnverified.device_id]: hundredDaysOldUnverified, + }; + const { container } = render(getComponent({ devices })); + expect(container).toMatchSnapshot(); + }); + + it('renders inactive devices section when user has inactive devices', () => { + const devices = { + [verifiedNoMetadata.device_id]: verifiedNoMetadata, + [hundredDaysOldUnverified.device_id]: hundredDaysOldUnverified, + }; + const { container } = render(getComponent({ devices })); + expect(container).toMatchSnapshot(); + }); - it('renders', () => { - const component = getComponent(); - expect(component).toBeTruthy(); + it('renders both cards when user has both unverified and inactive devices', () => { + const devices = { + [verifiedNoMetadata.device_id]: verifiedNoMetadata, + [hundredDaysOld.device_id]: hundredDaysOld, + [unverifiedNoMetadata.device_id]: unverifiedNoMetadata, + }; + const { container } = render(getComponent({ devices })); + expect(container).toMatchSnapshot(); }); }); diff --git a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap new file mode 100644 index 00000000000..d3cb175a793 --- /dev/null +++ b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap @@ -0,0 +1,274 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` renders both cards when user has both unverified and inactive devices 1`] = ` +
+
+

+ Security recommendations +

+
+ Improve your account security by following these recommendations +
+
+
+
+
+
+
+

+ Unverified sessions +

+

+ Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore. +

+ +
+
+
+
+
+
+
+
+

+ Inactive sessions +

+

+ Consider signing out from old sessions (90 days or older) you don't use anymore +

+ +
+
+
+
+
+`; + +exports[` renders inactive devices section when user has inactive devices 1`] = ` +
+
+

+ Security recommendations +

+
+ Improve your account security by following these recommendations +
+
+
+
+
+
+
+

+ Unverified sessions +

+

+ Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore. +

+ +
+
+
+
+
+
+
+
+

+ Inactive sessions +

+

+ Consider signing out from old sessions (90 days or older) you don't use anymore +

+ +
+
+
+
+
+`; + +exports[` renders unverified devices section when user has unverified devices 1`] = ` +
+
+

+ Security recommendations +

+
+ Improve your account security by following these recommendations +
+
+
+
+
+
+
+

+ Unverified sessions +

+

+ Verify your sessions for enhanced secure messaging or sign out from those you don't recognize or use anymore. +

+ +
+
+
+
+
+
+
+
+

+ Inactive sessions +

+

+ Consider signing out from old sessions (90 days or older) you don't use anymore +

+ +
+
+
+
+
+`; From b238dc74181f39b69c0ce918bf393d7b0a014c0f Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Fri, 12 Aug 2022 09:40:43 +0200 Subject: [PATCH 09/11] remove debug --- src/components/views/settings/devices/filter.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/views/settings/devices/filter.ts b/src/components/views/settings/devices/filter.ts index 0b12bff64cb..302c66969bd 100644 --- a/src/components/views/settings/devices/filter.ts +++ b/src/components/views/settings/devices/filter.ts @@ -18,7 +18,6 @@ import { DeviceWithVerification, DeviceSecurityVariation } from "./types"; type DeviceFilterCondition = (device: DeviceWithVerification) => boolean; -// export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days export const INACTIVE_DEVICE_AGE_MS = 7.776e+9; // 90 days export const isDeviceInactive: DeviceFilterCondition = device => From 572ae1e83b960334308af709c7564d111f905099 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 15 Aug 2022 09:15:16 +0200 Subject: [PATCH 10/11] use css for card spacing --- res/css/_components.pcss | 1 + .../devices/_SecurityRecommendations.pcss | 19 +++++++++++++++++++ .../devices/SecurityRecommendations.tsx | 2 +- .../devices/SecurityRecommendations-test.tsx | 2 +- .../SecurityRecommendations-test.tsx.snap | 12 +++++++++--- 5 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 res/css/components/views/settings/devices/_SecurityRecommendations.pcss diff --git a/res/css/_components.pcss b/res/css/_components.pcss index 5e43b2810db..aaba5257949 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -31,6 +31,7 @@ @import "./components/views/settings/devices/_DeviceSecurityCard.pcss"; @import "./components/views/settings/devices/_DeviceTile.pcss"; @import "./components/views/settings/devices/_FilteredDeviceList.pcss"; +@import "./components/views/settings/devices/_SecurityRecommendations.pcss"; @import "./components/views/settings/devices/_SelectableDeviceTile.pcss"; @import "./components/views/settings/shared/_SettingsSubsection.pcss"; @import "./components/views/spaces/_QuickThemeSwitcher.pcss"; diff --git a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss new file mode 100644 index 00000000000..e08c6f0e842 --- /dev/null +++ b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss @@ -0,0 +1,19 @@ +/* +Copyright 2022 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. +*/ + +.mx_SecurityRecommendations_spacing { + height: $spacing-16; +} \ No newline at end of file diff --git a/src/components/views/settings/devices/SecurityRecommendations.tsx b/src/components/views/settings/devices/SecurityRecommendations.tsx index 7d234362268..fcb8f086c93 100644 --- a/src/components/views/settings/devices/SecurityRecommendations.tsx +++ b/src/components/views/settings/devices/SecurityRecommendations.tsx @@ -75,7 +75,7 @@ const SecurityRecommendations: React.FC = ({ devices }) => { { !!inactiveDevicesCount && <> - { !!unverifiedDevicesCount &&
} + { !!unverifiedDevicesCount &&
} ', () => { const unverifiedNoMetadata = { device_id: 'unverified-no-metadata', isVerified: false }; const verifiedNoMetadata = { device_id: 'verified-no-metadata', isVerified: true }; diff --git a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap index d3cb175a793..6de70e4f506 100644 --- a/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap +++ b/test/components/views/settings/devices/__snapshots__/SecurityRecommendations-test.tsx.snap @@ -52,7 +52,9 @@ exports[` renders both cards when user has both unver
-
+
@@ -143,7 +145,9 @@ exports[` renders inactive devices section when user
-
+
@@ -234,7 +238,9 @@ exports[` renders unverified devices section when use
-
+
From d17f19b5d585b126f8e02e8143f33bfef9267a76 Mon Sep 17 00:00:00 2001 From: Kerry Archibald Date: Mon, 15 Aug 2022 10:00:17 +0200 Subject: [PATCH 11/11] stylelint --- .../views/settings/devices/_SecurityRecommendations.pcss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss index e08c6f0e842..d0a53335590 100644 --- a/res/css/components/views/settings/devices/_SecurityRecommendations.pcss +++ b/res/css/components/views/settings/devices/_SecurityRecommendations.pcss @@ -16,4 +16,4 @@ limitations under the License. .mx_SecurityRecommendations_spacing { height: $spacing-16; -} \ No newline at end of file +}