diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 5034915c00..f0f5a7330a 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -110,6 +110,8 @@ module.exports = { // eslint rules need to remove '@typescript-eslint/no-shadow': 'off', 'import/no-cycle': 'off', + // https://typescript-eslint.io/rules/consistent-return/ check the warning for details + 'consistent-return': 'off', 'prettier/prettier': [ 'error', {}, diff --git a/frontend/src/AppRoutes/Private.tsx b/frontend/src/AppRoutes/Private.tsx index d1d5f87585..092fedaae6 100644 --- a/frontend/src/AppRoutes/Private.tsx +++ b/frontend/src/AppRoutes/Private.tsx @@ -1,6 +1,6 @@ import getLocalStorageApi from 'api/browser/localstorage/get'; import setLocalStorageApi from 'api/browser/localstorage/set'; -import getOrgUser from 'api/v1/user/getOrgUser'; +import getAll from 'api/v1/user/get'; import { FeatureKeys } from 'constants/features'; import { LOCALSTORAGE } from 'constants/localStorage'; import ROUTES from 'constants/routes'; @@ -11,8 +11,11 @@ import { useAppContext } from 'providers/App/App'; import { ReactChild, useCallback, useEffect, useMemo, useState } from 'react'; import { useQuery } from 'react-query'; import { matchPath, useLocation } from 'react-router-dom'; +import { SuccessResponseV2 } from 'types/api'; +import APIError from 'types/api/error'; import { LicensePlatform, LicenseState } from 'types/api/licensesV3/getActive'; import { Organization } from 'types/api/user/getOrganization'; +import { UserResponse } from 'types/api/user/getUser'; import { USER_ROLES } from 'types/roles'; import { routePermission } from 'utils/permission'; @@ -58,12 +61,13 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element { const [orgData, setOrgData] = useState(undefined); - const { data: orgUsers, isFetching: isFetchingOrgUsers } = useQuery({ + const { data: usersData, isFetching: isFetchingUsers } = useQuery< + SuccessResponseV2 | undefined, + APIError + >({ queryFn: () => { if (orgData && orgData.id !== undefined) { - return getOrgUser({ - orgId: orgData.id, - }); + return getAll(); } return undefined; }, @@ -72,23 +76,23 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element { }); const checkFirstTimeUser = useCallback((): boolean => { - const users = orgUsers?.payload || []; + const users = usersData?.data || []; const remainingUsers = users.filter( (user) => user.email !== 'admin@signoz.cloud', ); return remainingUsers.length === 1; - }, [orgUsers?.payload]); + }, [usersData?.data]); useEffect(() => { if ( isCloudUserVal && !isFetchingOrgPreferences && orgPreferences && - !isFetchingOrgUsers && - orgUsers && - orgUsers.payload + !isFetchingUsers && + usersData && + usersData.data ) { const isOnboardingComplete = orgPreferences?.find( (preference: Record) => preference.key === 'ORG_ONBOARDING', @@ -108,9 +112,9 @@ function PrivateRoute({ children }: PrivateRouteProps): JSX.Element { checkFirstTimeUser, isCloudUserVal, isFetchingOrgPreferences, - isFetchingOrgUsers, + isFetchingUsers, orgPreferences, - orgUsers, + usersData, pathname, ]); diff --git a/frontend/src/AppRoutes/index.tsx b/frontend/src/AppRoutes/index.tsx index c034ebece3..e24704a22c 100644 --- a/frontend/src/AppRoutes/index.tsx +++ b/frontend/src/AppRoutes/index.tsx @@ -70,14 +70,14 @@ function App(): JSX.Element { const orgName = org && Array.isArray(org) && org.length > 0 ? org[0].displayName : ''; - const { name, email, role } = user; + const { displayName, email, role } = user; const domain = extractDomain(email); const hostNameParts = hostname.split('.'); const identifyPayload = { email, - name, + name: displayName, company_name: orgName, tenant_id: hostNameParts[0], data_region: hostNameParts[1], @@ -106,7 +106,7 @@ function App(): JSX.Element { Userpilot.identify(email, { email, - name, + name: displayName, orgName, tenant_id: hostNameParts[0], data_region: hostNameParts[1], @@ -118,7 +118,7 @@ function App(): JSX.Element { posthog?.identify(email, { email, - name, + name: displayName, orgName, tenant_id: hostNameParts[0], data_region: hostNameParts[1], @@ -144,7 +144,7 @@ function App(): JSX.Element { ) { window.cioanalytics.reset(); window.cioanalytics.identify(email, { - name: user.name, + name: user.displayName, email, role: user.role, }); @@ -258,7 +258,7 @@ function App(): JSX.Element { window.Intercom('boot', { app_id: process.env.INTERCOM_APP_ID, email: user?.email || '', - name: user?.name || '', + name: user?.displayName || '', }); } } diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 25f2ad061d..f58e240516 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -2,7 +2,7 @@ /* eslint-disable no-param-reassign */ /* eslint-disable @typescript-eslint/no-explicit-any */ import getLocalStorageApi from 'api/browser/localstorage/get'; -import loginApi from 'api/v1/user/login'; +import loginApi from 'api/v1/login/login'; import afterLogin from 'AppRoutes/utils'; import axios, { AxiosResponse, InternalAxiosRequestConfig } from 'axios'; import { ENVIRONMENT } from 'constants/env'; @@ -71,15 +71,15 @@ const interceptorRejected = async ( const { response } = value; // reject the refresh token error if (response.status === 401 && response.config.url !== '/login') { - const response = await loginApi({ - refreshToken: getLocalStorageApi(LOCALSTORAGE.REFRESH_AUTH_TOKEN) || '', - }); + try { + const response = await loginApi({ + refreshToken: getLocalStorageApi(LOCALSTORAGE.REFRESH_AUTH_TOKEN) || '', + }); - if (response.statusCode === 200) { afterLogin( - response.payload.userId, - response.payload.accessJwt, - response.payload.refreshJwt, + response.data.userId, + response.data.accessJwt, + response.data.refreshJwt, true, ); @@ -89,23 +89,22 @@ const interceptorRejected = async ( method: value.config.method, headers: { ...value.config.headers, - Authorization: `Bearer ${response.payload.accessJwt}`, + Authorization: `Bearer ${response.data.accessJwt}`, }, data: { ...JSON.parse(value.config.data || '{}'), }, }, ); - if (reResponse.status === 200) { return await Promise.resolve(reResponse); } Logout(); return await Promise.reject(reResponse); + } catch (error) { + Logout(); } - Logout(); } - // when refresh token is expired if (response.status === 401 && response.config.url === '/login') { Logout(); diff --git a/frontend/src/api/v1/factor_password/changeMyPassword.ts b/frontend/src/api/v1/factor_password/changeMyPassword.ts index cdca2cd6bb..d55a23b44c 100644 --- a/frontend/src/api/v1/factor_password/changeMyPassword.ts +++ b/frontend/src/api/v1/factor_password/changeMyPassword.ts @@ -1,25 +1,26 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; import { PayloadProps, Props } from 'types/api/user/changeMyPassword'; const changeMyPassword = async ( props: Props, -): Promise | ErrorResponse> => { +): Promise> => { try { - const response = await axios.post(`/changePassword/${props.userId}`, { - ...props, - }); + const response = await axios.post( + `/changePassword/${props.userId}`, + { + ...props, + }, + ); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: response.data, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/factor_password/getResetPasswordToken.ts b/frontend/src/api/v1/factor_password/getResetPasswordToken.ts index 845826ed70..c9329cc577 100644 --- a/frontend/src/api/v1/factor_password/getResetPasswordToken.ts +++ b/frontend/src/api/v1/factor_password/getResetPasswordToken.ts @@ -1,23 +1,27 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/getResetPasswordToken'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { + GetResetPasswordToken, + PayloadProps, + Props, +} from 'types/api/user/getResetPasswordToken'; const getResetPasswordToken = async ( props: Props, -): Promise | ErrorResponse> => { +): Promise> => { try { - const response = await axios.get(`/getResetPasswordToken/${props.userId}`); + const response = await axios.get( + `/getResetPasswordToken/${props.userId}`, + ); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: response.data.data, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/factor_password/resetPassword.ts b/frontend/src/api/v1/factor_password/resetPassword.ts index eb6d2752c7..58d54765bf 100644 --- a/frontend/src/api/v1/factor_password/resetPassword.ts +++ b/frontend/src/api/v1/factor_password/resetPassword.ts @@ -1,25 +1,23 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; import { PayloadProps, Props } from 'types/api/user/resetPassword'; const resetPassword = async ( props: Props, -): Promise | ErrorResponse> => { +): Promise> => { try { - const response = await axios.post(`/resetPassword`, { + const response = await axios.post(`/resetPassword`, { ...props, }); return { - statusCode: 200, - error: null, - message: response.statusText, - payload: response.data, + httpStatusCode: response.status, + data: response.data, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/invite/bulk/create.ts b/frontend/src/api/v1/invite/bulk/create.ts index d7afb7ff53..c0c7952ecb 100644 --- a/frontend/src/api/v1/invite/bulk/create.ts +++ b/frontend/src/api/v1/invite/bulk/create.ts @@ -1,18 +1,21 @@ import axios from 'api'; -import { SuccessResponse } from 'types/api'; -import { InviteUsersResponse, UsersProps } from 'types/api/user/inviteUsers'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; +import { AxiosError } from 'axios'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { UsersProps } from 'types/api/user/inviteUsers'; const inviteUsers = async ( users: UsersProps, -): Promise> => { - const response = await axios.post(`/invite/bulk`, users); - - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; +): Promise> => { + try { + const response = await axios.post(`/invite/bulk`, users); + return { + httpStatusCode: response.status, + data: null, + }; + } catch (error) { + ErrorResponseHandlerV2(error as AxiosError); + } }; export default inviteUsers; diff --git a/frontend/src/api/v1/invite/create.ts b/frontend/src/api/v1/invite/create.ts index 9835588907..dbf48d3a96 100644 --- a/frontend/src/api/v1/invite/create.ts +++ b/frontend/src/api/v1/invite/create.ts @@ -1,25 +1,23 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; import { PayloadProps, Props } from 'types/api/user/setInvite'; const sendInvite = async ( props: Props, -): Promise | ErrorResponse> => { +): Promise> => { try { - const response = await axios.post(`/invite`, { + const response = await axios.post(`/invite`, { ...props, }); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: response.data, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/invite/get.ts b/frontend/src/api/v1/invite/get.ts new file mode 100644 index 0000000000..00d769054f --- /dev/null +++ b/frontend/src/api/v1/invite/get.ts @@ -0,0 +1,19 @@ +import axios from 'api'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; +import { AxiosError } from 'axios'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { PayloadProps, PendingInvite } from 'types/api/user/getPendingInvites'; + +const get = async (): Promise> => { + try { + const response = await axios.get(`/invite`); + return { + httpStatusCode: response.status, + data: response.data.data, + }; + } catch (error) { + ErrorResponseHandlerV2(error as AxiosError); + } +}; + +export default get; diff --git a/frontend/src/api/v1/invite/getPendingInvites.ts b/frontend/src/api/v1/invite/getPendingInvites.ts deleted file mode 100644 index 947b7bf755..0000000000 --- a/frontend/src/api/v1/invite/getPendingInvites.ts +++ /dev/null @@ -1,24 +0,0 @@ -import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps } from 'types/api/user/getPendingInvites'; - -const getPendingInvites = async (): Promise< - SuccessResponse | ErrorResponse -> => { - try { - const response = await axios.get(`/invite`); - - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default getPendingInvites; diff --git a/frontend/src/api/v1/invite/id/accept.ts b/frontend/src/api/v1/invite/id/accept.ts new file mode 100644 index 0000000000..3c466fbbd2 --- /dev/null +++ b/frontend/src/api/v1/invite/id/accept.ts @@ -0,0 +1,25 @@ +import axios from 'api'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; +import { AxiosError } from 'axios'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { + LoginPrecheckResponse, + PayloadProps, + Props, +} from 'types/api/user/accept'; + +const accept = async ( + props: Props, +): Promise> => { + try { + const response = await axios.post(`/invite/accept`, props); + return { + httpStatusCode: response.status, + data: response.data.data, + }; + } catch (error) { + ErrorResponseHandlerV2(error as AxiosError); + } +}; + +export default accept; diff --git a/frontend/src/api/v1/invite/id/delete.ts b/frontend/src/api/v1/invite/id/delete.ts index 16233ef97f..ec7c6f7460 100644 --- a/frontend/src/api/v1/invite/id/delete.ts +++ b/frontend/src/api/v1/invite/id/delete.ts @@ -1,24 +1,20 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/deleteInvite'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { Props } from 'types/api/user/deleteInvite'; -const deleteInvite = async ( - props: Props, -): Promise | ErrorResponse> => { +const del = async (props: Props): Promise> => { try { - const response = await axios.delete(`/invite/${props.email}`); + const response = await axios.delete(`/invite/${props.id}`); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: null, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; -export default deleteInvite; +export default del; diff --git a/frontend/src/api/v1/invite/id/get.ts b/frontend/src/api/v1/invite/id/get.ts index 22d49cf96c..6c08333492 100644 --- a/frontend/src/api/v1/invite/id/get.ts +++ b/frontend/src/api/v1/invite/id/get.ts @@ -1,25 +1,27 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/getInviteDetails'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { + InviteDetails, + PayloadProps, + Props, +} from 'types/api/user/getInviteDetails'; const getInviteDetails = async ( props: Props, -): Promise | ErrorResponse> => { +): Promise> => { try { - const response = await axios.get( + const response = await axios.get( `/invite/${props.inviteId}?ref=${window.location.href}`, ); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: response.data.data, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/login/login.ts b/frontend/src/api/v1/login/login.ts index a8a6af4d72..46f17ad711 100644 --- a/frontend/src/api/v1/login/login.ts +++ b/frontend/src/api/v1/login/login.ts @@ -2,11 +2,11 @@ import axios from 'api'; import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/login'; +import { PayloadProps, Props, UserLoginResponse } from 'types/api/user/login'; const login = async ( props: Props, -): Promise> => { +): Promise> => { try { const response = await axios.post(`/login`, { ...props, @@ -14,12 +14,10 @@ const login = async ( return { httpStatusCode: response.status, - data: response.data, + data: response.data.data, }; } catch (error) { ErrorResponseHandlerV2(error as AxiosError); - // this line is never reached but ts isn't detecting the never type properly for the ErrorResponseHandlerV2 - throw error; } }; diff --git a/frontend/src/api/v1/user/get.ts b/frontend/src/api/v1/user/get.ts new file mode 100644 index 0000000000..a5a6b1594d --- /dev/null +++ b/frontend/src/api/v1/user/get.ts @@ -0,0 +1,21 @@ +import axios from 'api'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; +import { AxiosError } from 'axios'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { UserResponse } from 'types/api/user/getUser'; +import { PayloadProps } from 'types/api/user/getUsers'; + +const getAll = async (): Promise> => { + try { + const response = await axios.get(`/user`); + + return { + httpStatusCode: response.status, + data: response.data.data, + }; + } catch (error) { + ErrorResponseHandlerV2(error as AxiosError); + } +}; + +export default getAll; diff --git a/frontend/src/api/v1/user/getOrgUser.ts b/frontend/src/api/v1/user/getOrgUser.ts deleted file mode 100644 index 8956adc1ba..0000000000 --- a/frontend/src/api/v1/user/getOrgUser.ts +++ /dev/null @@ -1,24 +0,0 @@ -import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/getOrgMembers'; - -const getOrgUser = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.get(`/orgUsers/${props.orgId}`); - - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default getOrgUser; diff --git a/frontend/src/api/v1/user/id/delete.ts b/frontend/src/api/v1/user/id/delete.ts index 4eb2694782..5474ad4b2f 100644 --- a/frontend/src/api/v1/user/id/delete.ts +++ b/frontend/src/api/v1/user/id/delete.ts @@ -1,23 +1,19 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/deleteUser'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { Props } from 'types/api/user/deleteUser'; -const deleteUser = async ( - props: Props, -): Promise | ErrorResponse> => { +const deleteUser = async (props: Props): Promise> => { try { const response = await axios.delete(`/user/${props.userId}`); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: null, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; diff --git a/frontend/src/api/v1/user/id/get.ts b/frontend/src/api/v1/user/id/get.ts index 63a9397e32..fef6d3e539 100644 --- a/frontend/src/api/v1/user/id/get.ts +++ b/frontend/src/api/v1/user/id/get.ts @@ -1,18 +1,22 @@ import axios from 'api'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/getUser'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; +import { AxiosError } from 'axios'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { PayloadProps, Props, UserResponse } from 'types/api/user/getUser'; const getUser = async ( props: Props, -): Promise | ErrorResponse> => { - const response = await axios.get(`/user/${props.userId}`); +): Promise> => { + try { + const response = await axios.get(`/user/${props.userId}`); - return { - statusCode: 200, - error: null, - message: 'Success', - payload: response.data, - }; + return { + httpStatusCode: response.status, + data: response.data.data, + }; + } catch (error) { + ErrorResponseHandlerV2(error as AxiosError); + } }; export default getUser; diff --git a/frontend/src/api/v1/user/id/getRoles.ts b/frontend/src/api/v1/user/id/getRoles.ts deleted file mode 100644 index 0602a0aa63..0000000000 --- a/frontend/src/api/v1/user/id/getRoles.ts +++ /dev/null @@ -1,28 +0,0 @@ -import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/getUserRole'; - -const getRoles = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.get(`/rbac/role/${props.userId}`, { - headers: { - Authorization: `bearer ${props.token}`, - }, - }); - - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default getRoles; diff --git a/frontend/src/api/v1/user/id/update.ts b/frontend/src/api/v1/user/id/update.ts index 88f7c40a25..b1ca2c76f7 100644 --- a/frontend/src/api/v1/user/id/update.ts +++ b/frontend/src/api/v1/user/id/update.ts @@ -1,26 +1,23 @@ import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; +import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2'; import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/editUser'; +import { ErrorV2Resp, SuccessResponseV2 } from 'types/api'; +import { Props } from 'types/api/user/editUser'; -const editUser = async ( - props: Props, -): Promise | ErrorResponse> => { +const update = async (props: Props): Promise> => { try { const response = await axios.put(`/user/${props.userId}`, { - Name: props.name, + displayName: props.displayName, + role: props.role, }); return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data, + httpStatusCode: response.status, + data: null, }; } catch (error) { - return ErrorResponseHandler(error as AxiosError); + ErrorResponseHandlerV2(error as AxiosError); } }; -export default editUser; +export default update; diff --git a/frontend/src/api/v1/user/id/updateRole.ts b/frontend/src/api/v1/user/id/updateRole.ts deleted file mode 100644 index 5d82a3d991..0000000000 --- a/frontend/src/api/v1/user/id/updateRole.ts +++ /dev/null @@ -1,26 +0,0 @@ -import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/updateRole'; - -const updateRole = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.put(`/rbac/role/${props.userId}`, { - group_name: props.group_name, - }); - - return { - statusCode: 200, - error: null, - message: response.data.status, - payload: response.data.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default updateRole; diff --git a/frontend/src/api/v1/user/login.ts b/frontend/src/api/v1/user/login.ts deleted file mode 100644 index 4eff88337b..0000000000 --- a/frontend/src/api/v1/user/login.ts +++ /dev/null @@ -1,26 +0,0 @@ -import axios from 'api'; -import { ErrorResponseHandler } from 'api/ErrorResponseHandler'; -import { AxiosError } from 'axios'; -import { ErrorResponse, SuccessResponse } from 'types/api'; -import { PayloadProps, Props } from 'types/api/user/login'; - -const login = async ( - props: Props, -): Promise | ErrorResponse> => { - try { - const response = await axios.post(`/login`, { - ...props, - }); - - return { - statusCode: 200, - error: null, - message: response.statusText, - payload: response.data, - }; - } catch (error) { - return ErrorResponseHandler(error as AxiosError); - } -}; - -export default login; diff --git a/frontend/src/container/Login/index.tsx b/frontend/src/container/Login/index.tsx index 02cb4ef125..1239682b15 100644 --- a/frontend/src/container/Login/index.tsx +++ b/frontend/src/container/Login/index.tsx @@ -1,8 +1,8 @@ import { Button, Form, Input, Space, Tooltip, Typography } from 'antd'; import getLocalStorageApi from 'api/browser/localstorage/get'; import setLocalStorageApi from 'api/browser/localstorage/set'; +import loginApi from 'api/v1/login/login'; import loginPrecheckApi from 'api/v1/login/loginPrecheck'; -import loginApi from 'api/v1/user/login'; import getUserVersion from 'api/v1/version/getVersion'; import afterLogin from 'AppRoutes/utils'; import { LOCALSTORAGE } from 'constants/localStorage'; @@ -13,6 +13,7 @@ import { useAppContext } from 'providers/App/App'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useQuery } from 'react-query'; +import APIError from 'types/api/error'; import { PayloadProps as PrecheckResultType } from 'types/api/user/loginPrecheck'; import { FormContainer, FormWrapper, Label, ParentContainer } from './styles'; @@ -166,22 +167,18 @@ function Login({ email, password, }); - if (response.statusCode === 200) { - afterLogin( - response.payload.userId, - response.payload.accessJwt, - response.payload.refreshJwt, - ); - } else { - notifications.error({ - message: response.error || t('unexpected_error'), - }); - } + + afterLogin( + response.data.userId, + response.data.accessJwt, + response.data.refreshJwt, + ); setIsLoading(false); } catch (error) { setIsLoading(false); notifications.error({ - message: t('unexpected_error'), + message: (error as APIError).getErrorCode(), + description: (error as APIError).getErrorMessage(), }); } }; diff --git a/frontend/src/container/MySettings/Password/index.tsx b/frontend/src/container/MySettings/Password/index.tsx index bb2958bc90..aa434232bb 100644 --- a/frontend/src/container/MySettings/Password/index.tsx +++ b/frontend/src/container/MySettings/Password/index.tsx @@ -6,6 +6,7 @@ import { isPasswordNotValidMessage, isPasswordValid } from 'pages/SignUp/utils'; import { useAppContext } from 'providers/App/App'; import { useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; +import APIError from 'types/api/error'; import { Password } from '../styles'; @@ -44,36 +45,22 @@ function PasswordContainer(): JSX.Element { setIsLoading(false); return; } - - const { statusCode, error } = await changeMyPassword({ + await changeMyPassword({ newPassword: updatePassword, oldPassword: currentPassword, userId: user.id, }); - - if (statusCode === 200) { - notifications.success({ - message: t('success', { - ns: 'common', - }), - }); - } else { - notifications.error({ - message: - error || - t('something_went_wrong', { - ns: 'common', - }), - }); - } + notifications.success({ + message: t('success', { + ns: 'common', + }), + }); setIsLoading(false); } catch (error) { setIsLoading(false); - notifications.error({ - message: t('something_went_wrong', { - ns: 'common', - }), + message: (error as APIError).error.error.code, + description: (error as APIError).error.error.message, }); } }; diff --git a/frontend/src/container/MySettings/UserInfo/index.tsx b/frontend/src/container/MySettings/UserInfo/index.tsx index 3bf38253f5..06361724ac 100644 --- a/frontend/src/container/MySettings/UserInfo/index.tsx +++ b/frontend/src/container/MySettings/UserInfo/index.tsx @@ -8,6 +8,7 @@ import { PencilIcon } from 'lucide-react'; import { useAppContext } from 'providers/App/App'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; +import APIError from 'types/api/error'; import { NameInput } from '../styles'; @@ -15,7 +16,9 @@ function UserInfo(): JSX.Element { const { user, org, updateUser } = useAppContext(); const { t } = useTranslation(); - const [changedName, setChangedName] = useState(user?.name || ''); + const [changedName, setChangedName] = useState( + user?.displayName || '', + ); const [loading, setLoading] = useState(false); const { notifications } = useNotifications(); @@ -27,34 +30,25 @@ function UserInfo(): JSX.Element { const onClickUpdateHandler = async (): Promise => { try { setLoading(true); - const { statusCode } = await editUser({ - name: changedName, + await editUser({ + displayName: changedName, userId: user.id, }); - if (statusCode === 200) { - notifications.success({ - message: t('success', { - ns: 'common', - }), - }); - updateUser({ - ...user, - name: changedName, - }); - } else { - notifications.error({ - message: t('something_went_wrong', { - ns: 'common', - }), - }); - } + notifications.success({ + message: t('success', { + ns: 'common', + }), + }); + updateUser({ + ...user, + displayName: changedName, + }); setLoading(false); } catch (error) { notifications.error({ - message: t('something_went_wrong', { - ns: 'common', - }), + message: (error as APIError).getErrorCode(), + description: (error as APIError).getErrorMessage(), }); } setLoading(false); diff --git a/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx b/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx index ec68855785..532b6542e1 100644 --- a/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx +++ b/frontend/src/container/OnboardingQuestionaire/InviteTeamMembers/InviteTeamMembers.tsx @@ -4,7 +4,7 @@ import { Color } from '@signozhq/design-tokens'; import { Button, Input, Select, Typography } from 'antd'; import logEvent from 'api/common/logEvent'; import inviteUsers from 'api/v1/invite/bulk/create'; -import { AxiosError } from 'axios'; +import { useNotifications } from 'hooks/useNotifications'; import { cloneDeep, debounce, isEmpty } from 'lodash-es'; import { ArrowLeft, @@ -17,12 +17,7 @@ import { } from 'lucide-react'; import { useCallback, useEffect, useState } from 'react'; import { useMutation } from 'react-query'; -import { SuccessResponse } from 'types/api'; -import { - FailedInvite, - InviteUsersResponse, - SuccessfulInvite, -} from 'types/api/user/inviteUsers'; +import APIError from 'types/api/error'; import { v4 as uuid } from 'uuid'; interface TeamMember { @@ -55,20 +50,7 @@ function InviteTeamMembers({ {}, ); const [hasInvalidEmails, setHasInvalidEmails] = useState(false); - - const [hasErrors, setHasErrors] = useState(true); - - const [error, setError] = useState(null); - - const [inviteUsersErrorResponse, setInviteUsersErrorResponse] = useState< - string[] | null - >(null); - - const [inviteUsersSuccessResponse, setInviteUsersSuccessResponse] = useState< - string[] | null - >(null); - - const [disableNextButton, setDisableNextButton] = useState(false); + const { notifications } = useNotifications(); const defaultTeamMember: TeamMember = { email: '', @@ -122,92 +104,32 @@ function InviteTeamMembers({ return isValid; }; - const parseInviteUsersSuccessResponse = ( - response: SuccessfulInvite[], - ): string[] => response.map((invite) => `${invite.email} - Invite Sent`); - - const parseInviteUsersErrorResponse = (response: FailedInvite[]): string[] => - response.map((invite) => `${invite.email} - ${invite.error}`); - - const handleError = (error: AxiosError): void => { - const errorMessage = error.response?.data as InviteUsersResponse; - - if (errorMessage?.status === 'failure') { - setHasErrors(true); - - const failedInvitesErrorResponse = parseInviteUsersErrorResponse( - errorMessage.failed_invites, - ); - - setInviteUsersErrorResponse(failedInvitesErrorResponse); - } - }; - - const handleInviteUsersSuccess = ( - response: SuccessResponse, - ): void => { - const inviteUsersResponse = response.payload as InviteUsersResponse; - - if (inviteUsersResponse?.status === 'success') { - const successfulInvites = parseInviteUsersSuccessResponse( - inviteUsersResponse.successful_invites, - ); - - setDisableNextButton(true); - - setError(null); - setHasErrors(false); - setInviteUsersErrorResponse(null); - - setInviteUsersSuccessResponse(successfulInvites); - - logEvent('Org Onboarding: Invite Team Members Success', { - teamMembers: teamMembersToInvite, - totalInvites: inviteUsersResponse.summary.total_invites, - successfulInvites: inviteUsersResponse.summary.successful_invites, - failedInvites: inviteUsersResponse.summary.failed_invites, - }); - - setTimeout(() => { - setDisableNextButton(false); - onNext(); - }, 1000); - } else if (inviteUsersResponse?.status === 'partial_success') { - const successfulInvites = parseInviteUsersSuccessResponse( - inviteUsersResponse.successful_invites, - ); - - setInviteUsersSuccessResponse(successfulInvites); - - logEvent('Org Onboarding: Invite Team Members Partial Success', { - teamMembers: teamMembersToInvite, - totalInvites: inviteUsersResponse.summary.total_invites, - successfulInvites: inviteUsersResponse.summary.successful_invites, - failedInvites: inviteUsersResponse.summary.failed_invites, - }); - - if (inviteUsersResponse.failed_invites.length > 0) { - setHasErrors(true); - - setInviteUsersErrorResponse( - parseInviteUsersErrorResponse(inviteUsersResponse.failed_invites), - ); - } - } + const handleInviteUsersSuccess = (): void => { + logEvent('Org Onboarding: Invite Team Members Success', { + teamMembers: teamMembersToInvite, + }); + notifications.success({ + message: 'Invites sent successfully!', + }); + setTimeout(() => { + onNext(); + }, 1000); }; const { mutate: sendInvites, isLoading: isSendingInvites } = useMutation( inviteUsers, { - onSuccess: (response: SuccessResponse): void => { - handleInviteUsersSuccess(response); + onSuccess: (): void => { + handleInviteUsersSuccess(); }, - onError: (error: AxiosError): void => { + onError: (error: APIError): void => { logEvent('Org Onboarding: Invite Team Members Failed', { teamMembers: teamMembersToInvite, }); - - handleError(error); + notifications.error({ + message: error.getErrorCode(), + description: error.getErrorMessage(), + }); }, }, ); @@ -215,15 +137,9 @@ function InviteTeamMembers({ const handleNext = (): void => { if (validateAllUsers()) { setTeamMembers(teamMembersToInvite || []); - setHasInvalidEmails(false); - setError(null); - setHasErrors(false); - setInviteUsersErrorResponse(null); - setInviteUsersSuccessResponse(null); - sendInvites({ - users: teamMembersToInvite || [], + invites: teamMembersToInvite || [], }); } }; @@ -356,63 +272,8 @@ function InviteTeamMembers({ )} - - {error && ( -
- - {error} - -
- )} - - {hasErrors && ( - <> - {/* show only when invites are sent successfully & partial error is present */} - {inviteUsersSuccessResponse && inviteUsersErrorResponse && ( -
- {inviteUsersSuccessResponse?.map((success, index) => ( - - {success} - - ))} -
- )} - -
- {inviteUsersErrorResponse?.map((error, index) => ( - - {error} - - ))} -
- - )} - {/* Partially sent invites */} - {inviteUsersSuccessResponse && inviteUsersErrorResponse && ( -
- - - Some invites were sent successfully. Please fix the errors above and - resend invites. - - - - You can click on I'll do this later to go to next step. - -
- )} -
- - {/* Partially sent invites */} - {inviteUsersSuccessResponse && inviteUsersErrorResponse && ( -
- - - Some invites were sent successfully. Please fix the errors above and - resend invites. - - - - You can click on I'll do this later to go to next step. - -
- )} -
,
)} - {isPreferenceVisible && ( + {isSignUp && ( { - if (!isFetchingUser && userData && userData.payload) { + if (!isFetchingUser && userData && userData.data) { setUser((prev) => ({ ...prev, - ...userData.payload, + ...userData.data, })); setOrg((prev) => { if (!prev) { @@ -82,19 +82,19 @@ export function AppProvider({ children }: PropsWithChildren): JSX.Element { return [ { createdAt: 0, - id: userData.payload.orgId, - displayName: userData.payload.organization, + id: userData.data.orgId, + displayName: userData.data.organization, }, ]; } // else mutate the existing entry - const orgIndex = prev.findIndex((e) => e.id === userData.payload.orgId); + const orgIndex = prev.findIndex((e) => e.id === userData.data.orgId); const updatedOrg: Organization[] = [ ...prev.slice(0, orgIndex), { createdAt: 0, - id: userData.payload.orgId, - displayName: userData.payload.organization, + id: userData.data.orgId, + displayName: userData.data.organization, }, ...prev.slice(orgIndex + 1, prev.length), ]; diff --git a/frontend/src/providers/App/types.ts b/frontend/src/providers/App/types.ts index 89a5c76cca..8c9d2117dc 100644 --- a/frontend/src/providers/App/types.ts +++ b/frontend/src/providers/App/types.ts @@ -2,7 +2,7 @@ import { FeatureFlagProps as FeatureFlags } from 'types/api/features/getFeatures import { PayloadProps as LicensesResModel } from 'types/api/licenses/getAll'; import { LicenseV3ResModel, TrialInfo } from 'types/api/licensesV3/getActive'; import { Organization } from 'types/api/user/getOrganization'; -import { PayloadProps as User } from 'types/api/user/getUser'; +import { UserResponse as User } from 'types/api/user/getUser'; import { OrgPreference } from 'types/reducer/app'; export interface IAppContext { diff --git a/frontend/src/providers/App/utils.ts b/frontend/src/providers/App/utils.ts index 9654a910c7..8b919569d3 100644 --- a/frontend/src/providers/App/utils.ts +++ b/frontend/src/providers/App/utils.ts @@ -17,8 +17,7 @@ function getUserDefaults(): IUser { refreshJwt, id: userId, email: '', - name: '', - profilePictureURL: '', + displayName: '', createdAt: 0, organization: '', orgId: '', diff --git a/frontend/src/providers/EventSource.tsx b/frontend/src/providers/EventSource.tsx index 376d53f72e..b11bd73a73 100644 --- a/frontend/src/providers/EventSource.tsx +++ b/frontend/src/providers/EventSource.tsx @@ -1,7 +1,7 @@ import { apiV3 } from 'api/apiV1'; import getLocalStorageApi from 'api/browser/localstorage/get'; import { Logout } from 'api/utils'; -import loginApi from 'api/v1/user/login'; +import loginApi from 'api/v1/login/login'; import afterLogin from 'AppRoutes/utils'; import { ENVIRONMENT } from 'constants/env'; import { LIVE_TAIL_HEARTBEAT_TIMEOUT } from 'constants/liveTail'; @@ -18,6 +18,7 @@ import { useRef, useState, } from 'react'; +import APIError from 'types/api/error'; interface IEventSourceContext { eventSourceInstance: EventSourcePolyfill | null; @@ -80,34 +81,24 @@ export function EventSourceProvider({ const response = await loginApi({ refreshToken: getLocalStorageApi(LOCALSTORAGE.REFRESH_AUTH_TOKEN) || '', }); - - if (response.statusCode === 200) { - // Update tokens in local storage - afterLogin( - response.payload.userId, - response.payload.accessJwt, - response.payload.refreshJwt, - true, - ); - - // If token refresh was successful, we'll let the component - // handle reconnection through the reconnectDueToError state - setReconnectDueToError(true); - setIsConnectionError(true); - return; - } - - notifications.error({ message: 'Sorry, something went wrong' }); - // If token refresh failed, logout the user - if (!eventSourceRef.current) return; - eventSourceRef.current.close(); + afterLogin( + response.data.userId, + response.data.accessJwt, + response.data.refreshJwt, + true, + ); + // If token refresh was successful, we'll let the component + // handle reconnection through the reconnectDueToError state + setReconnectDueToError(true); setIsConnectionError(true); - Logout(); + return; } catch (error) { // If there was an error during token refresh, we'll just // let the component handle the error state - notifications.error({ message: 'Sorry, something went wrong' }); - console.error('Error refreshing token:', error); + notifications.error({ + message: (error as APIError).getErrorCode(), + description: (error as APIError).getErrorMessage(), + }); setIsConnectionError(true); if (!eventSourceRef.current) return; eventSourceRef.current.close(); diff --git a/frontend/src/tests/test-utils.tsx b/frontend/src/tests/test-utils.tsx index c11f8a7cb6..71f253afe5 100644 --- a/frontend/src/tests/test-utils.tsx +++ b/frontend/src/tests/test-utils.tsx @@ -145,8 +145,7 @@ export function getAppContextMock( refreshJwt: 'some-refresh-token', id: 'some-user-id', email: 'does-not-matter@signoz.io', - name: 'John Doe', - profilePictureURL: '', + displayName: 'John Doe', createdAt: 1732544623, organization: 'Nightswatch', orgId: 'does-not-matter-id', diff --git a/frontend/src/types/api/user/accept.ts b/frontend/src/types/api/user/accept.ts new file mode 100644 index 0000000000..dcbcf73761 --- /dev/null +++ b/frontend/src/types/api/user/accept.ts @@ -0,0 +1,18 @@ +export interface Props { + token: string; + password: string; + displayName?: string; + sourceUrl?: string; +} + +export interface LoginPrecheckResponse { + sso: boolean; + ssoUrl?: string; + canSelfRegister?: boolean; + isUser: boolean; +} + +export interface PayloadProps { + data: LoginPrecheckResponse; + status: string; +} diff --git a/frontend/src/types/api/user/changeMyPassword.ts b/frontend/src/types/api/user/changeMyPassword.ts index 154d0b819a..fd821355a4 100644 --- a/frontend/src/types/api/user/changeMyPassword.ts +++ b/frontend/src/types/api/user/changeMyPassword.ts @@ -7,5 +7,6 @@ export interface Props { } export interface PayloadProps { + status: string; data: string; } diff --git a/frontend/src/types/api/user/deleteInvite.ts b/frontend/src/types/api/user/deleteInvite.ts index 1caab7e694..7d3136189c 100644 --- a/frontend/src/types/api/user/deleteInvite.ts +++ b/frontend/src/types/api/user/deleteInvite.ts @@ -1,7 +1,5 @@ -import { User } from 'types/reducer/app'; - export interface Props { - email: User['email']; + id: string; } export interface PayloadProps { diff --git a/frontend/src/types/api/user/deleteUser.ts b/frontend/src/types/api/user/deleteUser.ts index a3eae2b19f..1c289fddfd 100644 --- a/frontend/src/types/api/user/deleteUser.ts +++ b/frontend/src/types/api/user/deleteUser.ts @@ -6,4 +6,5 @@ export interface Props { export interface PayloadProps { data: string; + status: string; } diff --git a/frontend/src/types/api/user/editUser.ts b/frontend/src/types/api/user/editUser.ts index a080214158..e1d71c81c3 100644 --- a/frontend/src/types/api/user/editUser.ts +++ b/frontend/src/types/api/user/editUser.ts @@ -1,4 +1,5 @@ import { User } from 'types/reducer/app'; +import { ROLES } from 'types/roles'; import { PayloadProps as Payload } from './getUser'; @@ -6,5 +7,6 @@ export type PayloadProps = Payload; export interface Props { userId: User['userId']; - name: User['name']; + displayName: User['displayName']; + role?: ROLES; } diff --git a/frontend/src/types/api/user/getInviteDetails.ts b/frontend/src/types/api/user/getInviteDetails.ts index 2244793015..88807a3fd8 100644 --- a/frontend/src/types/api/user/getInviteDetails.ts +++ b/frontend/src/types/api/user/getInviteDetails.ts @@ -9,9 +9,14 @@ export interface Props { } export interface PayloadProps { + data: InviteDetails; + status: string; +} + +export interface InviteDetails { createdAt: number; email: User['email']; - name: User['name']; + name: User['displayName']; role: ROLES; token: string; organization: Organization['displayName']; diff --git a/frontend/src/types/api/user/getOrgMembers.ts b/frontend/src/types/api/user/getOrgMembers.ts deleted file mode 100644 index 23b9dd2d30..0000000000 --- a/frontend/src/types/api/user/getOrgMembers.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { ROLES } from 'types/roles'; - -import { Organization } from './getOrganization'; - -export interface Props { - orgId: Organization['id']; -} - -interface OrgMembers { - createdAt: number; - email: string; - name: string; - role: ROLES; - token: string; - id: string; -} - -export type PayloadProps = OrgMembers[]; diff --git a/frontend/src/types/api/user/getPendingInvites.ts b/frontend/src/types/api/user/getPendingInvites.ts index 4b64bf79af..f3f09a77d4 100644 --- a/frontend/src/types/api/user/getPendingInvites.ts +++ b/frontend/src/types/api/user/getPendingInvites.ts @@ -4,9 +4,13 @@ import { ROLES } from 'types/roles'; export interface PendingInvite { createdAt: number; email: User['email']; - name: User['name']; + name: User['displayName']; role: ROLES; + id: string; token: string; } -export type PayloadProps = PendingInvite[]; +export type PayloadProps = { + data: PendingInvite[]; + status: string; +}; diff --git a/frontend/src/types/api/user/getResetPasswordToken.ts b/frontend/src/types/api/user/getResetPasswordToken.ts index dee9863006..e83142bff2 100644 --- a/frontend/src/types/api/user/getResetPasswordToken.ts +++ b/frontend/src/types/api/user/getResetPasswordToken.ts @@ -4,7 +4,12 @@ export interface Props { userId: User['userId']; } -export interface PayloadProps { +export interface GetResetPasswordToken { token: string; userId: string; } + +export interface PayloadProps { + data: GetResetPasswordToken; + status: string; +} diff --git a/frontend/src/types/api/user/getUser.ts b/frontend/src/types/api/user/getUser.ts index e066ec3103..2e47547a20 100644 --- a/frontend/src/types/api/user/getUser.ts +++ b/frontend/src/types/api/user/getUser.ts @@ -6,13 +6,16 @@ export interface Props { token?: string; } -export interface PayloadProps { +export interface UserResponse { createdAt: number; email: string; id: string; - name: string; + displayName: string; orgId: string; - profilePictureURL: string; organization: string; role: ROLES; } +export interface PayloadProps { + data: UserResponse; + status: string; +} diff --git a/frontend/src/types/api/user/getUsers.ts b/frontend/src/types/api/user/getUsers.ts new file mode 100644 index 0000000000..e0a74e11b5 --- /dev/null +++ b/frontend/src/types/api/user/getUsers.ts @@ -0,0 +1,15 @@ +import { ROLES } from 'types/roles'; + +export interface UserResponse { + createdAt: number; + email: string; + id: string; + displayName: string; + orgId: string; + organization: string; + role: ROLES; +} +export interface PayloadProps { + data: UserResponse[]; + status: string; +} diff --git a/frontend/src/types/api/user/inviteUsers.ts b/frontend/src/types/api/user/inviteUsers.ts index e173ca8f8c..7bd56707f2 100644 --- a/frontend/src/types/api/user/inviteUsers.ts +++ b/frontend/src/types/api/user/inviteUsers.ts @@ -1,40 +1,12 @@ import { User } from 'types/reducer/app'; -import { ErrorResponse } from '..'; - export interface UserProps { - name: User['name']; + name: User['displayName']; email: User['email']; role: string; frontendBaseUrl: string; } export interface UsersProps { - users: UserProps[]; -} - -export interface PayloadProps { - data: string; -} - -export interface FailedInvite { - email: string; - error: string; -} - -export interface SuccessfulInvite { - email: string; - invite_link: string; - status: string; -} - -export interface InviteUsersResponse extends ErrorResponse { - status: string; - summary: { - total_invites: number; - successful_invites: number; - failed_invites: number; - }; - successful_invites: SuccessfulInvite[]; - failed_invites: FailedInvite[]; + invites: UserProps[]; } diff --git a/frontend/src/types/api/user/login.ts b/frontend/src/types/api/user/login.ts index db5f1875e9..db2d03f42d 100644 --- a/frontend/src/types/api/user/login.ts +++ b/frontend/src/types/api/user/login.ts @@ -1,13 +1,18 @@ export interface PayloadProps { + data: UserLoginResponse; + status: string; +} + +export interface Props { + email?: string; + password?: string; + refreshToken?: UserLoginResponse['refreshJwt']; +} + +export interface UserLoginResponse { accessJwt: string; accessJwtExpiry: number; refreshJwt: string; refreshJwtExpiry: number; userId: string; } - -export interface Props { - email?: string; - password?: string; - refreshToken?: PayloadProps['refreshJwt']; -} diff --git a/frontend/src/types/api/user/resetPassword.ts b/frontend/src/types/api/user/resetPassword.ts index e97197acf0..fd00e40494 100644 --- a/frontend/src/types/api/user/resetPassword.ts +++ b/frontend/src/types/api/user/resetPassword.ts @@ -5,4 +5,5 @@ export interface Props { export interface PayloadProps { data: string; + status: string; } diff --git a/frontend/src/types/api/user/setInvite.ts b/frontend/src/types/api/user/setInvite.ts index e29e487cb1..d07202e43c 100644 --- a/frontend/src/types/api/user/setInvite.ts +++ b/frontend/src/types/api/user/setInvite.ts @@ -2,7 +2,7 @@ import { User } from 'types/reducer/app'; import { ROLES } from 'types/roles'; export interface Props { - name: User['name']; + name: User['displayName']; email: User['email']; role: ROLES; frontendBaseUrl: string; @@ -10,4 +10,5 @@ export interface Props { export interface PayloadProps { data: string; + status: string; } diff --git a/frontend/src/types/reducer/app.ts b/frontend/src/types/reducer/app.ts index 8fa8acf4e5..607a8fca79 100644 --- a/frontend/src/types/reducer/app.ts +++ b/frontend/src/types/reducer/app.ts @@ -1,13 +1,12 @@ import { PayloadProps as ConfigPayload } from 'types/api/dynamicConfigs/getDynamicConfigs'; -import { PayloadProps as UserPayload } from 'types/api/user/getUser'; +import { UserResponse as UserPayload } from 'types/api/user/getUser'; export interface User { accessJwt: string; refreshJwt: string; userId: string; email: UserPayload['email']; - name: UserPayload['name']; - profilePictureURL: UserPayload['profilePictureURL']; + displayName: UserPayload['displayName']; } export interface OrgPreference { diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index b903fd60b4..96d2f8f388 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -3,6 +3,7 @@ "sourceMap": true, "outDir": "./dist/", "noImplicitAny": true, + "noImplicitReturns": true, "module": "esnext", "target": "es5", "jsx": "react-jsx",