New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@firebase/messaging

Package Overview
Dependencies
Maintainers
3
Versions
3364
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@firebase/messaging - npm Package Compare versions

Comparing version 0.2.3-canary.2a0a33f to 0.2.3-canary.452a4be

dist/cjs/src/helpers/is-array-buffer-equal.d.ts

3

dist/cjs/index.d.ts

@@ -0,3 +1,4 @@

import { _FirebaseNamespace } from '@firebase/app-types/private';
import * as types from '@firebase/messaging-types';
export declare function registerMessaging(instance: any): void;
export declare function registerMessaging(instance: _FirebaseNamespace): void;
/**

@@ -4,0 +5,0 @@ * Define extension behavior of `registerMessaging`

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,7 +17,6 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var app_1 = require("@firebase/app");
var sw_controller_1 = require("./src/controllers/sw-controller");
var window_controller_1 = require("./src/controllers/window-controller");
var sw_controller_1 = require("./src/controllers/sw-controller");
var app_1 = require("@firebase/app");
function registerMessaging(instance) {

@@ -23,0 +23,0 @@ var messagingName = 'messaging';

@@ -0,18 +1,34 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { ErrorFactory, NextFn, PartialObserver } from '@firebase/util';
import { IIDModel } from '../models/iid-model';
import { TokenDetailsModel } from '../models/token-details-model';
import { VapidDetailsModel } from '../models/vapid-details-model';
import { IIDModel } from '../models/iid-model';
export declare const TOKEN_EXPIRATION_MILLIS: number;
export declare class ControllerInterface {
app: any;
export declare abstract class ControllerInterface {
app: FirebaseApp;
INTERNAL: any;
protected errorFactory_: any;
private messagingSenderId_;
private tokenDetailsModel_;
private vapidDetailsModel_;
private iidModel_;
protected errorFactory_: ErrorFactory<string>;
private readonly messagingSenderId_;
private readonly tokenDetailsModel_;
private readonly vapidDetailsModel_;
private readonly iidModel_;
/**
* An interface of the Messaging Service API
* @param {!firebase.app.App} app
*/
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -32,3 +48,2 @@ * @export

private manageExistingToken(swReg, pushSubscription, publicVapidKey, tokenDetails);
private isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
private updateToken(swReg, pushSubscription, publicVapidKey, tokenDetails);

@@ -43,3 +58,3 @@ private getNewToken(swReg, pushSubscription, publicVapidKey);

*/
deleteToken(token: string): Promise<Boolean>;
deleteToken(token: string): Promise<boolean>;
/**

@@ -51,4 +66,4 @@ * This method will delete the token from the client database, and make a

private deleteTokenFromDB(token);
getSWRegistration_(): Promise<ServiceWorkerRegistration>;
getPublicVapidKey_(): Promise<Uint8Array>;
abstract getSWRegistration_(): Promise<ServiceWorkerRegistration>;
abstract getPublicVapidKey_(): Promise<Uint8Array>;
/**

@@ -59,37 +74,8 @@ * Gets a PushSubscription for the current user.

requestPermission(): void;
useServiceWorker(registration: ServiceWorkerRegistration): void;
usePublicVapidKey(b64PublicKey: string): void;
onMessage(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): void;
onTokenRefresh(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): void;
setBackgroundMessageHandler(callback: (a: any) => any): void;
/**
* @export
* @param {!ServiceWorkerRegistration} registration
*/
useServiceWorker(registration: any): void;
/**
* @export
* @param {!string} b64PublicKey
*/
usePublicVapidKey(b64PublicKey: any): void;
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver
* @param {function(!Error)=} optError
* @param {function()=} optCompleted
* @return {!function()}
*/
onMessage(nextOrObserver: any, optError: any, optCompleted: any): void;
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
*/
onTokenRefresh(nextOrObserver: any, optError: any, optCompleted: any): void;
/**
* @export
* @param {function(Object)} callback
*/
setBackgroundMessageHandler(callback: any): void;
/**
* This method is required to adhere to the Firebase interface.

@@ -101,6 +87,4 @@ * It closes any currently open indexdb database connections.

* Returns the current Notification Permission state.
* @private
* @return {string} The currenct permission state.
*/
getNotificationPermission_(): any;
getNotificationPermission_(): NotificationPermission;
getTokenDetailsModel(): TokenDetailsModel;

@@ -110,5 +94,4 @@ getVapidDetailsModel(): VapidDetailsModel;

* @protected
* @returns {IIDModel}
*/
getIIDModel(): IIDModel;
}

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,12 +17,10 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var util_1 = require("@firebase/util");
var is_array_buffer_equal_1 = require("../helpers/is-array-buffer-equal");
var errors_1 = require("../models/errors");
var iid_model_1 = require("../models/iid-model");
var token_details_model_1 = require("../models/token-details-model");
var vapid_details_model_1 = require("../models/vapid-details-model");
var notification_permission_1 = require("../models/notification-permission");
var iid_model_1 = require("../models/iid-model");
var array_buffer_to_base64_1 = require("../helpers/array-buffer-to-base64");
var SENDER_ID_OPTION_NAME = 'messagingSenderId';

@@ -33,3 +32,2 @@ // Database cache should be invalidated once a week.

* An interface of the Messaging Service API
* @param {!firebase.app.App} app
*/

@@ -61,4 +59,4 @@ function ControllerInterface(app) {

currentPermission = this.getNotificationPermission_();
if (currentPermission !== notification_permission_1.NotificationPermission.GRANTED) {
if (currentPermission === notification_permission_1.NotificationPermission.DENIED) {
if (currentPermission !== 'granted') {
if (currentPermission === 'denied') {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.NOTIFICATIONS_BLOCKED))];

@@ -104,7 +102,7 @@ }

case 0:
isTokenValid = this.isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
isTokenValid = isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
if (isTokenValid) {
now = Date.now();
if (now < tokenDetails['createTime'] + exports.TOKEN_EXPIRATION_MILLIS) {
return [2 /*return*/, tokenDetails['fcmToken']];
if (now < tokenDetails.createTime + exports.TOKEN_EXPIRATION_MILLIS) {
return [2 /*return*/, tokenDetails.fcmToken];
}

@@ -119,3 +117,3 @@ else {

// good push subscription that we'd like to use in getNewToken.
return [4 /*yield*/, this.deleteTokenFromDB(tokenDetails['fcmToken'])];
return [4 /*yield*/, this.deleteTokenFromDB(tokenDetails.fcmToken)];
case 1:

@@ -132,17 +130,2 @@ // If the token is no longer valid (for example if the VAPID details

};
/*
* Checks if the tokenDetails match the details provided in the clients.
*/
ControllerInterface.prototype.isTokenStillValid = function (pushSubscription, publicVapidKey, tokenDetails) {
if (array_buffer_to_base64_1.arrayBufferToBase64(publicVapidKey) !== tokenDetails['vapidKey']) {
return false;
}
// getKey() isn't defined in the PushSubscription externs file, hence
// subscription['getKey']('<key name>').
return (pushSubscription.endpoint === tokenDetails['endpoint'] &&
array_buffer_to_base64_1.arrayBufferToBase64(pushSubscription['getKey']('auth')) ===
tokenDetails['auth'] &&
array_buffer_to_base64_1.arrayBufferToBase64(pushSubscription['getKey']('p256dh')) ===
tokenDetails['p256dh']);
};
ControllerInterface.prototype.updateToken = function (swReg, pushSubscription, publicVapidKey, tokenDetails) {

@@ -155,3 +138,3 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

_a.trys.push([0, 4, , 6]);
return [4 /*yield*/, this.iidModel_.updateToken(this.messagingSenderId_, tokenDetails['fcmToken'], tokenDetails['fcmPushSet'], pushSubscription, publicVapidKey)];
return [4 /*yield*/, this.iidModel_.updateToken(this.messagingSenderId_, tokenDetails.fcmToken, tokenDetails.fcmPushSet, pushSubscription, publicVapidKey)];
case 1:

@@ -162,6 +145,9 @@ updatedToken = _a.sent();

vapidKey: publicVapidKey,
subscription: pushSubscription,
fcmSenderId: this.messagingSenderId_,
fcmToken: updatedToken,
fcmPushSet: tokenDetails['fcmPushSet']
fcmPushSet: tokenDetails.fcmPushSet,
createTime: Date.now(),
endpoint: pushSubscription.endpoint,
auth: pushSubscription.getKey('auth'),
p256dh: pushSubscription.getKey('p256dh')
};

@@ -177,3 +163,3 @@ return [4 /*yield*/, this.tokenDetailsModel_.saveTokenDetails(allDetails)];

e_1 = _a.sent();
return [4 /*yield*/, this.deleteToken(tokenDetails['fcmToken'])];
return [4 /*yield*/, this.deleteToken(tokenDetails.fcmToken)];
case 5:

@@ -198,6 +184,9 @@ _a.sent();

vapidKey: publicVapidKey,
subscription: pushSubscription,
fcmSenderId: this.messagingSenderId_,
fcmToken: tokenDetails['token'],
fcmPushSet: tokenDetails['pushSet']
fcmToken: tokenDetails.token,
fcmPushSet: tokenDetails.pushSet,
createTime: Date.now(),
endpoint: pushSubscription.endpoint,
auth: pushSubscription.getKey('auth'),
p256dh: pushSubscription.getKey('p256dh')
};

@@ -210,3 +199,3 @@ return [4 /*yield*/, this.tokenDetailsModel_.saveTokenDetails(allDetails)];

_a.sent();
return [2 /*return*/, tokenDetails['token']];
return [2 /*return*/, tokenDetails.token];
}

@@ -265,3 +254,3 @@ });

details = _a.sent();
return [4 /*yield*/, this.iidModel_.deleteToken(details['fcmSenderId'], details['fcmToken'], details['fcmPushSet'])];
return [4 /*yield*/, this.iidModel_.deleteToken(details.fcmSenderId, details.fcmToken, details.fcmPushSet)];
case 2:

@@ -274,8 +263,2 @@ _a.sent();

};
ControllerInterface.prototype.getSWRegistration_ = function () {
throw this.errorFactory_.create(errors_1.ERROR_CODES.SHOULD_BE_INHERITED);
};
ControllerInterface.prototype.getPublicVapidKey_ = function () {
throw this.errorFactory_.create(errors_1.ERROR_CODES.SHOULD_BE_INHERITED);
};
/**

@@ -301,37 +284,12 @@ * Gets a PushSubscription for the current user.

};
/**
* @export
* @param {!ServiceWorkerRegistration} registration
*/
ControllerInterface.prototype.useServiceWorker = function (registration) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!string} b64PublicKey
*/
ControllerInterface.prototype.usePublicVapidKey = function (b64PublicKey) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver
* @param {function(!Error)=} optError
* @param {function()=} optCompleted
* @return {!function()}
*/
ControllerInterface.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {
ControllerInterface.prototype.onMessage = function (nextOrObserver, error, completed) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
*/
ControllerInterface.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {
ControllerInterface.prototype.onTokenRefresh = function (nextOrObserver, error, completed) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.AVAILABLE_IN_WINDOW);

@@ -342,6 +300,2 @@ };

//
/**
* @export
* @param {function(Object)} callback
*/
ControllerInterface.prototype.setBackgroundMessageHandler = function (callback) {

@@ -366,4 +320,2 @@ throw this.errorFactory_.create(errors_1.ERROR_CODES.AVAILABLE_IN_SW);

* Returns the current Notification Permission state.
* @private
* @return {string} The currenct permission state.
*/

@@ -381,3 +333,2 @@ ControllerInterface.prototype.getNotificationPermission_ = function () {

* @protected
* @returns {IIDModel}
*/

@@ -390,3 +341,15 @@ ControllerInterface.prototype.getIIDModel = function () {

exports.ControllerInterface = ControllerInterface;
/**
* Checks if the tokenDetails match the details provided in the clients.
*/
function isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails) {
if (!is_array_buffer_equal_1.isArrayBufferEqual(publicVapidKey.buffer, tokenDetails.vapidKey.buffer)) {
return false;
}
var isEndpointEqual = pushSubscription.endpoint === tokenDetails.endpoint;
var isAuthEqual = is_array_buffer_equal_1.isArrayBufferEqual(pushSubscription.getKey('auth'), tokenDetails.auth);
var isP256dhEqual = is_array_buffer_equal_1.isArrayBufferEqual(pushSubscription.getKey('p256dh'), tokenDetails.p256dh);
return isEndpointEqual && isAuthEqual && isP256dhEqual;
}
//# sourceMappingURL=controller-interface.js.map

@@ -0,5 +1,22 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { ControllerInterface } from './controller-interface';
export declare type BgMessageHandler = (input: any) => Promise<any>;
export declare class SWController extends ControllerInterface {
private bgMessageHandler_;
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -16,20 +33,8 @@ * A handler for push events that shows notifications based on the content of

* shown.
* @private
*/
onPush_(event: any): void;
/**
* @private
*/
onSubChange_(event: any): void;
/**
* @private
*/
onNotificationClick_(event: any): void;
getNotificationData_(msgPayload: any): NotificationOptions | undefined;
/**
* @private
* @param {Object} msgPayload
* @return {NotificationOptions|undefined}
*/
getNotificationData_(msgPayload: any): any;
/**
* Calling setBackgroundMessageHandler will opt in to some specific

@@ -44,46 +49,38 @@ * behaviours.

* developer can handle them in a their own 'push' event callback
* @export
* @param {function(Object)} callback The callback to be called when a push
* message is received and a notification must be shown. The callback will
* be given the data from the push message.
*
* @param callback The callback to be called when a push message is received
* and a notification must be shown. The callback will be given the data from
* the push message.
*/
setBackgroundMessageHandler(callback: any): void;
setBackgroundMessageHandler(callback: BgMessageHandler): void;
/**
* @private
* @param {string} url The URL to look for when focusing a client.
* @return {Object} Returns an existing window client or a newly opened
* WindowClient.
* @param url The URL to look for when focusing a client.
* @return Returns an existing window client or a newly opened WindowClient.
*/
getWindowClient_(url: any): any;
getWindowClient_(url: string): Promise<any>;
/**
* This message will attempt to send the message to a window client.
* @private
* @param {Object} client The WindowClient to send the message to.
* @param {Object} message The message to send to the client.
* @returns {Promise} Returns a promise that resolves after sending the
* message. This does not guarantee that the message was successfully
* received.
* @param client The WindowClient to send the message to.
* @param message The message to send to the client.
* @returns Returns a promise that resolves after sending the message. This
* does not guarantee that the message was successfully received.
*/
attemptToMessageClient_(client: any, message: any): Promise<never>;
attemptToMessageClient_(client: any, message: any): Promise<void>;
/**
* @private
* @returns {Promise<boolean>} If there is currently a visible WindowClient,
* this method will resolve to true, otherwise false.
* @returns If there is currently a visible WindowClient, this method will
* resolve to true, otherwise false.
*/
hasVisibleClients_(): any;
hasVisibleClients_(): Promise<boolean>;
/**
* @private
* @param {Object} msgPayload The data from the push event that should be sent
* to all available pages.
* @returns {Promise} Returns a promise that resolves once the message
* has been sent to all WindowClients.
* @param msgPayload The data from the push event that should be sent to all
* available pages.
* @returns Returns a promise that resolves once the message has been sent to
* all WindowClients.
*/
sendMessageToWindowClients_(msgPayload: any): any;
sendMessageToWindowClients_(msgPayload: any): Promise<void>;
/**
* This will register the default service worker and return the registration.
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* @return he service worker registration to be used for the push service.
*/
getSWRegistration_(): Promise<any>;
getSWRegistration_(): Promise<ServiceWorkerRegistration>;
/**

@@ -90,0 +87,0 @@ * This will return the default VAPID key or the uint8array version of the

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,9 +17,8 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var controller_interface_1 = require("./controller-interface");
var errors_1 = require("../models/errors");
var fcm_details_1 = require("../models/fcm-details");
var worker_page_message_1 = require("../models/worker-page-message");
var WorkerPageMessage = require("../models/worker-page-message");
var controller_interface_1 = require("./controller-interface");
var FCM_MSG = 'FCM_MSG';

@@ -29,10 +29,12 @@ var SWController = /** @class */ (function (_super) {

var _this = _super.call(this, app) || this;
self.addEventListener('push', function (e) { return _this.onPush_(e); }, false);
self.addEventListener('pushsubscriptionchange', function (e) { return _this.onSubChange_(e); }, false);
self.addEventListener('notificationclick', function (e) { return _this.onNotificationClick_(e); }, false);
/**
* @private
* @type {function(Object)|null}
*/
_this.bgMessageHandler_ = null;
self.addEventListener('push', function (e) {
_this.onPush_(e);
}, false);
self.addEventListener('pushsubscriptionchange', function (e) {
_this.onSubChange_(e);
}, false);
self.addEventListener('notificationclick', function (e) {
_this.onNotificationClick_(e);
}, false);
return _this;

@@ -51,4 +53,5 @@ }

* shown.
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onPush_ = function (event) {

@@ -86,5 +89,4 @@ var _this = this;

};
/**
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onSubChange_ = function (event) {

@@ -126,5 +128,4 @@ var _this = this;

};
/**
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onNotificationClick_ = function (event) {

@@ -167,3 +168,3 @@ var _this = this;

delete msgPayload['notification'];
var internalMsg = worker_page_message_1.default.createNewMsg(worker_page_message_1.default.TYPES_OF_MSG.NOTIFICATION_CLICKED, msgPayload);
var internalMsg = WorkerPageMessage.createNewMsg(WorkerPageMessage.TYPES_OF_MSG.NOTIFICATION_CLICKED, msgPayload);
// Attempt to send a message to the client to handle the data

@@ -175,7 +176,4 @@ // Is affected by: https://github.com/slightlyoff/ServiceWorker/issues/728

};
/**
* @private
* @param {Object} msgPayload
* @return {NotificationOptions|undefined}
*/
// Visible for testing
// TODO: Make private
SWController.prototype.getNotificationData_ = function (msgPayload) {

@@ -188,3 +186,3 @@ if (!msgPayload) {

}
var notificationInformation = Object.assign({}, msgPayload.notification);
var notificationInformation = tslib_1.__assign({}, msgPayload.notification);
// Put the message payload under FCM_MSG name so we can identify the

@@ -210,6 +208,6 @@ // notification as being an FCM notification vs a notification from

* developer can handle them in a their own 'push' event callback
* @export
* @param {function(Object)} callback The callback to be called when a push
* message is received and a notification must be shown. The callback will
* be given the data from the push message.
*
* @param callback The callback to be called when a push message is received
* and a notification must be shown. The callback will be given the data from
* the push message.
*/

@@ -223,7 +221,7 @@ SWController.prototype.setBackgroundMessageHandler = function (callback) {

/**
* @private
* @param {string} url The URL to look for when focusing a client.
* @return {Object} Returns an existing window client or a newly opened
* WindowClient.
* @param url The URL to look for when focusing a client.
* @return Returns an existing window client or a newly opened WindowClient.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.getWindowClient_ = function (url) {

@@ -255,9 +253,9 @@ // Use URL to normalize the URL when comparing to windowClients.

* This message will attempt to send the message to a window client.
* @private
* @param {Object} client The WindowClient to send the message to.
* @param {Object} message The message to send to the client.
* @returns {Promise} Returns a promise that resolves after sending the
* message. This does not guarantee that the message was successfully
* received.
* @param client The WindowClient to send the message to.
* @param message The message to send to the client.
* @returns Returns a promise that resolves after sending the message. This
* does not guarantee that the message was successfully received.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.attemptToMessageClient_ = function (client, message) {

@@ -277,6 +275,7 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

/**
* @private
* @returns {Promise<boolean>} If there is currently a visible WindowClient,
* this method will resolve to true, otherwise false.
* @returns If there is currently a visible WindowClient, this method will
* resolve to true, otherwise false.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.hasVisibleClients_ = function () {

@@ -293,8 +292,9 @@ return self.clients

/**
* @private
* @param {Object} msgPayload The data from the push event that should be sent
* to all available pages.
* @returns {Promise} Returns a promise that resolves once the message
* has been sent to all WindowClients.
* @param msgPayload The data from the push event that should be sent to all
* available pages.
* @returns Returns a promise that resolves once the message has been sent to
* all WindowClients.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.sendMessageToWindowClients_ = function (msgPayload) {

@@ -308,3 +308,3 @@ var _this = this;

.then(function (clientList) {
var internalMsg = worker_page_message_1.default.createNewMsg(worker_page_message_1.default.TYPES_OF_MSG.PUSH_MSG_RECEIVED, msgPayload);
var internalMsg = WorkerPageMessage.createNewMsg(WorkerPageMessage.TYPES_OF_MSG.PUSH_MSG_RECEIVED, msgPayload);
return Promise.all(clientList.map(function (client) {

@@ -317,5 +317,3 @@ return _this.attemptToMessageClient_(client, internalMsg);

* This will register the default service worker and return the registration.
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* @return he service worker registration to be used for the push service.
*/

@@ -330,12 +328,21 @@ SWController.prototype.getSWRegistration_ = function () {

SWController.prototype.getPublicVapidKey_ = function () {
var _this = this;
return this.getSWRegistration_()
.then(function (swReg) {
return _this.getVapidDetailsModel().getVapidFromSWScope(swReg.scope);
})
.then(function (vapidKeyFromDatabase) {
if (vapidKeyFromDatabase === null) {
return fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY;
}
return vapidKeyFromDatabase;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var swReg, vapidKeyFromDatabase;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getSWRegistration_()];
case 1:
swReg = _a.sent();
if (!swReg) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.SW_REGISTRATION_EXPECTED);
}
return [4 /*yield*/, this.getVapidDetailsModel().getVapidFromSWScope(swReg.scope)];
case 2:
vapidKeyFromDatabase = _a.sent();
if (vapidKeyFromDatabase == null) {
return [2 /*return*/, fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY];
}
return [2 /*return*/, vapidKeyFromDatabase];
}
});
});

@@ -342,0 +349,0 @@ };

@@ -0,2 +1,19 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseMessaging } from '@firebase/messaging-types';
import { NextFn, PartialObserver, Unsubscribe } from '@firebase/util';
import { ControllerInterface } from './controller-interface';

@@ -8,10 +25,9 @@ export declare class WindowController extends ControllerInterface implements FirebaseMessaging {

private messageObserver_;
private onMessage_;
private readonly onMessage_;
private tokenRefreshObserver_;
private onTokenRefresh_;
private readonly onTokenRefresh_;
/**
* A service that provides a MessagingService instance.
* @param {!firebase.app.App} app
*/
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -22,7 +38,7 @@ * This method returns an FCM token if it can be generated.

* possible to generate a token.
* @export
* @return {Promise<string> | Promise<null>} Returns a promise the
* resolves to an FCM token or null if permission isn't granted.
*
* @return Returns a promise that resolves to an FCM token or null if
* permission isn't granted.
*/
getToken(): any;
getToken(): Promise<string | null>;
/**

@@ -35,62 +51,51 @@ * The method checks that a manifest is defined and has the correct GCM

*/
manifestCheck_(): any;
manifestCheck_(): Promise<void>;
/**
* Request permission if it is not currently granted
* @export
* @returns {Promise} Resolves if the permission was granted, otherwise
* rejects
*
* @return Resolves if the permission was granted, otherwise rejects
*/
requestPermission(): Promise<{}>;
requestPermission(): Promise<void>;
/**
* This method allows a developer to override the default service worker and
* instead use a custom service worker.
* @export
* @param {!ServiceWorkerRegistration} registration The service worker
* registration that should be used to receive the push messages.
*
* @param registration The service worker registration that should be used to
* receive the push messages.
*/
useServiceWorker(registration: any): void;
useServiceWorker(registration: ServiceWorkerRegistration): void;
/**
* This method allows a developer to override the default vapid key
* and instead use a custom VAPID public key.
* @export
* @param {!string} publicKey A URL safe base64 encoded string.
*
* @param publicKey A URL safe base64 encoded string.
*/
usePublicVapidKey(publicKey: any): void;
usePublicVapidKey(publicKey: string): void;
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver An observer object
* or a function triggered on message.
* @param {function(!Error)=} optError Optional A function triggered on
* message error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on
* message.
* @param error A function triggered on message error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
onMessage(nextOrObserver: any, optError?: any, optCompleted?: any): () => void;
onMessage(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): Unsubscribe;
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on token
* refresh.
* @param error A function triggered on token refresh error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
onTokenRefresh(nextOrObserver: any, optError: any, optCompleted: any): () => void;
onTokenRefresh(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): Unsubscribe;
/**
* Given a registration, wait for the service worker it relates to
* become activer
* @private
* @param {ServiceWorkerRegistration} registration Registration to wait
* for service worker to become active
* @return {Promise<!ServiceWorkerRegistration>} Wait for service worker
* registration to become active
* @param registration Registration to wait for service worker to become active
* @return Wait for service worker registration to become active
*/
waitForRegistrationToActivate_(registration: any): Promise<ServiceWorkerRegistration>;
waitForRegistrationToActivate_(registration: ServiceWorkerRegistration): Promise<ServiceWorkerRegistration>;
/**
* This will regiater the default service worker and return the registration
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* This will register the default service worker and return the registration
* @return The service worker registration to be used for the push service.
*/

@@ -101,3 +106,2 @@ getSWRegistration_(): Promise<ServiceWorkerRegistration>;

* provided by the developer.
* @private
*/

@@ -109,4 +113,2 @@ getPublicVapidKey_(): Promise<Uint8Array>;

* events in the page.
*
* @private
*/

@@ -116,6 +118,5 @@ setupSWMessageListener_(): void;

* Checks to see if the required API's are valid or not.
* @private
* @return {boolean} Returns true if the desired APIs are available.
* @return Returns true if the desired APIs are available.
*/
isSupported_(): boolean;
}

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,13 +17,11 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var controller_interface_1 = require("./controller-interface");
var util_1 = require("@firebase/util");
var base64_to_array_buffer_1 = require("../helpers/base64-to-array-buffer");
var default_sw_1 = require("../models/default-sw");
var errors_1 = require("../models/errors");
var worker_page_message_1 = require("../models/worker-page-message");
var default_sw_1 = require("../models/default-sw");
var notification_permission_1 = require("../models/notification-permission");
var fcm_details_1 = require("../models/fcm-details");
var base64_to_array_buffer_1 = require("../helpers/base64-to-array-buffer");
var util_1 = require("@firebase/util");
var WorkerPageMessage = require("../models/worker-page-message");
var controller_interface_1 = require("./controller-interface");
var WindowController = /** @class */ (function (_super) {

@@ -32,6 +31,8 @@ tslib_1.__extends(WindowController, _super);

* A service that provides a MessagingService instance.
* @param {!firebase.app.App} app
*/
function WindowController(app) {
var _this = _super.call(this, app) || this;
_this.registrationToUse_ = null;
_this.publicVapidKeyToUse_ = null;
_this.manifestCheckPromise_ = null;
_this.messageObserver_ = null;

@@ -45,32 +46,2 @@ _this.onMessage_ = util_1.createSubscribe(function (observer) {

});
/**
* @private
* @type {ServiceWorkerRegistration}
*/
_this.registrationToUse_;
/**
* @private
* @type {Promise}
*/
_this.manifestCheckPromise_;
/**
* @private
* @type {firebase.Observer}
*/
_this.messageObserver_ = null;
/**
* @private {!firebase.Subscribe} The subscribe function to the onMessage
* observer.
*/
_this.onMessage_ = util_1.createSubscribe(function (observer) {
_this.messageObserver_ = observer;
});
/**
* @private
* @type {firebase.Observer}
*/
_this.tokenRefreshObserver_ = null;
_this.onTokenRefresh_ = util_1.createSubscribe(function (observer) {
_this.tokenRefreshObserver_ = observer;
});
_this.setupSWMessageListener_();

@@ -84,5 +55,5 @@ return _this;

* possible to generate a token.
* @export
* @return {Promise<string> | Promise<null>} Returns a promise the
* resolves to an FCM token or null if permission isn't granted.
*
* @return Returns a promise that resolves to an FCM token or null if
* permission isn't granted.
*/

@@ -140,5 +111,4 @@ WindowController.prototype.getToken = function () {

* Request permission if it is not currently granted
* @export
* @returns {Promise} Resolves if the permission was granted, otherwise
* rejects
*
* @return Resolves if the permission was granted, otherwise rejects
*/

@@ -149,3 +119,3 @@ WindowController.prototype.requestPermission = function () {

return tslib_1.__generator(this, function (_a) {
if (Notification.permission === notification_permission_1.NotificationPermission.GRANTED) {
if (Notification.permission === 'granted') {
return [2 /*return*/];

@@ -155,6 +125,6 @@ }

var managePermissionResult = function (result) {
if (result === notification_permission_1.NotificationPermission.GRANTED) {
if (result === 'granted') {
return resolve();
}
else if (result === notification_permission_1.NotificationPermission.DENIED) {
else if (result === 'denied') {
return reject(_this.errorFactory_.create(errors_1.ERROR_CODES.PERMISSION_BLOCKED));

@@ -181,5 +151,5 @@ }

* instead use a custom service worker.
* @export
* @param {!ServiceWorkerRegistration} registration The service worker
* registration that should be used to receive the push messages.
*
* @param registration The service worker registration that should be used to
* receive the push messages.
*/

@@ -190,3 +160,3 @@ WindowController.prototype.useServiceWorker = function (registration) {

}
if (typeof this.registrationToUse_ !== 'undefined') {
if (this.registrationToUse_ != null) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.USE_SW_BEFORE_GET_TOKEN);

@@ -199,4 +169,4 @@ }

* and instead use a custom VAPID public key.
* @export
* @param {!string} publicKey A URL safe base64 encoded string.
*
* @param publicKey A URL safe base64 encoded string.
*/

@@ -207,3 +177,3 @@ WindowController.prototype.usePublicVapidKey = function (publicKey) {

}
if (typeof this.publicVapidKeyToUse_ !== 'undefined') {
if (this.publicVapidKeyToUse_ != null) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.USE_PUBLIC_KEY_BEFORE_GET_TOKEN);

@@ -219,25 +189,30 @@ }

* @export
* @param {!firebase.Observer|function(*)} nextOrObserver An observer object
* or a function triggered on message.
* @param {function(!Error)=} optError Optional A function triggered on
* message error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on
* message.
* @param error A function triggered on message error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
WindowController.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {
return this.onMessage_(nextOrObserver, optError, optCompleted);
WindowController.prototype.onMessage = function (nextOrObserver, error, completed) {
if (typeof nextOrObserver === 'function') {
return this.onMessage_(nextOrObserver, error, completed);
}
else {
return this.onMessage_(nextOrObserver);
}
};
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on token
* refresh.
* @param error A function triggered on token refresh error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
WindowController.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {
return this.onTokenRefresh_(nextOrObserver, optError, optCompleted);
WindowController.prototype.onTokenRefresh = function (nextOrObserver, error, completed) {
if (typeof nextOrObserver === 'function') {
return this.onTokenRefresh_(nextOrObserver, error, completed);
}
else {
return this.onTokenRefresh_(nextOrObserver);
}
};

@@ -247,8 +222,7 @@ /**

* become activer
* @private
* @param {ServiceWorkerRegistration} registration Registration to wait
* for service worker to become active
* @return {Promise<!ServiceWorkerRegistration>} Wait for service worker
* registration to become active
* @param registration Registration to wait for service worker to become active
* @return Wait for service worker registration to become active
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.waitForRegistrationToActivate_ = function (registration) {

@@ -290,6 +264,4 @@ var _this = this;

/**
* This will regiater the default service worker and return the registration
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* This will register the default service worker and return the registration
* @return The service worker registration to be used for the push service.
*/

@@ -327,3 +299,2 @@ WindowController.prototype.getSWRegistration_ = function () {

* provided by the developer.
* @private
*/

@@ -340,5 +311,5 @@ WindowController.prototype.getPublicVapidKey_ = function () {

* events in the page.
*
* @private
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.setupSWMessageListener_ = function () {

@@ -350,3 +321,3 @@ var _this = this;

navigator.serviceWorker.addEventListener('message', function (event) {
if (!event.data || !event.data[worker_page_message_1.default.PARAMS.TYPE_OF_MSG]) {
if (!event.data || !event.data[WorkerPageMessage.PARAMS.TYPE_OF_MSG]) {
// Not a message from FCM

@@ -356,6 +327,6 @@ return;

var workerPageMessage = event.data;
switch (workerPageMessage[worker_page_message_1.default.PARAMS.TYPE_OF_MSG]) {
case worker_page_message_1.default.TYPES_OF_MSG.PUSH_MSG_RECEIVED:
case worker_page_message_1.default.TYPES_OF_MSG.NOTIFICATION_CLICKED:
var pushMessage = workerPageMessage[worker_page_message_1.default.PARAMS.DATA];
switch (workerPageMessage[WorkerPageMessage.PARAMS.TYPE_OF_MSG]) {
case WorkerPageMessage.TYPES_OF_MSG.PUSH_MSG_RECEIVED:
case WorkerPageMessage.TYPES_OF_MSG.NOTIFICATION_CLICKED:
var pushMessage = workerPageMessage[WorkerPageMessage.PARAMS.DATA];
if (_this.messageObserver_) {

@@ -373,5 +344,6 @@ _this.messageObserver_.next(pushMessage);

* Checks to see if the required API's are valid or not.
* @private
* @return {boolean} Returns true if the desired APIs are available.
* @return Returns true if the desired APIs are available.
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.isSupported_ = function () {

@@ -378,0 +350,0 @@ return ('serviceWorker' in navigator &&

@@ -1,1 +0,1 @@

export declare function arrayBufferToBase64(arrayBuffer: any): string;
export declare function arrayBufferToBase64(arrayBuffer: ArrayBuffer | Uint8Array): string;

@@ -20,3 +20,3 @@ "use strict";

var uint8Version = new Uint8Array(arrayBuffer);
return window.btoa(String.fromCharCode.apply(null, uint8Version));
return btoa(String.fromCharCode.apply(null, uint8Version));
}

@@ -23,0 +23,0 @@ function arrayBufferToBase64(arrayBuffer) {

@@ -16,2 +16,2 @@ /**

*/
export declare function base64ToArrayBuffer(base64String: any): Uint8Array;
export declare function base64ToArrayBuffer(base64String: string): Uint8Array;

@@ -1,2 +0,1 @@

declare function cleanV1(): void;
export { cleanV1 };
export declare function cleanV1(): void;

@@ -0,29 +1,50 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ErrorFactory } from '@firebase/util';
export declare class DBInterface {
private DB_NAME_;
private dbVersion_;
private openDbPromise_;
protected errorFactory_: ErrorFactory<string>;
protected TRANSACTION_READ_WRITE: IDBTransactionMode;
export declare abstract class DBInterface {
private dbPromise;
protected readonly abstract dbName: string;
protected readonly abstract dbVersion: number;
protected readonly abstract objectStoreName: string;
protected readonly errorFactory: ErrorFactory<string>;
/**
* @param {string} dbName
* @param {number} dbVersion
* Database initialization.
*
* This function should create and update object stores.
*/
constructor(dbName: any, dbVersion: any);
protected abstract onDbUpgrade(request: IDBOpenDBRequest, event: IDBVersionChangeEvent): void;
/** Gets record(s) from the objectStore that match the given key. */
get<T>(key: IDBValidKey): Promise<T | undefined>;
/** Gets record(s) from the objectStore that match the given index. */
getIndex<T>(index: string, key: IDBValidKey): Promise<T | undefined>;
/** Assigns or overwrites the record for the given value. */
put(value: any): Promise<void>;
/** Deletes record(s) from the objectStore that match the given key. */
delete(key: IDBValidKey | IDBKeyRange): Promise<void>;
/**
* Get the indexedDB as a promsie.
* @protected
* @return {!Promise<!IDBDatabase>} The IndexedDB database
*/
openDatabase(): Promise<IDBDatabase>;
/**
* Close the currently open database.
* @return {!Promise} Returns the result of the promise chain.
*/
closeDatabase(): Promise<void>;
/**
* @protected
* @param {!IDBDatabase} db
* Creates an IndexedDB Transaction and passes its objectStore to the
* runRequest function, which runs the database request.
*
* @return Promise that resolves with the result of the runRequest function
*/
onDBUpgrade(db: IDBDatabase, event: IDBVersionChangeEvent): void;
private createTransaction<T>(runRequest, mode?);
/** Gets the cached db connection or opens a new one. */
private getDb();
}

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,76 +17,117 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var util_1 = require("@firebase/util");
var errors_1 = require("./errors");
var DBInterface = /** @class */ (function () {
/**
* @param {string} dbName
* @param {number} dbVersion
*/
function DBInterface(dbName, dbVersion) {
this.errorFactory_ = new util_1.ErrorFactory('messaging', 'Messaging', errors_1.ERROR_MAP);
this.DB_NAME_ = dbName;
this.dbVersion_ = dbVersion;
this.openDbPromise_ = null;
this.TRANSACTION_READ_WRITE = 'readwrite';
function DBInterface() {
this.dbPromise = null;
this.errorFactory = new util_1.ErrorFactory('messaging', 'Messaging', errors_1.ERROR_MAP);
}
/**
* Get the indexedDB as a promsie.
* @protected
* @return {!Promise<!IDBDatabase>} The IndexedDB database
*/
DBInterface.prototype.openDatabase = function () {
var _this = this;
if (this.openDbPromise_) {
return this.openDbPromise_;
/** Gets record(s) from the objectStore that match the given key. */
DBInterface.prototype.get = function (key) {
return this.createTransaction(function (objectStore) { return objectStore.get(key); });
};
/** Gets record(s) from the objectStore that match the given index. */
DBInterface.prototype.getIndex = function (index, key) {
function runRequest(objectStore) {
var idbIndex = objectStore.index(index);
return idbIndex.get(key);
}
this.openDbPromise_ = new Promise(function (resolve, reject) {
var request = indexedDB.open(_this.DB_NAME_, _this.dbVersion_);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve(event.target.result);
};
request.onupgradeneeded = function (event) {
try {
var db = event.target.result;
_this.onDBUpgrade(db, event);
}
catch (err) {
// close the database as it can't be used.
db.close();
reject(err);
}
};
});
return this.openDbPromise_;
return this.createTransaction(runRequest);
};
/** Assigns or overwrites the record for the given value. */
// tslint:disable-next-line:no-any IndexedDB values are of type "any"
DBInterface.prototype.put = function (value) {
return this.createTransaction(function (objectStore) { return objectStore.put(value); }, 'readwrite');
};
/** Deletes record(s) from the objectStore that match the given key. */
DBInterface.prototype.delete = function (key) {
return this.createTransaction(function (objectStore) { return objectStore.delete(key); }, 'readwrite');
};
/**
* Close the currently open database.
* @return {!Promise} Returns the result of the promise chain.
*/
DBInterface.prototype.closeDatabase = function () {
var _this = this;
return Promise.resolve().then(function () {
if (_this.openDbPromise_) {
return _this.openDbPromise_.then(function (db) {
db.close();
_this.openDbPromise_ = null;
});
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.dbPromise) return [3 /*break*/, 2];
return [4 /*yield*/, this.dbPromise];
case 1:
db = _a.sent();
db.close();
this.dbPromise = null;
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
/**
* @protected
* @param {!IDBDatabase} db
* Creates an IndexedDB Transaction and passes its objectStore to the
* runRequest function, which runs the database request.
*
* @return Promise that resolves with the result of the runRequest function
*/
DBInterface.prototype.onDBUpgrade = function (db, event) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.SHOULD_BE_INHERITED);
DBInterface.prototype.createTransaction = function (runRequest, mode) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction, request, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getDb()];
case 1:
db = _a.sent();
transaction = db.transaction(this.objectStoreName, mode);
request = transaction.objectStore(this.objectStoreName);
return [4 /*yield*/, promisify(runRequest(request))];
case 2:
result = _a.sent();
return [2 /*return*/, new Promise(function (resolve, reject) {
transaction.oncomplete = function () {
resolve(result);
};
transaction.onerror = function () {
reject(transaction.error);
};
})];
}
});
});
};
/** Gets the cached db connection or opens a new one. */
DBInterface.prototype.getDb = function () {
var _this = this;
if (!this.dbPromise) {
this.dbPromise = new Promise(function (resolve, reject) {
var request = indexedDB.open(_this.dbName, _this.dbVersion);
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
_this.dbPromise = null;
reject(request.error);
};
request.onupgradeneeded = function (event) { return _this.onDbUpgrade(request, event); };
});
}
return this.dbPromise;
};
return DBInterface;
}());
exports.DBInterface = DBInterface;
/** Promisifies an IDBRequest. Resolves with the IDBRequest's result. */
function promisify(request) {
return new Promise(function (resolve, reject) {
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
reject(request.error);
};
});
}
//# sourceMappingURL=db-interface.js.map

@@ -0,2 +1,17 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const DEFAULT_SW_PATH = "/firebase-messaging-sw.js";
export declare const DEFAULT_SW_SCOPE = "/firebase-cloud-messaging-push-scope";

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,3 +17,2 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });

@@ -19,0 +19,0 @@ exports.DEFAULT_SW_PATH = '/firebase-messaging-sw.js';

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const ERROR_CODES: {

@@ -2,0 +17,0 @@ AVAILABLE_IN_WINDOW: string;

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,3 +17,2 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });

@@ -19,0 +19,0 @@ exports.ERROR_CODES = {

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const DEFAULT_PUBLIC_VAPID_KEY: Uint8Array;

@@ -2,0 +17,0 @@ export declare const SUBSCRIPTION_DETAILS: {

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,3 +17,2 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });

@@ -19,0 +19,0 @@ exports.DEFAULT_PUBLIC_VAPID_KEY = new Uint8Array([

@@ -0,15 +1,10 @@

export interface IIDDetails {
token: string;
pushSet: string;
}
export declare class IIDModel {
private errorFactory_;
private readonly errorFactory_;
constructor();
getToken(senderId: string, subscription: PushSubscription, publicVapidKey: Uint8Array): Promise<IIDDetails>;
/**
* Given a PushSubscription and messagingSenderId, get an FCM token.
* @public
* @param {string} senderId The 'messagingSenderId' to tie the token to.
* @param {PushSubscription} subscription The PushSusbcription to "federate".
* @param {Uint8Array} publicVapidKey The public VAPID key.
* @return {Promise<!Object>} Returns the FCM token to be used in place
* of the PushSubscription.
*/
getToken(senderId: any, subscription: any, publicVapidKey: any): Promise<Object>;
/**
* Update the underlying token details for fcmToken.

@@ -16,0 +11,0 @@ */

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,8 +17,9 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var util_1 = require("@firebase/util");
var array_buffer_to_base64_1 = require("../helpers/array-buffer-to-base64");
var errors_1 = require("./errors");
var array_buffer_to_base64_1 = require("../helpers/array-buffer-to-base64");
var fcm_details_1 = require("./fcm-details");
// tslint:enable interface-name
var IIDModel = /** @class */ (function () {

@@ -27,53 +29,58 @@ function IIDModel() {

}
/**
* Given a PushSubscription and messagingSenderId, get an FCM token.
* @public
* @param {string} senderId The 'messagingSenderId' to tie the token to.
* @param {PushSubscription} subscription The PushSusbcription to "federate".
* @param {Uint8Array} publicVapidKey The public VAPID key.
* @return {Promise<!Object>} Returns the FCM token to be used in place
* of the PushSubscription.
*/
IIDModel.prototype.getToken = function (senderId, subscription, publicVapidKey) {
var _this = this;
var p256dh = array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('p256dh'));
var auth = array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('auth'));
var fcmSubscribeBody = "authorized_entity=" + senderId + "&" +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY) {
var applicationPubKey = array_buffer_to_base64_1.arrayBufferToBase64(publicVapidKey);
fcmSubscribeBody += "&application_pub_key=" + applicationPubKey;
}
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var subscribeOptions = {
method: 'POST',
headers: headers,
body: fcmSubscribeBody
};
return fetch(fcm_details_1.ENDPOINT + '/fcm/connect/subscribe', subscribeOptions)
.then(function (response) { return response.json(); })
.catch(function () {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_FAILED);
})
.then(function (response) {
var fcmTokenResponse = response;
if (fcmTokenResponse['error']) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_FAILED, {
message: message
});
}
if (!fcmTokenResponse['token']) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_NO_TOKEN);
}
if (!fcmTokenResponse['pushSet']) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET);
}
return {
token: fcmTokenResponse['token'],
pushSet: fcmTokenResponse['pushSet']
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
var p256dh, auth, fcmSubscribeBody, applicationPubKey, headers, subscribeOptions, responseData, response, err_1, message;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
p256dh = array_buffer_to_base64_1.arrayBufferToBase64(subscription.getKey('p256dh'));
auth = array_buffer_to_base64_1.arrayBufferToBase64(subscription.getKey('auth'));
fcmSubscribeBody = "authorized_entity=" + senderId + "&" +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY) {
applicationPubKey = array_buffer_to_base64_1.arrayBufferToBase64(publicVapidKey);
fcmSubscribeBody += "&application_pub_key=" + applicationPubKey;
}
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
subscribeOptions = {
method: 'POST',
headers: headers,
body: fcmSubscribeBody
};
responseData = null;
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(fcm_details_1.ENDPOINT + '/fcm/connect/subscribe', subscribeOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
return [3 /*break*/, 5];
case 4:
err_1 = _a.sent();
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_FAILED);
case 5:
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_FAILED, {
message: message
});
}
if (!responseData['token']) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_NO_TOKEN);
}
if (!responseData['pushSet']) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET);
}
return [2 /*return*/, {
token: responseData['token'],
pushSet: responseData['pushSet']
}];
}
});
});

@@ -85,42 +92,53 @@ };

IIDModel.prototype.updateToken = function (senderId, fcmToken, fcmPushSet, subscription, publicVapidKey) {
var _this = this;
var p256dh = array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('p256dh'));
var auth = array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('auth'));
var fcmUpdateBody = "push_set=" + fcmPushSet + "&" +
("token=" + fcmToken + "&") +
("authorized_entity=" + senderId + "&") +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY) {
var applicationPubKey = array_buffer_to_base64_1.arrayBufferToBase64(publicVapidKey);
fcmUpdateBody += "&application_pub_key=" + applicationPubKey;
}
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var updateOptions = {
method: 'POST',
headers: headers,
body: fcmUpdateBody
};
var updateFetchRes;
return fetch(fcm_details_1.ENDPOINT + '/fcm/connect/subscribe', updateOptions)
.then(function (fetchResponse) {
updateFetchRes = fetchResponse;
return fetchResponse.json();
})
.catch(function () {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_FAILED);
})
.then(function (fcmTokenResponse) {
if (!updateFetchRes.ok) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_FAILED, {
message: message
});
}
if (!fcmTokenResponse['token']) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_NO_TOKEN);
}
return fcmTokenResponse['token'];
return tslib_1.__awaiter(this, void 0, void 0, function () {
var p256dh, auth, fcmUpdateBody, applicationPubKey, headers, updateOptions, responseData, response, err_2, message;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
p256dh = array_buffer_to_base64_1.arrayBufferToBase64(subscription.getKey('p256dh'));
auth = array_buffer_to_base64_1.arrayBufferToBase64(subscription.getKey('auth'));
fcmUpdateBody = "push_set=" + fcmPushSet + "&" +
("token=" + fcmToken + "&") +
("authorized_entity=" + senderId + "&") +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== fcm_details_1.DEFAULT_PUBLIC_VAPID_KEY) {
applicationPubKey = array_buffer_to_base64_1.arrayBufferToBase64(publicVapidKey);
fcmUpdateBody += "&application_pub_key=" + applicationPubKey;
}
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
updateOptions = {
method: 'POST',
headers: headers,
body: fcmUpdateBody
};
responseData = null;
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(fcm_details_1.ENDPOINT + '/fcm/connect/subscribe', updateOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
return [3 /*break*/, 5];
case 4:
err_2 = _a.sent();
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_FAILED);
case 5:
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_FAILED, {
message: message
});
}
if (!responseData['token']) {
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UPDATE_NO_TOKEN);
}
return [2 /*return*/, responseData['token']];
}
});
});

@@ -132,26 +150,39 @@ };

IIDModel.prototype.deleteToken = function (senderId, fcmToken, fcmPushSet) {
var _this = this;
var fcmUnsubscribeBody = "authorized_entity=" + senderId + "&" +
("token=" + fcmToken + "&") +
("pushSet=" + fcmPushSet);
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var unsubscribeOptions = {
method: 'POST',
headers: headers,
body: fcmUnsubscribeBody
};
return fetch(fcm_details_1.ENDPOINT + '/fcm/connect/unsubscribe', unsubscribeOptions).then(function (fetchResponse) {
if (!fetchResponse.ok) {
return fetchResponse.json().then(function (fcmTokenResponse) {
if (fcmTokenResponse['error']) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED, {
message: message
});
}
}, function (err) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED);
});
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var fcmUnsubscribeBody, headers, unsubscribeOptions, response, responseData, message, err_3;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
fcmUnsubscribeBody = "authorized_entity=" + senderId + "&" +
("token=" + fcmToken + "&") +
("pushSet=" + fcmPushSet);
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
unsubscribeOptions = {
method: 'POST',
headers: headers,
body: fcmUnsubscribeBody
};
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(fcm_details_1.ENDPOINT + '/fcm/connect/unsubscribe', unsubscribeOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED, {
message: message
});
}
return [3 /*break*/, 5];
case 4:
err_3 = _a.sent();
throw this.errorFactory_.create(errors_1.ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED);
case 5: return [2 /*return*/];
}
});
});

@@ -158,0 +189,0 @@ };

@@ -0,43 +1,31 @@

import { TokenDetails } from '../interfaces/token-details';
import { DBInterface } from './db-interface';
export declare class TokenDetailsModel extends DBInterface {
constructor();
onDBUpgrade(db: IDBDatabase, evt: IDBVersionChangeEvent): void;
protected readonly dbName: string;
protected readonly dbVersion: number;
protected readonly objectStoreName: string;
protected onDbUpgrade(request: IDBOpenDBRequest, event: IDBVersionChangeEvent): void;
/**
* This method takes an object and will check for known arguments and
* validate the input.
* @private
* @param {!ValidateInput} input
* @return {!Promise} Returns promise that resolves if input is valid,
* rejects otherwise.
* @return Promise that resolves if input is valid, rejects otherwise.
*/
validateInputs_(input: any): Promise<never>;
private validateInputs(input);
/**
* Given a token, this method will look up the details in indexedDB.
* @param {string} fcmToken
* @return {Promise<Object>} The details associated with that token.
* @return {Promise<TokenDetails>} The details associated with that token.
*/
getTokenDetailsFromToken(fcmToken: any): Promise<{}>;
getTokenDetailsFromToken(fcmToken: string): Promise<TokenDetails | undefined>;
/**
* Given a service worker scope, this method will look up the details in
* indexedDB.
* @public
* @param {string} swScope
* @return {Promise<Object>} The details associated with that token.
* @return The details associated with that token.
*/
getTokenDetailsFromSWScope(swScope: any): Promise<{}>;
getTokenDetailsFromSWScope(swScope: string): Promise<TokenDetails | undefined>;
/**
* Save the details for the fcm token for re-use at a later date.
* @param {{swScope: !string, vapidKey: !string,
* subscription: !PushSubscription, fcmSenderId: !string, fcmToken: !string,
* fcmPushSet: !string}} input A plain js object containing args to save.
* @return {Promise<void>}
* @param input A plain js object containing args to save.
*/
saveTokenDetails({swScope, vapidKey, subscription, fcmSenderId, fcmToken, fcmPushSet}: {
swScope: any;
vapidKey: any;
subscription: any;
fcmSenderId: any;
fcmToken: any;
fcmPushSet: any;
}): Promise<{}>;
saveTokenDetails(tokenDetails: TokenDetails): Promise<void>;
/**

@@ -47,6 +35,7 @@ * This method deletes details of the current FCM token.

* method for deleting at a later date.
* @return {Promise<Object>} Resolves once the FCM token details have been
* deleted and returns the deleted details.
*
* @return Resolves once the FCM token details have been deleted and returns
* the deleted details.
*/
deleteToken(token: string): Promise<{}>;
deleteToken(token: string): Promise<TokenDetails>;
}

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,51 +17,64 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var tslib_1 = require("tslib");
var base64_to_array_buffer_1 = require("../helpers/base64-to-array-buffer");
var clean_v1_undefined_1 = require("./clean-v1-undefined");
var db_interface_1 = require("./db-interface");
var errors_1 = require("./errors");
var array_buffer_to_base64_1 = require("../helpers/array-buffer-to-base64");
var clean_v1_undefined_1 = require("./clean-v1-undefined");
var FCM_TOKEN_OBJ_STORE = 'fcm_token_object_Store';
var DB_NAME = 'fcm_token_details_db';
var DB_VERSION = 2;
/** @record */
function ValidateInput() { }
/** @type {string|undefined} */
ValidateInput.prototype.fcmToken;
/** @type {string|undefined} */
ValidateInput.prototype.swScope;
/** @type {string|undefined} */
ValidateInput.prototype.vapidKey;
/** @type {PushSubscription|undefined} */
ValidateInput.prototype.subscription;
/** @type {string|undefined} */
ValidateInput.prototype.fcmSenderId;
/** @type {string|undefined} */
ValidateInput.prototype.fcmPushSet;
var TokenDetailsModel = /** @class */ (function (_super) {
tslib_1.__extends(TokenDetailsModel, _super);
function TokenDetailsModel() {
return _super.call(this, DB_NAME, DB_VERSION) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.dbName = 'fcm_token_details_db';
_this.dbVersion = 3;
_this.objectStoreName = 'fcm_token_object_Store';
return _this;
}
TokenDetailsModel.prototype.onDBUpgrade = function (db, evt) {
if (evt.oldVersion < 1) {
// New IDB instance
var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, {
keyPath: 'swScope'
});
// Make sure the sender ID can be searched
objectStore.createIndex('fcmSenderId', 'fcmSenderId', {
unique: false
});
objectStore.createIndex('fcmToken', 'fcmToken', {
unique: true
});
TokenDetailsModel.prototype.onDbUpgrade = function (request, event) {
var db = request.result;
// Lack of 'break' statements is intentional.
switch (event.oldVersion) {
case 0: {
// New IDB instance
var objectStore = db.createObjectStore(this.objectStoreName, {
keyPath: 'swScope'
});
// Make sure the sender ID can be searched
objectStore.createIndex('fcmSenderId', 'fcmSenderId', {
unique: false
});
objectStore.createIndex('fcmToken', 'fcmToken', { unique: true });
}
case 1: {
// Prior to version 2, we were using either 'fcm_token_details_db'
// or 'undefined' as the database name due to bug in the SDK
// So remove the old tokens and databases.
clean_v1_undefined_1.cleanV1();
}
case 2: {
var objectStore = request.transaction.objectStore(this.objectStoreName);
var cursorRequest_1 = objectStore.openCursor();
cursorRequest_1.onsuccess = function () {
var cursor = cursorRequest_1.result;
if (cursor) {
var value = cursor.value;
var newValue = tslib_1.__assign({}, value);
if (!value.createTime) {
newValue.createTime = Date.now();
}
if (typeof value.vapidKey === 'string') {
newValue.vapidKey = base64_to_array_buffer_1.base64ToArrayBuffer(value.vapidKey);
}
if (typeof value.auth === 'string') {
newValue.auth = base64_to_array_buffer_1.base64ToArrayBuffer(value.auth).buffer;
}
if (typeof value.auth === 'string') {
newValue.p256dh = base64_to_array_buffer_1.base64ToArrayBuffer(value.p256dh).buffer;
}
cursor.update(newValue);
cursor.continue();
}
};
}
}
if (evt.oldVersion < 2) {
// Prior to version 2, we were using either 'fcm_token_details_db'
// or 'undefined' as the database name due to bug in the SDK
// So remove the old tokens and databases.
clean_v1_undefined_1.cleanV1();
}
};

@@ -70,46 +84,48 @@ /**

* validate the input.
* @private
* @param {!ValidateInput} input
* @return {!Promise} Returns promise that resolves if input is valid,
* rejects otherwise.
* @return Promise that resolves if input is valid, rejects otherwise.
*/
TokenDetailsModel.prototype.validateInputs_ = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (input.fcmToken) {
if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_TOKEN))];
}
}
if (input.swScope) {
if (typeof input.swScope !== 'string' || input.swScope.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SCOPE))];
}
}
if (input.vapidKey) {
if (!(input.vapidKey instanceof Uint8Array) ||
input.vapidKey.length !== 65) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_VAPID_KEY))];
}
}
if (input.subscription) {
if (!(input.subscription instanceof PushSubscription)) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION))];
}
}
if (input.fcmSenderId) {
if (typeof input.fcmSenderId !== 'string' ||
input.fcmSenderId.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SENDER_ID))];
}
}
if (input.fcmPushSet) {
if (typeof input.fcmPushSet !== 'string' ||
input.fcmPushSet.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_PUSH_SET))];
}
}
return [2 /*return*/];
});
});
TokenDetailsModel.prototype.validateInputs = function (input) {
if (input.fcmToken) {
if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_TOKEN);
}
}
if (input.swScope) {
if (typeof input.swScope !== 'string' || input.swScope.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SCOPE);
}
}
if (input.vapidKey) {
if (!(input.vapidKey instanceof Uint8Array) ||
input.vapidKey.length !== 65) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_VAPID_KEY);
}
}
if (input.endpoint) {
if (typeof input.endpoint !== 'string' || input.endpoint.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.auth) {
if (!(input.auth instanceof ArrayBuffer)) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.p256dh) {
if (!(input.p256dh instanceof ArrayBuffer)) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.fcmSenderId) {
if (typeof input.fcmSenderId !== 'string' ||
input.fcmSenderId.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SENDER_ID);
}
}
if (input.fcmPushSet) {
if (typeof input.fcmPushSet !== 'string' ||
input.fcmPushSet.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_PUSH_SET);
}
}
};

@@ -119,28 +135,12 @@ /**

* @param {string} fcmToken
* @return {Promise<Object>} The details associated with that token.
* @return {Promise<TokenDetails>} The details associated with that token.
*/
TokenDetailsModel.prototype.getTokenDetailsFromToken = function (fcmToken) {
var _this = this;
if (!fcmToken) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_TOKEN));
}
return this.validateInputs_({ fcmToken: fcmToken })
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var index = objectStore.index('fcmToken');
var request = index.get(fcmToken);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
var result = event.target.result
? event.target.result
: null;
resolve(result);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!fcmToken) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_TOKEN);
}
this.validateInputs({ fcmToken: fcmToken });
return [2 /*return*/, this.getIndex('fcmToken', fcmToken)];
});

@@ -152,29 +152,12 @@ });

* indexedDB.
* @public
* @param {string} swScope
* @return {Promise<Object>} The details associated with that token.
* @return The details associated with that token.
*/
TokenDetailsModel.prototype.getTokenDetailsFromSWScope = function (swScope) {
var _this = this;
if (!swScope) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SCOPE));
}
return this.validateInputs_({ swScope: swScope })
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var scopeRequest = objectStore.get(swScope);
scopeRequest.onerror = function (event) {
reject(event.target.error);
};
scopeRequest.onsuccess = function (event) {
var result = event.target.result
? event.target.result
: null;
resolve(result);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!swScope) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SCOPE);
}
this.validateInputs({ swScope: swScope });
return [2 /*return*/, this.get(swScope)];
});

@@ -185,64 +168,27 @@ });

* Save the details for the fcm token for re-use at a later date.
* @param {{swScope: !string, vapidKey: !string,
* subscription: !PushSubscription, fcmSenderId: !string, fcmToken: !string,
* fcmPushSet: !string}} input A plain js object containing args to save.
* @return {Promise<void>}
* @param input A plain js object containing args to save.
*/
TokenDetailsModel.prototype.saveTokenDetails = function (_a) {
var _this = this;
var swScope = _a.swScope, vapidKey = _a.vapidKey, subscription = _a.subscription, fcmSenderId = _a.fcmSenderId, fcmToken = _a.fcmToken, fcmPushSet = _a.fcmPushSet;
if (!swScope) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SCOPE));
}
if (!vapidKey) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_VAPID_KEY));
}
if (!subscription) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION));
}
if (!fcmSenderId) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SENDER_ID));
}
if (!fcmToken) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_TOKEN));
}
if (!fcmPushSet) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_PUSH_SET));
}
return this.validateInputs_({
swScope: swScope,
vapidKey: vapidKey,
subscription: subscription,
fcmSenderId: fcmSenderId,
fcmToken: fcmToken,
fcmPushSet: fcmPushSet
})
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
/**
* @dict
*/
var details = {
swScope: swScope,
vapidKey: array_buffer_to_base64_1.arrayBufferToBase64(vapidKey),
endpoint: subscription.endpoint,
auth: array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('auth')),
p256dh: array_buffer_to_base64_1.arrayBufferToBase64(subscription['getKey']('p256dh')),
fcmSenderId: fcmSenderId,
fcmToken: fcmToken,
fcmPushSet: fcmPushSet,
createTime: Date.now()
};
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var request = objectStore.put(details);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve();
};
TokenDetailsModel.prototype.saveTokenDetails = function (tokenDetails) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!tokenDetails.swScope) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SCOPE);
}
if (!tokenDetails.vapidKey) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_VAPID_KEY);
}
if (!tokenDetails.endpoint || !tokenDetails.auth || !tokenDetails.p256dh) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SUBSCRIPTION);
}
if (!tokenDetails.fcmSenderId) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SENDER_ID);
}
if (!tokenDetails.fcmToken) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_TOKEN);
}
if (!tokenDetails.fcmPushSet) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_PUSH_SET);
}
this.validateInputs(tokenDetails);
return [2 /*return*/, this.put(tokenDetails)];
});

@@ -255,30 +201,26 @@ });

* method for deleting at a later date.
* @return {Promise<Object>} Resolves once the FCM token details have been
* deleted and returns the deleted details.
*
* @return Resolves once the FCM token details have been deleted and returns
* the deleted details.
*/
TokenDetailsModel.prototype.deleteToken = function (token) {
var _this = this;
if (typeof token !== 'string' || token.length === 0) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.INVALID_DELETE_TOKEN));
}
return this.getTokenDetailsFromToken(token).then(function (details) {
if (!details) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.DELETE_TOKEN_NOT_FOUND);
}
return _this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var request = objectStore.delete(details['swScope']);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
if (event.target.result === 0) {
reject(_this.errorFactory_.create(errors_1.ERROR_CODES.FAILED_TO_DELETE_TOKEN));
return;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var details;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (typeof token !== 'string' || token.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory.create(errors_1.ERROR_CODES.INVALID_DELETE_TOKEN))];
}
resolve(details);
};
});
return [4 /*yield*/, this.getTokenDetailsFromToken(token)];
case 1:
details = _a.sent();
if (!details) {
throw this.errorFactory.create(errors_1.ERROR_CODES.DELETE_TOKEN_NOT_FOUND);
}
return [4 /*yield*/, this.delete(details.swScope)];
case 2:
_a.sent();
return [2 /*return*/, details];
}
});

@@ -290,3 +232,14 @@ });

exports.TokenDetailsModel = TokenDetailsModel;
/** Promisifies an IDBRequest. Resolves with the IDBRequest's result. */
function promisify(request) {
return new Promise(function (resolve, reject) {
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
reject(request.error);
};
});
}
//# sourceMappingURL=token-details-model.js.map
import { DBInterface } from './db-interface';
export declare class VapidDetailsModel extends DBInterface {
constructor();
protected readonly dbName: string;
protected readonly dbVersion: number;
protected readonly objectStoreName: string;
protected onDbUpgrade(request: IDBOpenDBRequest): void;
/**
* @override
* @param {IDBDatabase} db
*/
onDBUpgrade(db: any): void;
/**
* Given a service worker scope, this method will look up the vapid key
* in indexedDB.
*/
getVapidFromSWScope(swScope: string): Promise<Uint8Array>;
getVapidFromSWScope(swScope: string): Promise<Uint8Array | undefined>;
/**

@@ -15,0 +13,0 @@ * Save a vapid key against a swScope for later date.

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,3 +17,2 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });

@@ -22,5 +22,2 @@ var tslib_1 = require("tslib");

var errors_1 = require("./errors");
var FCM_VAPID_OBJ_STORE = 'fcm_vapid_object_Store';
var DB_NAME = 'fcm_vapid_details_db';
var DB_VERSION = 1;
var UNCOMPRESSED_PUBLIC_KEY_SIZE = 65;

@@ -30,12 +27,11 @@ var VapidDetailsModel = /** @class */ (function (_super) {

function VapidDetailsModel() {
return _super.call(this, DB_NAME, DB_VERSION) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.dbName = 'fcm_vapid_details_db';
_this.dbVersion = 1;
_this.objectStoreName = 'fcm_vapid_object_Store';
return _this;
}
/**
* @override
* @param {IDBDatabase} db
*/
VapidDetailsModel.prototype.onDBUpgrade = function (db) {
db.createObjectStore(FCM_VAPID_OBJ_STORE, {
keyPath: 'swScope'
});
VapidDetailsModel.prototype.onDbUpgrade = function (request) {
var db = request.result;
db.createObjectStore(this.objectStoreName, { keyPath: 'swScope' });
};

@@ -47,21 +43,15 @@ /**

VapidDetailsModel.prototype.getVapidFromSWScope = function (swScope) {
if (typeof swScope !== 'string' || swScope.length === 0) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SCOPE));
}
return this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var scopeRequest = objectStore.get(swScope);
scopeRequest.onerror = function () {
reject(scopeRequest.error);
};
scopeRequest.onsuccess = function () {
var result = scopeRequest.result;
var vapidKey = null;
if (result) {
vapidKey = result.vapidKey;
}
resolve(vapidKey);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
var result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (typeof swScope !== 'string' || swScope.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SCOPE);
}
return [4 /*yield*/, this.get(swScope)];
case 1:
result = _a.sent();
return [2 /*return*/, result ? result.vapidKey : undefined];
}
});

@@ -74,24 +64,16 @@ });

VapidDetailsModel.prototype.saveVapidDetails = function (swScope, vapidKey) {
var _this = this;
if (typeof swScope !== 'string' || swScope.length === 0) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_SCOPE));
}
if (vapidKey === null || vapidKey.length !== UNCOMPRESSED_PUBLIC_KEY_SIZE) {
return Promise.reject(this.errorFactory_.create(errors_1.ERROR_CODES.BAD_VAPID_KEY));
}
var details = {
swScope: swScope,
vapidKey: vapidKey
};
return this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var request = objectStore.put(details);
request.onerror = function () {
reject(request.error);
return tslib_1.__awaiter(this, void 0, void 0, function () {
var details;
return tslib_1.__generator(this, function (_a) {
if (typeof swScope !== 'string' || swScope.length === 0) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_SCOPE);
}
if (vapidKey === null || vapidKey.length !== UNCOMPRESSED_PUBLIC_KEY_SIZE) {
throw this.errorFactory.create(errors_1.ERROR_CODES.BAD_VAPID_KEY);
}
details = {
swScope: swScope,
vapidKey: vapidKey
};
request.onsuccess = function () {
resolve();
};
return [2 /*return*/, this.put(details)];
});

@@ -106,23 +88,17 @@ });

VapidDetailsModel.prototype.deleteVapidDetails = function (swScope) {
var _this = this;
return this.getVapidFromSWScope(swScope).then(function (vapidKey) {
if (!vapidKey) {
throw _this.errorFactory_.create(errors_1.ERROR_CODES.DELETE_SCOPE_NOT_FOUND);
}
return _this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var request = objectStore.delete(swScope);
request.onerror = function () {
reject(request.error);
};
request.onsuccess = function () {
if (request.result === 0) {
reject(_this.errorFactory_.create(errors_1.ERROR_CODES.FAILED_DELETE_VAPID_KEY));
return;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var vapidKey;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getVapidFromSWScope(swScope)];
case 1:
vapidKey = _a.sent();
if (!vapidKey) {
throw this.errorFactory.create(errors_1.ERROR_CODES.DELETE_SCOPE_NOT_FOUND);
}
resolve(vapidKey);
};
});
return [4 /*yield*/, this.delete(swScope)];
case 2:
_a.sent();
return [2 /*return*/, vapidKey];
}
});

@@ -129,0 +105,0 @@ });

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const PARAMS: {

@@ -5,15 +20,8 @@ TYPE_OF_MSG: string;

};
declare const _default: {
PARAMS: {
TYPE_OF_MSG: string;
DATA: string;
};
TYPES_OF_MSG: {
PUSH_MSG_RECEIVED: string;
NOTIFICATION_CLICKED: string;
};
createNewMsg: (msgType: any, msgData: any) => {
[x: string]: any;
};
export declare const TYPES_OF_MSG: {
PUSH_MSG_RECEIVED: string;
NOTIFICATION_CLICKED: string;
};
export default _default;
export declare function createNewMsg(msgType: any, msgData: any): {
[key: string]: any;
};

@@ -0,1 +1,2 @@

"use strict";
/**

@@ -16,3 +17,2 @@ * Copyright 2017 Google Inc.

*/
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });

@@ -27,20 +27,15 @@ // These fields are strings to prevent closure from thinking goog.getMsg

// expects the variable to be defined via goog.getMsg
var msgType = {
exports.TYPES_OF_MSG = {
PUSH_MSG_RECEIVED: 'push-msg-received',
NOTIFICATION_CLICKED: 'notification-clicked'
};
var createNewMsg = function (msgType, msgData) {
var message = (_a = {},
function createNewMsg(msgType, msgData) {
return _a = {},
_a[exports.PARAMS.TYPE_OF_MSG] = msgType,
_a[exports.PARAMS.DATA] = msgData,
_a);
return message;
_a;
var _a;
};
exports.default = {
PARAMS: exports.PARAMS,
TYPES_OF_MSG: msgType,
createNewMsg: createNewMsg
};
}
exports.createNewMsg = createNewMsg;
//# sourceMappingURL=worker-page-message.js.map

@@ -0,3 +1,4 @@

import { _FirebaseNamespace } from '@firebase/app-types/private';
import * as types from '@firebase/messaging-types';
export declare function registerMessaging(instance: any): void;
export declare function registerMessaging(instance: _FirebaseNamespace): void;
/**

@@ -4,0 +5,0 @@ * Define extension behavior of `registerMessaging`

@@ -16,6 +16,5 @@ /**

*/
'use strict';
import { firebase } from '@firebase/app';
import { SWController } from './src/controllers/sw-controller';
import { WindowController } from './src/controllers/window-controller';
import { SWController } from './src/controllers/sw-controller';
import { firebase } from '@firebase/app';
export function registerMessaging(instance) {

@@ -22,0 +21,0 @@ var messagingName = 'messaging';

@@ -0,18 +1,34 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { ErrorFactory, NextFn, PartialObserver } from '@firebase/util';
import { IIDModel } from '../models/iid-model';
import { TokenDetailsModel } from '../models/token-details-model';
import { VapidDetailsModel } from '../models/vapid-details-model';
import { IIDModel } from '../models/iid-model';
export declare const TOKEN_EXPIRATION_MILLIS: number;
export declare class ControllerInterface {
app: any;
export declare abstract class ControllerInterface {
app: FirebaseApp;
INTERNAL: any;
protected errorFactory_: any;
private messagingSenderId_;
private tokenDetailsModel_;
private vapidDetailsModel_;
private iidModel_;
protected errorFactory_: ErrorFactory<string>;
private readonly messagingSenderId_;
private readonly tokenDetailsModel_;
private readonly vapidDetailsModel_;
private readonly iidModel_;
/**
* An interface of the Messaging Service API
* @param {!firebase.app.App} app
*/
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -32,3 +48,2 @@ * @export

private manageExistingToken(swReg, pushSubscription, publicVapidKey, tokenDetails);
private isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
private updateToken(swReg, pushSubscription, publicVapidKey, tokenDetails);

@@ -43,3 +58,3 @@ private getNewToken(swReg, pushSubscription, publicVapidKey);

*/
deleteToken(token: string): Promise<Boolean>;
deleteToken(token: string): Promise<boolean>;
/**

@@ -51,4 +66,4 @@ * This method will delete the token from the client database, and make a

private deleteTokenFromDB(token);
getSWRegistration_(): Promise<ServiceWorkerRegistration>;
getPublicVapidKey_(): Promise<Uint8Array>;
abstract getSWRegistration_(): Promise<ServiceWorkerRegistration>;
abstract getPublicVapidKey_(): Promise<Uint8Array>;
/**

@@ -59,37 +74,8 @@ * Gets a PushSubscription for the current user.

requestPermission(): void;
useServiceWorker(registration: ServiceWorkerRegistration): void;
usePublicVapidKey(b64PublicKey: string): void;
onMessage(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): void;
onTokenRefresh(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): void;
setBackgroundMessageHandler(callback: (a: any) => any): void;
/**
* @export
* @param {!ServiceWorkerRegistration} registration
*/
useServiceWorker(registration: any): void;
/**
* @export
* @param {!string} b64PublicKey
*/
usePublicVapidKey(b64PublicKey: any): void;
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver
* @param {function(!Error)=} optError
* @param {function()=} optCompleted
* @return {!function()}
*/
onMessage(nextOrObserver: any, optError: any, optCompleted: any): void;
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
*/
onTokenRefresh(nextOrObserver: any, optError: any, optCompleted: any): void;
/**
* @export
* @param {function(Object)} callback
*/
setBackgroundMessageHandler(callback: any): void;
/**
* This method is required to adhere to the Firebase interface.

@@ -101,6 +87,4 @@ * It closes any currently open indexdb database connections.

* Returns the current Notification Permission state.
* @private
* @return {string} The currenct permission state.
*/
getNotificationPermission_(): any;
getNotificationPermission_(): NotificationPermission;
getTokenDetailsModel(): TokenDetailsModel;

@@ -110,5 +94,4 @@ getVapidDetailsModel(): VapidDetailsModel;

* @protected
* @returns {IIDModel}
*/
getIIDModel(): IIDModel;
}

@@ -16,11 +16,9 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { ErrorFactory } from '@firebase/util';
import { isArrayBufferEqual } from '../helpers/is-array-buffer-equal';
import { ERROR_CODES, ERROR_MAP } from '../models/errors';
import { IIDModel } from '../models/iid-model';
import { TokenDetailsModel } from '../models/token-details-model';
import { VapidDetailsModel } from '../models/vapid-details-model';
import { NotificationPermission } from '../models/notification-permission';
import { IIDModel } from '../models/iid-model';
import { arrayBufferToBase64 } from '../helpers/array-buffer-to-base64';
var SENDER_ID_OPTION_NAME = 'messagingSenderId';

@@ -32,3 +30,2 @@ // Database cache should be invalidated once a week.

* An interface of the Messaging Service API
* @param {!firebase.app.App} app
*/

@@ -60,4 +57,4 @@ function ControllerInterface(app) {

currentPermission = this.getNotificationPermission_();
if (currentPermission !== NotificationPermission.GRANTED) {
if (currentPermission === NotificationPermission.DENIED) {
if (currentPermission !== 'granted') {
if (currentPermission === 'denied') {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.NOTIFICATIONS_BLOCKED))];

@@ -103,7 +100,7 @@ }

case 0:
isTokenValid = this.isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
isTokenValid = isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails);
if (isTokenValid) {
now = Date.now();
if (now < tokenDetails['createTime'] + TOKEN_EXPIRATION_MILLIS) {
return [2 /*return*/, tokenDetails['fcmToken']];
if (now < tokenDetails.createTime + TOKEN_EXPIRATION_MILLIS) {
return [2 /*return*/, tokenDetails.fcmToken];
}

@@ -118,3 +115,3 @@ else {

// good push subscription that we'd like to use in getNewToken.
return [4 /*yield*/, this.deleteTokenFromDB(tokenDetails['fcmToken'])];
return [4 /*yield*/, this.deleteTokenFromDB(tokenDetails.fcmToken)];
case 1:

@@ -131,17 +128,2 @@ // If the token is no longer valid (for example if the VAPID details

};
/*
* Checks if the tokenDetails match the details provided in the clients.
*/
ControllerInterface.prototype.isTokenStillValid = function (pushSubscription, publicVapidKey, tokenDetails) {
if (arrayBufferToBase64(publicVapidKey) !== tokenDetails['vapidKey']) {
return false;
}
// getKey() isn't defined in the PushSubscription externs file, hence
// subscription['getKey']('<key name>').
return (pushSubscription.endpoint === tokenDetails['endpoint'] &&
arrayBufferToBase64(pushSubscription['getKey']('auth')) ===
tokenDetails['auth'] &&
arrayBufferToBase64(pushSubscription['getKey']('p256dh')) ===
tokenDetails['p256dh']);
};
ControllerInterface.prototype.updateToken = function (swReg, pushSubscription, publicVapidKey, tokenDetails) {

@@ -154,3 +136,3 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

_a.trys.push([0, 4, , 6]);
return [4 /*yield*/, this.iidModel_.updateToken(this.messagingSenderId_, tokenDetails['fcmToken'], tokenDetails['fcmPushSet'], pushSubscription, publicVapidKey)];
return [4 /*yield*/, this.iidModel_.updateToken(this.messagingSenderId_, tokenDetails.fcmToken, tokenDetails.fcmPushSet, pushSubscription, publicVapidKey)];
case 1:

@@ -161,6 +143,9 @@ updatedToken = _a.sent();

vapidKey: publicVapidKey,
subscription: pushSubscription,
fcmSenderId: this.messagingSenderId_,
fcmToken: updatedToken,
fcmPushSet: tokenDetails['fcmPushSet']
fcmPushSet: tokenDetails.fcmPushSet,
createTime: Date.now(),
endpoint: pushSubscription.endpoint,
auth: pushSubscription.getKey('auth'),
p256dh: pushSubscription.getKey('p256dh')
};

@@ -176,3 +161,3 @@ return [4 /*yield*/, this.tokenDetailsModel_.saveTokenDetails(allDetails)];

e_1 = _a.sent();
return [4 /*yield*/, this.deleteToken(tokenDetails['fcmToken'])];
return [4 /*yield*/, this.deleteToken(tokenDetails.fcmToken)];
case 5:

@@ -197,6 +182,9 @@ _a.sent();

vapidKey: publicVapidKey,
subscription: pushSubscription,
fcmSenderId: this.messagingSenderId_,
fcmToken: tokenDetails['token'],
fcmPushSet: tokenDetails['pushSet']
fcmToken: tokenDetails.token,
fcmPushSet: tokenDetails.pushSet,
createTime: Date.now(),
endpoint: pushSubscription.endpoint,
auth: pushSubscription.getKey('auth'),
p256dh: pushSubscription.getKey('p256dh')
};

@@ -209,3 +197,3 @@ return [4 /*yield*/, this.tokenDetailsModel_.saveTokenDetails(allDetails)];

_a.sent();
return [2 /*return*/, tokenDetails['token']];
return [2 /*return*/, tokenDetails.token];
}

@@ -264,3 +252,3 @@ });

details = _a.sent();
return [4 /*yield*/, this.iidModel_.deleteToken(details['fcmSenderId'], details['fcmToken'], details['fcmPushSet'])];
return [4 /*yield*/, this.iidModel_.deleteToken(details.fcmSenderId, details.fcmToken, details.fcmPushSet)];
case 2:

@@ -273,8 +261,2 @@ _a.sent();

};
ControllerInterface.prototype.getSWRegistration_ = function () {
throw this.errorFactory_.create(ERROR_CODES.SHOULD_BE_INHERITED);
};
ControllerInterface.prototype.getPublicVapidKey_ = function () {
throw this.errorFactory_.create(ERROR_CODES.SHOULD_BE_INHERITED);
};
/**

@@ -300,37 +282,12 @@ * Gets a PushSubscription for the current user.

};
/**
* @export
* @param {!ServiceWorkerRegistration} registration
*/
ControllerInterface.prototype.useServiceWorker = function (registration) {
throw this.errorFactory_.create(ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!string} b64PublicKey
*/
ControllerInterface.prototype.usePublicVapidKey = function (b64PublicKey) {
throw this.errorFactory_.create(ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver
* @param {function(!Error)=} optError
* @param {function()=} optCompleted
* @return {!function()}
*/
ControllerInterface.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {
ControllerInterface.prototype.onMessage = function (nextOrObserver, error, completed) {
throw this.errorFactory_.create(ERROR_CODES.AVAILABLE_IN_WINDOW);
};
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
*/
ControllerInterface.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {
ControllerInterface.prototype.onTokenRefresh = function (nextOrObserver, error, completed) {
throw this.errorFactory_.create(ERROR_CODES.AVAILABLE_IN_WINDOW);

@@ -341,6 +298,2 @@ };

//
/**
* @export
* @param {function(Object)} callback
*/
ControllerInterface.prototype.setBackgroundMessageHandler = function (callback) {

@@ -365,4 +318,2 @@ throw this.errorFactory_.create(ERROR_CODES.AVAILABLE_IN_SW);

* Returns the current Notification Permission state.
* @private
* @return {string} The currenct permission state.
*/

@@ -380,3 +331,2 @@ ControllerInterface.prototype.getNotificationPermission_ = function () {

* @protected
* @returns {IIDModel}
*/

@@ -389,3 +339,15 @@ ControllerInterface.prototype.getIIDModel = function () {

export { ControllerInterface };
/**
* Checks if the tokenDetails match the details provided in the clients.
*/
function isTokenStillValid(pushSubscription, publicVapidKey, tokenDetails) {
if (!isArrayBufferEqual(publicVapidKey.buffer, tokenDetails.vapidKey.buffer)) {
return false;
}
var isEndpointEqual = pushSubscription.endpoint === tokenDetails.endpoint;
var isAuthEqual = isArrayBufferEqual(pushSubscription.getKey('auth'), tokenDetails.auth);
var isP256dhEqual = isArrayBufferEqual(pushSubscription.getKey('p256dh'), tokenDetails.p256dh);
return isEndpointEqual && isAuthEqual && isP256dhEqual;
}
//# sourceMappingURL=controller-interface.js.map

@@ -0,5 +1,22 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { ControllerInterface } from './controller-interface';
export declare type BgMessageHandler = (input: any) => Promise<any>;
export declare class SWController extends ControllerInterface {
private bgMessageHandler_;
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -16,20 +33,8 @@ * A handler for push events that shows notifications based on the content of

* shown.
* @private
*/
onPush_(event: any): void;
/**
* @private
*/
onSubChange_(event: any): void;
/**
* @private
*/
onNotificationClick_(event: any): void;
getNotificationData_(msgPayload: any): NotificationOptions | undefined;
/**
* @private
* @param {Object} msgPayload
* @return {NotificationOptions|undefined}
*/
getNotificationData_(msgPayload: any): any;
/**
* Calling setBackgroundMessageHandler will opt in to some specific

@@ -44,46 +49,38 @@ * behaviours.

* developer can handle them in a their own 'push' event callback
* @export
* @param {function(Object)} callback The callback to be called when a push
* message is received and a notification must be shown. The callback will
* be given the data from the push message.
*
* @param callback The callback to be called when a push message is received
* and a notification must be shown. The callback will be given the data from
* the push message.
*/
setBackgroundMessageHandler(callback: any): void;
setBackgroundMessageHandler(callback: BgMessageHandler): void;
/**
* @private
* @param {string} url The URL to look for when focusing a client.
* @return {Object} Returns an existing window client or a newly opened
* WindowClient.
* @param url The URL to look for when focusing a client.
* @return Returns an existing window client or a newly opened WindowClient.
*/
getWindowClient_(url: any): any;
getWindowClient_(url: string): Promise<any>;
/**
* This message will attempt to send the message to a window client.
* @private
* @param {Object} client The WindowClient to send the message to.
* @param {Object} message The message to send to the client.
* @returns {Promise} Returns a promise that resolves after sending the
* message. This does not guarantee that the message was successfully
* received.
* @param client The WindowClient to send the message to.
* @param message The message to send to the client.
* @returns Returns a promise that resolves after sending the message. This
* does not guarantee that the message was successfully received.
*/
attemptToMessageClient_(client: any, message: any): Promise<never>;
attemptToMessageClient_(client: any, message: any): Promise<void>;
/**
* @private
* @returns {Promise<boolean>} If there is currently a visible WindowClient,
* this method will resolve to true, otherwise false.
* @returns If there is currently a visible WindowClient, this method will
* resolve to true, otherwise false.
*/
hasVisibleClients_(): any;
hasVisibleClients_(): Promise<boolean>;
/**
* @private
* @param {Object} msgPayload The data from the push event that should be sent
* to all available pages.
* @returns {Promise} Returns a promise that resolves once the message
* has been sent to all WindowClients.
* @param msgPayload The data from the push event that should be sent to all
* available pages.
* @returns Returns a promise that resolves once the message has been sent to
* all WindowClients.
*/
sendMessageToWindowClients_(msgPayload: any): any;
sendMessageToWindowClients_(msgPayload: any): Promise<void>;
/**
* This will register the default service worker and return the registration.
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* @return he service worker registration to be used for the push service.
*/
getSWRegistration_(): Promise<any>;
getSWRegistration_(): Promise<ServiceWorkerRegistration>;
/**

@@ -90,0 +87,0 @@ * This will return the default VAPID key or the uint8array version of the

@@ -16,8 +16,7 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { ControllerInterface } from './controller-interface';
import { ERROR_CODES } from '../models/errors';
import { DEFAULT_PUBLIC_VAPID_KEY } from '../models/fcm-details';
import WorkerPageMessage from '../models/worker-page-message';
import * as WorkerPageMessage from '../models/worker-page-message';
import { ControllerInterface } from './controller-interface';
var FCM_MSG = 'FCM_MSG';

@@ -28,10 +27,12 @@ var SWController = /** @class */ (function (_super) {

var _this = _super.call(this, app) || this;
self.addEventListener('push', function (e) { return _this.onPush_(e); }, false);
self.addEventListener('pushsubscriptionchange', function (e) { return _this.onSubChange_(e); }, false);
self.addEventListener('notificationclick', function (e) { return _this.onNotificationClick_(e); }, false);
/**
* @private
* @type {function(Object)|null}
*/
_this.bgMessageHandler_ = null;
self.addEventListener('push', function (e) {
_this.onPush_(e);
}, false);
self.addEventListener('pushsubscriptionchange', function (e) {
_this.onSubChange_(e);
}, false);
self.addEventListener('notificationclick', function (e) {
_this.onNotificationClick_(e);
}, false);
return _this;

@@ -50,4 +51,5 @@ }

* shown.
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onPush_ = function (event) {

@@ -85,5 +87,4 @@ var _this = this;

};
/**
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onSubChange_ = function (event) {

@@ -125,5 +126,4 @@ var _this = this;

};
/**
* @private
*/
// Visible for testing
// TODO: Make private
SWController.prototype.onNotificationClick_ = function (event) {

@@ -173,7 +173,4 @@ var _this = this;

};
/**
* @private
* @param {Object} msgPayload
* @return {NotificationOptions|undefined}
*/
// Visible for testing
// TODO: Make private
SWController.prototype.getNotificationData_ = function (msgPayload) {

@@ -186,3 +183,3 @@ if (!msgPayload) {

}
var notificationInformation = Object.assign({}, msgPayload.notification);
var notificationInformation = tslib_1.__assign({}, msgPayload.notification);
// Put the message payload under FCM_MSG name so we can identify the

@@ -208,6 +205,6 @@ // notification as being an FCM notification vs a notification from

* developer can handle them in a their own 'push' event callback
* @export
* @param {function(Object)} callback The callback to be called when a push
* message is received and a notification must be shown. The callback will
* be given the data from the push message.
*
* @param callback The callback to be called when a push message is received
* and a notification must be shown. The callback will be given the data from
* the push message.
*/

@@ -221,7 +218,7 @@ SWController.prototype.setBackgroundMessageHandler = function (callback) {

/**
* @private
* @param {string} url The URL to look for when focusing a client.
* @return {Object} Returns an existing window client or a newly opened
* WindowClient.
* @param url The URL to look for when focusing a client.
* @return Returns an existing window client or a newly opened WindowClient.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.getWindowClient_ = function (url) {

@@ -253,9 +250,9 @@ // Use URL to normalize the URL when comparing to windowClients.

* This message will attempt to send the message to a window client.
* @private
* @param {Object} client The WindowClient to send the message to.
* @param {Object} message The message to send to the client.
* @returns {Promise} Returns a promise that resolves after sending the
* message. This does not guarantee that the message was successfully
* received.
* @param client The WindowClient to send the message to.
* @param message The message to send to the client.
* @returns Returns a promise that resolves after sending the message. This
* does not guarantee that the message was successfully received.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.attemptToMessageClient_ = function (client, message) {

@@ -275,6 +272,7 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

/**
* @private
* @returns {Promise<boolean>} If there is currently a visible WindowClient,
* this method will resolve to true, otherwise false.
* @returns If there is currently a visible WindowClient, this method will
* resolve to true, otherwise false.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.hasVisibleClients_ = function () {

@@ -291,8 +289,9 @@ return self.clients

/**
* @private
* @param {Object} msgPayload The data from the push event that should be sent
* to all available pages.
* @returns {Promise} Returns a promise that resolves once the message
* has been sent to all WindowClients.
* @param msgPayload The data from the push event that should be sent to all
* available pages.
* @returns Returns a promise that resolves once the message has been sent to
* all WindowClients.
*/
// Visible for testing
// TODO: Make private
SWController.prototype.sendMessageToWindowClients_ = function (msgPayload) {

@@ -314,5 +313,3 @@ var _this = this;

* This will register the default service worker and return the registration.
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* @return he service worker registration to be used for the push service.
*/

@@ -327,12 +324,21 @@ SWController.prototype.getSWRegistration_ = function () {

SWController.prototype.getPublicVapidKey_ = function () {
var _this = this;
return this.getSWRegistration_()
.then(function (swReg) {
return _this.getVapidDetailsModel().getVapidFromSWScope(swReg.scope);
})
.then(function (vapidKeyFromDatabase) {
if (vapidKeyFromDatabase === null) {
return DEFAULT_PUBLIC_VAPID_KEY;
}
return vapidKeyFromDatabase;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var swReg, vapidKeyFromDatabase;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getSWRegistration_()];
case 1:
swReg = _a.sent();
if (!swReg) {
throw this.errorFactory_.create(ERROR_CODES.SW_REGISTRATION_EXPECTED);
}
return [4 /*yield*/, this.getVapidDetailsModel().getVapidFromSWScope(swReg.scope)];
case 2:
vapidKeyFromDatabase = _a.sent();
if (vapidKeyFromDatabase == null) {
return [2 /*return*/, DEFAULT_PUBLIC_VAPID_KEY];
}
return [2 /*return*/, vapidKeyFromDatabase];
}
});
});

@@ -339,0 +345,0 @@ };

@@ -0,2 +1,19 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { FirebaseApp } from '@firebase/app-types';
import { FirebaseMessaging } from '@firebase/messaging-types';
import { NextFn, PartialObserver, Unsubscribe } from '@firebase/util';
import { ControllerInterface } from './controller-interface';

@@ -8,10 +25,9 @@ export declare class WindowController extends ControllerInterface implements FirebaseMessaging {

private messageObserver_;
private onMessage_;
private readonly onMessage_;
private tokenRefreshObserver_;
private onTokenRefresh_;
private readonly onTokenRefresh_;
/**
* A service that provides a MessagingService instance.
* @param {!firebase.app.App} app
*/
constructor(app: any);
constructor(app: FirebaseApp);
/**

@@ -22,7 +38,7 @@ * This method returns an FCM token if it can be generated.

* possible to generate a token.
* @export
* @return {Promise<string> | Promise<null>} Returns a promise the
* resolves to an FCM token or null if permission isn't granted.
*
* @return Returns a promise that resolves to an FCM token or null if
* permission isn't granted.
*/
getToken(): any;
getToken(): Promise<string | null>;
/**

@@ -35,62 +51,51 @@ * The method checks that a manifest is defined and has the correct GCM

*/
manifestCheck_(): any;
manifestCheck_(): Promise<void>;
/**
* Request permission if it is not currently granted
* @export
* @returns {Promise} Resolves if the permission was granted, otherwise
* rejects
*
* @return Resolves if the permission was granted, otherwise rejects
*/
requestPermission(): Promise<{}>;
requestPermission(): Promise<void>;
/**
* This method allows a developer to override the default service worker and
* instead use a custom service worker.
* @export
* @param {!ServiceWorkerRegistration} registration The service worker
* registration that should be used to receive the push messages.
*
* @param registration The service worker registration that should be used to
* receive the push messages.
*/
useServiceWorker(registration: any): void;
useServiceWorker(registration: ServiceWorkerRegistration): void;
/**
* This method allows a developer to override the default vapid key
* and instead use a custom VAPID public key.
* @export
* @param {!string} publicKey A URL safe base64 encoded string.
*
* @param publicKey A URL safe base64 encoded string.
*/
usePublicVapidKey(publicKey: any): void;
usePublicVapidKey(publicKey: string): void;
/**
* @export
* @param {!firebase.Observer|function(*)} nextOrObserver An observer object
* or a function triggered on message.
* @param {function(!Error)=} optError Optional A function triggered on
* message error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on
* message.
* @param error A function triggered on message error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
onMessage(nextOrObserver: any, optError?: any, optCompleted?: any): () => void;
onMessage(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): Unsubscribe;
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on token
* refresh.
* @param error A function triggered on token refresh error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
onTokenRefresh(nextOrObserver: any, optError: any, optCompleted: any): () => void;
onTokenRefresh(nextOrObserver: NextFn<{}> | PartialObserver<{}>, error?: (e: Error) => void, completed?: () => void): Unsubscribe;
/**
* Given a registration, wait for the service worker it relates to
* become activer
* @private
* @param {ServiceWorkerRegistration} registration Registration to wait
* for service worker to become active
* @return {Promise<!ServiceWorkerRegistration>} Wait for service worker
* registration to become active
* @param registration Registration to wait for service worker to become active
* @return Wait for service worker registration to become active
*/
waitForRegistrationToActivate_(registration: any): Promise<ServiceWorkerRegistration>;
waitForRegistrationToActivate_(registration: ServiceWorkerRegistration): Promise<ServiceWorkerRegistration>;
/**
* This will regiater the default service worker and return the registration
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* This will register the default service worker and return the registration
* @return The service worker registration to be used for the push service.
*/

@@ -101,3 +106,2 @@ getSWRegistration_(): Promise<ServiceWorkerRegistration>;

* provided by the developer.
* @private
*/

@@ -109,4 +113,2 @@ getPublicVapidKey_(): Promise<Uint8Array>;

* events in the page.
*
* @private
*/

@@ -116,6 +118,5 @@ setupSWMessageListener_(): void;

* Checks to see if the required API's are valid or not.
* @private
* @return {boolean} Returns true if the desired APIs are available.
* @return Returns true if the desired APIs are available.
*/
isSupported_(): boolean;
}

@@ -16,12 +16,10 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { ControllerInterface } from './controller-interface';
import { createSubscribe } from '@firebase/util';
import { base64ToArrayBuffer } from '../helpers/base64-to-array-buffer';
import { DEFAULT_SW_PATH, DEFAULT_SW_SCOPE } from '../models/default-sw';
import { ERROR_CODES } from '../models/errors';
import WorkerPageMessage from '../models/worker-page-message';
import { DEFAULT_SW_PATH, DEFAULT_SW_SCOPE } from '../models/default-sw';
import { NotificationPermission } from '../models/notification-permission';
import { DEFAULT_PUBLIC_VAPID_KEY } from '../models/fcm-details';
import { base64ToArrayBuffer } from '../helpers/base64-to-array-buffer';
import { createSubscribe } from '@firebase/util';
import * as WorkerPageMessage from '../models/worker-page-message';
import { ControllerInterface } from './controller-interface';
var WindowController = /** @class */ (function (_super) {

@@ -31,6 +29,8 @@ tslib_1.__extends(WindowController, _super);

* A service that provides a MessagingService instance.
* @param {!firebase.app.App} app
*/
function WindowController(app) {
var _this = _super.call(this, app) || this;
_this.registrationToUse_ = null;
_this.publicVapidKeyToUse_ = null;
_this.manifestCheckPromise_ = null;
_this.messageObserver_ = null;

@@ -44,32 +44,2 @@ _this.onMessage_ = createSubscribe(function (observer) {

});
/**
* @private
* @type {ServiceWorkerRegistration}
*/
_this.registrationToUse_;
/**
* @private
* @type {Promise}
*/
_this.manifestCheckPromise_;
/**
* @private
* @type {firebase.Observer}
*/
_this.messageObserver_ = null;
/**
* @private {!firebase.Subscribe} The subscribe function to the onMessage
* observer.
*/
_this.onMessage_ = createSubscribe(function (observer) {
_this.messageObserver_ = observer;
});
/**
* @private
* @type {firebase.Observer}
*/
_this.tokenRefreshObserver_ = null;
_this.onTokenRefresh_ = createSubscribe(function (observer) {
_this.tokenRefreshObserver_ = observer;
});
_this.setupSWMessageListener_();

@@ -83,5 +53,5 @@ return _this;

* possible to generate a token.
* @export
* @return {Promise<string> | Promise<null>} Returns a promise the
* resolves to an FCM token or null if permission isn't granted.
*
* @return Returns a promise that resolves to an FCM token or null if
* permission isn't granted.
*/

@@ -139,5 +109,4 @@ WindowController.prototype.getToken = function () {

* Request permission if it is not currently granted
* @export
* @returns {Promise} Resolves if the permission was granted, otherwise
* rejects
*
* @return Resolves if the permission was granted, otherwise rejects
*/

@@ -148,3 +117,3 @@ WindowController.prototype.requestPermission = function () {

return tslib_1.__generator(this, function (_a) {
if (Notification.permission === NotificationPermission.GRANTED) {
if (Notification.permission === 'granted') {
return [2 /*return*/];

@@ -154,6 +123,6 @@ }

var managePermissionResult = function (result) {
if (result === NotificationPermission.GRANTED) {
if (result === 'granted') {
return resolve();
}
else if (result === NotificationPermission.DENIED) {
else if (result === 'denied') {
return reject(_this.errorFactory_.create(ERROR_CODES.PERMISSION_BLOCKED));

@@ -180,5 +149,5 @@ }

* instead use a custom service worker.
* @export
* @param {!ServiceWorkerRegistration} registration The service worker
* registration that should be used to receive the push messages.
*
* @param registration The service worker registration that should be used to
* receive the push messages.
*/

@@ -189,3 +158,3 @@ WindowController.prototype.useServiceWorker = function (registration) {

}
if (typeof this.registrationToUse_ !== 'undefined') {
if (this.registrationToUse_ != null) {
throw this.errorFactory_.create(ERROR_CODES.USE_SW_BEFORE_GET_TOKEN);

@@ -198,4 +167,4 @@ }

* and instead use a custom VAPID public key.
* @export
* @param {!string} publicKey A URL safe base64 encoded string.
*
* @param publicKey A URL safe base64 encoded string.
*/

@@ -206,3 +175,3 @@ WindowController.prototype.usePublicVapidKey = function (publicKey) {

}
if (typeof this.publicVapidKeyToUse_ !== 'undefined') {
if (this.publicVapidKeyToUse_ != null) {
throw this.errorFactory_.create(ERROR_CODES.USE_PUBLIC_KEY_BEFORE_GET_TOKEN);

@@ -218,25 +187,30 @@ }

* @export
* @param {!firebase.Observer|function(*)} nextOrObserver An observer object
* or a function triggered on message.
* @param {function(!Error)=} optError Optional A function triggered on
* message error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on
* message.
* @param error A function triggered on message error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
WindowController.prototype.onMessage = function (nextOrObserver, optError, optCompleted) {
return this.onMessage_(nextOrObserver, optError, optCompleted);
WindowController.prototype.onMessage = function (nextOrObserver, error, completed) {
if (typeof nextOrObserver === 'function') {
return this.onMessage_(nextOrObserver, error, completed);
}
else {
return this.onMessage_(nextOrObserver);
}
};
/**
* @export
* @param {!firebase.Observer|function()} nextOrObserver An observer object
* or a function triggered on token refresh.
* @param {function(!Error)=} optError Optional A function
* triggered on token refresh error.
* @param {function()=} optCompleted Optional function triggered when the
* observer is removed.
* @return {!function()} The unsubscribe function for the observer.
* @param nextOrObserver An observer object or a function triggered on token
* refresh.
* @param error A function triggered on token refresh error.
* @param completed function triggered when the observer is removed.
* @return The unsubscribe function for the observer.
*/
WindowController.prototype.onTokenRefresh = function (nextOrObserver, optError, optCompleted) {
return this.onTokenRefresh_(nextOrObserver, optError, optCompleted);
WindowController.prototype.onTokenRefresh = function (nextOrObserver, error, completed) {
if (typeof nextOrObserver === 'function') {
return this.onTokenRefresh_(nextOrObserver, error, completed);
}
else {
return this.onTokenRefresh_(nextOrObserver);
}
};

@@ -246,8 +220,7 @@ /**

* become activer
* @private
* @param {ServiceWorkerRegistration} registration Registration to wait
* for service worker to become active
* @return {Promise<!ServiceWorkerRegistration>} Wait for service worker
* registration to become active
* @param registration Registration to wait for service worker to become active
* @return Wait for service worker registration to become active
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.waitForRegistrationToActivate_ = function (registration) {

@@ -289,6 +262,4 @@ var _this = this;

/**
* This will regiater the default service worker and return the registration
* @private
* @return {Promise<!ServiceWorkerRegistration>} The service worker
* registration to be used for the push service.
* This will register the default service worker and return the registration
* @return The service worker registration to be used for the push service.
*/

@@ -326,3 +297,2 @@ WindowController.prototype.getSWRegistration_ = function () {

* provided by the developer.
* @private
*/

@@ -339,5 +309,5 @@ WindowController.prototype.getPublicVapidKey_ = function () {

* events in the page.
*
* @private
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.setupSWMessageListener_ = function () {

@@ -370,5 +340,6 @@ var _this = this;

* Checks to see if the required API's are valid or not.
* @private
* @return {boolean} Returns true if the desired APIs are available.
* @return Returns true if the desired APIs are available.
*/
// Visible for testing
// TODO: Make private
WindowController.prototype.isSupported_ = function () {

@@ -375,0 +346,0 @@ return ('serviceWorker' in navigator &&

@@ -1,1 +0,1 @@

export declare function arrayBufferToBase64(arrayBuffer: any): string;
export declare function arrayBufferToBase64(arrayBuffer: ArrayBuffer | Uint8Array): string;

@@ -18,3 +18,3 @@ /**

var uint8Version = new Uint8Array(arrayBuffer);
return window.btoa(String.fromCharCode.apply(null, uint8Version));
return btoa(String.fromCharCode.apply(null, uint8Version));
}

@@ -21,0 +21,0 @@ export function arrayBufferToBase64(arrayBuffer) {

@@ -16,2 +16,2 @@ /**

*/
export declare function base64ToArrayBuffer(base64String: any): Uint8Array;
export declare function base64ToArrayBuffer(base64String: string): Uint8Array;

@@ -1,2 +0,1 @@

declare function cleanV1(): void;
export { cleanV1 };
export declare function cleanV1(): void;

@@ -59,3 +59,3 @@ /**

}
function cleanV1() {
export function cleanV1() {
var request = indexedDB.open(OLD_DB_NAME);

@@ -70,4 +70,3 @@ request.onerror = function (event) {

}
export { cleanV1 };
//# sourceMappingURL=clean-v1-undefined.js.map

@@ -0,29 +1,50 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ErrorFactory } from '@firebase/util';
export declare class DBInterface {
private DB_NAME_;
private dbVersion_;
private openDbPromise_;
protected errorFactory_: ErrorFactory<string>;
protected TRANSACTION_READ_WRITE: IDBTransactionMode;
export declare abstract class DBInterface {
private dbPromise;
protected readonly abstract dbName: string;
protected readonly abstract dbVersion: number;
protected readonly abstract objectStoreName: string;
protected readonly errorFactory: ErrorFactory<string>;
/**
* @param {string} dbName
* @param {number} dbVersion
* Database initialization.
*
* This function should create and update object stores.
*/
constructor(dbName: any, dbVersion: any);
protected abstract onDbUpgrade(request: IDBOpenDBRequest, event: IDBVersionChangeEvent): void;
/** Gets record(s) from the objectStore that match the given key. */
get<T>(key: IDBValidKey): Promise<T | undefined>;
/** Gets record(s) from the objectStore that match the given index. */
getIndex<T>(index: string, key: IDBValidKey): Promise<T | undefined>;
/** Assigns or overwrites the record for the given value. */
put(value: any): Promise<void>;
/** Deletes record(s) from the objectStore that match the given key. */
delete(key: IDBValidKey | IDBKeyRange): Promise<void>;
/**
* Get the indexedDB as a promsie.
* @protected
* @return {!Promise<!IDBDatabase>} The IndexedDB database
*/
openDatabase(): Promise<IDBDatabase>;
/**
* Close the currently open database.
* @return {!Promise} Returns the result of the promise chain.
*/
closeDatabase(): Promise<void>;
/**
* @protected
* @param {!IDBDatabase} db
* Creates an IndexedDB Transaction and passes its objectStore to the
* runRequest function, which runs the database request.
*
* @return Promise that resolves with the result of the runRequest function
*/
onDBUpgrade(db: IDBDatabase, event: IDBVersionChangeEvent): void;
private createTransaction<T>(runRequest, mode?);
/** Gets the cached db connection or opens a new one. */
private getDb();
}

@@ -16,75 +16,116 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { ErrorFactory } from '@firebase/util';
import { ERROR_CODES, ERROR_MAP } from './errors';
import { ERROR_MAP } from './errors';
var DBInterface = /** @class */ (function () {
/**
* @param {string} dbName
* @param {number} dbVersion
*/
function DBInterface(dbName, dbVersion) {
this.errorFactory_ = new ErrorFactory('messaging', 'Messaging', ERROR_MAP);
this.DB_NAME_ = dbName;
this.dbVersion_ = dbVersion;
this.openDbPromise_ = null;
this.TRANSACTION_READ_WRITE = 'readwrite';
function DBInterface() {
this.dbPromise = null;
this.errorFactory = new ErrorFactory('messaging', 'Messaging', ERROR_MAP);
}
/**
* Get the indexedDB as a promsie.
* @protected
* @return {!Promise<!IDBDatabase>} The IndexedDB database
*/
DBInterface.prototype.openDatabase = function () {
var _this = this;
if (this.openDbPromise_) {
return this.openDbPromise_;
/** Gets record(s) from the objectStore that match the given key. */
DBInterface.prototype.get = function (key) {
return this.createTransaction(function (objectStore) { return objectStore.get(key); });
};
/** Gets record(s) from the objectStore that match the given index. */
DBInterface.prototype.getIndex = function (index, key) {
function runRequest(objectStore) {
var idbIndex = objectStore.index(index);
return idbIndex.get(key);
}
this.openDbPromise_ = new Promise(function (resolve, reject) {
var request = indexedDB.open(_this.DB_NAME_, _this.dbVersion_);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve(event.target.result);
};
request.onupgradeneeded = function (event) {
try {
var db = event.target.result;
_this.onDBUpgrade(db, event);
}
catch (err) {
// close the database as it can't be used.
db.close();
reject(err);
}
};
});
return this.openDbPromise_;
return this.createTransaction(runRequest);
};
/** Assigns or overwrites the record for the given value. */
// tslint:disable-next-line:no-any IndexedDB values are of type "any"
DBInterface.prototype.put = function (value) {
return this.createTransaction(function (objectStore) { return objectStore.put(value); }, 'readwrite');
};
/** Deletes record(s) from the objectStore that match the given key. */
DBInterface.prototype.delete = function (key) {
return this.createTransaction(function (objectStore) { return objectStore.delete(key); }, 'readwrite');
};
/**
* Close the currently open database.
* @return {!Promise} Returns the result of the promise chain.
*/
DBInterface.prototype.closeDatabase = function () {
var _this = this;
return Promise.resolve().then(function () {
if (_this.openDbPromise_) {
return _this.openDbPromise_.then(function (db) {
db.close();
_this.openDbPromise_ = null;
});
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!this.dbPromise) return [3 /*break*/, 2];
return [4 /*yield*/, this.dbPromise];
case 1:
db = _a.sent();
db.close();
this.dbPromise = null;
_a.label = 2;
case 2: return [2 /*return*/];
}
});
});
};
/**
* @protected
* @param {!IDBDatabase} db
* Creates an IndexedDB Transaction and passes its objectStore to the
* runRequest function, which runs the database request.
*
* @return Promise that resolves with the result of the runRequest function
*/
DBInterface.prototype.onDBUpgrade = function (db, event) {
throw this.errorFactory_.create(ERROR_CODES.SHOULD_BE_INHERITED);
DBInterface.prototype.createTransaction = function (runRequest, mode) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var db, transaction, request, result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getDb()];
case 1:
db = _a.sent();
transaction = db.transaction(this.objectStoreName, mode);
request = transaction.objectStore(this.objectStoreName);
return [4 /*yield*/, promisify(runRequest(request))];
case 2:
result = _a.sent();
return [2 /*return*/, new Promise(function (resolve, reject) {
transaction.oncomplete = function () {
resolve(result);
};
transaction.onerror = function () {
reject(transaction.error);
};
})];
}
});
});
};
/** Gets the cached db connection or opens a new one. */
DBInterface.prototype.getDb = function () {
var _this = this;
if (!this.dbPromise) {
this.dbPromise = new Promise(function (resolve, reject) {
var request = indexedDB.open(_this.dbName, _this.dbVersion);
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
_this.dbPromise = null;
reject(request.error);
};
request.onupgradeneeded = function (event) { return _this.onDbUpgrade(request, event); };
});
}
return this.dbPromise;
};
return DBInterface;
}());
export { DBInterface };
/** Promisifies an IDBRequest. Resolves with the IDBRequest's result. */
function promisify(request) {
return new Promise(function (resolve, reject) {
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
reject(request.error);
};
});
}
//# sourceMappingURL=db-interface.js.map

@@ -0,2 +1,17 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const DEFAULT_SW_PATH = "/firebase-messaging-sw.js";
export declare const DEFAULT_SW_SCOPE = "/firebase-cloud-messaging-push-scope";

@@ -16,3 +16,2 @@ /**

*/
'use strict';
export var DEFAULT_SW_PATH = '/firebase-messaging-sw.js';

@@ -19,0 +18,0 @@ export var DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const ERROR_CODES: {

@@ -2,0 +17,0 @@ AVAILABLE_IN_WINDOW: string;

@@ -16,3 +16,2 @@ /**

*/
'use strict';
export var ERROR_CODES = {

@@ -19,0 +18,0 @@ AVAILABLE_IN_WINDOW: 'only-available-in-window',

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const DEFAULT_PUBLIC_VAPID_KEY: Uint8Array;

@@ -2,0 +17,0 @@ export declare const SUBSCRIPTION_DETAILS: {

@@ -16,3 +16,2 @@ /**

*/
'use strict';
export var DEFAULT_PUBLIC_VAPID_KEY = new Uint8Array([

@@ -19,0 +18,0 @@ 0x04,

@@ -0,15 +1,10 @@

export interface IIDDetails {
token: string;
pushSet: string;
}
export declare class IIDModel {
private errorFactory_;
private readonly errorFactory_;
constructor();
getToken(senderId: string, subscription: PushSubscription, publicVapidKey: Uint8Array): Promise<IIDDetails>;
/**
* Given a PushSubscription and messagingSenderId, get an FCM token.
* @public
* @param {string} senderId The 'messagingSenderId' to tie the token to.
* @param {PushSubscription} subscription The PushSusbcription to "federate".
* @param {Uint8Array} publicVapidKey The public VAPID key.
* @return {Promise<!Object>} Returns the FCM token to be used in place
* of the PushSubscription.
*/
getToken(senderId: any, subscription: any, publicVapidKey: any): Promise<Object>;
/**
* Update the underlying token details for fcmToken.

@@ -16,0 +11,0 @@ */

@@ -16,7 +16,8 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { ErrorFactory } from '@firebase/util';
import { arrayBufferToBase64 } from '../helpers/array-buffer-to-base64';
import { ERROR_CODES, ERROR_MAP } from './errors';
import { arrayBufferToBase64 } from '../helpers/array-buffer-to-base64';
import { DEFAULT_PUBLIC_VAPID_KEY, ENDPOINT } from './fcm-details';
// tslint:enable interface-name
var IIDModel = /** @class */ (function () {

@@ -26,53 +27,58 @@ function IIDModel() {

}
/**
* Given a PushSubscription and messagingSenderId, get an FCM token.
* @public
* @param {string} senderId The 'messagingSenderId' to tie the token to.
* @param {PushSubscription} subscription The PushSusbcription to "federate".
* @param {Uint8Array} publicVapidKey The public VAPID key.
* @return {Promise<!Object>} Returns the FCM token to be used in place
* of the PushSubscription.
*/
IIDModel.prototype.getToken = function (senderId, subscription, publicVapidKey) {
var _this = this;
var p256dh = arrayBufferToBase64(subscription['getKey']('p256dh'));
var auth = arrayBufferToBase64(subscription['getKey']('auth'));
var fcmSubscribeBody = "authorized_entity=" + senderId + "&" +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== DEFAULT_PUBLIC_VAPID_KEY) {
var applicationPubKey = arrayBufferToBase64(publicVapidKey);
fcmSubscribeBody += "&application_pub_key=" + applicationPubKey;
}
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var subscribeOptions = {
method: 'POST',
headers: headers,
body: fcmSubscribeBody
};
return fetch(ENDPOINT + '/fcm/connect/subscribe', subscribeOptions)
.then(function (response) { return response.json(); })
.catch(function () {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_FAILED);
})
.then(function (response) {
var fcmTokenResponse = response;
if (fcmTokenResponse['error']) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_FAILED, {
message: message
});
}
if (!fcmTokenResponse['token']) {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_NO_TOKEN);
}
if (!fcmTokenResponse['pushSet']) {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET);
}
return {
token: fcmTokenResponse['token'],
pushSet: fcmTokenResponse['pushSet']
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
var p256dh, auth, fcmSubscribeBody, applicationPubKey, headers, subscribeOptions, responseData, response, err_1, message;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
p256dh = arrayBufferToBase64(subscription.getKey('p256dh'));
auth = arrayBufferToBase64(subscription.getKey('auth'));
fcmSubscribeBody = "authorized_entity=" + senderId + "&" +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== DEFAULT_PUBLIC_VAPID_KEY) {
applicationPubKey = arrayBufferToBase64(publicVapidKey);
fcmSubscribeBody += "&application_pub_key=" + applicationPubKey;
}
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
subscribeOptions = {
method: 'POST',
headers: headers,
body: fcmSubscribeBody
};
responseData = null;
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(ENDPOINT + '/fcm/connect/subscribe', subscribeOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
return [3 /*break*/, 5];
case 4:
err_1 = _a.sent();
throw this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_FAILED);
case 5:
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_FAILED, {
message: message
});
}
if (!responseData['token']) {
throw this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_NO_TOKEN);
}
if (!responseData['pushSet']) {
throw this.errorFactory_.create(ERROR_CODES.TOKEN_SUBSCRIBE_NO_PUSH_SET);
}
return [2 /*return*/, {
token: responseData['token'],
pushSet: responseData['pushSet']
}];
}
});
});

@@ -84,42 +90,53 @@ };

IIDModel.prototype.updateToken = function (senderId, fcmToken, fcmPushSet, subscription, publicVapidKey) {
var _this = this;
var p256dh = arrayBufferToBase64(subscription['getKey']('p256dh'));
var auth = arrayBufferToBase64(subscription['getKey']('auth'));
var fcmUpdateBody = "push_set=" + fcmPushSet + "&" +
("token=" + fcmToken + "&") +
("authorized_entity=" + senderId + "&") +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== DEFAULT_PUBLIC_VAPID_KEY) {
var applicationPubKey = arrayBufferToBase64(publicVapidKey);
fcmUpdateBody += "&application_pub_key=" + applicationPubKey;
}
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var updateOptions = {
method: 'POST',
headers: headers,
body: fcmUpdateBody
};
var updateFetchRes;
return fetch(ENDPOINT + '/fcm/connect/subscribe', updateOptions)
.then(function (fetchResponse) {
updateFetchRes = fetchResponse;
return fetchResponse.json();
})
.catch(function () {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_FAILED);
})
.then(function (fcmTokenResponse) {
if (!updateFetchRes.ok) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_FAILED, {
message: message
});
}
if (!fcmTokenResponse['token']) {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_NO_TOKEN);
}
return fcmTokenResponse['token'];
return tslib_1.__awaiter(this, void 0, void 0, function () {
var p256dh, auth, fcmUpdateBody, applicationPubKey, headers, updateOptions, responseData, response, err_2, message;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
p256dh = arrayBufferToBase64(subscription.getKey('p256dh'));
auth = arrayBufferToBase64(subscription.getKey('auth'));
fcmUpdateBody = "push_set=" + fcmPushSet + "&" +
("token=" + fcmToken + "&") +
("authorized_entity=" + senderId + "&") +
("endpoint=" + subscription.endpoint + "&") +
("encryption_key=" + p256dh + "&") +
("encryption_auth=" + auth);
if (publicVapidKey !== DEFAULT_PUBLIC_VAPID_KEY) {
applicationPubKey = arrayBufferToBase64(publicVapidKey);
fcmUpdateBody += "&application_pub_key=" + applicationPubKey;
}
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
updateOptions = {
method: 'POST',
headers: headers,
body: fcmUpdateBody
};
responseData = null;
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(ENDPOINT + '/fcm/connect/subscribe', updateOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
return [3 /*break*/, 5];
case 4:
err_2 = _a.sent();
throw this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_FAILED);
case 5:
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_FAILED, {
message: message
});
}
if (!responseData['token']) {
throw this.errorFactory_.create(ERROR_CODES.TOKEN_UPDATE_NO_TOKEN);
}
return [2 /*return*/, responseData['token']];
}
});
});

@@ -131,26 +148,39 @@ };

IIDModel.prototype.deleteToken = function (senderId, fcmToken, fcmPushSet) {
var _this = this;
var fcmUnsubscribeBody = "authorized_entity=" + senderId + "&" +
("token=" + fcmToken + "&") +
("pushSet=" + fcmPushSet);
var headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
var unsubscribeOptions = {
method: 'POST',
headers: headers,
body: fcmUnsubscribeBody
};
return fetch(ENDPOINT + '/fcm/connect/unsubscribe', unsubscribeOptions).then(function (fetchResponse) {
if (!fetchResponse.ok) {
return fetchResponse.json().then(function (fcmTokenResponse) {
if (fcmTokenResponse['error']) {
var message = fcmTokenResponse['error']['message'];
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED, {
message: message
});
}
}, function (err) {
throw _this.errorFactory_.create(ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED);
});
}
return tslib_1.__awaiter(this, void 0, void 0, function () {
var fcmUnsubscribeBody, headers, unsubscribeOptions, response, responseData, message, err_3;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
fcmUnsubscribeBody = "authorized_entity=" + senderId + "&" +
("token=" + fcmToken + "&") +
("pushSet=" + fcmPushSet);
headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
unsubscribeOptions = {
method: 'POST',
headers: headers,
body: fcmUnsubscribeBody
};
_a.label = 1;
case 1:
_a.trys.push([1, 4, , 5]);
return [4 /*yield*/, fetch(ENDPOINT + '/fcm/connect/unsubscribe', unsubscribeOptions)];
case 2:
response = _a.sent();
return [4 /*yield*/, response.json()];
case 3:
responseData = _a.sent();
if (responseData['error']) {
message = responseData['error']['message'];
throw this.errorFactory_.create(ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED, {
message: message
});
}
return [3 /*break*/, 5];
case 4:
err_3 = _a.sent();
throw this.errorFactory_.create(ERROR_CODES.TOKEN_UNSUBSCRIBE_FAILED);
case 5: return [2 /*return*/];
}
});
});

@@ -157,0 +187,0 @@ };

@@ -0,43 +1,31 @@

import { TokenDetails } from '../interfaces/token-details';
import { DBInterface } from './db-interface';
export declare class TokenDetailsModel extends DBInterface {
constructor();
onDBUpgrade(db: IDBDatabase, evt: IDBVersionChangeEvent): void;
protected readonly dbName: string;
protected readonly dbVersion: number;
protected readonly objectStoreName: string;
protected onDbUpgrade(request: IDBOpenDBRequest, event: IDBVersionChangeEvent): void;
/**
* This method takes an object and will check for known arguments and
* validate the input.
* @private
* @param {!ValidateInput} input
* @return {!Promise} Returns promise that resolves if input is valid,
* rejects otherwise.
* @return Promise that resolves if input is valid, rejects otherwise.
*/
validateInputs_(input: any): Promise<never>;
private validateInputs(input);
/**
* Given a token, this method will look up the details in indexedDB.
* @param {string} fcmToken
* @return {Promise<Object>} The details associated with that token.
* @return {Promise<TokenDetails>} The details associated with that token.
*/
getTokenDetailsFromToken(fcmToken: any): Promise<{}>;
getTokenDetailsFromToken(fcmToken: string): Promise<TokenDetails | undefined>;
/**
* Given a service worker scope, this method will look up the details in
* indexedDB.
* @public
* @param {string} swScope
* @return {Promise<Object>} The details associated with that token.
* @return The details associated with that token.
*/
getTokenDetailsFromSWScope(swScope: any): Promise<{}>;
getTokenDetailsFromSWScope(swScope: string): Promise<TokenDetails | undefined>;
/**
* Save the details for the fcm token for re-use at a later date.
* @param {{swScope: !string, vapidKey: !string,
* subscription: !PushSubscription, fcmSenderId: !string, fcmToken: !string,
* fcmPushSet: !string}} input A plain js object containing args to save.
* @return {Promise<void>}
* @param input A plain js object containing args to save.
*/
saveTokenDetails({swScope, vapidKey, subscription, fcmSenderId, fcmToken, fcmPushSet}: {
swScope: any;
vapidKey: any;
subscription: any;
fcmSenderId: any;
fcmToken: any;
fcmPushSet: any;
}): Promise<{}>;
saveTokenDetails(tokenDetails: TokenDetails): Promise<void>;
/**

@@ -47,6 +35,7 @@ * This method deletes details of the current FCM token.

* method for deleting at a later date.
* @return {Promise<Object>} Resolves once the FCM token details have been
* deleted and returns the deleted details.
*
* @return Resolves once the FCM token details have been deleted and returns
* the deleted details.
*/
deleteToken(token: string): Promise<{}>;
deleteToken(token: string): Promise<TokenDetails>;
}

@@ -16,50 +16,63 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { base64ToArrayBuffer } from '../helpers/base64-to-array-buffer';
import { cleanV1 } from './clean-v1-undefined';
import { DBInterface } from './db-interface';
import { ERROR_CODES } from './errors';
import { arrayBufferToBase64 } from '../helpers/array-buffer-to-base64';
import { cleanV1 } from './clean-v1-undefined';
var FCM_TOKEN_OBJ_STORE = 'fcm_token_object_Store';
var DB_NAME = 'fcm_token_details_db';
var DB_VERSION = 2;
/** @record */
function ValidateInput() { }
/** @type {string|undefined} */
ValidateInput.prototype.fcmToken;
/** @type {string|undefined} */
ValidateInput.prototype.swScope;
/** @type {string|undefined} */
ValidateInput.prototype.vapidKey;
/** @type {PushSubscription|undefined} */
ValidateInput.prototype.subscription;
/** @type {string|undefined} */
ValidateInput.prototype.fcmSenderId;
/** @type {string|undefined} */
ValidateInput.prototype.fcmPushSet;
var TokenDetailsModel = /** @class */ (function (_super) {
tslib_1.__extends(TokenDetailsModel, _super);
function TokenDetailsModel() {
return _super.call(this, DB_NAME, DB_VERSION) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.dbName = 'fcm_token_details_db';
_this.dbVersion = 3;
_this.objectStoreName = 'fcm_token_object_Store';
return _this;
}
TokenDetailsModel.prototype.onDBUpgrade = function (db, evt) {
if (evt.oldVersion < 1) {
// New IDB instance
var objectStore = db.createObjectStore(FCM_TOKEN_OBJ_STORE, {
keyPath: 'swScope'
});
// Make sure the sender ID can be searched
objectStore.createIndex('fcmSenderId', 'fcmSenderId', {
unique: false
});
objectStore.createIndex('fcmToken', 'fcmToken', {
unique: true
});
TokenDetailsModel.prototype.onDbUpgrade = function (request, event) {
var db = request.result;
// Lack of 'break' statements is intentional.
switch (event.oldVersion) {
case 0: {
// New IDB instance
var objectStore = db.createObjectStore(this.objectStoreName, {
keyPath: 'swScope'
});
// Make sure the sender ID can be searched
objectStore.createIndex('fcmSenderId', 'fcmSenderId', {
unique: false
});
objectStore.createIndex('fcmToken', 'fcmToken', { unique: true });
}
case 1: {
// Prior to version 2, we were using either 'fcm_token_details_db'
// or 'undefined' as the database name due to bug in the SDK
// So remove the old tokens and databases.
cleanV1();
}
case 2: {
var objectStore = request.transaction.objectStore(this.objectStoreName);
var cursorRequest_1 = objectStore.openCursor();
cursorRequest_1.onsuccess = function () {
var cursor = cursorRequest_1.result;
if (cursor) {
var value = cursor.value;
var newValue = tslib_1.__assign({}, value);
if (!value.createTime) {
newValue.createTime = Date.now();
}
if (typeof value.vapidKey === 'string') {
newValue.vapidKey = base64ToArrayBuffer(value.vapidKey);
}
if (typeof value.auth === 'string') {
newValue.auth = base64ToArrayBuffer(value.auth).buffer;
}
if (typeof value.auth === 'string') {
newValue.p256dh = base64ToArrayBuffer(value.p256dh).buffer;
}
cursor.update(newValue);
cursor.continue();
}
};
}
}
if (evt.oldVersion < 2) {
// Prior to version 2, we were using either 'fcm_token_details_db'
// or 'undefined' as the database name due to bug in the SDK
// So remove the old tokens and databases.
cleanV1();
}
};

@@ -69,46 +82,48 @@ /**

* validate the input.
* @private
* @param {!ValidateInput} input
* @return {!Promise} Returns promise that resolves if input is valid,
* rejects otherwise.
* @return Promise that resolves if input is valid, rejects otherwise.
*/
TokenDetailsModel.prototype.validateInputs_ = function (input) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (input.fcmToken) {
if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_TOKEN))];
}
}
if (input.swScope) {
if (typeof input.swScope !== 'string' || input.swScope.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SCOPE))];
}
}
if (input.vapidKey) {
if (!(input.vapidKey instanceof Uint8Array) ||
input.vapidKey.length !== 65) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_VAPID_KEY))];
}
}
if (input.subscription) {
if (!(input.subscription instanceof PushSubscription)) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SUBSCRIPTION))];
}
}
if (input.fcmSenderId) {
if (typeof input.fcmSenderId !== 'string' ||
input.fcmSenderId.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SENDER_ID))];
}
}
if (input.fcmPushSet) {
if (typeof input.fcmPushSet !== 'string' ||
input.fcmPushSet.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_PUSH_SET))];
}
}
return [2 /*return*/];
});
});
TokenDetailsModel.prototype.validateInputs = function (input) {
if (input.fcmToken) {
if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_TOKEN);
}
}
if (input.swScope) {
if (typeof input.swScope !== 'string' || input.swScope.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_SCOPE);
}
}
if (input.vapidKey) {
if (!(input.vapidKey instanceof Uint8Array) ||
input.vapidKey.length !== 65) {
throw this.errorFactory.create(ERROR_CODES.BAD_VAPID_KEY);
}
}
if (input.endpoint) {
if (typeof input.endpoint !== 'string' || input.endpoint.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.auth) {
if (!(input.auth instanceof ArrayBuffer)) {
throw this.errorFactory.create(ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.p256dh) {
if (!(input.p256dh instanceof ArrayBuffer)) {
throw this.errorFactory.create(ERROR_CODES.BAD_SUBSCRIPTION);
}
}
if (input.fcmSenderId) {
if (typeof input.fcmSenderId !== 'string' ||
input.fcmSenderId.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_SENDER_ID);
}
}
if (input.fcmPushSet) {
if (typeof input.fcmPushSet !== 'string' ||
input.fcmPushSet.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_PUSH_SET);
}
}
};

@@ -118,28 +133,12 @@ /**

* @param {string} fcmToken
* @return {Promise<Object>} The details associated with that token.
* @return {Promise<TokenDetails>} The details associated with that token.
*/
TokenDetailsModel.prototype.getTokenDetailsFromToken = function (fcmToken) {
var _this = this;
if (!fcmToken) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_TOKEN));
}
return this.validateInputs_({ fcmToken: fcmToken })
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var index = objectStore.index('fcmToken');
var request = index.get(fcmToken);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
var result = event.target.result
? event.target.result
: null;
resolve(result);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!fcmToken) {
throw this.errorFactory.create(ERROR_CODES.BAD_TOKEN);
}
this.validateInputs({ fcmToken: fcmToken });
return [2 /*return*/, this.getIndex('fcmToken', fcmToken)];
});

@@ -151,29 +150,12 @@ });

* indexedDB.
* @public
* @param {string} swScope
* @return {Promise<Object>} The details associated with that token.
* @return The details associated with that token.
*/
TokenDetailsModel.prototype.getTokenDetailsFromSWScope = function (swScope) {
var _this = this;
if (!swScope) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SCOPE));
}
return this.validateInputs_({ swScope: swScope })
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var scopeRequest = objectStore.get(swScope);
scopeRequest.onerror = function (event) {
reject(event.target.error);
};
scopeRequest.onsuccess = function (event) {
var result = event.target.result
? event.target.result
: null;
resolve(result);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!swScope) {
throw this.errorFactory.create(ERROR_CODES.BAD_SCOPE);
}
this.validateInputs({ swScope: swScope });
return [2 /*return*/, this.get(swScope)];
});

@@ -184,64 +166,27 @@ });

* Save the details for the fcm token for re-use at a later date.
* @param {{swScope: !string, vapidKey: !string,
* subscription: !PushSubscription, fcmSenderId: !string, fcmToken: !string,
* fcmPushSet: !string}} input A plain js object containing args to save.
* @return {Promise<void>}
* @param input A plain js object containing args to save.
*/
TokenDetailsModel.prototype.saveTokenDetails = function (_a) {
var _this = this;
var swScope = _a.swScope, vapidKey = _a.vapidKey, subscription = _a.subscription, fcmSenderId = _a.fcmSenderId, fcmToken = _a.fcmToken, fcmPushSet = _a.fcmPushSet;
if (!swScope) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SCOPE));
}
if (!vapidKey) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_VAPID_KEY));
}
if (!subscription) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SUBSCRIPTION));
}
if (!fcmSenderId) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SENDER_ID));
}
if (!fcmToken) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_TOKEN));
}
if (!fcmPushSet) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_PUSH_SET));
}
return this.validateInputs_({
swScope: swScope,
vapidKey: vapidKey,
subscription: subscription,
fcmSenderId: fcmSenderId,
fcmToken: fcmToken,
fcmPushSet: fcmPushSet
})
.then(function () {
return _this.openDatabase();
})
.then(function (db) {
/**
* @dict
*/
var details = {
swScope: swScope,
vapidKey: arrayBufferToBase64(vapidKey),
endpoint: subscription.endpoint,
auth: arrayBufferToBase64(subscription['getKey']('auth')),
p256dh: arrayBufferToBase64(subscription['getKey']('p256dh')),
fcmSenderId: fcmSenderId,
fcmToken: fcmToken,
fcmPushSet: fcmPushSet,
createTime: Date.now()
};
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var request = objectStore.put(details);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
resolve();
};
TokenDetailsModel.prototype.saveTokenDetails = function (tokenDetails) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
return tslib_1.__generator(this, function (_a) {
if (!tokenDetails.swScope) {
throw this.errorFactory.create(ERROR_CODES.BAD_SCOPE);
}
if (!tokenDetails.vapidKey) {
throw this.errorFactory.create(ERROR_CODES.BAD_VAPID_KEY);
}
if (!tokenDetails.endpoint || !tokenDetails.auth || !tokenDetails.p256dh) {
throw this.errorFactory.create(ERROR_CODES.BAD_SUBSCRIPTION);
}
if (!tokenDetails.fcmSenderId) {
throw this.errorFactory.create(ERROR_CODES.BAD_SENDER_ID);
}
if (!tokenDetails.fcmToken) {
throw this.errorFactory.create(ERROR_CODES.BAD_TOKEN);
}
if (!tokenDetails.fcmPushSet) {
throw this.errorFactory.create(ERROR_CODES.BAD_PUSH_SET);
}
this.validateInputs(tokenDetails);
return [2 /*return*/, this.put(tokenDetails)];
});

@@ -254,30 +199,26 @@ });

* method for deleting at a later date.
* @return {Promise<Object>} Resolves once the FCM token details have been
* deleted and returns the deleted details.
*
* @return Resolves once the FCM token details have been deleted and returns
* the deleted details.
*/
TokenDetailsModel.prototype.deleteToken = function (token) {
var _this = this;
if (typeof token !== 'string' || token.length === 0) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.INVALID_DELETE_TOKEN));
}
return this.getTokenDetailsFromToken(token).then(function (details) {
if (!details) {
throw _this.errorFactory_.create(ERROR_CODES.DELETE_TOKEN_NOT_FOUND);
}
return _this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_TOKEN_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_TOKEN_OBJ_STORE);
var request = objectStore.delete(details['swScope']);
request.onerror = function (event) {
reject(event.target.error);
};
request.onsuccess = function (event) {
if (event.target.result === 0) {
reject(_this.errorFactory_.create(ERROR_CODES.FAILED_TO_DELETE_TOKEN));
return;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var details;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (typeof token !== 'string' || token.length === 0) {
return [2 /*return*/, Promise.reject(this.errorFactory.create(ERROR_CODES.INVALID_DELETE_TOKEN))];
}
resolve(details);
};
});
return [4 /*yield*/, this.getTokenDetailsFromToken(token)];
case 1:
details = _a.sent();
if (!details) {
throw this.errorFactory.create(ERROR_CODES.DELETE_TOKEN_NOT_FOUND);
}
return [4 /*yield*/, this.delete(details.swScope)];
case 2:
_a.sent();
return [2 /*return*/, details];
}
});

@@ -289,3 +230,14 @@ });

export { TokenDetailsModel };
/** Promisifies an IDBRequest. Resolves with the IDBRequest's result. */
function promisify(request) {
return new Promise(function (resolve, reject) {
request.onsuccess = function () {
resolve(request.result);
};
request.onerror = function () {
reject(request.error);
};
});
}
//# sourceMappingURL=token-details-model.js.map
import { DBInterface } from './db-interface';
export declare class VapidDetailsModel extends DBInterface {
constructor();
protected readonly dbName: string;
protected readonly dbVersion: number;
protected readonly objectStoreName: string;
protected onDbUpgrade(request: IDBOpenDBRequest): void;
/**
* @override
* @param {IDBDatabase} db
*/
onDBUpgrade(db: any): void;
/**
* Given a service worker scope, this method will look up the vapid key
* in indexedDB.
*/
getVapidFromSWScope(swScope: string): Promise<Uint8Array>;
getVapidFromSWScope(swScope: string): Promise<Uint8Array | undefined>;
/**

@@ -15,0 +13,0 @@ * Save a vapid key against a swScope for later date.

@@ -16,9 +16,5 @@ /**

*/
'use strict';
import * as tslib_1 from "tslib";
import { DBInterface } from './db-interface';
import { ERROR_CODES } from './errors';
var FCM_VAPID_OBJ_STORE = 'fcm_vapid_object_Store';
var DB_NAME = 'fcm_vapid_details_db';
var DB_VERSION = 1;
var UNCOMPRESSED_PUBLIC_KEY_SIZE = 65;

@@ -28,12 +24,11 @@ var VapidDetailsModel = /** @class */ (function (_super) {

function VapidDetailsModel() {
return _super.call(this, DB_NAME, DB_VERSION) || this;
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.dbName = 'fcm_vapid_details_db';
_this.dbVersion = 1;
_this.objectStoreName = 'fcm_vapid_object_Store';
return _this;
}
/**
* @override
* @param {IDBDatabase} db
*/
VapidDetailsModel.prototype.onDBUpgrade = function (db) {
db.createObjectStore(FCM_VAPID_OBJ_STORE, {
keyPath: 'swScope'
});
VapidDetailsModel.prototype.onDbUpgrade = function (request) {
var db = request.result;
db.createObjectStore(this.objectStoreName, { keyPath: 'swScope' });
};

@@ -45,21 +40,15 @@ /**

VapidDetailsModel.prototype.getVapidFromSWScope = function (swScope) {
if (typeof swScope !== 'string' || swScope.length === 0) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SCOPE));
}
return this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE]);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var scopeRequest = objectStore.get(swScope);
scopeRequest.onerror = function () {
reject(scopeRequest.error);
};
scopeRequest.onsuccess = function () {
var result = scopeRequest.result;
var vapidKey = null;
if (result) {
vapidKey = result.vapidKey;
}
resolve(vapidKey);
};
return tslib_1.__awaiter(this, void 0, void 0, function () {
var result;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
if (typeof swScope !== 'string' || swScope.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_SCOPE);
}
return [4 /*yield*/, this.get(swScope)];
case 1:
result = _a.sent();
return [2 /*return*/, result ? result.vapidKey : undefined];
}
});

@@ -72,24 +61,16 @@ });

VapidDetailsModel.prototype.saveVapidDetails = function (swScope, vapidKey) {
var _this = this;
if (typeof swScope !== 'string' || swScope.length === 0) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_SCOPE));
}
if (vapidKey === null || vapidKey.length !== UNCOMPRESSED_PUBLIC_KEY_SIZE) {
return Promise.reject(this.errorFactory_.create(ERROR_CODES.BAD_VAPID_KEY));
}
var details = {
swScope: swScope,
vapidKey: vapidKey
};
return this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var request = objectStore.put(details);
request.onerror = function () {
reject(request.error);
return tslib_1.__awaiter(this, void 0, void 0, function () {
var details;
return tslib_1.__generator(this, function (_a) {
if (typeof swScope !== 'string' || swScope.length === 0) {
throw this.errorFactory.create(ERROR_CODES.BAD_SCOPE);
}
if (vapidKey === null || vapidKey.length !== UNCOMPRESSED_PUBLIC_KEY_SIZE) {
throw this.errorFactory.create(ERROR_CODES.BAD_VAPID_KEY);
}
details = {
swScope: swScope,
vapidKey: vapidKey
};
request.onsuccess = function () {
resolve();
};
return [2 /*return*/, this.put(details)];
});

@@ -104,23 +85,17 @@ });

VapidDetailsModel.prototype.deleteVapidDetails = function (swScope) {
var _this = this;
return this.getVapidFromSWScope(swScope).then(function (vapidKey) {
if (!vapidKey) {
throw _this.errorFactory_.create(ERROR_CODES.DELETE_SCOPE_NOT_FOUND);
}
return _this.openDatabase().then(function (db) {
return new Promise(function (resolve, reject) {
var transaction = db.transaction([FCM_VAPID_OBJ_STORE], _this.TRANSACTION_READ_WRITE);
var objectStore = transaction.objectStore(FCM_VAPID_OBJ_STORE);
var request = objectStore.delete(swScope);
request.onerror = function () {
reject(request.error);
};
request.onsuccess = function () {
if (request.result === 0) {
reject(_this.errorFactory_.create(ERROR_CODES.FAILED_DELETE_VAPID_KEY));
return;
return tslib_1.__awaiter(this, void 0, void 0, function () {
var vapidKey;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0: return [4 /*yield*/, this.getVapidFromSWScope(swScope)];
case 1:
vapidKey = _a.sent();
if (!vapidKey) {
throw this.errorFactory.create(ERROR_CODES.DELETE_SCOPE_NOT_FOUND);
}
resolve(vapidKey);
};
});
return [4 /*yield*/, this.delete(swScope)];
case 2:
_a.sent();
return [2 /*return*/, vapidKey];
}
});

@@ -127,0 +102,0 @@ });

@@ -0,1 +1,16 @@

/**
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export declare const PARAMS: {

@@ -5,15 +20,8 @@ TYPE_OF_MSG: string;

};
declare const _default: {
PARAMS: {
TYPE_OF_MSG: string;
DATA: string;
};
TYPES_OF_MSG: {
PUSH_MSG_RECEIVED: string;
NOTIFICATION_CLICKED: string;
};
createNewMsg: (msgType: any, msgData: any) => {
[x: string]: any;
};
export declare const TYPES_OF_MSG: {
PUSH_MSG_RECEIVED: string;
NOTIFICATION_CLICKED: string;
};
export default _default;
export declare function createNewMsg(msgType: any, msgData: any): {
[key: string]: any;
};

@@ -16,3 +16,2 @@ /**

*/
'use strict';
// These fields are strings to prevent closure from thinking goog.getMsg

@@ -26,20 +25,14 @@ // should be used to initialise the values

// expects the variable to be defined via goog.getMsg
var msgType = {
export var TYPES_OF_MSG = {
PUSH_MSG_RECEIVED: 'push-msg-received',
NOTIFICATION_CLICKED: 'notification-clicked'
};
var createNewMsg = function (msgType, msgData) {
var message = (_a = {},
export function createNewMsg(msgType, msgData) {
return _a = {},
_a[PARAMS.TYPE_OF_MSG] = msgType,
_a[PARAMS.DATA] = msgData,
_a);
return message;
_a;
var _a;
};
export default {
PARAMS: PARAMS,
TYPES_OF_MSG: msgType,
createNewMsg: createNewMsg
};
}
//# sourceMappingURL=worker-page-message.js.map
{
"name": "@firebase/messaging",
"version": "0.2.3-canary.2a0a33f",
"version": "0.2.3-canary.452a4be",
"description": "",

@@ -10,13 +10,18 @@ "author": "Firebase <firebase-support@google.com> (https://firebase.google.com/)",

"dev": "gulp dev",
"test": "karma start --single-run",
"test": "run-p test:karma type-check lint",
"test:karma": "karma start --single-run",
"test:debug": "karma start --browsers=Chrome --auto-watch",
"prepare": "gulp build"
"prepare": "gulp build",
"type-check": "tsc --noEmit",
"lint": "tslint -p .",
"lint:fix": "yarn lint --fix"
},
"license": "Apache-2.0",
"peerDependencies": {
"@firebase/app": "0.1.10-canary.2a0a33f"
"@firebase/app": "0.1.10-canary.452a4be",
"@firebase/app-types": "0.1.2-canary.452a4be"
},
"dependencies": {
"@firebase/messaging-types": "0.1.2-canary.2a0a33f",
"@firebase/util": "0.1.10-canary.2a0a33f",
"@firebase/messaging-types": "0.1.2-canary.452a4be",
"@firebase/util": "0.1.10-canary.452a4be",
"tslib": "^1.9.0"

@@ -42,2 +47,3 @@ },

"ts-loader": "^3.5.0",
"tslint": "^5.9.1",
"typescript": "^2.7.2",

@@ -44,0 +50,0 @@ "webpack": "^3.11.0"

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc