diff --git a/packages/amplify-category-notifications/src/__tests__/channel-fcm.test.ts b/packages/amplify-category-notifications/src/__tests__/channel-fcm.test.ts index a43a7bec331..f5b0a457d7a 100644 --- a/packages/amplify-category-notifications/src/__tests__/channel-fcm.test.ts +++ b/packages/amplify-category-notifications/src/__tests__/channel-fcm.test.ts @@ -17,7 +17,12 @@ jest.mock('@aws-amplify/amplify-cli-core', () => { }; }); -const apiKey = 'ApiKey-abc123'; +const serviceJSONFilePath = '/my/service/account/jsonFile.json'; +const serviceAccountJson = '{ "valid": { "service": "accountJson"}}'; +jest.mock('fs-extra', () => ({ + readFile: () => Promise.resolve(serviceAccountJson), + existsSync: () => true, +})); jest.mock('@aws-amplify/amplify-prompts'); const prompterMock = prompter as jest.Mocked; @@ -97,7 +102,7 @@ describe('channel-FCM', () => { test('configure', async () => { mockChannelEnabledOutput.Enabled = true; prompterMock.yesOrNo.mockResolvedValueOnce(true); - prompterMock.input.mockResolvedValueOnce(apiKey); + prompterMock.input.mockResolvedValueOnce(serviceJSONFilePath); const mockContextObj = mockContext(mockChannelEnabledOutput, mockPinpointClient); await channelFCM.configure(mockContextObj).then(() => { @@ -118,20 +123,14 @@ describe('channel-FCM', () => { }); test('enable', async () => { - prompterMock.input.mockResolvedValueOnce(apiKey); + prompterMock.input.mockResolvedValueOnce(serviceJSONFilePath); const mockContextObj = mockContext(mockChannelEnabledOutput, mockPinpointClient); const data = await channelFCM.enable(mockContextObj, 'successMessage'); - expect(mockPinpointClient.updateGcmChannel).toBeCalled(); - expect(data).toEqual(mockPinpointResponseData(true, ChannelAction.ENABLE)); - }); - - test('enable with newline', async () => { - prompterMock.input.mockResolvedValueOnce(`${apiKey}\n`); - const data = await channelFCM.enable(mockContext(mockChannelEnabledOutput, mockPinpointClient), 'successMessage'); expect(mockPinpointClient.updateGcmChannel).toBeCalledWith({ ApplicationId: undefined, GCMChannelRequest: { - ApiKey: apiKey, + ServiceJson: serviceAccountJson, + DefaultAuthenticationMethod: 'TOKEN', Enabled: true, }, }); @@ -139,7 +138,7 @@ describe('channel-FCM', () => { }); test('enable unsuccessful', async () => { - prompterMock.input.mockResolvedValueOnce(apiKey); + prompterMock.input.mockResolvedValueOnce(serviceJSONFilePath); const context = mockContextReject(mockServiceOutput, mockPinpointClientReject); const errCert: AmplifyFault = await getError(async () => channelFCM.enable(context as unknown as $TSContext, 'successMessage')); diff --git a/packages/amplify-category-notifications/src/channel-fcm.ts b/packages/amplify-category-notifications/src/channel-fcm.ts index 46e5ec4718e..bffcec7bba5 100644 --- a/packages/amplify-category-notifications/src/channel-fcm.ts +++ b/packages/amplify-category-notifications/src/channel-fcm.ts @@ -3,6 +3,8 @@ import { printer, prompter } from '@aws-amplify/amplify-prompts'; import ora from 'ora'; import { ChannelAction, ChannelConfigDeploymentType, IChannelAPIResponse } from './channel-types'; import { buildPinpointChannelResponseSuccess } from './pinpoint-helper'; +import { validateFilePath } from './validate-filepath'; +import fs from 'fs-extra'; const channelName = 'FCM'; const spinner = ora(''); @@ -42,12 +44,11 @@ export const enable = async (context: $TSContext, successMessage: string | undef if (context.exeInfo.pinpointInputParams?.[channelName]) { answers = validateInputParams(context.exeInfo.pinpointInputParams[channelName]); } else { - let channelOutput: $TSAny = {}; - if (context.exeInfo.serviceMeta.output[channelName]) { - channelOutput = context.exeInfo.serviceMeta.output[channelName]; - } answers = { - ApiKey: await prompter.input('Server Key', { initial: channelOutput.ApiKey, transform: (input) => input.trim() }), + ServiceJson: await fs.readFile( + await prompter.input('The service account file path (.json): ', { validate: validateFilePath }), + 'utf8', + ), }; } @@ -55,6 +56,7 @@ export const enable = async (context: $TSContext, successMessage: string | undef ApplicationId: context.exeInfo.serviceMeta.output.Id, GCMChannelRequest: { ...answers, + DefaultAuthenticationMethod: 'TOKEN', Enabled: true, }, }; @@ -78,10 +80,10 @@ export const enable = async (context: $TSContext, successMessage: string | undef }; const validateInputParams = (channelInput: $TSAny): $TSAny => { - if (!channelInput.ApiKey) { + if (!channelInput.ServiceJson) { throw new AmplifyError('UserInputError', { - message: 'Server Key is missing for the FCM channel', - resolution: 'Server Key for the FCM channel', + message: 'ServiceJson is missing for the FCM channel', + resolution: 'Provide the JSON from your Firebase service account json file', }); } return channelInput; @@ -97,18 +99,18 @@ export const disable = async (context: $TSContext): Promise<$TSAny> => { if (context.exeInfo.pinpointInputParams?.[channelName]) { answers = validateInputParams(context.exeInfo.pinpointInputParams[channelName]); } else { - let channelOutput: $TSAny = {}; - if (context.exeInfo.serviceMeta.output[channelName]) { - channelOutput = context.exeInfo.serviceMeta.output[channelName]; - } answers = { - ApiKey: await prompter.input('Server Key', { initial: channelOutput.ApiKey, transform: (input) => input.trim() }), + ServiceJson: await fs.readFile( + await prompter.input('The service account file path (.json): ', { validate: validateFilePath }), + 'utf8', + ), }; } const params = { ApplicationId: context.exeInfo.serviceMeta.output.Id, GCMChannelRequest: { ...answers, + DefaultAuthenticationMethod: 'TOKEN', Enabled: false, }, };