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

Device manager - add extra details to device security and renaming (PSG-863) #9501

Merged
merged 9 commits into from
Oct 27, 2022
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
4 changes: 2 additions & 2 deletions src/components/views/elements/LearnMore.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import Modal from '../../../Modal';
import InfoDialog from '../dialogs/InfoDialog';
import AccessibleButton, { IAccessibleButtonProps } from './AccessibleButton';

interface Props extends IAccessibleButtonProps {
export interface LearnMoreProps extends IAccessibleButtonProps {
title: string;
description: string | React.ReactNode;
}

const LearnMore: React.FC<Props> = ({
const LearnMore: React.FC<LearnMoreProps> = ({
title,
description,
...rest
Expand Down
18 changes: 17 additions & 1 deletion src/components/views/settings/devices/DeviceDetailHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import React, { FormEvent, useEffect, useState } from 'react';
import { _t } from '../../../../languageHandler';
import AccessibleButton from '../../elements/AccessibleButton';
import Field from '../../elements/Field';
import LearnMore from '../../elements/LearnMore';
import Spinner from '../../elements/Spinner';
import { Caption } from '../../typography/Caption';
import Heading from '../../typography/Heading';
Expand Down Expand Up @@ -88,7 +89,22 @@ const DeviceNameEditor: React.FC<Props & { stopEditing: () => void }> = ({
<Caption
id={descriptionId}
>
{ _t('Please be aware that session names are also visible to people you communicate with') }
{ _t('Please be aware that session names are also visible to people you communicate with.') }
<LearnMore
title={_t('Renaming sessions')}
description={<>
<p>
{ _t(`Other users in direct messages and rooms that you join ` +
`are able to view a full list of your sessions.`,
) }
</p>
<p>
{ _t(`This provides them with confidence that they are really speaking to you, ` +
`but it also means they can see the session name you enter here.`,
) }
</p>
</>}
/>
{ !!error &&
<span
data-testid="device-rename-error"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
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 LearnMore, { LearnMoreProps } from "../../elements/LearnMore";
import { DeviceSecurityVariation } from "./types";

interface Props extends Omit<LearnMoreProps, 'title' | 'description'> {
variation: DeviceSecurityVariation;
}

const securityCardContent: Record<DeviceSecurityVariation, {
title: string;
description: React.ReactNode | string;
}> = {
[DeviceSecurityVariation.Verified]: {
title: _t('Verified sessions'),
description: <>
<p>{ _t('Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.') }
</p>
<p>
{ _t(
`This means they hold encryption keys for your previous messages, ` +
`and confirm to other users you are communicating with that these sessions are really you.`,
)
}
</p>
</>,
},
[DeviceSecurityVariation.Unverified]: {
title: _t('Unverified sessions'),
description: <>
<p>{ _t('Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.') }
</p>
<p>
{ _t(
`You should make especially certain that you recognise these sessions ` +
`as they could represent an unauthorised use of your account.`,
)
}
</p>
</>,
},
[DeviceSecurityVariation.Inactive]: {
title: _t('Inactive sessions'),
description: <>
<p>{ _t('Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.') }
</p>
<p>
{ _t(
`Removing inactive sessions improves security and performance, ` +
`and makes it easier for you to identify if a new session is suspicious.`,
)
}
</p>
</>,
},
};

/**
* LearnMore with content for device security warnings
*/
export const DeviceSecurityLearnMore: React.FC<Props> = ({ variation }) => {
const { title, description } = securityCardContent[variation];
return <LearnMore title={title} description={description} />;
};
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import React from 'react';
import { _t } from '../../../../languageHandler';
import AccessibleButton from '../../elements/AccessibleButton';
import DeviceSecurityCard from './DeviceSecurityCard';
import { DeviceSecurityLearnMore } from './DeviceSecurityLearnMore';
import {
DeviceSecurityVariation,
ExtendedDevice,
Expand All @@ -36,11 +37,17 @@ export const DeviceVerificationStatusCard: React.FC<Props> = ({
const securityCardProps = device.isVerified ? {
variation: DeviceSecurityVariation.Verified,
heading: _t('Verified session'),
description: _t('This session is ready for secure messaging.'),
description: <>
{ _t('This session is ready for secure messaging.') }
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Verified} />
</>,
} : {
variation: DeviceSecurityVariation.Unverified,
heading: _t('Unverified session'),
description: _t('Verify or sign out from this session for best security and reliability.'),
description: <>
{ _t('Verify or sign out from this session for best security and reliability.') }
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Unverified} />
</>,
};
return <DeviceSecurityCard
{...securityCardProps}
Expand Down
43 changes: 4 additions & 39 deletions src/components/views/settings/devices/FilteredDeviceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import {
import { DevicesState } from './useOwnDevices';
import FilteredDeviceListHeader from './FilteredDeviceListHeader';
import Spinner from '../../elements/Spinner';
import LearnMore from '../../elements/LearnMore';
import { DeviceSecurityLearnMore } from './DeviceSecurityLearnMore';

interface Props {
devices: DevicesDictionary;
Expand Down Expand Up @@ -77,40 +77,17 @@ type DeviceFilterKey = DeviceSecurityVariation | typeof ALL_FILTER_ID;
const securityCardContent: Record<DeviceSecurityVariation, {
title: string;
description: string;
learnMoreDescription: React.ReactNode | string;
}> = {
[DeviceSecurityVariation.Verified]: {
title: _t('Verified sessions'),
description: _t('For best security, sign out from any session that you don\'t recognize or use anymore.'),
learnMoreDescription: <>
<p>{ _t('Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.') }
</p>
<p>
{ _t(
`This means they hold encryption keys for your previous messages, ` +
`and confirm to other users you are communicating with that these sessions are really you.`,
)
}
</p>
</>,
},
[DeviceSecurityVariation.Unverified]: {
title: _t('Unverified sessions'),
description: _t(
`Verify your sessions for enhanced secure messaging or ` +
`sign out from those you don't recognize or use anymore.`,
),
learnMoreDescription: <>
<p>{ _t('Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.') }
</p>
<p>
{ _t(
`You should make especially certain that you recognise these sessions ` +
`as they could represent an unauthorised use of your account.`,
)
}
</p>
</>,
},
[DeviceSecurityVariation.Inactive]: {
title: _t('Inactive sessions'),
Expand All @@ -119,17 +96,6 @@ const securityCardContent: Record<DeviceSecurityVariation, {
`(%(inactiveAgeDays)s days or older) you don't use anymore.`,
{ inactiveAgeDays: INACTIVE_DEVICE_AGE_DAYS },
),
learnMoreDescription: <>
<p>{ _t('Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.') }
</p>
<p>
{ _t(
`Removing inactive sessions improves security and performance, ` +
`and makes it easier for you to identify if a new session is suspicious.`,
)
}
</p>
</>,
},
};

Expand All @@ -138,16 +104,15 @@ const isSecurityVariation = (filter?: DeviceFilterKey): filter is DeviceSecurity

const FilterSecurityCard: React.FC<{ filter?: DeviceFilterKey }> = ({ filter }) => {
if (isSecurityVariation(filter)) {
const { title, description, learnMoreDescription } = securityCardContent[filter];
const { title, description } = securityCardContent[filter];
return <div className='mx_FilteredDeviceList_securityCard'>
<DeviceSecurityCard
variation={filter}
heading={title}
description={<span>
{ description }
<LearnMore
title={title}
description={learnMoreDescription}
<DeviceSecurityLearnMore
variation={filter}
/>
</span>}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { _t } from '../../../../languageHandler';
import AccessibleButton from '../../elements/AccessibleButton';
import SettingsSubsection from '../shared/SettingsSubsection';
import DeviceSecurityCard from './DeviceSecurityCard';
import { DeviceSecurityLearnMore } from './DeviceSecurityLearnMore';
import { filterDevicesBySecurityRecommendation, INACTIVE_DEVICE_AGE_DAYS } from './filter';
import {
DeviceSecurityVariation,
Expand Down Expand Up @@ -70,10 +71,13 @@ const SecurityRecommendations: React.FC<Props> = ({
<DeviceSecurityCard
variation={DeviceSecurityVariation.Unverified}
heading={_t('Unverified sessions')}
description={_t(
`Verify your sessions for enhanced secure messaging` +
description={<>
{ _t(
`Verify your sessions for enhanced secure messaging` +
` or sign out from those you don't recognize or use anymore.`,
)}
) }
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Unverified} />
</>}
>
<AccessibleButton
kind='link_inline'
Expand All @@ -91,11 +95,15 @@ const SecurityRecommendations: React.FC<Props> = ({
<DeviceSecurityCard
variation={DeviceSecurityVariation.Inactive}
heading={_t('Inactive sessions')}
description={_t(
`Consider signing out from old sessions ` +
`(%(inactiveAgeDays)s days or older) you don't use anymore`,
{ inactiveAgeDays },
)}
description={<>
{ _t(
`Consider signing out from old sessions ` +
`(%(inactiveAgeDays)s days or older) you don't use anymore`,
{ inactiveAgeDays },
) }
<DeviceSecurityLearnMore variation={DeviceSecurityVariation.Inactive} />
</>
}
>
<AccessibleButton
kind='link_inline'
Expand Down
23 changes: 13 additions & 10 deletions src/i18n/strings/en_EN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1747,7 +1747,10 @@
"Sign out devices|one": "Sign out device",
"Authentication": "Authentication",
"Rename session": "Rename session",
"Please be aware that session names are also visible to people you communicate with": "Please be aware that session names are also visible to people you communicate with",
"Please be aware that session names are also visible to people you communicate with.": "Please be aware that session names are also visible to people you communicate with.",
"Renaming sessions": "Renaming sessions",
"Other users in direct messages and rooms that you join are able to view a full list of your sessions.": "Other users in direct messages and rooms that you join are able to view a full list of your sessions.",
"This provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here.": "This provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here.",
"Session ID": "Session ID",
"Last activity": "Last activity",
"Application": "Application",
Expand All @@ -1764,6 +1767,15 @@
"Receive push notifications on this session.": "Receive push notifications on this session.",
"Sign out of this session": "Sign out of this session",
"Toggle device details": "Toggle device details",
"Verified sessions": "Verified sessions",
"Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.": "Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.",
"This means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.": "This means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.",
"Unverified sessions": "Unverified sessions",
"Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.": "Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.",
"You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.": "You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.",
"Inactive sessions": "Inactive sessions",
"Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.": "Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.",
"Removing inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.": "Removing inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.",
"Inactive for %(inactiveAgeDays)s+ days": "Inactive for %(inactiveAgeDays)s+ days",
"Verified": "Verified",
"Unverified": "Unverified",
Expand All @@ -1776,18 +1788,9 @@
"Unverified session": "Unverified session",
"Verify or sign out from this session for best security and reliability.": "Verify or sign out from this session for best security and reliability.",
"Verify session": "Verify session",
"Verified sessions": "Verified sessions",
"For best security, sign out from any session that you don't recognize or use anymore.": "For best security, sign out from any session that you don't recognize or use anymore.",
"Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.": "Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.",
"This means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.": "This means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.",
"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.",
"Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.": "Unverified sessions are sessions that have logged in with your credentials but have not been cross-verified.",
"You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.": "You should make especially certain that you recognise these sessions as they could represent an unauthorised use of your account.",
"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.",
"Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.": "Inactive sessions are sessions you have not used in some time, but they continue to receive encryption keys.",
"Removing inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.": "Removing inactive sessions improves security and performance, and makes it easier for you to identify if a new session is suspicious.",
"No verified sessions found.": "No verified sessions found.",
"No unverified sessions found.": "No unverified sessions found.",
"No inactive sessions found.": "No inactive sessions found.",
Expand Down
Loading