diff --git a/packages/api-v4/src/iam/delegation.ts b/packages/api-v4/src/iam/delegation.ts index 18f439153d3..219a18f313e 100644 --- a/packages/api-v4/src/iam/delegation.ts +++ b/packages/api-v4/src/iam/delegation.ts @@ -1,6 +1,7 @@ import { BETA_API_ROOT } from '../constants'; import Request, { setData, + setHeaders, setMethod, setParams, setURL, @@ -12,6 +13,7 @@ import type { Token } from '../profile'; import type { ResourcePage as Page } from '../types'; import type { ChildAccount, + ChildAccountTokenPayload, ChildAccountWithDelegates, GetChildAccountDelegatesParams, GetChildAccountsIamParams, @@ -98,12 +100,16 @@ export const getDelegatedChildAccount = ({ euuid }: { euuid: string }) => setMethod('GET'), ); -export const generateChildAccountToken = ({ euuid }: { euuid: string }) => +export const generateChildAccountToken = ({ + euuid, + headers, +}: ChildAccountTokenPayload) => Request( setURL( `${BETA_API_ROOT}/iam/delegation/profile/child-accounts/${encodeURIComponent(euuid)}/token`, ), setMethod('POST'), + setHeaders(headers), setData(euuid), ); diff --git a/packages/api-v4/src/iam/delegation.types.ts b/packages/api-v4/src/iam/delegation.types.ts index 953ca57c467..14791a5b2b7 100644 --- a/packages/api-v4/src/iam/delegation.types.ts +++ b/packages/api-v4/src/iam/delegation.types.ts @@ -1,4 +1,4 @@ -import type { Filter, Params } from 'src/types'; +import type { Filter, Params, RequestOptions } from '../types'; export interface ChildAccount { company: string; @@ -37,3 +37,7 @@ export interface UpdateChildAccountDelegatesParams { euuid: string; users: string[]; } + +export interface ChildAccountTokenPayload extends RequestOptions { + euuid: string; +} diff --git a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx index 1699e2aa5e2..8faed748301 100644 --- a/packages/manager/src/features/Account/SwitchAccountDrawer.tsx +++ b/packages/manager/src/features/Account/SwitchAccountDrawer.tsx @@ -103,7 +103,7 @@ export const SwitchAccountDrawer = (props: Props) => { } : undefined, }, - isIAMDelegationEnabled === false + isIAMDelegationEnabled === false && isParentUserType ); const { @@ -170,7 +170,7 @@ export const SwitchAccountDrawer = (props: Props) => { // Error is handled by createTokenError. } }, - [createToken, updateCurrentToken, revokeToken, isIAMDelegationEnabled] + [createToken, isIAMDelegationEnabled, updateCurrentToken, revokeToken] ); const [isSwitchingChildAccounts, setIsSwitchingChildAccounts] = diff --git a/packages/manager/src/features/Account/SwitchAccounts/SessionExpirationDialog.tsx b/packages/manager/src/features/Account/SwitchAccounts/SessionExpirationDialog.tsx index 383afb8d172..807e681cd02 100644 --- a/packages/manager/src/features/Account/SwitchAccounts/SessionExpirationDialog.tsx +++ b/packages/manager/src/features/Account/SwitchAccounts/SessionExpirationDialog.tsx @@ -25,7 +25,6 @@ export const SessionExpirationDialog = React.memo( ); const { isProxyUserType, isDelegateUserType } = useDelegationRole(); const { isIAMDelegationEnabled } = useIsIAMDelegationEnabled(); - const [timeRemaining, setTimeRemaining] = React.useState<{ minutes: number; seconds: number; @@ -121,7 +120,6 @@ export const SessionExpirationDialog = React.memo( setTokenInLocalStorage({ prefix: tokenPrefix, - token: { ...proxyToken, token: `Bearer ${proxyToken.token}`, @@ -145,7 +143,7 @@ export const SessionExpirationDialog = React.memo( */ useEffect(() => { const checkTokenExpiry = () => { - const expiryString = isIAMDelegationEnabled + const expiryString = isProxyUserType ? getStorage('authentication/proxy_token/expire') : getStorage('authentication/delegate_token/expire'); diff --git a/packages/manager/src/features/Account/SwitchAccounts/useParentChildAuthentication.tsx b/packages/manager/src/features/Account/SwitchAccounts/useParentChildAuthentication.tsx index d7866b8eb6e..b43bc169a04 100644 --- a/packages/manager/src/features/Account/SwitchAccounts/useParentChildAuthentication.tsx +++ b/packages/manager/src/features/Account/SwitchAccounts/useParentChildAuthentication.tsx @@ -47,18 +47,22 @@ export const useParentChildAuthentication = () => { const createToken = useCallback( async (euuid: string): Promise => { - return isIAMDelegationEnabled - ? generateProxyToken({ euuid }) - : createProxyToken({ - euuid, - headers: { - /** - * Headers are required for proxy or delegate users when obtaining a proxy or delegate token. - * For 'proxy' or 'delegate' userType, use the stored parent token in the request. - */ - Authorization: getStorage('authentication/parent_token/token'), - }, - }); + const tokenParent = getStorage('authentication/parent_token/token'); + + const mutationFn = isIAMDelegationEnabled + ? generateProxyToken + : createProxyToken; + + return mutationFn({ + euuid, + headers: { + /** + * Headers are required for proxy or delegate users when obtaining a proxy or delegate token. + * For 'proxy' or 'delegate' userType, use the stored parent token in the request. + */ + Authorization: tokenParent, + }, + }); }, [createProxyToken, generateProxyToken, isIAMDelegationEnabled] ); diff --git a/packages/manager/src/routes/IAM/index.ts b/packages/manager/src/routes/IAM/index.ts index 54cb093ee29..a13e2dcfaba 100644 --- a/packages/manager/src/routes/IAM/index.ts +++ b/packages/manager/src/routes/IAM/index.ts @@ -178,7 +178,9 @@ const iamDelegationsRoute = createRoute({ } const isChildAccount = profile?.user_type === 'child'; - if (!isDelegationEnabled || isChildAccount) { + const isDelegateAccount = profile?.user_type === 'delegate'; + const isChildOrDelegate = isChildAccount || isDelegateAccount; + if (!isDelegationEnabled || isChildOrDelegate) { throw redirect({ to: '/iam/users', replace: true, diff --git a/packages/queries/src/iam/delegation.ts b/packages/queries/src/iam/delegation.ts index d50d49599ba..36c2bf95f1e 100644 --- a/packages/queries/src/iam/delegation.ts +++ b/packages/queries/src/iam/delegation.ts @@ -21,6 +21,7 @@ import type { Account, APIError, ChildAccount, + ChildAccountTokenPayload, ChildAccountWithDelegates, GetChildAccountDelegatesParams, GetChildAccountsIamParams, @@ -233,13 +234,10 @@ export const useGetChildAccountQuery = ( * - Audience: Clients that need temporary auth to perform actions in the child account. * - Data: Token for `POST /iam/delegation/child-accounts/:euuid/token`. */ -export const useGenerateChildAccountTokenQuery = (): UseMutationResult< - Token, - APIError[], - { euuid: string } -> => { - return useMutation({ - mutationFn: generateChildAccountToken, +export const useGenerateChildAccountTokenQuery = () => { + return useMutation({ + mutationFn: ({ euuid, headers }: ChildAccountTokenPayload) => + generateChildAccountToken({ euuid, headers }), }); };