import { TokenResult } from '@axinom/mosaic-id-utils'; import { MosaicError, MosaicErrors } from '@axinom/mosaic-service-common'; import { getGqlClient } from '../common/gql-client'; import { IdLinkBeErrors } from '../common/id-link-be-errors'; import { GetManagedServiceTokenDocument, GetManagedServiceTokenMutation, GetManagedServiceTokenMutationVariables, GetManagedServiceTokenWithEnvironmentScopeDocument, GetManagedServiceTokenWithEnvironmentScopeMutation, GetManagedServiceTokenWithEnvironmentScopeMutationVariables, GetServiceTokenDocument, GetServiceTokenMutation, GetServiceTokenMutationVariables, } from '../generated/graphql.types'; // TODO: Once we merge authenticateServiceAccount & authenticateManagedServiceAccount mutations, // these functions can also be merged into one. /** * This function authenticates a service account. * @param authEndpoint URL for id-service authEndpoint. * @param clientId Client ID of the service account. * @param clientSecret Client secret of the service account. * @returns {TokenResult} AccessToken for the service account. */ export const getServiceAccountToken = async ( authEndpoint: string, clientId: string, clientSecret: string, ): Promise => { const client = getGqlClient(new URL(`/graphql`, authEndpoint).href); let serviceAccountAccessToken: TokenResult; const result = await client.mutate< GetServiceTokenMutation, GetServiceTokenMutationVariables >({ mutation: GetServiceTokenDocument, variables: { clientId: clientId, clientSecret: clientSecret, }, errorPolicy: 'all', fetchPolicy: 'no-cache', }); if (!result.errors) { if (!result.data) { throw new MosaicError({ code: MosaicErrors.UnexpectedNullUndefined.code, message: `Unexpected null or undefined value received for 'getServiceAccountToken' result.`, }); } const tokenResponse = result.data.authenticateServiceAccount; serviceAccountAccessToken = { accessToken: tokenResponse.accessToken, tokenType: tokenResponse.tokenType, expiresInSeconds: tokenResponse.expiresInSeconds, }; return serviceAccountAccessToken; } else { const aggregatedErrorMessage = result.errors.reduce( (aggregatedError, gqlError) => { return (aggregatedError += gqlError.message); }, '', ); throw new MosaicError({ ...IdLinkBeErrors.ServiceAccountTokenGenerateError, details: { originalError: aggregatedErrorMessage, }, }); } }; /** * This function authenticates a managed service account. * @param authEndpoint URL for id-service authEndpoint. * @param clientId Client ID of the managed service account. * @param clientSecret Client secret of the managed service account. * @param targetTenantId Tenant ID to be used in resulting AccessToken. If not provided, Root Tenant ID will be used. * @param targetEnvironmentId Environment ID to be used in resulting AccessToken. If not provided, Root Environment ID will be used. * @returns {TokenResult} AccessToken for the managed service account. */ export const getManagedServiceAccountToken = async ( authEndpoint: string, clientId: string, clientSecret: string, targetTenantId?: string, targetEnvironmentId?: string, ): Promise => { const client = getGqlClient(new URL(`/graphql`, authEndpoint).href); let serviceAccountAccessToken: TokenResult; const result = await client.mutate< GetManagedServiceTokenMutation, GetManagedServiceTokenMutationVariables >({ mutation: GetManagedServiceTokenDocument, variables: { clientId: clientId, clientSecret: clientSecret, targetTenantId, targetEnvironmentId: targetEnvironmentId, }, errorPolicy: 'all', fetchPolicy: 'no-cache', }); if (!result.errors) { if (!result.data) { throw new MosaicError({ code: MosaicErrors.UnexpectedNullUndefined.code, message: `Unexpected null or undefined value received for 'getManagedServiceAccountToken' result.`, }); } const tokenResponse = result.data.authenticateManagedServiceAccount; serviceAccountAccessToken = { accessToken: tokenResponse.accessToken, tokenType: tokenResponse.tokenType, expiresInSeconds: tokenResponse.expiresInSeconds, }; return serviceAccountAccessToken; } else { const aggregatedErrorMessage = result.errors.reduce( (aggregatedError, gqlError) => { return (aggregatedError += gqlError.message); }, '', ); throw new MosaicError({ ...IdLinkBeErrors.ServiceAccountTokenGenerateError, details: { originalError: aggregatedErrorMessage, }, }); } }; /** * This function authenticates a managed service account and returns * a managed service access token scoped to the tenant/environment * of the passed-in Management JWT. * * @param authEndpoint * @param clientId * @param clientSecret * @param managementJWT * @returns */ export const getScopedManagedServiceAccountToken = async ( authEndpoint: string, clientId: string, clientSecret: string, managementJWT: string, ): Promise => { const client = getGqlClient(new URL(`/graphql`, authEndpoint).href); let serviceAccountAccessToken: TokenResult; const result = await client.mutate< GetManagedServiceTokenWithEnvironmentScopeMutation, GetManagedServiceTokenWithEnvironmentScopeMutationVariables >({ mutation: GetManagedServiceTokenWithEnvironmentScopeDocument, variables: { clientId: clientId, clientSecret: clientSecret, managementJWT, }, errorPolicy: 'all', fetchPolicy: 'no-cache', }); if (!result.errors) { if (!result.data) { throw new MosaicError({ code: MosaicErrors.UnexpectedNullUndefined.code, message: `Unexpected null or undefined value received for 'getScopedManagedServiceAccountToken' result.`, }); } const tokenResponse = result.data.authenticateManagedServiceAccountWithEnvironmentScope; serviceAccountAccessToken = { accessToken: tokenResponse.accessToken, tokenType: tokenResponse.tokenType, expiresInSeconds: tokenResponse.expiresInSeconds, }; return serviceAccountAccessToken; } else { const aggregatedErrorMessage = result.errors.reduce( (aggregatedError, gqlError) => { return (aggregatedError += gqlError.message); }, '', ); throw new MosaicError({ ...IdLinkBeErrors.ServiceAccountTokenGenerateError, details: { originalError: aggregatedErrorMessage, }, }); } };