Skip to content

Commit

Permalink
fix(mc-scripts): sends the app identifier header when using the MC API (
Browse files Browse the repository at this point in the history
#3154)

* fix(mc-scripts): sends the app identifier header when using the MC API

* fix: tests
  • Loading branch information
emmenko authored Aug 3, 2023
1 parent a908916 commit 4343c83
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 24 deletions.
5 changes: 5 additions & 0 deletions .changeset/afraid-timers-work.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@commercetools-frontend/mc-scripts': patch
---

Send the `x-application-id` header when using the MC API
11 changes: 9 additions & 2 deletions packages/mc-scripts/src/commands/config-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ const getMcUrlLink = (
async function run(options: TCliCommandConfigSyncOptions) {
const applicationConfig = processConfig();
const { data: localCustomAppData } = applicationConfig;
const { mcApiUrl } = applicationConfig.env;
const { mcApiUrl, applicationId, entryPointUriPath } = applicationConfig.env;
const applicationIdentifier = `${applicationId}:${entryPointUriPath}`;

console.log(`Using Merchant Center environment "${chalk.green(mcApiUrl)}".`);
console.log();
Expand All @@ -45,10 +46,14 @@ async function run(options: TCliCommandConfigSyncOptions) {
const fetchedCustomApplication = await fetchCustomApplication({
mcApiUrl,
entryPointUriPath: localCustomAppData.entryPointUriPath,
applicationIdentifier,
});

if (!fetchedCustomApplication) {
const userOrganizations = await fetchUserOrganizations({ mcApiUrl });
const userOrganizations = await fetchUserOrganizations({
mcApiUrl,
applicationIdentifier,
});

let organizationId: string, organizationName: string;

Expand Down Expand Up @@ -123,6 +128,7 @@ async function run(options: TCliCommandConfigSyncOptions) {
mcApiUrl,
organizationId,
data,
applicationIdentifier,
});

// This check is technically not necessary, as the `graphql-request` client
Expand Down Expand Up @@ -215,6 +221,7 @@ async function run(options: TCliCommandConfigSyncOptions) {
organizationId: fetchedCustomApplication.organizationId,
data: omit(localCustomAppData, ['id']),
applicationId: fetchedCustomApplication.application.id,
applicationIdentifier,
});

console.log(chalk.green(`Custom Application updated.`));
Expand Down
11 changes: 6 additions & 5 deletions packages/mc-scripts/src/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ const credentialsStorage = new CredentialsStorage();

async function run() {
const applicationConfig = processConfig();
const { mcApiUrl } = applicationConfig.env;
const { mcApiUrl, applicationId, entryPointUriPath } = applicationConfig.env;

console.log(`Using Merchant Center environment "${chalk.green(mcApiUrl)}".`);
console.log();
Expand All @@ -35,10 +35,11 @@ async function run() {
throw new Error(`Missing email or password values. Aborting.`);
}

const credentials = await getAuthToken(mcApiUrl, {
email,
password,
});
const credentials = await getAuthToken(
mcApiUrl,
{ email, password },
{ 'x-application-id': `${applicationId}:${entryPointUriPath}` }
);
credentialsStorage.setToken(mcApiUrl, credentials);

console.log(chalk.green(`Login successful.\n`));
Expand Down
7 changes: 6 additions & 1 deletion packages/mc-scripts/src/utils/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ type TAuthPayload = {
password: string;
};

const getAuthToken = async (mcApiUrl: string, payload: TAuthPayload) => {
const getAuthToken = async (
mcApiUrl: string,
payload: TAuthPayload,
headers?: Record<string, string>
) => {
const response = await fetch(`${mcApiUrl}/tokens/cli`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'x-user-agent': userAgent,
...headers,
},
body: JSON.stringify(payload),
});
Expand Down
5 changes: 5 additions & 0 deletions packages/mc-scripts/src/utils/graphql-requests.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ beforeAll(() =>
afterAll(() => mockServer.close());

const mcApiUrl = 'https://mc-api.europe-west1.gcp.commercetools.com';
const applicationIdentifier = '__local:test-custom-app';

describe('fetch custom application data', () => {
beforeEach(() => {
Expand Down Expand Up @@ -59,6 +60,7 @@ describe('fetch custom application data', () => {
await fetchCustomApplication({
entryPointUriPath: 'test-custom-app',
mcApiUrl,
applicationIdentifier,
});
expect(
organizationExtensionForCustomApplication?.application.entryPointUriPath
Expand Down Expand Up @@ -130,6 +132,7 @@ describe('register custom application', () => {
},
],
},
applicationIdentifier,
});
expect(createdCustomAppsData?.id).toEqual('application-id');
});
Expand Down Expand Up @@ -177,6 +180,7 @@ describe('update custom application', () => {
},
],
},
applicationIdentifier,
});
expect(updatedCustomAppsData?.id).toEqual('application-id');
});
Expand Down Expand Up @@ -205,6 +209,7 @@ describe('fetch user organizations', () => {
it('should match returned data', async () => {
const data = await fetchUserOrganizations({
mcApiUrl,
applicationIdentifier,
});
expect(data.results[0].id).toEqual('test-organization-id');
expect(data.results[0].name).toEqual('test-organization-name');
Expand Down
37 changes: 21 additions & 16 deletions packages/mc-scripts/src/utils/graphql-requests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,28 @@ import userAgent from './user-agent';
type TFetchCustomApplicationOptions = {
mcApiUrl: string;
entryPointUriPath: string;
applicationIdentifier: string;
};
type TUpdateCustomApplicationOptions = {
mcApiUrl: string;
applicationId: string;
organizationId: string;
data: TCustomApplicationDraftDataInput;
applicationIdentifier: string;
};
type TCreateCustomApplicationOptions = {
mcApiUrl: string;
organizationId: string;
data: TCustomApplicationDraftDataInput;
applicationIdentifier: string;
};
type TFetchUserOrganizationsOptions = {
mcApiUrl: string;
applicationIdentifier: string;
};

const credentialsStorage = new CredentialsStorage();

const client = new GraphQLClient(
'', // <-- Set on demand
{
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'x-user-agent': userAgent,
},
}
);

async function requestWithTokenRetry<Data, QueryVariables extends Variables>(
document: DocumentNode,
requestOptions: {
Expand All @@ -65,11 +58,15 @@ async function requestWithTokenRetry<Data, QueryVariables extends Variables>(
): Promise<Data> {
const token = credentialsStorage.getToken(requestOptions.mcApiUrl);

client.setEndpoint(`${requestOptions.mcApiUrl}/graphql`);
client.setHeaders(requestOptions.headers);
if (token) {
client.setHeader('x-mc-cli-access-token', token);
}
const client = new GraphQLClient(`${requestOptions.mcApiUrl}/graphql`, {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'x-user-agent': userAgent,
...(token ? { 'x-mc-cli-access-token': token } : {}),
...requestOptions.headers,
},
});

try {
const result = await client.rawRequest<Data, QueryVariables>(
Expand Down Expand Up @@ -133,6 +130,7 @@ async function requestWithTokenRetry<Data, QueryVariables extends Variables>(
const fetchCustomApplication = async ({
mcApiUrl,
entryPointUriPath,
applicationIdentifier,
}: TFetchCustomApplicationOptions) => {
const customAppData = await requestWithTokenRetry<
TFetchCustomApplicationFromCliQuery,
Expand All @@ -141,6 +139,7 @@ const fetchCustomApplication = async ({
variables: { entryPointUriPath },
mcApiUrl,
headers: {
'x-application-id': applicationIdentifier,
'x-graphql-target': GRAPHQL_TARGETS.SETTINGS_SERVICE,
},
});
Expand All @@ -152,6 +151,7 @@ const updateCustomApplication = async ({
applicationId,
organizationId,
data,
applicationIdentifier,
}: TUpdateCustomApplicationOptions) => {
const updatedCustomAppsData = await requestWithTokenRetry<
TUpdateCustomApplicationFromCliMutation,
Expand All @@ -164,6 +164,7 @@ const updateCustomApplication = async ({
},
mcApiUrl,
headers: {
'x-application-id': applicationIdentifier,
'x-graphql-target': GRAPHQL_TARGETS.SETTINGS_SERVICE,
},
});
Expand All @@ -174,6 +175,7 @@ const createCustomApplication = async ({
mcApiUrl,
organizationId,
data,
applicationIdentifier,
}: TCreateCustomApplicationOptions) => {
const createdCustomAppData = await requestWithTokenRetry<
TCreateCustomApplicationFromCliMutation,
Expand All @@ -185,6 +187,7 @@ const createCustomApplication = async ({
},
mcApiUrl,
headers: {
'x-application-id': applicationIdentifier,
'x-graphql-target': GRAPHQL_TARGETS.SETTINGS_SERVICE,
},
});
Expand All @@ -193,13 +196,15 @@ const createCustomApplication = async ({

const fetchUserOrganizations = async ({
mcApiUrl,
applicationIdentifier,
}: TFetchUserOrganizationsOptions) => {
const userOrganizations = await requestWithTokenRetry<
TFetchMyOrganizationsFromCliQuery,
TFetchMyOrganizationsFromCliQueryVariables
>(FetchMyOrganizationsFromCli, {
mcApiUrl,
headers: {
'x-application-id': applicationIdentifier,
'x-graphql-target': GRAPHQL_TARGETS.ADMINISTRATION_SERVICE,
},
});
Expand Down

1 comment on commit 4343c83

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for merchant-center-application-kit ready!

✅ Preview
https://merchant-center-application-gzvxoydo5-commercetools.vercel.app

Built with commit 4343c83.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.