Skip to content

Commit

Permalink
[v16] Display warning if a user that wants to authorize a web session…
Browse files Browse the repository at this point in the history
… is not logged in Connect (#50046)

* Display warning if a user that wants to authorize a web session is not logged in Connect (#49836)

* Display warning if a user that wants to authorize a web session is not logged in Connect

* Make the instructions more specific

* Fix types

* Convert the story to use controls

* Fix test name

(cherry picked from commit cfe482b)

* Adjust warning to the old `Alert` API

* Convert the story back to the non-control version

We don't have the addon on v16.
  • Loading branch information
gzdunek authored Dec 11, 2024
1 parent 7a51453 commit 763fe05
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const doc: types.DocumentAuthorizeWebSession = {
redirectUri: '',
token: '',
id: '',
username: 'alice',
},
};

Expand All @@ -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 (
<MockAppContextProvider appContext={appContext}>
<MockWorkspaceContextProvider rootClusterUri={rootCluster.uri}>
<DocumentAuthorizeWebSession doc={docForDifferentUser} visible={true} />
</MockWorkspaceContextProvider>
</MockAppContextProvider>
);
}

export function DeviceTrusted() {
const rootCluster = makeRootCluster({
loggedInUser: makeLoggedInUser({ isDeviceTrusted: true }),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 }),
});
Expand All @@ -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(
<MockAppContextProvider appContext={appContext}>
<MockWorkspaceContextProvider rootClusterUri={rootCluster.uri}>
<DocumentAuthorizeWebSession doc={doc} visible={true} />
</MockWorkspaceContextProvider>
</MockAppContextProvider>
);

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({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

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';
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -95,7 +98,7 @@ export function DocumentAuthorizeWebSession(props: {
<H1 mb="4">Authorize Web Session</H1>
<Flex flexDirection="column" gap={3}>
{/*It's technically possible to open a deep link to authorize a session on a device that is not enrolled.*/}
{!canAuthorize && (
{!isDeviceTrusted && (
<Alert mb={0}>
<Text>
This device is not trusted.
Expand All @@ -111,6 +114,32 @@ export function DocumentAuthorizeWebSession(props: {
</Text>
</Alert>
)}
{!isRequestedUserLoggedIn && (
<Alert mb={0}>
<Text>
Requested user is not logged in.
<br />
You are logged in as <b>{rootCluster.loggedInUser?.name}</b>. To
authorize this web session request, please{' '}
<Link
css={`
cursor: pointer;
`}
onClick={() => {
ctx.commandLauncher.executeCommand('cluster-logout', {
clusterUri: rootCluster.uri,
});
}}
>
log out
</Link>{' '}
in Teleport Connect and log in again as{' '}
<b>{props.doc.webSessionRequest.username}</b>.
<br />
Then click Launch Teleport Connect again in the browser.
</Text>
</Alert>
)}
{authorizeAttempt.status === 'error' && (
<Alert mb={0}>
Could not authorize the session: {authorizeAttempt.statusText}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export class DeepLinksService {
webSessionRequest: {
id,
token,
username: url.username,
redirectUri: redirect_uri,
},
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ export interface DocumentAuthorizeWebSession extends DocumentBase {
export interface WebSessionRequest {
id: string;
token: string;
username: string;
redirectUri: string;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ describe('state persistence', () => {
id: '',
token: '',
redirectUri: '',
username: '',
},
},
],
Expand Down

0 comments on commit 763fe05

Please sign in to comment.