diff --git a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.spec.tsx b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.spec.tsx index 7fe5c095be..8d81df88c0 100644 --- a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.spec.tsx +++ b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.spec.tsx @@ -8,12 +8,14 @@ import { setNewNotificationReceived, setLastReceivedNotification } from 'uiSrc/s import { setIsConnected } from 'uiSrc/slices/app/socket-connection' import { NotificationType } from 'uiSrc/slices/interfaces' import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils' -import { SocketEvent } from 'uiSrc/constants' +import { CloudJobEvents, SocketEvent } from 'uiSrc/constants' import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances' import { RecommendationsSocketEvents } from 'uiSrc/constants/recommendations' import { addUnreadRecommendations } from 'uiSrc/slices/recommendations/recommendations' +import { logoutUser } from 'uiSrc/slices/oauth/cloud' import { NotificationsDto } from 'apiSrc/modules/notification/dto' +import { CloudJobInfo } from 'apiSrc/modules/cloud/job/models' import CommonAppSubscription from './CommonAppSubscription' let store: typeof mockedStore @@ -108,4 +110,34 @@ describe('CommonAppSubscription', () => { unmount() }) + + it('should logout if cloud:job:monitor return statusCode=401', () => { + const { unmount } = render() + + const mockData: CloudJobInfo = { + id: '4d76ba0c-71d3-4c9c-ada5-a6e5f4102af5', + name: 'CREATE_FREE_SUBSCRIPTION_AND_DATABASE', + status: 'failed', + error: { + message: 'Authorization failed', + statusCode: 401, + error: 'CloudApiUnauthorized', + errorCode: 11001 + }, + step: 'subscription' + } + + socket.on(CloudJobEvents.Monitor, (data: CloudJobInfo) => { + expect(data).toEqual(mockData) + }) + + socket.socketClient.emit(CloudJobEvents.Monitor, mockData) + + const afterRenderActions = [ + logoutUser(), + ] + expect(store.getActions()).toEqual([...afterRenderActions]) + + unmount() + }) }) diff --git a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx index cd0dc11a8c..010c9ec7da 100644 --- a/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx +++ b/redisinsight/ui/src/components/global-subscriptions/CommonAppSubscription/CommonAppSubscription.tsx @@ -2,8 +2,8 @@ import { useEffect, useRef, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import { io, Socket } from 'socket.io-client' -import { remove } from 'lodash' -import { CloudJobEvents, SocketEvent, SocketFeaturesEvent } from 'uiSrc/constants' +import { get, remove } from 'lodash' +import { ApiStatusCode, CloudJobEvents, SocketEvent, SocketFeaturesEvent } from 'uiSrc/constants' import { NotificationEvent } from 'uiSrc/constants/notifications' import { setNewNotificationAction } from 'uiSrc/slices/app/notifications' import { setIsConnected } from 'uiSrc/slices/app/socket-connection' @@ -13,7 +13,7 @@ import { addUnreadRecommendations } from 'uiSrc/slices/recommendations/recommend import { RecommendationsSocketEvents } from 'uiSrc/constants/recommendations' import { getFeatureFlagsSuccess } from 'uiSrc/slices/app/features' import { CustomHeaders } from 'uiSrc/constants/api' -import { oauthCloudJobSelector, setJob } from 'uiSrc/slices/oauth/cloud' +import { logoutUser, oauthCloudJobSelector, setJob } from 'uiSrc/slices/oauth/cloud' import { CloudJobName } from 'uiSrc/electron/constants' import { CloudJobInfo } from 'apiSrc/modules/cloud/job/models' @@ -55,6 +55,13 @@ const CommonAppSubscription = () => { socketRef.current.on(CloudJobEvents.Monitor, (data: CloudJobInfo) => { const jobName = data.name as unknown + const statusCode = get(data, 'error.statusCode') + + if (statusCode === ApiStatusCode.Unauthorized) { + dispatch(logoutUser()) + return + } + if ( jobName === CloudJobName.CreateFreeDatabase || jobName === CloudJobName.CreateFreeSubscriptionAndDatabase diff --git a/redisinsight/ui/src/components/notifications/components/infinite-messages/InfiniteMessages.tsx b/redisinsight/ui/src/components/notifications/components/infinite-messages/InfiniteMessages.tsx index 0e5cc6253c..98640785fd 100644 --- a/redisinsight/ui/src/components/notifications/components/infinite-messages/InfiniteMessages.tsx +++ b/redisinsight/ui/src/components/notifications/components/infinite-messages/InfiniteMessages.tsx @@ -10,6 +10,7 @@ import { EuiTitle } from '@elastic/eui' import { find } from 'lodash' +import cx from 'classnames' import { CloudJobStep } from 'uiSrc/electron/constants' import ExternalLink from 'uiSrc/components/base/external-link' import ChampagneIcon from 'uiSrc/assets/img/icons/champagne.svg' @@ -42,7 +43,7 @@ export const INFINITE_MESSAGES = { > - + @@ -67,7 +68,7 @@ export const INFINITE_MESSAGES = { > - + @@ -259,7 +260,7 @@ export const INFINITE_MESSAGES = { > - + diff --git a/redisinsight/ui/src/components/notifications/components/infinite-messages/styles.module.scss b/redisinsight/ui/src/components/notifications/components/infinite-messages/styles.module.scss index 07c66b163e..29ee134b82 100644 --- a/redisinsight/ui/src/components/notifications/components/infinite-messages/styles.module.scss +++ b/redisinsight/ui/src/components/notifications/components/infinite-messages/styles.module.scss @@ -9,3 +9,7 @@ margin-right: 4px; } } + +.loading { + border-top-color: var(--euiColorGhost) !important; +} diff --git a/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.spec.tsx b/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.spec.tsx index 208902f7d0..129c23e06a 100644 --- a/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.spec.tsx +++ b/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.spec.tsx @@ -109,6 +109,7 @@ describe('OAuthCreateDb', () => { setSSOFlow(OAuthSocialAction.Create), showOAuthProgress(true), addInfiniteNotification(INFINITE_MESSAGES.PENDING_CREATE_DB(CloudJobStep.Credentials)), + setSocialDialogState(null), addFreeDb() ] expect(store.getActions()).toEqual(expectedActions) diff --git a/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.tsx b/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.tsx index acfb6a11a9..5e00b4a16a 100644 --- a/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.tsx +++ b/redisinsight/ui/src/components/oauth/oauth-sso/oauth-create-db/OAuthCreateDb.tsx @@ -5,6 +5,7 @@ import { createFreeDbJob, fetchPlans, oauthCloudUserSelector, + setSocialDialogState, showOAuthProgress } from 'uiSrc/slices/oauth/cloud' @@ -62,6 +63,7 @@ const OAuthCreateDb = (props: Props) => { dispatch(addInfiniteNotification(INFINITE_MESSAGES.PENDING_CREATE_DB(CloudJobStep.Credentials))) if (isRecommended) { + dispatch(setSocialDialogState(null)) dispatch(createFreeDbJob({ name: CloudJobName.CreateFreeSubscriptionAndDatabase, resources: { diff --git a/redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/texts.tsx b/redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/texts.tsx index c84132069a..664d6b4ee0 100644 --- a/redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/texts.tsx +++ b/redisinsight/ui/src/components/side-panels/panels/ai-assistant/components/texts.tsx @@ -82,7 +82,7 @@ export const EXPERT_CHAT_AGREEMENTS = ( export const EXPERT_CHAT_INITIAL_MESSAGE = ( <> - Welcome! + Hi! I am here to help you get started with data querying. Type /help to get more info on what questions I can answer.