diff --git a/packages/cli-kit/src/private/node/analytics.ts b/packages/cli-kit/src/private/node/analytics.ts index 0a46ad9528b..67a869ee8d8 100644 --- a/packages/cli-kit/src/private/node/analytics.ts +++ b/packages/cli-kit/src/private/node/analytics.ts @@ -97,9 +97,14 @@ export async function getEnvironmentData(config: Interfaces.Config): Promise key.startsWith('SHOPIFY_'))) +} + function getPluginNames(config: Interfaces.Config) { const pluginNames = [...config.plugins.keys()] return pluginNames.sort().filter((plugin) => !plugin.startsWith('@oclif/')) diff --git a/packages/cli-kit/src/public/node/analytics.test.ts b/packages/cli-kit/src/public/node/analytics.test.ts index 544d1e4ed37..437ee1bb93e 100644 --- a/packages/cli-kit/src/public/node/analytics.test.ts +++ b/packages/cli-kit/src/public/node/analytics.test.ts @@ -185,6 +185,36 @@ describe('event tracking', () => { }) }) + test('sends SHOPIFY_ environment variables in sensitive payload', async () => { + const originalEnv = {...process.env} + process.env.SHOPIFY_TEST_VAR = 'test_value' + process.env.SHOPIFY_ANOTHER_VAR = 'another_value' + process.env.NOT_SHOPIFY_VAR = 'should_not_appear' + + await inProjectWithFile('package.json', async (args) => { + const commandContent = {command: 'dev', topic: 'app'} + await startAnalytics({commandContent, args, currentTime: currentDate.getTime() - 100}) + + // When + const config = { + runHook: vi.fn().mockResolvedValue({successes: [], failures: []}), + plugins: [], + } as any + await reportAnalyticsEvent({config, exitMode: 'ok'}) + + // Then + const sensitivePayload = publishEventMock.mock.calls[0]![2] + expect(publishEventMock).toHaveBeenCalledOnce() + expect(sensitivePayload).toHaveProperty('env_shopify_variables') + expect(sensitivePayload.env_shopify_variables).toBeDefined() + + const shopifyVars = JSON.parse(sensitivePayload.env_shopify_variables as string) + expect(shopifyVars).toHaveProperty('SHOPIFY_TEST_VAR', 'test_value') + expect(shopifyVars).toHaveProperty('SHOPIFY_ANOTHER_VAR', 'another_value') + expect(shopifyVars).not.toHaveProperty('NOT_SHOPIFY_VAR') + }) + }) + test('does nothing when analytics are disabled', async () => { await inProjectWithFile('package.json', async (args) => { // Given diff --git a/packages/cli-kit/src/public/node/monorail.ts b/packages/cli-kit/src/public/node/monorail.ts index 10ff35ab7c1..10f1ecf1b8c 100644 --- a/packages/cli-kit/src/public/node/monorail.ts +++ b/packages/cli-kit/src/public/node/monorail.ts @@ -10,7 +10,7 @@ const url = 'https://monorail-edge.shopifysvc.com/v1/produce' type Optional = T | null // This is the topic name of the main event we log to Monorail, the command tracker -export const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.19' +export const MONORAIL_COMMAND_TOPIC = 'app_cli3_command/1.20' export interface Schemas { [MONORAIL_COMMAND_TOPIC]: { @@ -27,6 +27,7 @@ export interface Schemas { // Environment env_plugin_installed_all?: Optional + env_shopify_variables?: Optional } public: { business_platform_id?: Optional