diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx
index 7b697092f7c62..052af8793f406 100644
--- a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx
+++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.story.tsx
@@ -44,6 +44,7 @@ const doc: types.DocumentAuthorizeWebSession = {
redirectUri: '',
token: '',
id: '',
+ username: 'alice',
},
};
@@ -62,6 +63,31 @@ export function DeviceNotTrusted() {
);
}
+export function RequestedUserNotLoggedIn() {
+ const rootCluster = makeRootCluster({
+ loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }),
+ });
+ const docForDifferentUser: types.DocumentAuthorizeWebSession = {
+ ...doc,
+ webSessionRequest: {
+ ...doc.webSessionRequest,
+ username: 'bob',
+ },
+ };
+ const appContext = new MockAppContext();
+ appContext.clustersService.setState(draftState => {
+ draftState.clusters.set(rootCluster.uri, rootCluster);
+ });
+
+ return (
+
+
+
+
+
+ );
+}
+
export function DeviceTrusted() {
const rootCluster = makeRootCluster({
loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }),
diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx
index c06ff109ff93c..67f47026cde36 100644
--- a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx
+++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.test.tsx
@@ -40,10 +40,11 @@ const doc: types.DocumentAuthorizeWebSession = {
redirectUri: '',
token: '',
id: '',
+ username: 'alice',
},
};
-test('authorize button is disabled when device is not trusted', async () => {
+test('warning is visible and authorize button is disabled when device is not trusted', async () => {
const rootCluster = makeRootCluster({
loggedInUser: makeLoggedInUser({ isDeviceTrusted: false }),
});
@@ -64,6 +65,29 @@ test('authorize button is disabled when device is not trusted', async () => {
expect(await screen.findByText(/Authorize Session/)).toBeDisabled();
});
+test('warning is visible and authorize button is disabled when requested user is not logged in', async () => {
+ const rootCluster = makeRootCluster({
+ loggedInUser: makeLoggedInUser({ isDeviceTrusted: true, name: 'bob' }),
+ });
+ const appContext = new MockAppContext();
+ appContext.clustersService.setState(draftState => {
+ draftState.clusters.set(rootCluster.uri, rootCluster);
+ });
+
+ render(
+
+
+
+
+
+ );
+
+ expect(
+ await screen.findByText(/Requested user is not logged in/)
+ ).toBeVisible();
+ expect(await screen.findByText(/Authorize Session/)).toBeDisabled();
+});
+
test('authorizing a session opens its URL and closes document', async () => {
jest.spyOn(window, 'open').mockImplementation();
const rootCluster = makeRootCluster({
diff --git a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx
index fa85eb296c48b..92331f996fd9c 100644
--- a/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx
+++ b/web/packages/teleterm/src/ui/DocumentAuthorizeWebSession/DocumentAuthorizeWebSession.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { Text, Alert, ButtonPrimary, H1, ButtonText } from 'design';
+import { Text, Alert, ButtonPrimary, H1, ButtonText, Link } from 'design';
import Flex from 'design/Flex';
import { useAsync, Attempt } from 'shared/hooks/useAsync';
import { processRedirectUri } from 'shared/redirects';
@@ -50,7 +50,10 @@ export function DocumentAuthorizeWebSession(props: {
return confirmationToken;
});
const clusterName = routing.parseClusterName(props.doc.rootClusterUri);
- const canAuthorize = rootCluster.loggedInUser?.isDeviceTrusted;
+ const isDeviceTrusted = rootCluster.loggedInUser?.isDeviceTrusted;
+ const isRequestedUserLoggedIn =
+ props.doc.webSessionRequest.username === rootCluster.loggedInUser?.name;
+ const canAuthorize = isDeviceTrusted && isRequestedUserLoggedIn;
async function authorizeAndCloseDocument() {
const [confirmationToken, error] = await authorize();
@@ -95,7 +98,7 @@ export function DocumentAuthorizeWebSession(props: {
Authorize Web Session
{/*It's technically possible to open a deep link to authorize a session on a device that is not enrolled.*/}
- {!canAuthorize && (
+ {!isDeviceTrusted && (
This device is not trusted.
@@ -111,6 +114,32 @@ export function DocumentAuthorizeWebSession(props: {
)}
+ {!isRequestedUserLoggedIn && (
+
+
+ Requested user is not logged in.
+
+ You are logged in as {rootCluster.loggedInUser?.name}. To
+ authorize this web session request, please{' '}
+ {
+ ctx.commandLauncher.executeCommand('cluster-logout', {
+ clusterUri: rootCluster.uri,
+ });
+ }}
+ >
+ log out
+ {' '}
+ in Teleport Connect and log in again as{' '}
+ {props.doc.webSessionRequest.username}.
+
+ Then click Launch Teleport Connect again in the browser.
+
+
+ )}
{authorizeAttempt.status === 'error' && (
Could not authorize the session: {authorizeAttempt.statusText}
diff --git a/web/packages/teleterm/src/ui/services/deepLinks/deepLinksService.ts b/web/packages/teleterm/src/ui/services/deepLinks/deepLinksService.ts
index 6083df679f626..ea98c9a51ef40 100644
--- a/web/packages/teleterm/src/ui/services/deepLinks/deepLinksService.ts
+++ b/web/packages/teleterm/src/ui/services/deepLinks/deepLinksService.ts
@@ -117,6 +117,7 @@ export class DeepLinksService {
webSessionRequest: {
id,
token,
+ username: url.username,
redirectUri: redirect_uri,
},
});
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
index 0c7fd36952285..00238ae5b35fd 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/documentsService/types.ts
@@ -237,6 +237,7 @@ export interface DocumentAuthorizeWebSession extends DocumentBase {
export interface WebSessionRequest {
id: string;
token: string;
+ username: string;
redirectUri: string;
}
diff --git a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts
index ded2d08080df5..ccb1add834217 100644
--- a/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts
+++ b/web/packages/teleterm/src/ui/services/workspacesService/workspacesService.test.ts
@@ -218,6 +218,7 @@ describe('state persistence', () => {
id: '',
token: '',
redirectUri: '',
+ username: '',
},
},
],