{"version":3,"file":"firebase-messaging.js","sources":["../../node_modules/tslib/tslib.es6.js","../util/src/crypt.ts","../util/src/errors.ts","../util/src/subscribe.ts","../messaging/src/models/errors.ts","../messaging/src/models/worker-page-message.ts","../messaging/src/models/fcm-details.ts","../messaging/src/helpers/is-array-buffer-equal.ts","../messaging/src/helpers/array-buffer-to-base64.ts","../messaging/src/models/iid-model.ts","../messaging/src/helpers/base64-to-array-buffer.ts","../messaging/src/models/clean-v1-undefined.ts","../messaging/src/models/db-interface.ts","../messaging/src/models/token-details-model.ts","../messaging/src/models/vapid-details-model.ts","../messaging/src/controllers/base-controller.ts","../messaging/src/controllers/sw-controller.ts","../messaging/src/models/default-sw.ts","../messaging/index.ts","../messaging/src/controllers/window-controller.ts"],"sourcesContent":["/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation. All rights reserved.\r\nLicensed under the Apache License, Version 2.0 (the \"License\"); you may not use\r\nthis file except in compliance with the License. You may obtain a copy of the\r\nLicense at http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\nKIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED\r\nWARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,\r\nMERCHANTABLITY OR NON-INFRINGEMENT.\r\n\r\nSee the Apache Version 2.0 License for specific language governing permissions\r\nand limitations under the License.\r\n***************************************************************************** */\r\n/* global Reflect, Promise */\r\n\r\nvar extendStatics = function(d, b) {\r\n extendStatics = Object.setPrototypeOf ||\r\n ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||\r\n function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };\r\n return extendStatics(d, b);\r\n};\r\n\r\nexport function __extends(d, b) {\r\n extendStatics(d, b);\r\n function __() { this.constructor = d; }\r\n d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());\r\n}\r\n\r\nexport var __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n }\r\n return __assign.apply(this, arguments);\r\n}\r\n\r\nexport function __rest(s, e) {\r\n var t = {};\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)\r\n t[p] = s[p];\r\n if (s != null && typeof Object.getOwnPropertySymbols === \"function\")\r\n for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {\r\n if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))\r\n t[p[i]] = s[p[i]];\r\n }\r\n return t;\r\n}\r\n\r\nexport function __decorate(decorators, target, key, desc) {\r\n var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\r\n if (typeof Reflect === \"object\" && typeof Reflect.decorate === \"function\") r = Reflect.decorate(decorators, target, key, desc);\r\n else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\r\n return c > 3 && r && Object.defineProperty(target, key, r), r;\r\n}\r\n\r\nexport function __param(paramIndex, decorator) {\r\n return function (target, key) { decorator(target, key, paramIndex); }\r\n}\r\n\r\nexport function __metadata(metadataKey, metadataValue) {\r\n if (typeof Reflect === \"object\" && typeof Reflect.metadata === \"function\") return Reflect.metadata(metadataKey, metadataValue);\r\n}\r\n\r\nexport function __awaiter(thisArg, _arguments, P, generator) {\r\n return new (P || (P = Promise))(function (resolve, reject) {\r\n function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }\r\n function rejected(value) { try { step(generator[\"throw\"](value)); } catch (e) { reject(e); } }\r\n function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }\r\n step((generator = generator.apply(thisArg, _arguments || [])).next());\r\n });\r\n}\r\n\r\nexport function __generator(thisArg, body) {\r\n var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;\r\n return g = { next: verb(0), \"throw\": verb(1), \"return\": verb(2) }, typeof Symbol === \"function\" && (g[Symbol.iterator] = function() { return this; }), g;\r\n function verb(n) { return function (v) { return step([n, v]); }; }\r\n function step(op) {\r\n if (f) throw new TypeError(\"Generator is already executing.\");\r\n while (_) try {\r\n if (f = 1, y && (t = op[0] & 2 ? y[\"return\"] : op[0] ? y[\"throw\"] || ((t = y[\"return\"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;\r\n if (y = 0, t) op = [op[0] & 2, t.value];\r\n switch (op[0]) {\r\n case 0: case 1: t = op; break;\r\n case 4: _.label++; return { value: op[1], done: false };\r\n case 5: _.label++; y = op[1]; op = [0]; continue;\r\n case 7: op = _.ops.pop(); _.trys.pop(); continue;\r\n default:\r\n if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }\r\n if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }\r\n if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }\r\n if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }\r\n if (t[2]) _.ops.pop();\r\n _.trys.pop(); continue;\r\n }\r\n op = body.call(thisArg, _);\r\n } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }\r\n if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };\r\n }\r\n}\r\n\r\nexport function __exportStar(m, exports) {\r\n for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];\r\n}\r\n\r\nexport function __values(o) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator], i = 0;\r\n if (m) return m.call(o);\r\n return {\r\n next: function () {\r\n if (o && i >= o.length) o = void 0;\r\n return { value: o && o[i++], done: !o };\r\n }\r\n };\r\n}\r\n\r\nexport function __read(o, n) {\r\n var m = typeof Symbol === \"function\" && o[Symbol.iterator];\r\n if (!m) return o;\r\n var i = m.call(o), r, ar = [], e;\r\n try {\r\n while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);\r\n }\r\n catch (error) { e = { error: error }; }\r\n finally {\r\n try {\r\n if (r && !r.done && (m = i[\"return\"])) m.call(i);\r\n }\r\n finally { if (e) throw e.error; }\r\n }\r\n return ar;\r\n}\r\n\r\nexport function __spread() {\r\n for (var ar = [], i = 0; i < arguments.length; i++)\r\n ar = ar.concat(__read(arguments[i]));\r\n return ar;\r\n}\r\n\r\nexport function __spreadArrays() {\r\n for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n r[k] = a[j];\r\n return r;\r\n};\r\n\r\nexport function __await(v) {\r\n return this instanceof __await ? (this.v = v, this) : new __await(v);\r\n}\r\n\r\nexport function __asyncGenerator(thisArg, _arguments, generator) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var g = generator.apply(thisArg, _arguments || []), i, q = [];\r\n return i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i;\r\n function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }\r\n function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } }\r\n function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }\r\n function fulfill(value) { resume(\"next\", value); }\r\n function reject(value) { resume(\"throw\", value); }\r\n function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); }\r\n}\r\n\r\nexport function __asyncDelegator(o) {\r\n var i, p;\r\n return i = {}, verb(\"next\"), verb(\"throw\", function (e) { throw e; }), verb(\"return\"), i[Symbol.iterator] = function () { return this; }, i;\r\n function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === \"return\" } : f ? f(v) : v; } : f; }\r\n}\r\n\r\nexport function __asyncValues(o) {\r\n if (!Symbol.asyncIterator) throw new TypeError(\"Symbol.asyncIterator is not defined.\");\r\n var m = o[Symbol.asyncIterator], i;\r\n return m ? m.call(o) : (o = typeof __values === \"function\" ? __values(o) : o[Symbol.iterator](), i = {}, verb(\"next\"), verb(\"throw\"), verb(\"return\"), i[Symbol.asyncIterator] = function () { return this; }, i);\r\n function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }\r\n function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }\r\n}\r\n\r\nexport function __makeTemplateObject(cooked, raw) {\r\n if (Object.defineProperty) { Object.defineProperty(cooked, \"raw\", { value: raw }); } else { cooked.raw = raw; }\r\n return cooked;\r\n};\r\n\r\nexport function __importStar(mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result.default = mod;\r\n return result;\r\n}\r\n\r\nexport function __importDefault(mod) {\r\n return (mod && mod.__esModule) ? mod : { default: mod };\r\n}\r\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nconst stringToByteArray = function(str: string): number[] {\n // TODO(user): Use native implementations if/when available\n const out: number[] = [];\n let p = 0;\n for (let i = 0; i < str.length; i++) {\n let c = str.charCodeAt(i);\n if (c < 128) {\n out[p++] = c;\n } else if (c < 2048) {\n out[p++] = (c >> 6) | 192;\n out[p++] = (c & 63) | 128;\n } else if (\n (c & 0xfc00) === 0xd800 &&\n i + 1 < str.length &&\n (str.charCodeAt(i + 1) & 0xfc00) === 0xdc00\n ) {\n // Surrogate Pair\n c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff);\n out[p++] = (c >> 18) | 240;\n out[p++] = ((c >> 12) & 63) | 128;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n } else {\n out[p++] = (c >> 12) | 224;\n out[p++] = ((c >> 6) & 63) | 128;\n out[p++] = (c & 63) | 128;\n }\n }\n return out;\n};\n\n/**\n * Turns an array of numbers into the string given by the concatenation of the\n * characters to which the numbers correspond.\n * @param bytes Array of numbers representing characters.\n * @return Stringification of the array.\n */\nconst byteArrayToString = function(bytes: number[]): string {\n // TODO(user): Use native implementations if/when available\n const out: string[] = [];\n let pos = 0,\n c = 0;\n while (pos < bytes.length) {\n const c1 = bytes[pos++];\n if (c1 < 128) {\n out[c++] = String.fromCharCode(c1);\n } else if (c1 > 191 && c1 < 224) {\n const c2 = bytes[pos++];\n out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63));\n } else if (c1 > 239 && c1 < 365) {\n // Surrogate Pair\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n const c4 = bytes[pos++];\n const u =\n (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) -\n 0x10000;\n out[c++] = String.fromCharCode(0xd800 + (u >> 10));\n out[c++] = String.fromCharCode(0xdc00 + (u & 1023));\n } else {\n const c2 = bytes[pos++];\n const c3 = bytes[pos++];\n out[c++] = String.fromCharCode(\n ((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)\n );\n }\n }\n return out.join('');\n};\n\n// Static lookup maps, lazily populated by init_()\nclass Base64 {\n /**\n * Maps bytes to characters.\n */\n byteToCharMap_: { [key: number]: string } | null = null;\n\n /**\n * Maps characters to bytes.\n */\n charToByteMap_: { [key: string]: number } | null = null;\n\n /**\n * Maps bytes to websafe characters.\n */\n byteToCharMapWebSafe_: { [key: number]: string } | null = null;\n\n /**\n * Maps websafe characters to bytes.\n */\n charToByteMapWebSafe_: { [key: string]: number } | null = null;\n\n /**\n * Our default alphabet shared between\n * ENCODED_VALS and ENCODED_VALS_WEBSAFE\n */\n ENCODED_VALS_BASE: string =\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789';\n\n /**\n * Our default alphabet. Value 64 (=) is special; it means \"nothing.\"\n */\n get ENCODED_VALS(): string {\n return this.ENCODED_VALS_BASE + '+/=';\n }\n\n /**\n * Our websafe alphabet.\n */\n get ENCODED_VALS_WEBSAFE(): string {\n return this.ENCODED_VALS_BASE + '-_.';\n }\n\n /**\n * Whether this browser supports the atob and btoa functions. This extension\n * started at Mozilla but is now implemented by many browsers. We use the\n * ASSUME_* variables to avoid pulling in the full useragent detection library\n * but still allowing the standard per-browser compilations.\n */\n HAS_NATIVE_SUPPORT: boolean = typeof atob === 'function';\n\n /**\n * Base64-encode an array of bytes.\n *\n * @param input An array of bytes (numbers with\n * value in [0, 255]) to encode.\n * @param webSafe Boolean indicating we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeByteArray(input: number[] | Uint8Array, webSafe?: boolean): string {\n if (!Array.isArray(input)) {\n throw Error('encodeByteArray takes an array as a parameter');\n }\n\n this.init_();\n\n const byteToCharMap = webSafe\n ? this.byteToCharMapWebSafe_!\n : this.byteToCharMap_!;\n\n const output = [];\n\n for (let i = 0; i < input.length; i += 3) {\n const byte1 = input[i];\n const haveByte2 = i + 1 < input.length;\n const byte2 = haveByte2 ? input[i + 1] : 0;\n const haveByte3 = i + 2 < input.length;\n const byte3 = haveByte3 ? input[i + 2] : 0;\n\n const outByte1 = byte1 >> 2;\n const outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);\n let outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6);\n let outByte4 = byte3 & 0x3f;\n\n if (!haveByte3) {\n outByte4 = 64;\n\n if (!haveByte2) {\n outByte3 = 64;\n }\n }\n\n output.push(\n byteToCharMap[outByte1],\n byteToCharMap[outByte2],\n byteToCharMap[outByte3],\n byteToCharMap[outByte4]\n );\n }\n\n return output.join('');\n }\n\n /**\n * Base64-encode a string.\n *\n * @param input A string to encode.\n * @param webSafe If true, we should use the\n * alternative alphabet.\n * @return The base64 encoded string.\n */\n encodeString(input: string, webSafe?: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return btoa(input);\n }\n return this.encodeByteArray(stringToByteArray(input), webSafe);\n }\n\n /**\n * Base64-decode a string.\n *\n * @param input to decode.\n * @param webSafe True if we should use the\n * alternative alphabet.\n * @return string representing the decoded value.\n */\n decodeString(input: string, webSafe: boolean): string {\n // Shortcut for Mozilla browsers that implement\n // a native base64 encoder in the form of \"btoa/atob\"\n if (this.HAS_NATIVE_SUPPORT && !webSafe) {\n return atob(input);\n }\n return byteArrayToString(this.decodeStringToByteArray(input, webSafe));\n }\n\n /**\n * Base64-decode a string.\n *\n * In base-64 decoding, groups of four characters are converted into three\n * bytes. If the encoder did not apply padding, the input length may not\n * be a multiple of 4.\n *\n * In this case, the last group will have fewer than 4 characters, and\n * padding will be inferred. If the group has one or two characters, it decodes\n * to one byte. If the group has three characters, it decodes to two bytes.\n *\n * @param input Input to decode.\n * @param webSafe True if we should use the web-safe alphabet.\n * @return bytes representing the decoded value.\n */\n decodeStringToByteArray(input: string, webSafe: boolean): number[] {\n this.init_();\n\n const charToByteMap = webSafe\n ? this.charToByteMapWebSafe_!\n : this.charToByteMap_!;\n\n const output: number[] = [];\n\n for (let i = 0; i < input.length; ) {\n const byte1 = charToByteMap[input.charAt(i++)];\n\n const haveByte2 = i < input.length;\n const byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;\n ++i;\n\n const haveByte3 = i < input.length;\n const byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n const haveByte4 = i < input.length;\n const byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;\n ++i;\n\n if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) {\n throw Error();\n }\n\n const outByte1 = (byte1 << 2) | (byte2 >> 4);\n output.push(outByte1);\n\n if (byte3 !== 64) {\n const outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2);\n output.push(outByte2);\n\n if (byte4 !== 64) {\n const outByte3 = ((byte3 << 6) & 0xc0) | byte4;\n output.push(outByte3);\n }\n }\n }\n\n return output;\n }\n\n /**\n * Lazy static initialization function. Called before\n * accessing any of the static map variables.\n * @private\n */\n init_(): void {\n if (!this.byteToCharMap_) {\n this.byteToCharMap_ = {};\n this.charToByteMap_ = {};\n this.byteToCharMapWebSafe_ = {};\n this.charToByteMapWebSafe_ = {};\n\n // We want quick mappings back and forth, so we precompute two maps.\n for (let i = 0; i < this.ENCODED_VALS.length; i++) {\n this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i);\n this.charToByteMap_[this.byteToCharMap_[i]] = i;\n this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i);\n this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i;\n\n // Be forgiving when decoding and correctly decode both encodings.\n if (i >= this.ENCODED_VALS_BASE.length) {\n this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i;\n this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i;\n }\n }\n }\n }\n}\n\n/**\n * URL-safe base64 encoding\n */\nexport const base64Encode = function(str: string): string {\n const utf8Bytes = stringToByteArray(str);\n return base64.encodeByteArray(utf8Bytes, true);\n};\n\n/**\n * URL-safe base64 decoding\n *\n * NOTE: DO NOT use the global atob() function - it does NOT support the\n * base64Url variant encoding.\n *\n * @param str To be decoded\n * @return Decoded result, if possible\n */\nexport const base64Decode = function(str: string): string | null {\n try {\n return base64.decodeString(str, true);\n } catch (e) {\n console.error('base64Decode failed: ', e);\n }\n return null;\n};\n\nexport const base64 = new Base64();\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n/**\n * @fileoverview Standardized Firebase Error.\n *\n * Usage:\n *\n * // Typescript string literals for type-safe codes\n * type Err =\n * 'unknown' |\n * 'object-not-found'\n * ;\n *\n * // Closure enum for type-safe error codes\n * // at-enum {string}\n * var Err = {\n * UNKNOWN: 'unknown',\n * OBJECT_NOT_FOUND: 'object-not-found',\n * }\n *\n * let errors: Map = {\n * 'generic-error': \"Unknown error\",\n * 'file-not-found': \"Could not find file: {$file}\",\n * };\n *\n * // Type-safe function - must pass a valid error code as param.\n * let error = new ErrorFactory('service', 'Service', errors);\n *\n * ...\n * throw error.create(Err.GENERIC);\n * ...\n * throw error.create(Err.FILE_NOT_FOUND, {'file': fileName});\n * ...\n * // Service: Could not file file: foo.txt (service/file-not-found).\n *\n * catch (e) {\n * assert(e.message === \"Could not find file: foo.txt.\");\n * if (e.code === 'service/file-not-found') {\n * console.log(\"Could not read file: \" + e['file']);\n * }\n * }\n */\n\nexport type ErrorMap = {\n readonly [K in ErrorCode]: string;\n};\n\nconst ERROR_NAME = 'FirebaseError';\n\nexport interface StringLike {\n toString(): string;\n}\n\nexport interface ErrorData {\n [key: string]: StringLike | undefined;\n}\n\nexport interface FirebaseError extends Error, ErrorData {\n // Unique code for error - format is service/error-code-string.\n readonly code: string;\n\n // Developer-friendly error message.\n readonly message: string;\n\n // Always 'FirebaseError'.\n readonly name: typeof ERROR_NAME;\n\n // Where available - stack backtrace in a string.\n readonly stack?: string;\n}\n\n// Based on code from:\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Custom_Error_Types\nexport class FirebaseError extends Error {\n readonly name = ERROR_NAME;\n\n constructor(readonly code: string, message: string) {\n super(message);\n\n // Fix For ES5\n // https://github.com/Microsoft/TypeScript-wiki/blob/master/Breaking-Changes.md#extending-built-ins-like-error-array-and-map-may-no-longer-work\n Object.setPrototypeOf(this, FirebaseError.prototype);\n\n // Maintains proper stack trace for where our error was thrown.\n // Only available on V8.\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ErrorFactory.prototype.create);\n }\n }\n}\n\nexport class ErrorFactory<\n ErrorCode extends string,\n ErrorParams extends { readonly [K in ErrorCode]?: ErrorData } = {}\n> {\n constructor(\n private readonly service: string,\n private readonly serviceName: string,\n private readonly errors: ErrorMap\n ) {}\n\n create(\n code: K,\n ...data: K extends keyof ErrorParams ? [ErrorParams[K]] : []\n ): FirebaseError {\n const customData = (data[0] as ErrorData) || {};\n const fullCode = `${this.service}/${code}`;\n const template = this.errors[code];\n\n const message = template ? replaceTemplate(template, customData) : 'Error';\n // Service Name: Error message (service/code).\n const fullMessage = `${this.serviceName}: ${message} (${fullCode}).`;\n\n const error = new FirebaseError(fullCode, fullMessage);\n\n // Keys with an underscore at the end of their name are not included in\n // error.data for some reason.\n // TODO: Replace with Object.entries when lib is updated to es2017.\n for (const key of Object.keys(customData)) {\n if (key.slice(-1) !== '_') {\n if (key in error) {\n console.warn(\n `Overwriting FirebaseError base field \"${key}\" can cause unexpected behavior.`\n );\n }\n error[key] = customData[key];\n }\n }\n\n return error;\n }\n}\n\nfunction replaceTemplate(template: string, data: ErrorData): string {\n return template.replace(PATTERN, (_, key) => {\n const value = data[key];\n return value != null ? value.toString() : `<${key}?>`;\n });\n}\n\nconst PATTERN = /\\{\\$([^}]+)}/g;\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\nexport type NextFn = (value: T) => void;\nexport type ErrorFn = (error: Error) => void;\nexport type CompleteFn = () => void;\n\nexport interface Observer {\n // Called once for each value in a stream of values.\n next: NextFn;\n\n // A stream terminates by a single call to EITHER error() or complete().\n error: ErrorFn;\n\n // No events will be sent to next() once complete() is called.\n complete: CompleteFn;\n}\n\nexport type PartialObserver = Partial>;\n\n// TODO: Support also Unsubscribe.unsubscribe?\nexport type Unsubscribe = () => void;\n\n/**\n * The Subscribe interface has two forms - passing the inline function\n * callbacks, or a object interface with callback properties.\n */\nexport interface Subscribe {\n (next?: NextFn, error?: ErrorFn, complete?: CompleteFn): Unsubscribe;\n (observer: PartialObserver): Unsubscribe;\n}\n\nexport interface Observable {\n // Subscribe method\n subscribe: Subscribe;\n}\n\nexport type Executor = (observer: Observer) => void;\n\n/**\n * Helper to make a Subscribe function (just like Promise helps make a\n * Thenable).\n *\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\nexport function createSubscribe(\n executor: Executor,\n onNoObservers?: Executor\n): Subscribe {\n const proxy = new ObserverProxy(executor, onNoObservers);\n return proxy.subscribe.bind(proxy);\n}\n\n/**\n * Implement fan-out for any number of Observers attached via a subscribe\n * function.\n */\nclass ObserverProxy implements Observer {\n private observers: Array> | undefined = [];\n private unsubscribes: Unsubscribe[] = [];\n private onNoObservers: Executor | undefined;\n private observerCount = 0;\n // Micro-task scheduling by calling task.then().\n private task = Promise.resolve();\n private finalized = false;\n private finalError?: Error;\n\n /**\n * @param executor Function which can make calls to a single Observer\n * as a proxy.\n * @param onNoObservers Callback when count of Observers goes to zero.\n */\n constructor(executor: Executor, onNoObservers?: Executor) {\n this.onNoObservers = onNoObservers;\n // Call the executor asynchronously so subscribers that are called\n // synchronously after the creation of the subscribe function\n // can still receive the very first value generated in the executor.\n this.task\n .then(() => {\n executor(this);\n })\n .catch(e => {\n this.error(e);\n });\n }\n\n next(value: T): void {\n this.forEachObserver((observer: Observer) => {\n observer.next(value);\n });\n }\n\n error(error: Error): void {\n this.forEachObserver((observer: Observer) => {\n observer.error(error);\n });\n this.close(error);\n }\n\n complete(): void {\n this.forEachObserver((observer: Observer) => {\n observer.complete();\n });\n this.close();\n }\n\n /**\n * Subscribe function that can be used to add an Observer to the fan-out list.\n *\n * - We require that no event is sent to a subscriber sychronously to their\n * call to subscribe().\n */\n subscribe(\n nextOrObserver?: PartialObserver | Function,\n error?: ErrorFn,\n complete?: CompleteFn\n ): Unsubscribe {\n let observer: Observer;\n\n if (\n nextOrObserver === undefined &&\n error === undefined &&\n complete === undefined\n ) {\n throw new Error('Missing Observer.');\n }\n\n // Assemble an Observer object when passed as callback functions.\n if (\n implementsAnyMethods(nextOrObserver as { [key: string]: unknown }, [\n 'next',\n 'error',\n 'complete'\n ])\n ) {\n observer = nextOrObserver as Observer;\n } else {\n observer = {\n next: nextOrObserver as NextFn,\n error,\n complete\n } as Observer;\n }\n\n if (observer.next === undefined) {\n observer.next = noop as NextFn;\n }\n if (observer.error === undefined) {\n observer.error = noop as ErrorFn;\n }\n if (observer.complete === undefined) {\n observer.complete = noop as CompleteFn;\n }\n\n const unsub = this.unsubscribeOne.bind(this, this.observers!.length);\n\n // Attempt to subscribe to a terminated Observable - we\n // just respond to the Observer with the final error or complete\n // event.\n if (this.finalized) {\n // tslint:disable-next-line:no-floating-promises\n this.task.then(() => {\n try {\n if (this.finalError) {\n observer.error(this.finalError);\n } else {\n observer.complete();\n }\n } catch (e) {\n // nothing\n }\n return;\n });\n }\n\n this.observers!.push(observer as Observer);\n\n return unsub;\n }\n\n // Unsubscribe is synchronous - we guarantee that no events are sent to\n // any unsubscribed Observer.\n private unsubscribeOne(i: number): void {\n if (this.observers === undefined || this.observers[i] === undefined) {\n return;\n }\n\n delete this.observers[i];\n\n this.observerCount -= 1;\n if (this.observerCount === 0 && this.onNoObservers !== undefined) {\n this.onNoObservers(this);\n }\n }\n\n private forEachObserver(fn: (observer: Observer) => void): void {\n if (this.finalized) {\n // Already closed by previous event....just eat the additional values.\n return;\n }\n\n // Since sendOne calls asynchronously - there is no chance that\n // this.observers will become undefined.\n for (let i = 0; i < this.observers!.length; i++) {\n this.sendOne(i, fn);\n }\n }\n\n // Call the Observer via one of it's callback function. We are careful to\n // confirm that the observe has not been unsubscribed since this asynchronous\n // function had been queued.\n private sendOne(i: number, fn: (observer: Observer) => void): void {\n // Execute the callback asynchronously\n // tslint:disable-next-line:no-floating-promises\n this.task.then(() => {\n if (this.observers !== undefined && this.observers[i] !== undefined) {\n try {\n fn(this.observers[i]);\n } catch (e) {\n // Ignore exceptions raised in Observers or missing methods of an\n // Observer.\n // Log error to console. b/31404806\n if (typeof console !== 'undefined' && console.error) {\n console.error(e);\n }\n }\n }\n });\n }\n\n private close(err?: Error): void {\n if (this.finalized) {\n return;\n }\n this.finalized = true;\n if (err !== undefined) {\n this.finalError = err;\n }\n // Proxy is no longer needed - garbage collect references\n // tslint:disable-next-line:no-floating-promises\n this.task.then(() => {\n this.observers = undefined;\n this.onNoObservers = undefined;\n });\n }\n}\n\n/** Turn synchronous function into one called asynchronously. */\nexport function async(fn: Function, onError?: ErrorFn): Function {\n return (...args: unknown[]) => {\n Promise.resolve(true)\n .then(() => {\n fn(...args);\n })\n .catch((error: Error) => {\n if (onError) {\n onError(error);\n }\n });\n };\n}\n\n/**\n * Return true if the object passed in implements any of the named methods.\n */\nfunction implementsAnyMethods(\n obj: { [key: string]: unknown },\n methods: string[]\n): boolean {\n if (typeof obj !== 'object' || obj === null) {\n return false;\n }\n\n for (const method of methods) {\n if (method in obj && typeof obj[method] === 'function') {\n return true;\n }\n }\n\n return false;\n}\n\nfunction noop(): void {\n // do nothing\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ErrorFactory, ErrorMap } from '@firebase/util';\n\nexport const enum ErrorCode {\n AVAILABLE_IN_WINDOW = 'only-available-in-window',\n AVAILABLE_IN_SW = 'only-available-in-sw',\n SHOULD_BE_INHERITED = 'should-be-overriden',\n BAD_SENDER_ID = 'bad-sender-id',\n INCORRECT_GCM_SENDER_ID = 'incorrect-gcm-sender-id',\n PERMISSION_DEFAULT = 'permission-default',\n PERMISSION_BLOCKED = 'permission-blocked',\n UNSUPPORTED_BROWSER = 'unsupported-browser',\n NOTIFICATIONS_BLOCKED = 'notifications-blocked',\n FAILED_DEFAULT_REGISTRATION = 'failed-serviceworker-registration',\n SW_REGISTRATION_EXPECTED = 'sw-registration-expected',\n GET_SUBSCRIPTION_FAILED = 'get-subscription-failed',\n INVALID_SAVED_TOKEN = 'invalid-saved-token',\n SW_REG_REDUNDANT = 'sw-reg-redundant',\n TOKEN_SUBSCRIBE_FAILED = 'token-subscribe-failed',\n TOKEN_SUBSCRIBE_NO_TOKEN = 'token-subscribe-no-token',\n TOKEN_SUBSCRIBE_NO_PUSH_SET = 'token-subscribe-no-push-set',\n TOKEN_UNSUBSCRIBE_FAILED = 'token-unsubscribe-failed',\n TOKEN_UPDATE_FAILED = 'token-update-failed',\n TOKEN_UPDATE_NO_TOKEN = 'token-update-no-token',\n USE_SW_BEFORE_GET_TOKEN = 'use-sw-before-get-token',\n INVALID_DELETE_TOKEN = 'invalid-delete-token',\n DELETE_TOKEN_NOT_FOUND = 'delete-token-not-found',\n DELETE_SCOPE_NOT_FOUND = 'delete-scope-not-found',\n BG_HANDLER_FUNCTION_EXPECTED = 'bg-handler-function-expected',\n NO_WINDOW_CLIENT_TO_MSG = 'no-window-client-to-msg',\n UNABLE_TO_RESUBSCRIBE = 'unable-to-resubscribe',\n NO_FCM_TOKEN_FOR_RESUBSCRIBE = 'no-fcm-token-for-resubscribe',\n FAILED_TO_DELETE_TOKEN = 'failed-to-delete-token',\n NO_SW_IN_REG = 'no-sw-in-reg',\n BAD_SCOPE = 'bad-scope',\n BAD_VAPID_KEY = 'bad-vapid-key',\n BAD_SUBSCRIPTION = 'bad-subscription',\n BAD_TOKEN = 'bad-token',\n BAD_PUSH_SET = 'bad-push-set',\n FAILED_DELETE_VAPID_KEY = 'failed-delete-vapid-key',\n INVALID_PUBLIC_VAPID_KEY = 'invalid-public-vapid-key',\n USE_PUBLIC_KEY_BEFORE_GET_TOKEN = 'use-public-key-before-get-token',\n PUBLIC_KEY_DECRYPTION_FAILED = 'public-vapid-key-decryption-failed'\n}\n\nexport const ERROR_MAP: ErrorMap = {\n [ErrorCode.AVAILABLE_IN_WINDOW]:\n 'This method is available in a Window context.',\n [ErrorCode.AVAILABLE_IN_SW]:\n 'This method is available in a service worker context.',\n [ErrorCode.SHOULD_BE_INHERITED]:\n 'This method should be overriden by extended classes.',\n [ErrorCode.BAD_SENDER_ID]:\n \"Please ensure that 'messagingSenderId' is set \" +\n 'correctly in the options passed into firebase.initializeApp().',\n [ErrorCode.PERMISSION_DEFAULT]:\n 'The required permissions were not granted and dismissed instead.',\n [ErrorCode.PERMISSION_BLOCKED]:\n 'The required permissions were not granted and blocked instead.',\n [ErrorCode.UNSUPPORTED_BROWSER]:\n \"This browser doesn't support the API's \" +\n 'required to use the firebase SDK.',\n [ErrorCode.NOTIFICATIONS_BLOCKED]: 'Notifications have been blocked.',\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]:\n 'We are unable to register the ' +\n 'default service worker. {$browserErrorMessage}',\n [ErrorCode.SW_REGISTRATION_EXPECTED]:\n 'A service worker registration was the expected input.',\n [ErrorCode.GET_SUBSCRIPTION_FAILED]:\n 'There was an error when trying to get ' +\n 'any existing Push Subscriptions.',\n [ErrorCode.INVALID_SAVED_TOKEN]:\n 'Unable to access details of the saved token.',\n [ErrorCode.SW_REG_REDUNDANT]:\n 'The service worker being used for push was made redundant.',\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]:\n 'A problem occured while subscribing the user to FCM: {$errorInfo}',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN]:\n 'FCM returned no token when subscribing the user to push.',\n [ErrorCode.TOKEN_SUBSCRIBE_NO_PUSH_SET]:\n 'FCM returned an invalid response when getting an FCM token.',\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]:\n 'A problem occured while unsubscribing the ' +\n 'user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_FAILED]:\n 'A problem occured while updating the user from FCM: {$errorInfo}',\n [ErrorCode.TOKEN_UPDATE_NO_TOKEN]:\n 'FCM returned no token when updating the user to push.',\n [ErrorCode.USE_SW_BEFORE_GET_TOKEN]:\n 'The useServiceWorker() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your service worker is used.',\n [ErrorCode.INVALID_DELETE_TOKEN]:\n 'You must pass a valid token into ' +\n 'deleteToken(), i.e. the token from getToken().',\n [ErrorCode.DELETE_TOKEN_NOT_FOUND]:\n 'The deletion attempt for token could not ' +\n 'be performed as the token was not found.',\n [ErrorCode.DELETE_SCOPE_NOT_FOUND]:\n 'The deletion attempt for service worker ' +\n 'scope could not be performed as the scope was not found.',\n [ErrorCode.BG_HANDLER_FUNCTION_EXPECTED]:\n 'The input to setBackgroundMessageHandler() must be a function.',\n [ErrorCode.NO_WINDOW_CLIENT_TO_MSG]:\n 'An attempt was made to message a non-existant window client.',\n [ErrorCode.UNABLE_TO_RESUBSCRIBE]:\n 'There was an error while re-subscribing ' +\n 'the FCM token for push messaging. Will have to resubscribe the ' +\n 'user on next visit. {$errorInfo}',\n [ErrorCode.NO_FCM_TOKEN_FOR_RESUBSCRIBE]:\n 'Could not find an FCM token ' +\n 'and as a result, unable to resubscribe. Will have to resubscribe the ' +\n 'user on next visit.',\n [ErrorCode.FAILED_TO_DELETE_TOKEN]:\n 'Unable to delete the currently saved token.',\n [ErrorCode.NO_SW_IN_REG]:\n 'Even though the service worker registration was ' +\n 'successful, there was a problem accessing the service worker itself.',\n [ErrorCode.INCORRECT_GCM_SENDER_ID]:\n \"Please change your web app manifest's \" +\n \"'gcm_sender_id' value to '103953800507' to use Firebase messaging.\",\n [ErrorCode.BAD_SCOPE]:\n 'The service worker scope must be a string with at ' +\n 'least one character.',\n [ErrorCode.BAD_VAPID_KEY]:\n 'The public VAPID key is not a Uint8Array with 65 bytes.',\n [ErrorCode.BAD_SUBSCRIPTION]:\n 'The subscription must be a valid PushSubscription.',\n [ErrorCode.BAD_TOKEN]:\n 'The FCM Token used for storage / lookup was not ' +\n 'a valid token string.',\n [ErrorCode.BAD_PUSH_SET]:\n 'The FCM push set used for storage / lookup was not ' +\n 'not a valid push set string.',\n [ErrorCode.FAILED_DELETE_VAPID_KEY]: 'The VAPID key could not be deleted.',\n [ErrorCode.INVALID_PUBLIC_VAPID_KEY]:\n 'The public VAPID key must be a string.',\n [ErrorCode.USE_PUBLIC_KEY_BEFORE_GET_TOKEN]:\n 'The usePublicVapidKey() method may only be called once and must be ' +\n 'called before calling getToken() to ensure your VAPID key is used.',\n [ErrorCode.PUBLIC_KEY_DECRYPTION_FAILED]:\n 'The public VAPID key did not equal 65 bytes when decrypted.'\n};\n\ninterface ErrorParams {\n [ErrorCode.FAILED_DEFAULT_REGISTRATION]: { browserErrorMessage: string };\n [ErrorCode.TOKEN_SUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UNSUBSCRIBE_FAILED]: { errorInfo: string };\n [ErrorCode.TOKEN_UPDATE_FAILED]: { errorInfo: string };\n [ErrorCode.UNABLE_TO_RESUBSCRIBE]: { errorInfo: string };\n}\n\nexport const errorFactory = new ErrorFactory(\n 'messaging',\n 'Messaging',\n ERROR_MAP\n);\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { MessagePayload } from '../interfaces/message-payload';\n\nexport enum MessageParameter {\n TYPE_OF_MSG = 'firebase-messaging-msg-type',\n DATA = 'firebase-messaging-msg-data'\n}\n\nexport enum MessageType {\n PUSH_MSG_RECEIVED = 'push-msg-received',\n NOTIFICATION_CLICKED = 'notification-clicked'\n}\n\nexport interface InternalMessage {\n [MessageParameter.TYPE_OF_MSG]: MessageType;\n [MessageParameter.DATA]: MessagePayload;\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_PUBLIC_VAPID_KEY = new Uint8Array([\n 0x04,\n 0x33,\n 0x94,\n 0xf7,\n 0xdf,\n 0xa1,\n 0xeb,\n 0xb1,\n 0xdc,\n 0x03,\n 0xa2,\n 0x5e,\n 0x15,\n 0x71,\n 0xdb,\n 0x48,\n 0xd3,\n 0x2e,\n 0xed,\n 0xed,\n 0xb2,\n 0x34,\n 0xdb,\n 0xb7,\n 0x47,\n 0x3a,\n 0x0c,\n 0x8f,\n 0xc4,\n 0xcc,\n 0xe1,\n 0x6f,\n 0x3c,\n 0x8c,\n 0x84,\n 0xdf,\n 0xab,\n 0xb6,\n 0x66,\n 0x3e,\n 0xf2,\n 0x0c,\n 0xd4,\n 0x8b,\n 0xfe,\n 0xe3,\n 0xf9,\n 0x76,\n 0x2f,\n 0x14,\n 0x1c,\n 0x63,\n 0x08,\n 0x6a,\n 0x6f,\n 0x2d,\n 0xb1,\n 0x1a,\n 0x95,\n 0xb0,\n 0xce,\n 0x37,\n 0xc0,\n 0x9c,\n 0x6e\n]);\n\nexport const SUBSCRIPTION_DETAILS = {\n userVisibleOnly: true,\n applicationServerKey: DEFAULT_PUBLIC_VAPID_KEY\n};\n\nexport const ENDPOINT = 'https://fcm.googleapis.com';\n","/**\n * @license\n * Copyright 2018 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function isArrayBufferEqual(\n a: ArrayBufferLike | undefined | null,\n b: ArrayBufferLike | undefined | null\n): boolean {\n if (a == null || b == null) {\n return false;\n }\n\n if (a === b) {\n return true;\n }\n\n if (a.byteLength !== b.byteLength) {\n return false;\n }\n\n const viewA = new DataView(a);\n const viewB = new DataView(b);\n\n for (let i = 0; i < a.byteLength; i++) {\n if (viewA.getUint8(i) !== viewB.getUint8(i)) {\n return false;\n }\n }\n\n return true;\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nfunction toBase64(arrayBuffer: ArrayBuffer | Uint8Array): string {\n const uint8Version = new Uint8Array(arrayBuffer);\n return btoa(String.fromCharCode(...uint8Version));\n}\n\nexport function arrayBufferToBase64(\n arrayBuffer: ArrayBuffer | Uint8Array\n): string {\n const base64String = toBase64(arrayBuffer);\n return base64String\n .replace(/=/g, '')\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_');\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { arrayBufferToBase64 } from '../helpers/array-buffer-to-base64';\nimport { isArrayBufferEqual } from '../helpers/is-array-buffer-equal';\nimport { ErrorCode, errorFactory } from './errors';\nimport { DEFAULT_PUBLIC_VAPID_KEY, ENDPOINT } from './fcm-details';\n\nexport interface IidDetails {\n token: string;\n pushSet: string;\n}\n\ninterface ApiResponse extends Partial {\n error?: { message: string };\n}\n\nexport class IidModel {\n async getToken(\n senderId: string,\n subscription: PushSubscription,\n publicVapidKey: Uint8Array\n ): Promise {\n const p256dh = arrayBufferToBase64(subscription.getKey('p256dh')!);\n const auth = arrayBufferToBase64(subscription.getKey('auth')!);\n\n let fcmSubscribeBody =\n `authorized_entity=${senderId}&` +\n `endpoint=${subscription.endpoint}&` +\n `encryption_key=${p256dh}&` +\n `encryption_auth=${auth}`;\n\n if (\n !isArrayBufferEqual(\n publicVapidKey.buffer,\n DEFAULT_PUBLIC_VAPID_KEY.buffer\n )\n ) {\n const applicationPubKey = arrayBufferToBase64(publicVapidKey);\n fcmSubscribeBody += `&application_pub_key=${applicationPubKey}`;\n }\n\n const headers = new Headers();\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\n\n const subscribeOptions = {\n method: 'POST',\n headers,\n body: fcmSubscribeBody\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n ENDPOINT + '/fcm/connect/subscribe',\n subscribeOptions\n );\n\n responseData = await response.json();\n } catch (err) {\n throw errorFactory.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw errorFactory.create(ErrorCode.TOKEN_SUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw errorFactory.create(ErrorCode.TOKEN_SUBSCRIBE_NO_TOKEN);\n }\n\n if (!responseData.pushSet) {\n throw errorFactory.create(ErrorCode.TOKEN_SUBSCRIBE_NO_PUSH_SET);\n }\n\n return {\n token: responseData.token,\n pushSet: responseData.pushSet\n };\n }\n\n /**\n * Update the underlying token details for fcmToken.\n */\n async updateToken(\n senderId: string,\n fcmToken: string,\n fcmPushSet: string,\n subscription: PushSubscription,\n publicVapidKey: Uint8Array\n ): Promise {\n const p256dh = arrayBufferToBase64(subscription.getKey('p256dh')!);\n const auth = arrayBufferToBase64(subscription.getKey('auth')!);\n\n let fcmUpdateBody =\n `push_set=${fcmPushSet}&` +\n `token=${fcmToken}&` +\n `authorized_entity=${senderId}&` +\n `endpoint=${subscription.endpoint}&` +\n `encryption_key=${p256dh}&` +\n `encryption_auth=${auth}`;\n\n if (\n !isArrayBufferEqual(\n publicVapidKey.buffer,\n DEFAULT_PUBLIC_VAPID_KEY.buffer\n )\n ) {\n const applicationPubKey = arrayBufferToBase64(publicVapidKey);\n fcmUpdateBody += `&application_pub_key=${applicationPubKey}`;\n }\n\n const headers = new Headers();\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\n\n const updateOptions = {\n method: 'POST',\n headers,\n body: fcmUpdateBody\n };\n\n let responseData: ApiResponse;\n try {\n const response = await fetch(\n ENDPOINT + '/fcm/connect/subscribe',\n updateOptions\n );\n responseData = await response.json();\n } catch (err) {\n throw errorFactory.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: err\n });\n }\n\n if (responseData.error) {\n const message = responseData.error.message;\n throw errorFactory.create(ErrorCode.TOKEN_UPDATE_FAILED, {\n errorInfo: message\n });\n }\n\n if (!responseData.token) {\n throw errorFactory.create(ErrorCode.TOKEN_UPDATE_NO_TOKEN);\n }\n\n return responseData.token;\n }\n\n /**\n * Given a fcmToken, pushSet and messagingSenderId, delete an FCM token.\n */\n async deleteToken(\n senderId: string,\n fcmToken: string,\n fcmPushSet: string\n ): Promise {\n const fcmUnsubscribeBody =\n `authorized_entity=${senderId}&` +\n `token=${fcmToken}&` +\n `pushSet=${fcmPushSet}`;\n\n const headers = new Headers();\n headers.append('Content-Type', 'application/x-www-form-urlencoded');\n\n const unsubscribeOptions = {\n method: 'POST',\n headers,\n body: fcmUnsubscribeBody\n };\n\n try {\n const response = await fetch(\n ENDPOINT + '/fcm/connect/unsubscribe',\n unsubscribeOptions\n );\n const responseData: ApiResponse = await response.json();\n if (responseData.error) {\n const message = responseData.error.message;\n throw errorFactory.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: message\n });\n }\n } catch (err) {\n throw errorFactory.create(ErrorCode.TOKEN_UNSUBSCRIBE_FAILED, {\n errorInfo: err\n });\n }\n }\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport function base64ToArrayBuffer(base64String: string): Uint8Array {\n const padding = '='.repeat((4 - (base64String.length % 4)) % 4);\n const base64 = (base64String + padding)\n .replace(/\\-/g, '+')\n .replace(/_/g, '/');\n\n const rawData = atob(base64);\n const outputArray = new Uint8Array(rawData.length);\n\n for (let i = 0; i < rawData.length; ++i) {\n outputArray[i] = rawData.charCodeAt(i);\n }\n return outputArray;\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * There seems to have been a bug in the messaging SDK versions <= 4.9.x\n * where the IndexedDB model was using a database name of 'undefined'.\n *\n * In 4.10.x we changed the model implementation, but kept the database\n * name as it should have been. This however introduced an issue where\n * two tokens were pointing to the same underlying PushSubscription.\n *\n * This code will look for the undefined database and delete any of the\n * underlying tokens.\n */\n\nimport { IidModel } from '../models/iid-model';\n\nconst OLD_DB_NAME = 'undefined';\nconst OLD_OBJECT_STORE_NAME = 'fcm_token_object_Store';\n\nfunction handleDb(db: IDBDatabase): void {\n if (!db.objectStoreNames.contains(OLD_OBJECT_STORE_NAME)) {\n // We found a database with the name 'undefined', but our expected object\n // store isn't defined.\n return;\n }\n\n const transaction = db.transaction(OLD_OBJECT_STORE_NAME);\n const objectStore = transaction.objectStore(OLD_OBJECT_STORE_NAME);\n\n const iidModel = new IidModel();\n\n const openCursorRequest: IDBRequest = objectStore.openCursor();\n openCursorRequest.onerror = event => {\n // NOOP - Nothing we can do.\n console.warn('Unable to cleanup old IDB.', event);\n };\n\n openCursorRequest.onsuccess = () => {\n const cursor = openCursorRequest.result;\n if (cursor) {\n // cursor.value contains the current record being iterated through\n // this is where you'd do something with the result\n const tokenDetails = cursor.value;\n\n // tslint:disable-next-line:no-floating-promises\n iidModel.deleteToken(\n tokenDetails.fcmSenderId,\n tokenDetails.fcmToken,\n tokenDetails.fcmPushSet\n );\n\n cursor.continue();\n } else {\n db.close();\n indexedDB.deleteDatabase(OLD_DB_NAME);\n }\n };\n}\n\nexport function cleanV1(): void {\n const request: IDBOpenDBRequest = indexedDB.open(OLD_DB_NAME);\n request.onerror = _event => {\n // NOOP - Nothing we can do.\n };\n request.onsuccess = _event => {\n const db = request.result;\n handleDb(db);\n };\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport abstract class DbInterface {\n private dbPromise: Promise | null = null;\n\n protected abstract readonly dbName: string;\n protected abstract readonly dbVersion: number;\n protected abstract readonly objectStoreName: string;\n\n /**\n * Database initialization.\n *\n * This function should create and update object stores.\n */\n protected abstract onDbUpgrade(\n request: IDBOpenDBRequest,\n event: IDBVersionChangeEvent\n ): void;\n\n /** Gets record(s) from the objectStore that match the given key. */\n get(key: IDBValidKey): Promise {\n return this.createTransaction(objectStore => objectStore.get(key));\n }\n\n /** Gets record(s) from the objectStore that match the given index. */\n getIndex(index: string, key: IDBValidKey): Promise {\n function runRequest(objectStore: IDBObjectStore): IDBRequest {\n const idbIndex = objectStore.index(index);\n return idbIndex.get(key);\n }\n\n return this.createTransaction(runRequest);\n }\n\n /** Assigns or overwrites the record for the given value. */\n // IndexedDB values are of type \"any\"\n put(value: unknown): Promise {\n return this.createTransaction(\n objectStore => objectStore.put(value),\n 'readwrite'\n );\n }\n\n /** Deletes record(s) from the objectStore that match the given key. */\n delete(key: IDBValidKey | IDBKeyRange): Promise {\n return this.createTransaction(\n objectStore => objectStore.delete(key),\n 'readwrite'\n );\n }\n\n /**\n * Close the currently open database.\n */\n async closeDatabase(): Promise {\n if (this.dbPromise) {\n const db = await this.dbPromise;\n db.close();\n this.dbPromise = null;\n }\n }\n\n /**\n * Creates an IndexedDB Transaction and passes its objectStore to the\n * runRequest function, which runs the database request.\n *\n * @return Promise that resolves with the result of the runRequest function\n */\n private async createTransaction(\n runRequest: (objectStore: IDBObjectStore) => IDBRequest,\n mode: 'readonly' | 'readwrite' = 'readonly'\n ): Promise {\n const db = await this.getDb();\n const transaction = db.transaction(this.objectStoreName, mode);\n const request = transaction.objectStore(this.objectStoreName);\n const result = await promisify(runRequest(request));\n\n return new Promise((resolve, reject) => {\n transaction.oncomplete = () => {\n resolve(result);\n };\n transaction.onerror = () => {\n reject(transaction.error);\n };\n });\n }\n\n /** Gets the cached db connection or opens a new one. */\n private getDb(): Promise {\n if (!this.dbPromise) {\n this.dbPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.dbVersion);\n request.onsuccess = () => {\n resolve(request.result);\n };\n request.onerror = () => {\n this.dbPromise = null;\n reject(request.error);\n };\n request.onupgradeneeded = event => this.onDbUpgrade(request, event);\n });\n }\n\n return this.dbPromise;\n }\n}\n\n/** Promisifies an IDBRequest. Resolves with the IDBRequest's result. */\nfunction promisify(request: IDBRequest): Promise {\n return new Promise((resolve, reject) => {\n request.onsuccess = () => {\n resolve(request.result);\n };\n request.onerror = () => {\n reject(request.error);\n };\n });\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { base64ToArrayBuffer } from '../helpers/base64-to-array-buffer';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { cleanV1 } from './clean-v1-undefined';\nimport { DbInterface } from './db-interface';\nimport { ErrorCode, errorFactory } from './errors';\n\nexport class TokenDetailsModel extends DbInterface {\n protected readonly dbName: string = 'fcm_token_details_db';\n protected readonly dbVersion: number = 3;\n protected readonly objectStoreName: string = 'fcm_token_object_Store';\n\n protected onDbUpgrade(\n request: IDBOpenDBRequest,\n event: IDBVersionChangeEvent\n ): void {\n const db: IDBDatabase = request.result;\n\n // Lack of 'break' statements is intentional.\n switch (event.oldVersion) {\n case 0: {\n // New IDB instance\n const objectStore = db.createObjectStore(this.objectStoreName, {\n keyPath: 'swScope'\n });\n\n // Make sure the sender ID can be searched\n objectStore.createIndex('fcmSenderId', 'fcmSenderId', {\n unique: false\n });\n\n objectStore.createIndex('fcmToken', 'fcmToken', { unique: true });\n }\n\n case 1: {\n // Prior to version 2, we were using either 'fcm_token_details_db'\n // or 'undefined' as the database name due to bug in the SDK\n // So remove the old tokens and databases.\n cleanV1();\n }\n\n case 2: {\n const objectStore = request.transaction!.objectStore(\n this.objectStoreName\n );\n const cursorRequest = objectStore.openCursor();\n cursorRequest.onsuccess = () => {\n const cursor: IDBCursorWithValue | null = cursorRequest.result;\n if (cursor) {\n const value = cursor.value;\n const newValue: Partial = { ...value };\n\n if (!value.createTime) {\n newValue.createTime = Date.now();\n }\n\n if (typeof value.vapidKey === 'string') {\n newValue.vapidKey = base64ToArrayBuffer(value.vapidKey);\n }\n\n if (typeof value.auth === 'string') {\n newValue.auth = base64ToArrayBuffer(value.auth).buffer;\n }\n\n if (typeof value.auth === 'string') {\n newValue.p256dh = base64ToArrayBuffer(value.p256dh).buffer;\n }\n\n cursor.update(newValue);\n cursor.continue();\n }\n };\n }\n\n default: // ignore\n }\n }\n\n /**\n * Given a token, this method will look up the details in indexedDB.\n */\n async getTokenDetailsFromToken(\n fcmToken: string\n ): Promise {\n if (!fcmToken) {\n throw errorFactory.create(ErrorCode.BAD_TOKEN);\n }\n\n validateInputs({ fcmToken });\n\n return this.getIndex('fcmToken', fcmToken);\n }\n\n /**\n * Given a service worker scope, this method will look up the details in\n * indexedDB.\n * @return The details associated with that token.\n */\n async getTokenDetailsFromSWScope(\n swScope: string\n ): Promise {\n if (!swScope) {\n throw errorFactory.create(ErrorCode.BAD_SCOPE);\n }\n\n validateInputs({ swScope });\n\n return this.get(swScope);\n }\n\n /**\n * Save the details for the fcm token for re-use at a later date.\n * @param input A plain js object containing args to save.\n */\n async saveTokenDetails(tokenDetails: TokenDetails): Promise {\n if (!tokenDetails.swScope) {\n throw errorFactory.create(ErrorCode.BAD_SCOPE);\n }\n\n if (!tokenDetails.vapidKey) {\n throw errorFactory.create(ErrorCode.BAD_VAPID_KEY);\n }\n\n if (!tokenDetails.endpoint || !tokenDetails.auth || !tokenDetails.p256dh) {\n throw errorFactory.create(ErrorCode.BAD_SUBSCRIPTION);\n }\n\n if (!tokenDetails.fcmSenderId) {\n throw errorFactory.create(ErrorCode.BAD_SENDER_ID);\n }\n\n if (!tokenDetails.fcmToken) {\n throw errorFactory.create(ErrorCode.BAD_TOKEN);\n }\n\n if (!tokenDetails.fcmPushSet) {\n throw errorFactory.create(ErrorCode.BAD_PUSH_SET);\n }\n\n validateInputs(tokenDetails);\n\n return this.put(tokenDetails);\n }\n\n /**\n * This method deletes details of the current FCM token.\n * It's returning a promise in case we need to move to an async\n * method for deleting at a later date.\n *\n * @return Resolves once the FCM token details have been deleted and returns\n * the deleted details.\n */\n async deleteToken(token: string): Promise {\n if (typeof token !== 'string' || token.length === 0) {\n return Promise.reject(\n errorFactory.create(ErrorCode.INVALID_DELETE_TOKEN)\n );\n }\n\n const details = await this.getTokenDetailsFromToken(token);\n if (!details) {\n throw errorFactory.create(ErrorCode.DELETE_TOKEN_NOT_FOUND);\n }\n\n await this.delete(details.swScope);\n return details;\n }\n}\n\n/**\n * This method takes an object and will check for known arguments and\n * validate the input.\n * @return Promise that resolves if input is valid, rejects otherwise.\n */\nfunction validateInputs(input: Partial): void {\n if (input.fcmToken) {\n if (typeof input.fcmToken !== 'string' || input.fcmToken.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_TOKEN);\n }\n }\n\n if (input.swScope) {\n if (typeof input.swScope !== 'string' || input.swScope.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_SCOPE);\n }\n }\n\n if (input.vapidKey) {\n if (\n !(input.vapidKey instanceof Uint8Array) ||\n input.vapidKey.length !== 65\n ) {\n throw errorFactory.create(ErrorCode.BAD_VAPID_KEY);\n }\n }\n\n if (input.endpoint) {\n if (typeof input.endpoint !== 'string' || input.endpoint.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_SUBSCRIPTION);\n }\n }\n\n if (input.auth) {\n if (!(input.auth instanceof ArrayBuffer)) {\n throw errorFactory.create(ErrorCode.BAD_SUBSCRIPTION);\n }\n }\n\n if (input.p256dh) {\n if (!(input.p256dh instanceof ArrayBuffer)) {\n throw errorFactory.create(ErrorCode.BAD_SUBSCRIPTION);\n }\n }\n\n if (input.fcmSenderId) {\n if (\n typeof input.fcmSenderId !== 'string' ||\n input.fcmSenderId.length === 0\n ) {\n throw errorFactory.create(ErrorCode.BAD_SENDER_ID);\n }\n }\n\n if (input.fcmPushSet) {\n if (typeof input.fcmPushSet !== 'string' || input.fcmPushSet.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_PUSH_SET);\n }\n }\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { VapidDetails } from '../interfaces/vapid-details';\nimport { DbInterface } from './db-interface';\nimport { ErrorCode, errorFactory } from './errors';\n\nconst UNCOMPRESSED_PUBLIC_KEY_SIZE = 65;\n\nexport class VapidDetailsModel extends DbInterface {\n protected readonly dbName: string = 'fcm_vapid_details_db';\n protected readonly dbVersion: number = 1;\n protected readonly objectStoreName: string = 'fcm_vapid_object_Store';\n\n protected onDbUpgrade(request: IDBOpenDBRequest): void {\n const db: IDBDatabase = request.result;\n db.createObjectStore(this.objectStoreName, { keyPath: 'swScope' });\n }\n\n /**\n * Given a service worker scope, this method will look up the vapid key\n * in indexedDB.\n */\n async getVapidFromSWScope(swScope: string): Promise {\n if (typeof swScope !== 'string' || swScope.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_SCOPE);\n }\n\n const result = await this.get(swScope);\n return result ? result.vapidKey : undefined;\n }\n\n /**\n * Save a vapid key against a swScope for later date.\n */\n async saveVapidDetails(swScope: string, vapidKey: Uint8Array): Promise {\n if (typeof swScope !== 'string' || swScope.length === 0) {\n throw errorFactory.create(ErrorCode.BAD_SCOPE);\n }\n\n if (vapidKey === null || vapidKey.length !== UNCOMPRESSED_PUBLIC_KEY_SIZE) {\n throw errorFactory.create(ErrorCode.BAD_VAPID_KEY);\n }\n\n const details: VapidDetails = {\n swScope,\n vapidKey\n };\n\n return this.put(details);\n }\n\n /**\n * This method deletes details of the current FCM VAPID key for a SW scope.\n * Resolves once the scope/vapid details have been deleted and returns the\n * deleted vapid key.\n */\n async deleteVapidDetails(swScope: string): Promise {\n const vapidKey = await this.getVapidFromSWScope(swScope);\n if (!vapidKey) {\n throw errorFactory.create(ErrorCode.DELETE_SCOPE_NOT_FOUND);\n }\n\n await this.delete(swScope);\n return vapidKey;\n }\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport { FirebaseServiceInternals } from '@firebase/app-types/private';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\nimport {\n CompleteFn,\n ErrorFn,\n NextFn,\n Observer,\n Unsubscribe\n} from '@firebase/util';\n\nimport { isArrayBufferEqual } from '../helpers/is-array-buffer-equal';\nimport { MessagePayload } from '../interfaces/message-payload';\nimport { TokenDetails } from '../interfaces/token-details';\nimport { ErrorCode, errorFactory } from '../models/errors';\nimport { IidModel } from '../models/iid-model';\nimport { TokenDetailsModel } from '../models/token-details-model';\nimport { VapidDetailsModel } from '../models/vapid-details-model';\n\nexport type BgMessageHandler = (\n payload: MessagePayload\n) => Promise | void;\n\nconst SENDER_ID_OPTION_NAME = 'messagingSenderId';\n// Database cache should be invalidated once a week.\nexport const TOKEN_EXPIRATION_MILLIS = 7 * 24 * 60 * 60 * 1000; // 7 days\n\nexport abstract class BaseController implements FirebaseMessaging {\n app: FirebaseApp;\n INTERNAL: FirebaseServiceInternals;\n private readonly messagingSenderId: string;\n private readonly tokenDetailsModel: TokenDetailsModel;\n private readonly vapidDetailsModel: VapidDetailsModel;\n private readonly iidModel: IidModel;\n\n /**\n * An interface of the Messaging Service API\n */\n constructor(app: FirebaseApp) {\n if (\n !app.options[SENDER_ID_OPTION_NAME] ||\n typeof app.options[SENDER_ID_OPTION_NAME] !== 'string'\n ) {\n throw errorFactory.create(ErrorCode.BAD_SENDER_ID);\n }\n\n this.messagingSenderId = app.options[SENDER_ID_OPTION_NAME]!;\n\n this.tokenDetailsModel = new TokenDetailsModel();\n this.vapidDetailsModel = new VapidDetailsModel();\n this.iidModel = new IidModel();\n\n this.app = app;\n this.INTERNAL = {\n delete: () => this.delete()\n };\n }\n\n /**\n * @export\n */\n async getToken(): Promise {\n // Check with permissions\n const currentPermission = this.getNotificationPermission_();\n if (currentPermission === 'denied') {\n throw errorFactory.create(ErrorCode.NOTIFICATIONS_BLOCKED);\n } else if (currentPermission !== 'granted') {\n // We must wait for permission to be granted\n return null;\n }\n\n const swReg = await this.getSWRegistration_();\n const publicVapidKey = await this.getPublicVapidKey_();\n // If a PushSubscription exists it's returned, otherwise a new subscription\n // is generated and returned.\n const pushSubscription = await this.getPushSubscription(\n swReg,\n publicVapidKey\n );\n const tokenDetails = await this.tokenDetailsModel.getTokenDetailsFromSWScope(\n swReg.scope\n );\n\n if (tokenDetails) {\n return this.manageExistingToken(\n swReg,\n pushSubscription,\n publicVapidKey,\n tokenDetails\n );\n }\n return this.getNewToken(swReg, pushSubscription, publicVapidKey);\n }\n\n /**\n * manageExistingToken is triggered if there's an existing FCM token in the\n * database and it can take 3 different actions:\n * 1) Retrieve the existing FCM token from the database.\n * 2) If VAPID details have changed: Delete the existing token and create a\n * new one with the new VAPID key.\n * 3) If the database cache is invalidated: Send a request to FCM to update\n * the token, and to check if the token is still valid on FCM-side.\n */\n private async manageExistingToken(\n swReg: ServiceWorkerRegistration,\n pushSubscription: PushSubscription,\n publicVapidKey: Uint8Array,\n tokenDetails: TokenDetails\n ): Promise {\n const isTokenValid = isTokenStillValid(\n pushSubscription,\n publicVapidKey,\n tokenDetails\n );\n if (isTokenValid) {\n const now = Date.now();\n if (now < tokenDetails.createTime + TOKEN_EXPIRATION_MILLIS) {\n return tokenDetails.fcmToken;\n } else {\n return this.updateToken(\n swReg,\n pushSubscription,\n publicVapidKey,\n tokenDetails\n );\n }\n }\n\n // If the token is no longer valid (for example if the VAPID details\n // have changed), delete the existing token from the FCM client and server\n // database. No need to unsubscribe from the Service Worker as we have a\n // good push subscription that we'd like to use in getNewToken.\n await this.deleteTokenFromDB(tokenDetails.fcmToken);\n return this.getNewToken(swReg, pushSubscription, publicVapidKey);\n }\n\n private async updateToken(\n swReg: ServiceWorkerRegistration,\n pushSubscription: PushSubscription,\n publicVapidKey: Uint8Array,\n tokenDetails: TokenDetails\n ): Promise {\n try {\n const updatedToken = await this.iidModel.updateToken(\n this.messagingSenderId,\n tokenDetails.fcmToken,\n tokenDetails.fcmPushSet,\n pushSubscription,\n publicVapidKey\n );\n\n const allDetails: TokenDetails = {\n swScope: swReg.scope,\n vapidKey: publicVapidKey,\n fcmSenderId: this.messagingSenderId,\n fcmToken: updatedToken,\n fcmPushSet: tokenDetails.fcmPushSet,\n createTime: Date.now(),\n endpoint: pushSubscription.endpoint,\n auth: pushSubscription.getKey('auth')!,\n p256dh: pushSubscription.getKey('p256dh')!\n };\n\n await this.tokenDetailsModel.saveTokenDetails(allDetails);\n await this.vapidDetailsModel.saveVapidDetails(\n swReg.scope,\n publicVapidKey\n );\n return updatedToken;\n } catch (e) {\n await this.deleteToken(tokenDetails.fcmToken);\n throw e;\n }\n }\n\n private async getNewToken(\n swReg: ServiceWorkerRegistration,\n pushSubscription: PushSubscription,\n publicVapidKey: Uint8Array\n ): Promise {\n const tokenDetails = await this.iidModel.getToken(\n this.messagingSenderId,\n pushSubscription,\n publicVapidKey\n );\n const allDetails: TokenDetails = {\n swScope: swReg.scope,\n vapidKey: publicVapidKey,\n fcmSenderId: this.messagingSenderId,\n fcmToken: tokenDetails.token,\n fcmPushSet: tokenDetails.pushSet,\n createTime: Date.now(),\n endpoint: pushSubscription.endpoint,\n auth: pushSubscription.getKey('auth')!,\n p256dh: pushSubscription.getKey('p256dh')!\n };\n await this.tokenDetailsModel.saveTokenDetails(allDetails);\n await this.vapidDetailsModel.saveVapidDetails(swReg.scope, publicVapidKey);\n return tokenDetails.token;\n }\n\n /**\n * This method deletes tokens that the token manager looks after,\n * unsubscribes the token from FCM and then unregisters the push\n * subscription if it exists. It returns a promise that indicates\n * whether or not the unsubscribe request was processed successfully.\n */\n async deleteToken(token: string): Promise {\n // Delete the token details from the database.\n await this.deleteTokenFromDB(token);\n // Unsubscribe from the SW.\n const registration = await this.getSWRegistration_();\n if (registration) {\n const pushSubscription = await registration.pushManager.getSubscription();\n if (pushSubscription) {\n return pushSubscription.unsubscribe();\n }\n }\n // If there's no SW, consider it a success.\n return true;\n }\n\n /**\n * This method will delete the token from the client database, and make a\n * call to FCM to remove it from the server DB. Does not temper with the\n * push subscription.\n */\n private async deleteTokenFromDB(token: string): Promise {\n const details = await this.tokenDetailsModel.deleteToken(token);\n await this.iidModel.deleteToken(\n details.fcmSenderId,\n details.fcmToken,\n details.fcmPushSet\n );\n }\n\n // Visible for testing\n // TODO: Make protected\n abstract getSWRegistration_(): Promise;\n\n // Visible for testing\n // TODO: Make protected\n abstract getPublicVapidKey_(): Promise;\n\n /**\n * Gets a PushSubscription for the current user.\n */\n getPushSubscription(\n swRegistration: ServiceWorkerRegistration,\n publicVapidKey: Uint8Array\n ): Promise {\n return swRegistration.pushManager.getSubscription().then(subscription => {\n if (subscription) {\n return subscription;\n }\n\n return swRegistration.pushManager.subscribe({\n userVisibleOnly: true,\n applicationServerKey: publicVapidKey\n });\n });\n }\n\n //\n // The following methods should only be available in the window.\n //\n\n /**\n * @deprecated Use Notification.requestPermission() instead.\n * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\n */\n requestPermission(): Promise {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n useServiceWorker(_registration: ServiceWorkerRegistration): void {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n usePublicVapidKey(_b64PublicKey: string): void {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onMessage(\n _nextOrObserver: NextFn | Observer,\n _error?: ErrorFn,\n _completed?: CompleteFn\n ): Unsubscribe {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n onTokenRefresh(\n _nextOrObserver: NextFn | Observer,\n _error?: ErrorFn,\n _completed?: CompleteFn\n ): Unsubscribe {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_WINDOW);\n }\n\n //\n // The following methods are used by the service worker only.\n //\n\n setBackgroundMessageHandler(_callback: BgMessageHandler): void {\n throw errorFactory.create(ErrorCode.AVAILABLE_IN_SW);\n }\n\n //\n // The following methods are used by the service themselves and not exposed\n // publicly or not expected to be used by developers.\n //\n\n /**\n * This method is required to adhere to the Firebase interface.\n * It closes any currently open indexdb database connections.\n */\n async delete(): Promise {\n await Promise.all([\n this.tokenDetailsModel.closeDatabase(),\n this.vapidDetailsModel.closeDatabase()\n ]);\n }\n\n /**\n * Returns the current Notification Permission state.\n */\n getNotificationPermission_(): NotificationPermission {\n return Notification.permission;\n }\n\n getTokenDetailsModel(): TokenDetailsModel {\n return this.tokenDetailsModel;\n }\n\n getVapidDetailsModel(): VapidDetailsModel {\n return this.vapidDetailsModel;\n }\n\n // Visible for testing\n // TODO: make protected\n getIidModel(): IidModel {\n return this.iidModel;\n }\n}\n\n/**\n * Checks if the tokenDetails match the details provided in the clients.\n */\nfunction isTokenStillValid(\n pushSubscription: PushSubscription,\n publicVapidKey: Uint8Array,\n tokenDetails: TokenDetails\n): boolean {\n if (\n !tokenDetails.vapidKey ||\n !isArrayBufferEqual(publicVapidKey.buffer, tokenDetails.vapidKey.buffer)\n ) {\n return false;\n }\n\n const isEndpointEqual = pushSubscription.endpoint === tokenDetails.endpoint;\n const isAuthEqual = isArrayBufferEqual(\n pushSubscription.getKey('auth'),\n tokenDetails.auth\n );\n const isP256dhEqual = isArrayBufferEqual(\n pushSubscription.getKey('p256dh'),\n tokenDetails.p256dh\n );\n\n return isEndpointEqual && isAuthEqual && isP256dhEqual;\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport './sw-types';\n\nimport { FirebaseApp } from '@firebase/app-types';\n\nimport {\n MessagePayload,\n NotificationDetails\n} from '../interfaces/message-payload';\nimport { ErrorCode, errorFactory } from '../models/errors';\nimport { DEFAULT_PUBLIC_VAPID_KEY } from '../models/fcm-details';\nimport {\n InternalMessage,\n MessageParameter,\n MessageType\n} from '../models/worker-page-message';\nimport { BaseController, BgMessageHandler } from './base-controller';\n\n// Let TS know that this is a service worker\ndeclare const self: ServiceWorkerGlobalScope;\n\nconst FCM_MSG = 'FCM_MSG';\n\nexport class SwController extends BaseController {\n private bgMessageHandler: BgMessageHandler | null = null;\n\n constructor(app: FirebaseApp) {\n super(app);\n\n self.addEventListener('push', e => {\n this.onPush(e);\n });\n self.addEventListener('pushsubscriptionchange', e => {\n this.onSubChange(e);\n });\n self.addEventListener('notificationclick', e => {\n this.onNotificationClick(e);\n });\n }\n\n // Visible for testing\n // TODO: Make private\n onPush(event: PushEvent): void {\n event.waitUntil(this.onPush_(event));\n }\n\n // Visible for testing\n // TODO: Make private\n onSubChange(event: PushSubscriptionChangeEvent): void {\n event.waitUntil(this.onSubChange_(event));\n }\n\n // Visible for testing\n // TODO: Make private\n onNotificationClick(event: NotificationEvent): void {\n event.waitUntil(this.onNotificationClick_(event));\n }\n\n /**\n * A handler for push events that shows notifications based on the content of\n * the payload.\n *\n * The payload must be a JSON-encoded Object with a `notification` key. The\n * value of the `notification` property will be used as the NotificationOptions\n * object passed to showNotification. Additionally, the `title` property of the\n * notification object will be used as the title.\n *\n * If there is no notification data in the payload then no notification will be\n * shown.\n */\n private async onPush_(event: PushEvent): Promise {\n if (!event.data) {\n return;\n }\n\n let msgPayload: MessagePayload;\n try {\n msgPayload = event.data.json();\n } catch (err) {\n // Not JSON so not an FCM message\n return;\n }\n\n const hasVisibleClients = await this.hasVisibleClients_();\n if (hasVisibleClients) {\n // App in foreground. Send to page.\n return this.sendMessageToWindowClients_(msgPayload);\n }\n\n const notificationDetails = this.getNotificationData_(msgPayload);\n if (notificationDetails) {\n const notificationTitle = notificationDetails.title || '';\n const reg = await this.getSWRegistration_();\n\n const { actions } = notificationDetails;\n const { maxActions } = Notification;\n // tslint:enable no-any\n if (actions && maxActions && actions.length > maxActions) {\n console.warn(\n `This browser only supports ${maxActions} actions.` +\n `The remaining actions will not be displayed.`\n );\n }\n\n return reg.showNotification(notificationTitle, notificationDetails);\n } else if (this.bgMessageHandler) {\n await this.bgMessageHandler(msgPayload);\n return;\n }\n }\n\n private async onSubChange_(\n _event: PushSubscriptionChangeEvent\n ): Promise {\n let registration: ServiceWorkerRegistration;\n try {\n registration = await this.getSWRegistration_();\n } catch (err) {\n throw errorFactory.create(ErrorCode.UNABLE_TO_RESUBSCRIBE, {\n errorInfo: err\n });\n }\n\n try {\n await registration.pushManager.getSubscription();\n // TODO: Check if it's still valid. If not, then update token.\n } catch (err) {\n // The best thing we can do is log this to the terminal so\n // developers might notice the error.\n const tokenDetailsModel = this.getTokenDetailsModel();\n const tokenDetails = await tokenDetailsModel.getTokenDetailsFromSWScope(\n registration.scope\n );\n if (!tokenDetails) {\n // This should rarely occure, but could if indexedDB\n // is corrupted or wiped\n throw err;\n }\n\n // Attempt to delete the token if we know it's bad\n await this.deleteToken(tokenDetails.fcmToken);\n throw err;\n }\n }\n\n private async onNotificationClick_(event: NotificationEvent): Promise {\n if (\n !event.notification ||\n !event.notification.data ||\n !event.notification.data[FCM_MSG]\n ) {\n // Not an FCM notification, do nothing.\n return;\n } else if (event.action) {\n // User clicked on an action button.\n // This will allow devs to act on action button clicks by using a custom\n // onNotificationClick listener that they define.\n return;\n }\n\n // Prevent other listeners from receiving the event\n event.stopImmediatePropagation();\n event.notification.close();\n\n const msgPayload: MessagePayload = event.notification.data[FCM_MSG];\n if (!msgPayload.notification) {\n // Nothing to do.\n return;\n }\n\n const link =\n (msgPayload.fcmOptions && msgPayload.fcmOptions.link) ||\n msgPayload.notification.click_action;\n if (!link) {\n // Nothing to do.\n return;\n }\n\n let windowClient = await this.getWindowClient_(link);\n if (!windowClient) {\n // Unable to find window client so need to open one.\n windowClient = await self.clients.openWindow(link);\n } else {\n windowClient = await windowClient.focus();\n }\n\n if (!windowClient) {\n // Window Client will not be returned if it's for a third party origin.\n return;\n }\n\n // Delete notification and fcmOptions data from payload before sending to\n // the page.\n delete msgPayload.notification;\n delete msgPayload.fcmOptions;\n\n const internalMsg = createNewMsg(\n MessageType.NOTIFICATION_CLICKED,\n msgPayload\n );\n\n // Attempt to send a message to the client to handle the data\n // Is affected by: https://github.com/slightlyoff/ServiceWorker/issues/728\n return this.attemptToMessageClient_(windowClient, internalMsg);\n }\n\n // Visible for testing\n // TODO: Make private\n getNotificationData_(\n msgPayload: MessagePayload\n ): NotificationDetails | undefined {\n if (!msgPayload) {\n return;\n }\n\n if (typeof msgPayload.notification !== 'object') {\n return;\n }\n\n const notificationInformation: NotificationDetails = {\n ...msgPayload.notification\n };\n\n // Put the message payload under FCM_MSG name so we can identify the\n // notification as being an FCM notification vs a notification from\n // somewhere else (i.e. normal web push or developer generated\n // notification).\n notificationInformation.data = {\n ...msgPayload.notification.data,\n [FCM_MSG]: msgPayload\n };\n\n return notificationInformation;\n }\n\n /**\n * Calling setBackgroundMessageHandler will opt in to some specific\n * behaviours.\n * 1.) If a notification doesn't need to be shown due to a window already\n * being visible, then push messages will be sent to the page.\n * 2.) If a notification needs to be shown, and the message contains no\n * notification data this method will be called\n * and the promise it returns will be passed to event.waitUntil.\n * If you do not set this callback then all push messages will let and the\n * developer can handle them in a their own 'push' event callback\n *\n * @param callback The callback to be called when a push message is received\n * and a notification must be shown. The callback will be given the data from\n * the push message.\n */\n setBackgroundMessageHandler(callback: BgMessageHandler): void {\n if (!callback || typeof callback !== 'function') {\n throw errorFactory.create(ErrorCode.BG_HANDLER_FUNCTION_EXPECTED);\n }\n\n this.bgMessageHandler = callback;\n }\n\n /**\n * @param url The URL to look for when focusing a client.\n * @return Returns an existing window client or a newly opened WindowClient.\n */\n // Visible for testing\n // TODO: Make private\n async getWindowClient_(url: string): Promise {\n // Use URL to normalize the URL when comparing to windowClients.\n // This at least handles whether to include trailing slashes or not\n const parsedURL = new URL(url, self.location.href).href;\n\n const clientList = await getClientList();\n\n let suitableClient: WindowClient | null = null;\n for (let i = 0; i < clientList.length; i++) {\n const parsedClientUrl = new URL(clientList[i].url, self.location.href)\n .href;\n if (parsedClientUrl === parsedURL) {\n suitableClient = clientList[i];\n break;\n }\n }\n\n return suitableClient;\n }\n\n /**\n * This message will attempt to send the message to a window client.\n * @param client The WindowClient to send the message to.\n * @param message The message to send to the client.\n * @returns Returns a promise that resolves after sending the message. This\n * does not guarantee that the message was successfully received.\n */\n // Visible for testing\n // TODO: Make private\n async attemptToMessageClient_(\n client: WindowClient,\n message: InternalMessage\n ): Promise {\n // NOTE: This returns a promise in case this API is abstracted later on to\n // do additional work\n if (!client) {\n throw errorFactory.create(ErrorCode.NO_WINDOW_CLIENT_TO_MSG);\n }\n\n client.postMessage(message);\n }\n\n /**\n * @returns If there is currently a visible WindowClient, this method will\n * resolve to true, otherwise false.\n */\n // Visible for testing\n // TODO: Make private\n async hasVisibleClients_(): Promise {\n const clientList = await getClientList();\n\n return clientList.some(\n (client: WindowClient) =>\n client.visibilityState === 'visible' &&\n // Ignore chrome-extension clients as that matches the background pages\n // of extensions, which are always considered visible.\n !client.url.startsWith('chrome-extension://')\n );\n }\n\n /**\n * @param msgPayload The data from the push event that should be sent to all\n * available pages.\n * @returns Returns a promise that resolves once the message has been sent to\n * all WindowClients.\n */\n // Visible for testing\n // TODO: Make private\n async sendMessageToWindowClients_(msgPayload: MessagePayload): Promise {\n const clientList = await getClientList();\n\n const internalMsg = createNewMsg(MessageType.PUSH_MSG_RECEIVED, msgPayload);\n\n await Promise.all(\n clientList.map(client =>\n this.attemptToMessageClient_(client, internalMsg)\n )\n );\n }\n\n /**\n * This will register the default service worker and return the registration.\n * @return he service worker registration to be used for the push service.\n */\n async getSWRegistration_(): Promise {\n return self.registration;\n }\n\n /**\n * This will return the default VAPID key or the uint8array version of the\n * public VAPID key provided by the developer.\n */\n async getPublicVapidKey_(): Promise {\n const swReg = await this.getSWRegistration_();\n if (!swReg) {\n throw errorFactory.create(ErrorCode.SW_REGISTRATION_EXPECTED);\n }\n\n const vapidKeyFromDatabase = await this.getVapidDetailsModel().getVapidFromSWScope(\n swReg.scope\n );\n if (vapidKeyFromDatabase == null) {\n return DEFAULT_PUBLIC_VAPID_KEY;\n }\n\n return vapidKeyFromDatabase;\n }\n}\n\nfunction getClientList(): Promise {\n return self.clients.matchAll({\n type: 'window',\n includeUncontrolled: true\n // TS doesn't know that \"type: 'window'\" means it'll return WindowClient[]\n }) as Promise;\n}\n\nfunction createNewMsg(\n msgType: MessageType,\n msgData: MessagePayload\n): InternalMessage {\n return {\n [MessageParameter.TYPE_OF_MSG]: msgType,\n [MessageParameter.DATA]: msgData\n };\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport const DEFAULT_SW_PATH = '/firebase-messaging-sw.js';\nexport const DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope';\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport firebase from '@firebase/app';\nimport {\n _FirebaseNamespace,\n FirebaseServiceFactory\n} from '@firebase/app-types/private';\nimport { FirebaseMessaging } from '@firebase/messaging-types';\n\nimport { SwController } from './src/controllers/sw-controller';\nimport { WindowController } from './src/controllers/window-controller';\nimport { ErrorCode, errorFactory } from './src/models/errors';\n\nexport function registerMessaging(instance: _FirebaseNamespace): void {\n const messagingName = 'messaging';\n\n const factoryMethod: FirebaseServiceFactory = app => {\n if (!isSupported()) {\n throw errorFactory.create(ErrorCode.UNSUPPORTED_BROWSER);\n }\n\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return new SwController(app);\n } else {\n // Assume we are in the window context.\n return new WindowController(app);\n }\n };\n\n const namespaceExports = {\n isSupported\n };\n\n instance.INTERNAL.registerService(\n messagingName,\n factoryMethod,\n namespaceExports\n );\n}\n\nregisterMessaging(firebase as _FirebaseNamespace);\n\n/**\n * Define extension behavior of `registerMessaging`\n */\ndeclare module '@firebase/app-types' {\n interface FirebaseNamespace {\n messaging: {\n (app?: FirebaseApp): FirebaseMessaging;\n isSupported(): boolean;\n };\n }\n interface FirebaseApp {\n messaging(): FirebaseMessaging;\n }\n}\n\nexport function isSupported(): boolean {\n if (self && 'ServiceWorkerGlobalScope' in self) {\n // Running in ServiceWorker context\n return isSWControllerSupported();\n } else {\n // Assume we are in the window context.\n return isWindowControllerSupported();\n }\n}\n\n/**\n * Checks to see if the required APIs exist.\n */\nfunction isWindowControllerSupported(): boolean {\n return (\n navigator.cookieEnabled &&\n 'serviceWorker' in navigator &&\n 'PushManager' in window &&\n 'Notification' in window &&\n 'fetch' in window &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n\n/**\n * Checks to see if the required APIs exist within SW Context.\n */\nfunction isSWControllerSupported(): boolean {\n return (\n 'PushManager' in self &&\n 'Notification' in self &&\n ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') &&\n PushSubscription.prototype.hasOwnProperty('getKey')\n );\n}\n","/**\n * @license\n * Copyright 2017 Google Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { FirebaseApp } from '@firebase/app-types';\nimport {\n CompleteFn,\n createSubscribe,\n ErrorFn,\n NextFn,\n Observer,\n Subscribe,\n Unsubscribe\n} from '@firebase/util';\n\nimport { base64ToArrayBuffer } from '../helpers/base64-to-array-buffer';\nimport { DEFAULT_SW_PATH, DEFAULT_SW_SCOPE } from '../models/default-sw';\nimport { ErrorCode, errorFactory } from '../models/errors';\nimport { DEFAULT_PUBLIC_VAPID_KEY } from '../models/fcm-details';\nimport {\n InternalMessage,\n MessageParameter,\n MessageType\n} from '../models/worker-page-message';\nimport { BaseController } from './base-controller';\n\ninterface ManifestContent {\n // eslint-disable-next-line camelcase\n gcm_sender_id: string;\n}\n\nexport class WindowController extends BaseController {\n private registrationToUse: ServiceWorkerRegistration | null = null;\n private publicVapidKeyToUse: Uint8Array | null = null;\n private manifestCheckPromise: Promise | null = null;\n\n private messageObserver: Observer | null = null;\n // @ts-ignore: Unused variable error, this is not implemented yet.\n private tokenRefreshObserver: Observer | null = null;\n\n private readonly onMessageInternal: Subscribe = createSubscribe(\n observer => {\n this.messageObserver = observer;\n }\n );\n\n private readonly onTokenRefreshInternal: Subscribe = createSubscribe(\n observer => {\n this.tokenRefreshObserver = observer;\n }\n );\n\n /**\n * A service that provides a MessagingService instance.\n */\n constructor(app: FirebaseApp) {\n super(app);\n\n this.setupSWMessageListener_();\n }\n\n /**\n * This method returns an FCM token if it can be generated.\n * The return promise will reject if the browser doesn't support\n * FCM, if permission is denied for notifications or it's not\n * possible to generate a token.\n *\n * @return Returns a promise that resolves to an FCM token or null if\n * permission isn't granted.\n */\n async getToken(): Promise {\n if (!this.manifestCheckPromise) {\n this.manifestCheckPromise = manifestCheck();\n }\n await this.manifestCheckPromise;\n return super.getToken();\n }\n\n /**\n * Request permission if it is not currently granted\n *\n * @return Resolves if the permission was granted, otherwise rejects\n *\n * @deprecated Use Notification.requestPermission() instead.\n * https://developer.mozilla.org/en-US/docs/Web/API/Notification/requestPermission\n */\n async requestPermission(): Promise {\n if (this.getNotificationPermission_() === 'granted') {\n return;\n }\n\n const permissionResult = await Notification.requestPermission();\n if (permissionResult === 'granted') {\n return;\n } else if (permissionResult === 'denied') {\n throw errorFactory.create(ErrorCode.PERMISSION_BLOCKED);\n } else {\n throw errorFactory.create(ErrorCode.PERMISSION_DEFAULT);\n }\n }\n\n /**\n * This method allows a developer to override the default service worker and\n * instead use a custom service worker.\n *\n * @param registration The service worker registration that should be used to\n * receive the push messages.\n */\n useServiceWorker(registration: ServiceWorkerRegistration): void {\n if (!(registration instanceof ServiceWorkerRegistration)) {\n throw errorFactory.create(ErrorCode.SW_REGISTRATION_EXPECTED);\n }\n\n if (this.registrationToUse != null) {\n throw errorFactory.create(ErrorCode.USE_SW_BEFORE_GET_TOKEN);\n }\n\n this.registrationToUse = registration;\n }\n\n /**\n * This method allows a developer to override the default vapid key\n * and instead use a custom VAPID public key.\n *\n * @param publicKey A URL safe base64 encoded string.\n */\n usePublicVapidKey(publicKey: string): void {\n if (typeof publicKey !== 'string') {\n throw errorFactory.create(ErrorCode.INVALID_PUBLIC_VAPID_KEY);\n }\n\n if (this.publicVapidKeyToUse != null) {\n throw errorFactory.create(ErrorCode.USE_PUBLIC_KEY_BEFORE_GET_TOKEN);\n }\n\n const parsedKey = base64ToArrayBuffer(publicKey);\n\n if (parsedKey.length !== 65) {\n throw errorFactory.create(ErrorCode.PUBLIC_KEY_DECRYPTION_FAILED);\n }\n\n this.publicVapidKeyToUse = parsedKey;\n }\n\n /**\n * @export\n * @param nextOrObserver An observer object or a function triggered on\n * message.\n * @param error A function triggered on message error.\n * @param completed function triggered when the observer is removed.\n * @return The unsubscribe function for the observer.\n */\n onMessage(\n nextOrObserver: NextFn | Observer,\n error?: ErrorFn,\n completed?: CompleteFn\n ): Unsubscribe {\n if (typeof nextOrObserver === 'function') {\n return this.onMessageInternal(nextOrObserver, error, completed);\n } else {\n return this.onMessageInternal(nextOrObserver);\n }\n }\n\n /**\n * @param nextOrObserver An observer object or a function triggered on token\n * refresh.\n * @param error A function triggered on token refresh error.\n * @param completed function triggered when the observer is removed.\n * @return The unsubscribe function for the observer.\n */\n onTokenRefresh(\n nextOrObserver: NextFn | Observer,\n error?: ErrorFn,\n completed?: CompleteFn\n ): Unsubscribe {\n if (typeof nextOrObserver === 'function') {\n return this.onTokenRefreshInternal(nextOrObserver, error, completed);\n } else {\n return this.onTokenRefreshInternal(nextOrObserver);\n }\n }\n\n /**\n * Given a registration, wait for the service worker it relates to\n * become activer\n * @param registration Registration to wait for service worker to become active\n * @return Wait for service worker registration to become active\n */\n // Visible for testing\n // TODO: Make private\n waitForRegistrationToActivate_(\n registration: ServiceWorkerRegistration\n ): Promise {\n const serviceWorker =\n registration.installing || registration.waiting || registration.active;\n\n return new Promise((resolve, reject) => {\n if (!serviceWorker) {\n // This is a rare scenario but has occured in firefox\n reject(errorFactory.create(ErrorCode.NO_SW_IN_REG));\n return;\n }\n // Because the Promise function is called on next tick there is a\n // small chance that the worker became active or redundant already.\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n return;\n }\n\n if (serviceWorker.state === 'redundant') {\n reject(errorFactory.create(ErrorCode.SW_REG_REDUNDANT));\n return;\n }\n\n const stateChangeListener = (): void => {\n if (serviceWorker.state === 'activated') {\n resolve(registration);\n } else if (serviceWorker.state === 'redundant') {\n reject(errorFactory.create(ErrorCode.SW_REG_REDUNDANT));\n } else {\n // Return early and wait to next state change\n return;\n }\n serviceWorker.removeEventListener('statechange', stateChangeListener);\n };\n serviceWorker.addEventListener('statechange', stateChangeListener);\n });\n }\n\n /**\n * This will register the default service worker and return the registration\n * @return The service worker registration to be used for the push service.\n */\n getSWRegistration_(): Promise {\n if (this.registrationToUse) {\n return this.waitForRegistrationToActivate_(this.registrationToUse);\n }\n\n // Make the registration null so we know useServiceWorker will not\n // use a new service worker as registrationToUse is no longer undefined\n this.registrationToUse = null;\n\n return navigator.serviceWorker\n .register(DEFAULT_SW_PATH, {\n scope: DEFAULT_SW_SCOPE\n })\n .catch((err: Error) => {\n throw errorFactory.create(ErrorCode.FAILED_DEFAULT_REGISTRATION, {\n browserErrorMessage: err.message\n });\n })\n .then((registration: ServiceWorkerRegistration) => {\n return this.waitForRegistrationToActivate_(registration).then(() => {\n this.registrationToUse = registration;\n\n // We update after activation due to an issue with Firefox v49 where\n // a race condition occassionally causes the service worker to not\n // install\n // tslint:disable-next-line:no-floating-promises\n registration.update();\n\n return registration;\n });\n });\n }\n\n /**\n * This will return the default VAPID key or the uint8array version of the public VAPID key\n * provided by the developer.\n */\n async getPublicVapidKey_(): Promise {\n if (this.publicVapidKeyToUse) {\n return this.publicVapidKeyToUse;\n }\n\n return DEFAULT_PUBLIC_VAPID_KEY;\n }\n\n /**\n * This method will set up a message listener to handle\n * events from the service worker that should trigger\n * events in the page.\n */\n // Visible for testing\n // TODO: Make private\n setupSWMessageListener_(): void {\n navigator.serviceWorker.addEventListener(\n 'message',\n event => {\n if (!event.data || !event.data[MessageParameter.TYPE_OF_MSG]) {\n // Not a message from FCM\n return;\n }\n\n const workerPageMessage: InternalMessage = event.data;\n switch (workerPageMessage[MessageParameter.TYPE_OF_MSG]) {\n case MessageType.PUSH_MSG_RECEIVED:\n case MessageType.NOTIFICATION_CLICKED:\n const pushMessage = workerPageMessage[MessageParameter.DATA];\n if (this.messageObserver) {\n this.messageObserver.next(pushMessage);\n }\n break;\n default:\n // Noop.\n break;\n }\n },\n false\n );\n }\n}\n\n/**\n * The method checks that a manifest is defined and has the correct GCM\n * sender ID.\n * @return Returns a promise that resolves if the manifest matches\n * our required sender ID\n */\n// Exported for testing\nexport async function manifestCheck(): Promise {\n const manifestTag = document.querySelector(\n 'link[rel=\"manifest\"]'\n );\n\n if (!manifestTag) {\n return;\n }\n\n let manifestContent: ManifestContent;\n try {\n const response = await fetch(manifestTag.href);\n manifestContent = await response.json();\n } catch (e) {\n // If the download or parsing fails allow check.\n // We only want to error if we KNOW that the gcm_sender_id is incorrect.\n return;\n }\n\n if (!manifestContent || !manifestContent.gcm_sender_id) {\n return;\n }\n\n if (manifestContent.gcm_sender_id !== '103953800507') {\n throw errorFactory.create(ErrorCode.INCORRECT_GCM_SENDER_ID);\n }\n}\n"],"names":["extendStatics","d","b","Object","setPrototypeOf","__proto__","Array","p","hasOwnProperty","__extends","__","this","constructor","prototype","create","__assign","assign","t","s","i","n","arguments","length","call","apply","__awaiter","thisArg","_arguments","P","generator","Promise","resolve","reject","fulfilled","value","step","next","e","rejected","result","done","then","__generator","body","f","y","g","_","label","sent","trys","ops","verb","throw","return","Symbol","iterator","v","op","TypeError","pop","push","__values","o","m","__read","r","ar","error","atob","Base64","ENCODED_VALS_BASE","input","webSafe","isArray","Error","init_","byteToCharMap","byteToCharMapWebSafe_","byteToCharMap_","output","byte1","haveByte2","byte2","haveByte3","byte3","outByte1","outByte2","outByte3","outByte4","join","HAS_NATIVE_SUPPORT","btoa","encodeByteArray","str","out","c","charCodeAt","stringToByteArray","bytes","pos","c1","String","fromCharCode","c2","u","c3","byteArrayToString","decodeStringToByteArray","charToByteMap","charToByteMapWebSafe_","charToByteMap_","charAt","byte4","ENCODED_VALS","ENCODED_VALS_WEBSAFE","code","message","_super","_this","FirebaseError","captureStackTrace","ErrorFactory","tslib_1.__extends","service","serviceName","errors","_i","data","customData","fullCode","template","replace","PATTERN","key","toString","fullMessage","_b","tslib_1.__values","keys","slice","console","warn","createSubscribe","executor","onNoObservers","proxy","ObserverProxy","subscribe","bind","task","catch","forEachObserver","observer","close","complete","nextOrObserver","undefined","obj","methods","methods_1","method","implementsAnyMethods","noop","unsub","unsubscribeOne","observers","finalized","finalError","observerCount","fn","sendOne","err","MessageParameter","MessageType","ERROR_MAP","_a","errorFactory","DEFAULT_PUBLIC_VAPID_KEY","Uint8Array","ENDPOINT","isArrayBufferEqual","a","byteLength","viewA","DataView","viewB","getUint8","toBase64","arrayBuffer","uint8Version","concat","arrayBufferToBase64","IidModel","senderId","subscription","publicVapidKey","p256dh","getKey","auth","fcmSubscribeBody","endpoint","buffer","applicationPubKey","headers","Headers","append","subscribeOptions","fetch","json","responseData","errorInfo","err_1","token","pushSet","fcmToken","fcmPushSet","fcmUpdateBody","updateOptions","err_2","fcmUnsubscribeBody","unsubscribeOptions","err_3","base64ToArrayBuffer","base64String","base64","repeat","rawData","outputArray","OLD_DB_NAME","OLD_OBJECT_STORE_NAME","cleanV1","request","indexedDB","open","onerror","_event","onsuccess","db","objectStoreNames","contains","objectStore","transaction","iidModel","openCursorRequest","openCursor","event","cursor","tokenDetails","deleteToken","fcmSenderId","continue","deleteDatabase","handleDb","DbInterface","createTransaction","get","index","put","delete","dbPromise","runRequest","mode","getDb","objectStoreName","oncomplete","dbName","dbVersion","onupgradeneeded","onDbUpgrade","TokenDetailsModel","oldVersion","createObjectStore","keyPath","createIndex","unique","cursorRequest_1","newValue","createTime","Date","now","vapidKey","update","validateInputs","getIndex","swScope","getTokenDetailsFromToken","details","ArrayBuffer","VapidDetailsModel","getVapidFromSWScope","SENDER_ID_OPTION_NAME","app","options","messagingSenderId","tokenDetailsModel","vapidDetailsModel","INTERNAL","BaseController","currentPermission","getNotificationPermission_","getSWRegistration_","swReg","getPublicVapidKey_","getPushSubscription","pushSubscription","getTokenDetailsFromSWScope","scope","manageExistingToken","getNewToken","isEndpointEqual","isAuthEqual","isP256dhEqual","isTokenStillValid","updateToken","deleteTokenFromDB","updatedToken","allDetails","saveTokenDetails","saveVapidDetails","e_1","getToken","registration","pushManager","getSubscription","unsubscribe","swRegistration","userVisibleOnly","applicationServerKey","_registration","_b64PublicKey","_nextOrObserver","_error","_completed","_callback","all","closeDatabase","Notification","permission","FCM_MSG","self","addEventListener","onPush","onSubChange","onNotificationClick","SwController","waitUntil","onPush_","onSubChange_","onNotificationClick_","msgPayload","hasVisibleClients_","sendMessageToWindowClients_","notificationDetails","getNotificationData_","notificationTitle","title","reg","actions","maxActions","showNotification","bgMessageHandler","getTokenDetailsModel","notification","action","stopImmediatePropagation","link","fcmOptions","click_action","getWindowClient_","windowClient","clients","openWindow","focus","internalMsg","createNewMsg","NOTIFICATION_CLICKED","attemptToMessageClient_","notificationInformation","callback","url","parsedURL","URL","location","href","getClientList","clientList","suitableClient","client","postMessage","some","visibilityState","startsWith","PUSH_MSG_RECEIVED","map","getVapidDetailsModel","vapidKeyFromDatabase","matchAll","type","includeUncontrolled","msgType","msgData","TYPE_OF_MSG","DATA","namespaceExports","messageObserver","tokenRefreshObserver","setupSWMessageListener_","WindowController","manifestCheckPromise","manifestTag","document","querySelector","manifestContent","gcm_sender_id","manifestCheck","requestPermission","permissionResult","ServiceWorkerRegistration","registrationToUse","publicKey","publicVapidKeyToUse","parsedKey","completed","onMessageInternal","onTokenRefreshInternal","serviceWorker","installing","waiting","active","state","stateChangeListener","removeEventListener","waitForRegistrationToActivate_","navigator","register","browserErrorMessage","workerPageMessage","pushMessage","isSupported","PushSubscription","cookieEnabled","window","firebase","registerService"],"mappings":"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"}