Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 0 additions & 58 deletions packages/messaging/src/controllers/window-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,15 +37,9 @@ import {
} from '../models/worker-page-message';
import { BaseController } from './base-controller';

interface ManifestContent {
// eslint-disable-next-line camelcase
gcm_sender_id: string;
}

export class WindowController extends BaseController {
private registrationToUse: ServiceWorkerRegistration | null = null;
private publicVapidKeyToUse: Uint8Array | null = null;
private manifestCheckPromise: Promise<void> | null = null;

private messageObserver: Observer<object> | null = null;
// @ts-ignore: Unused variable error, this is not implemented yet.
Expand All @@ -72,23 +66,6 @@ export class WindowController extends BaseController {
this.setupSWMessageListener_();
}

/**
* This method returns an FCM token if it can be generated.
* The return promise will reject if the browser doesn't support
* FCM, if permission is denied for notifications or it's not
* possible to generate a token.
*
* @return Returns a promise that resolves to an FCM token or null if
* permission isn't granted.
*/
async getToken(): Promise<string | null> {
if (!this.manifestCheckPromise) {
this.manifestCheckPromise = manifestCheck();
}
await this.manifestCheckPromise;
return super.getToken();
}

/**
* Request permission if it is not currently granted
*
Expand Down Expand Up @@ -324,38 +301,3 @@ export class WindowController extends BaseController {
);
}
}

/**
* The method checks that a manifest is defined and has the correct GCM
* sender ID.
* @return Returns a promise that resolves if the manifest matches
* our required sender ID
*/
// Exported for testing
export async function manifestCheck(): Promise<void> {
const manifestTag = document.querySelector<HTMLAnchorElement>(
'link[rel="manifest"]'
);

if (!manifestTag) {
return;
}

let manifestContent: ManifestContent;
try {
const response = await fetch(manifestTag.href);
manifestContent = await response.json();
} catch (e) {
// If the download or parsing fails allow check.
// We only want to error if we KNOW that the gcm_sender_id is incorrect.
return;
}

if (!manifestContent || !manifestContent.gcm_sender_id) {
return;
}

if (manifestContent.gcm_sender_id !== '103953800507') {
throw errorFactory.create(ErrorCode.INCORRECT_GCM_SENDER_ID);
}
}
4 changes: 0 additions & 4 deletions packages/messaging/src/models/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export const enum ErrorCode {
AVAILABLE_IN_SW = 'only-available-in-sw',
SHOULD_BE_INHERITED = 'should-be-overriden',
BAD_SENDER_ID = 'bad-sender-id',
INCORRECT_GCM_SENDER_ID = 'incorrect-gcm-sender-id',
PERMISSION_DEFAULT = 'permission-default',
PERMISSION_BLOCKED = 'permission-blocked',
UNSUPPORTED_BROWSER = 'unsupported-browser',
Expand Down Expand Up @@ -131,9 +130,6 @@ export const ERROR_MAP: ErrorMap<ErrorCode> = {
[ErrorCode.NO_SW_IN_REG]:
'Even though the service worker registration was ' +
'successful, there was a problem accessing the service worker itself.',
[ErrorCode.INCORRECT_GCM_SENDER_ID]:
"Please change your web app manifest's " +
"'gcm_sender_id' value to '103953800507' to use Firebase messaging.",
[ErrorCode.BAD_SCOPE]:
'The service worker scope must be a string with at ' +
'least one character.',
Expand Down
111 changes: 1 addition & 110 deletions packages/messaging/test/window-controller.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,7 @@ import * as sinon from 'sinon';
import { makeFakeApp } from './testing-utils/make-fake-app';
import { makeFakeSWReg } from './testing-utils/make-fake-sw-reg';

import {
manifestCheck,
WindowController
} from '../src/controllers/window-controller';
import { WindowController } from '../src/controllers/window-controller';
import { base64ToArrayBuffer } from '../src/helpers/base64-to-array-buffer';
import { DEFAULT_PUBLIC_VAPID_KEY } from '../src/models/fcm-details';

Expand All @@ -48,112 +45,6 @@ describe('Firebase Messaging > *WindowController', () => {
return cleanup();
});

describe('manifestCheck()', () => {
it("should resolve when the tag isn't defined", () => {
sandbox
.stub(document, 'querySelector')
.withArgs('link[rel="manifest"]')
.returns(null);

return manifestCheck();
});

it('should fetch the manifest if defined and resolve when no gcm_sender_id', () => {
sandbox
.stub(document, 'querySelector')
.withArgs('link[rel="manifest"]')
.returns({
href: 'https://firebase.io/messaging/example'
} as any);

sandbox
.stub(window, 'fetch')
.withArgs('https://firebase.io/messaging/example')
.returns(
Promise.resolve({
json: () => {
return {};
}
} as any)
);

return manifestCheck();
});

it('should fetch the manifest if defined and resolve with expected gcm_sender_id', () => {
sandbox
.stub(document, 'querySelector')
.withArgs('link[rel="manifest"]')
.returns({
href: 'https://firebase.io/messaging/example'
} as any);

sandbox
.stub(window, 'fetch')
.withArgs('https://firebase.io/messaging/example')
.returns(
Promise.resolve({
json: () => {
return {
// eslint-disable-next-line camelcase
gcm_sender_id: '103953800507'
};
}
} as any)
);

return manifestCheck();
});

it('should fetch the manifest if defined and reject when using wrong gcm_sender_id', () => {
sandbox
.stub(document, 'querySelector')
.withArgs('link[rel="manifest"]')
.returns({
href: 'https://firebase.io/messaging/example'
} as any);

sandbox
.stub(window, 'fetch')
.withArgs('https://firebase.io/messaging/example')
.returns(
Promise.resolve({
json: () => {
return {
// eslint-disable-next-line camelcase
gcm_sender_id: 'incorrect-sender-id'
};
}
} as any)
);

return manifestCheck().then(
() => {
throw new Error('Expected error to be thrown.');
},
err => {
expect(err.code).to.equal('messaging/incorrect-gcm-sender-id');
}
);
});

it('should fetch the manifest and resolve if the request fails', () => {
sandbox
.stub(document, 'querySelector')
.withArgs('link[rel="manifest"]')
.returns({
href: 'https://firebase.io/messaging/example'
} as any);

sandbox
.stub(window, 'fetch')
.withArgs('https://firebase.io/messaging/example')
.returns(Promise.reject(new Error('Injected Failure.')));

return manifestCheck();
});
});

describe('requestPermission', () => {
it('should resolve if the permission is already granted', () => {
sandbox.stub(Notification as any, 'permission').value('granted');
Expand Down