No Description
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.cjs.js 57KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var app = require('@firebase/app');
  4. var component = require('@firebase/component');
  5. var tslib = require('tslib');
  6. var util = require('@firebase/util');
  7. var idb = require('idb');
  8. var name = "@firebase/installations";
  9. var version = "0.6.1";
  10. /**
  11. * @license
  12. * Copyright 2019 Google LLC
  13. *
  14. * Licensed under the Apache License, Version 2.0 (the "License");
  15. * you may not use this file except in compliance with the License.
  16. * You may obtain a copy of the License at
  17. *
  18. * http://www.apache.org/licenses/LICENSE-2.0
  19. *
  20. * Unless required by applicable law or agreed to in writing, software
  21. * distributed under the License is distributed on an "AS IS" BASIS,
  22. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  23. * See the License for the specific language governing permissions and
  24. * limitations under the License.
  25. */
  26. var PENDING_TIMEOUT_MS = 10000;
  27. var PACKAGE_VERSION = "w:".concat(version);
  28. var INTERNAL_AUTH_VERSION = 'FIS_v2';
  29. var INSTALLATIONS_API_URL = 'https://firebaseinstallations.googleapis.com/v1';
  30. var TOKEN_EXPIRATION_BUFFER = 60 * 60 * 1000; // One hour
  31. var SERVICE = 'installations';
  32. var SERVICE_NAME = 'Installations';
  33. /**
  34. * @license
  35. * Copyright 2019 Google LLC
  36. *
  37. * Licensed under the Apache License, Version 2.0 (the "License");
  38. * you may not use this file except in compliance with the License.
  39. * You may obtain a copy of the License at
  40. *
  41. * http://www.apache.org/licenses/LICENSE-2.0
  42. *
  43. * Unless required by applicable law or agreed to in writing, software
  44. * distributed under the License is distributed on an "AS IS" BASIS,
  45. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  46. * See the License for the specific language governing permissions and
  47. * limitations under the License.
  48. */
  49. var _a;
  50. var ERROR_DESCRIPTION_MAP = (_a = {},
  51. _a["missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */] = 'Missing App configuration value: "{$valueName}"',
  52. _a["not-registered" /* ErrorCode.NOT_REGISTERED */] = 'Firebase Installation is not registered.',
  53. _a["installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */] = 'Firebase Installation not found.',
  54. _a["request-failed" /* ErrorCode.REQUEST_FAILED */] = '{$requestName} request failed with error "{$serverCode} {$serverStatus}: {$serverMessage}"',
  55. _a["app-offline" /* ErrorCode.APP_OFFLINE */] = 'Could not process request. Application offline.',
  56. _a["delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */] = "Can't delete installation while there is a pending registration request.",
  57. _a);
  58. var ERROR_FACTORY = new util.ErrorFactory(SERVICE, SERVICE_NAME, ERROR_DESCRIPTION_MAP);
  59. /** Returns true if error is a FirebaseError that is based on an error from the server. */
  60. function isServerError(error) {
  61. return (error instanceof util.FirebaseError &&
  62. error.code.includes("request-failed" /* ErrorCode.REQUEST_FAILED */));
  63. }
  64. /**
  65. * @license
  66. * Copyright 2019 Google LLC
  67. *
  68. * Licensed under the Apache License, Version 2.0 (the "License");
  69. * you may not use this file except in compliance with the License.
  70. * You may obtain a copy of the License at
  71. *
  72. * http://www.apache.org/licenses/LICENSE-2.0
  73. *
  74. * Unless required by applicable law or agreed to in writing, software
  75. * distributed under the License is distributed on an "AS IS" BASIS,
  76. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  77. * See the License for the specific language governing permissions and
  78. * limitations under the License.
  79. */
  80. function getInstallationsEndpoint(_a) {
  81. var projectId = _a.projectId;
  82. return "".concat(INSTALLATIONS_API_URL, "/projects/").concat(projectId, "/installations");
  83. }
  84. function extractAuthTokenInfoFromResponse(response) {
  85. return {
  86. token: response.token,
  87. requestStatus: 2 /* RequestStatus.COMPLETED */,
  88. expiresIn: getExpiresInFromResponseExpiresIn(response.expiresIn),
  89. creationTime: Date.now()
  90. };
  91. }
  92. function getErrorFromResponse(requestName, response) {
  93. return tslib.__awaiter(this, void 0, void 0, function () {
  94. var responseJson, errorData;
  95. return tslib.__generator(this, function (_a) {
  96. switch (_a.label) {
  97. case 0: return [4 /*yield*/, response.json()];
  98. case 1:
  99. responseJson = _a.sent();
  100. errorData = responseJson.error;
  101. return [2 /*return*/, ERROR_FACTORY.create("request-failed" /* ErrorCode.REQUEST_FAILED */, {
  102. requestName: requestName,
  103. serverCode: errorData.code,
  104. serverMessage: errorData.message,
  105. serverStatus: errorData.status
  106. })];
  107. }
  108. });
  109. });
  110. }
  111. function getHeaders(_a) {
  112. var apiKey = _a.apiKey;
  113. return new Headers({
  114. 'Content-Type': 'application/json',
  115. Accept: 'application/json',
  116. 'x-goog-api-key': apiKey
  117. });
  118. }
  119. function getHeadersWithAuth(appConfig, _a) {
  120. var refreshToken = _a.refreshToken;
  121. var headers = getHeaders(appConfig);
  122. headers.append('Authorization', getAuthorizationHeader(refreshToken));
  123. return headers;
  124. }
  125. /**
  126. * Calls the passed in fetch wrapper and returns the response.
  127. * If the returned response has a status of 5xx, re-runs the function once and
  128. * returns the response.
  129. */
  130. function retryIfServerError(fn) {
  131. return tslib.__awaiter(this, void 0, void 0, function () {
  132. var result;
  133. return tslib.__generator(this, function (_a) {
  134. switch (_a.label) {
  135. case 0: return [4 /*yield*/, fn()];
  136. case 1:
  137. result = _a.sent();
  138. if (result.status >= 500 && result.status < 600) {
  139. // Internal Server Error. Retry request.
  140. return [2 /*return*/, fn()];
  141. }
  142. return [2 /*return*/, result];
  143. }
  144. });
  145. });
  146. }
  147. function getExpiresInFromResponseExpiresIn(responseExpiresIn) {
  148. // This works because the server will never respond with fractions of a second.
  149. return Number(responseExpiresIn.replace('s', '000'));
  150. }
  151. function getAuthorizationHeader(refreshToken) {
  152. return "".concat(INTERNAL_AUTH_VERSION, " ").concat(refreshToken);
  153. }
  154. /**
  155. * @license
  156. * Copyright 2019 Google LLC
  157. *
  158. * Licensed under the Apache License, Version 2.0 (the "License");
  159. * you may not use this file except in compliance with the License.
  160. * You may obtain a copy of the License at
  161. *
  162. * http://www.apache.org/licenses/LICENSE-2.0
  163. *
  164. * Unless required by applicable law or agreed to in writing, software
  165. * distributed under the License is distributed on an "AS IS" BASIS,
  166. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  167. * See the License for the specific language governing permissions and
  168. * limitations under the License.
  169. */
  170. function createInstallationRequest(_a, _b) {
  171. var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
  172. var fid = _b.fid;
  173. return tslib.__awaiter(this, void 0, void 0, function () {
  174. var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, registeredInstallationEntry;
  175. return tslib.__generator(this, function (_c) {
  176. switch (_c.label) {
  177. case 0:
  178. endpoint = getInstallationsEndpoint(appConfig);
  179. headers = getHeaders(appConfig);
  180. heartbeatService = heartbeatServiceProvider.getImmediate({
  181. optional: true
  182. });
  183. if (!heartbeatService) return [3 /*break*/, 2];
  184. return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
  185. case 1:
  186. heartbeatsHeader = _c.sent();
  187. if (heartbeatsHeader) {
  188. headers.append('x-firebase-client', heartbeatsHeader);
  189. }
  190. _c.label = 2;
  191. case 2:
  192. body = {
  193. fid: fid,
  194. authVersion: INTERNAL_AUTH_VERSION,
  195. appId: appConfig.appId,
  196. sdkVersion: PACKAGE_VERSION
  197. };
  198. request = {
  199. method: 'POST',
  200. headers: headers,
  201. body: JSON.stringify(body)
  202. };
  203. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  204. case 3:
  205. response = _c.sent();
  206. if (!response.ok) return [3 /*break*/, 5];
  207. return [4 /*yield*/, response.json()];
  208. case 4:
  209. responseValue = _c.sent();
  210. registeredInstallationEntry = {
  211. fid: responseValue.fid || fid,
  212. registrationStatus: 2 /* RequestStatus.COMPLETED */,
  213. refreshToken: responseValue.refreshToken,
  214. authToken: extractAuthTokenInfoFromResponse(responseValue.authToken)
  215. };
  216. return [2 /*return*/, registeredInstallationEntry];
  217. case 5: return [4 /*yield*/, getErrorFromResponse('Create Installation', response)];
  218. case 6: throw _c.sent();
  219. }
  220. });
  221. });
  222. }
  223. /**
  224. * @license
  225. * Copyright 2019 Google LLC
  226. *
  227. * Licensed under the Apache License, Version 2.0 (the "License");
  228. * you may not use this file except in compliance with the License.
  229. * You may obtain a copy of the License at
  230. *
  231. * http://www.apache.org/licenses/LICENSE-2.0
  232. *
  233. * Unless required by applicable law or agreed to in writing, software
  234. * distributed under the License is distributed on an "AS IS" BASIS,
  235. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  236. * See the License for the specific language governing permissions and
  237. * limitations under the License.
  238. */
  239. /** Returns a promise that resolves after given time passes. */
  240. function sleep(ms) {
  241. return new Promise(function (resolve) {
  242. setTimeout(resolve, ms);
  243. });
  244. }
  245. /**
  246. * @license
  247. * Copyright 2019 Google LLC
  248. *
  249. * Licensed under the Apache License, Version 2.0 (the "License");
  250. * you may not use this file except in compliance with the License.
  251. * You may obtain a copy of the License at
  252. *
  253. * http://www.apache.org/licenses/LICENSE-2.0
  254. *
  255. * Unless required by applicable law or agreed to in writing, software
  256. * distributed under the License is distributed on an "AS IS" BASIS,
  257. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  258. * See the License for the specific language governing permissions and
  259. * limitations under the License.
  260. */
  261. function bufferToBase64UrlSafe(array) {
  262. var b64 = btoa(String.fromCharCode.apply(String, tslib.__spreadArray([], tslib.__read(array), false)));
  263. return b64.replace(/\+/g, '-').replace(/\//g, '_');
  264. }
  265. /**
  266. * @license
  267. * Copyright 2019 Google LLC
  268. *
  269. * Licensed under the Apache License, Version 2.0 (the "License");
  270. * you may not use this file except in compliance with the License.
  271. * You may obtain a copy of the License at
  272. *
  273. * http://www.apache.org/licenses/LICENSE-2.0
  274. *
  275. * Unless required by applicable law or agreed to in writing, software
  276. * distributed under the License is distributed on an "AS IS" BASIS,
  277. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  278. * See the License for the specific language governing permissions and
  279. * limitations under the License.
  280. */
  281. var VALID_FID_PATTERN = /^[cdef][\w-]{21}$/;
  282. var INVALID_FID = '';
  283. /**
  284. * Generates a new FID using random values from Web Crypto API.
  285. * Returns an empty string if FID generation fails for any reason.
  286. */
  287. function generateFid() {
  288. try {
  289. // A valid FID has exactly 22 base64 characters, which is 132 bits, or 16.5
  290. // bytes. our implementation generates a 17 byte array instead.
  291. var fidByteArray = new Uint8Array(17);
  292. var crypto_1 = self.crypto || self.msCrypto;
  293. crypto_1.getRandomValues(fidByteArray);
  294. // Replace the first 4 random bits with the constant FID header of 0b0111.
  295. fidByteArray[0] = 112 + (fidByteArray[0] % 16);
  296. var fid = encode(fidByteArray);
  297. return VALID_FID_PATTERN.test(fid) ? fid : INVALID_FID;
  298. }
  299. catch (_a) {
  300. // FID generation errored
  301. return INVALID_FID;
  302. }
  303. }
  304. /** Converts a FID Uint8Array to a base64 string representation. */
  305. function encode(fidByteArray) {
  306. var b64String = bufferToBase64UrlSafe(fidByteArray);
  307. // Remove the 23rd character that was added because of the extra 4 bits at the
  308. // end of our 17 byte array, and the '=' padding.
  309. return b64String.substr(0, 22);
  310. }
  311. /**
  312. * @license
  313. * Copyright 2019 Google LLC
  314. *
  315. * Licensed under the Apache License, Version 2.0 (the "License");
  316. * you may not use this file except in compliance with the License.
  317. * You may obtain a copy of the License at
  318. *
  319. * http://www.apache.org/licenses/LICENSE-2.0
  320. *
  321. * Unless required by applicable law or agreed to in writing, software
  322. * distributed under the License is distributed on an "AS IS" BASIS,
  323. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  324. * See the License for the specific language governing permissions and
  325. * limitations under the License.
  326. */
  327. /** Returns a string key that can be used to identify the app. */
  328. function getKey(appConfig) {
  329. return "".concat(appConfig.appName, "!").concat(appConfig.appId);
  330. }
  331. /**
  332. * @license
  333. * Copyright 2019 Google LLC
  334. *
  335. * Licensed under the Apache License, Version 2.0 (the "License");
  336. * you may not use this file except in compliance with the License.
  337. * You may obtain a copy of the License at
  338. *
  339. * http://www.apache.org/licenses/LICENSE-2.0
  340. *
  341. * Unless required by applicable law or agreed to in writing, software
  342. * distributed under the License is distributed on an "AS IS" BASIS,
  343. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  344. * See the License for the specific language governing permissions and
  345. * limitations under the License.
  346. */
  347. var fidChangeCallbacks = new Map();
  348. /**
  349. * Calls the onIdChange callbacks with the new FID value, and broadcasts the
  350. * change to other tabs.
  351. */
  352. function fidChanged(appConfig, fid) {
  353. var key = getKey(appConfig);
  354. callFidChangeCallbacks(key, fid);
  355. broadcastFidChange(key, fid);
  356. }
  357. function addCallback(appConfig, callback) {
  358. // Open the broadcast channel if it's not already open,
  359. // to be able to listen to change events from other tabs.
  360. getBroadcastChannel();
  361. var key = getKey(appConfig);
  362. var callbackSet = fidChangeCallbacks.get(key);
  363. if (!callbackSet) {
  364. callbackSet = new Set();
  365. fidChangeCallbacks.set(key, callbackSet);
  366. }
  367. callbackSet.add(callback);
  368. }
  369. function removeCallback(appConfig, callback) {
  370. var key = getKey(appConfig);
  371. var callbackSet = fidChangeCallbacks.get(key);
  372. if (!callbackSet) {
  373. return;
  374. }
  375. callbackSet.delete(callback);
  376. if (callbackSet.size === 0) {
  377. fidChangeCallbacks.delete(key);
  378. }
  379. // Close broadcast channel if there are no more callbacks.
  380. closeBroadcastChannel();
  381. }
  382. function callFidChangeCallbacks(key, fid) {
  383. var e_1, _a;
  384. var callbacks = fidChangeCallbacks.get(key);
  385. if (!callbacks) {
  386. return;
  387. }
  388. try {
  389. for (var callbacks_1 = tslib.__values(callbacks), callbacks_1_1 = callbacks_1.next(); !callbacks_1_1.done; callbacks_1_1 = callbacks_1.next()) {
  390. var callback = callbacks_1_1.value;
  391. callback(fid);
  392. }
  393. }
  394. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  395. finally {
  396. try {
  397. if (callbacks_1_1 && !callbacks_1_1.done && (_a = callbacks_1.return)) _a.call(callbacks_1);
  398. }
  399. finally { if (e_1) throw e_1.error; }
  400. }
  401. }
  402. function broadcastFidChange(key, fid) {
  403. var channel = getBroadcastChannel();
  404. if (channel) {
  405. channel.postMessage({ key: key, fid: fid });
  406. }
  407. closeBroadcastChannel();
  408. }
  409. var broadcastChannel = null;
  410. /** Opens and returns a BroadcastChannel if it is supported by the browser. */
  411. function getBroadcastChannel() {
  412. if (!broadcastChannel && 'BroadcastChannel' in self) {
  413. broadcastChannel = new BroadcastChannel('[Firebase] FID Change');
  414. broadcastChannel.onmessage = function (e) {
  415. callFidChangeCallbacks(e.data.key, e.data.fid);
  416. };
  417. }
  418. return broadcastChannel;
  419. }
  420. function closeBroadcastChannel() {
  421. if (fidChangeCallbacks.size === 0 && broadcastChannel) {
  422. broadcastChannel.close();
  423. broadcastChannel = null;
  424. }
  425. }
  426. /**
  427. * @license
  428. * Copyright 2019 Google LLC
  429. *
  430. * Licensed under the Apache License, Version 2.0 (the "License");
  431. * you may not use this file except in compliance with the License.
  432. * You may obtain a copy of the License at
  433. *
  434. * http://www.apache.org/licenses/LICENSE-2.0
  435. *
  436. * Unless required by applicable law or agreed to in writing, software
  437. * distributed under the License is distributed on an "AS IS" BASIS,
  438. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  439. * See the License for the specific language governing permissions and
  440. * limitations under the License.
  441. */
  442. var DATABASE_NAME = 'firebase-installations-database';
  443. var DATABASE_VERSION = 1;
  444. var OBJECT_STORE_NAME = 'firebase-installations-store';
  445. var dbPromise = null;
  446. function getDbPromise() {
  447. if (!dbPromise) {
  448. dbPromise = idb.openDB(DATABASE_NAME, DATABASE_VERSION, {
  449. upgrade: function (db, oldVersion) {
  450. // We don't use 'break' in this switch statement, the fall-through
  451. // behavior is what we want, because if there are multiple versions between
  452. // the old version and the current version, we want ALL the migrations
  453. // that correspond to those versions to run, not only the last one.
  454. // eslint-disable-next-line default-case
  455. switch (oldVersion) {
  456. case 0:
  457. db.createObjectStore(OBJECT_STORE_NAME);
  458. }
  459. }
  460. });
  461. }
  462. return dbPromise;
  463. }
  464. /** Assigns or overwrites the record for the given key with the given value. */
  465. function set(appConfig, value) {
  466. return tslib.__awaiter(this, void 0, void 0, function () {
  467. var key, db, tx, objectStore, oldValue;
  468. return tslib.__generator(this, function (_a) {
  469. switch (_a.label) {
  470. case 0:
  471. key = getKey(appConfig);
  472. return [4 /*yield*/, getDbPromise()];
  473. case 1:
  474. db = _a.sent();
  475. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  476. objectStore = tx.objectStore(OBJECT_STORE_NAME);
  477. return [4 /*yield*/, objectStore.get(key)];
  478. case 2:
  479. oldValue = (_a.sent());
  480. return [4 /*yield*/, objectStore.put(value, key)];
  481. case 3:
  482. _a.sent();
  483. return [4 /*yield*/, tx.done];
  484. case 4:
  485. _a.sent();
  486. if (!oldValue || oldValue.fid !== value.fid) {
  487. fidChanged(appConfig, value.fid);
  488. }
  489. return [2 /*return*/, value];
  490. }
  491. });
  492. });
  493. }
  494. /** Removes record(s) from the objectStore that match the given key. */
  495. function remove(appConfig) {
  496. return tslib.__awaiter(this, void 0, void 0, function () {
  497. var key, db, tx;
  498. return tslib.__generator(this, function (_a) {
  499. switch (_a.label) {
  500. case 0:
  501. key = getKey(appConfig);
  502. return [4 /*yield*/, getDbPromise()];
  503. case 1:
  504. db = _a.sent();
  505. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  506. return [4 /*yield*/, tx.objectStore(OBJECT_STORE_NAME).delete(key)];
  507. case 2:
  508. _a.sent();
  509. return [4 /*yield*/, tx.done];
  510. case 3:
  511. _a.sent();
  512. return [2 /*return*/];
  513. }
  514. });
  515. });
  516. }
  517. /**
  518. * Atomically updates a record with the result of updateFn, which gets
  519. * called with the current value. If newValue is undefined, the record is
  520. * deleted instead.
  521. * @return Updated value
  522. */
  523. function update(appConfig, updateFn) {
  524. return tslib.__awaiter(this, void 0, void 0, function () {
  525. var key, db, tx, store, oldValue, newValue;
  526. return tslib.__generator(this, function (_a) {
  527. switch (_a.label) {
  528. case 0:
  529. key = getKey(appConfig);
  530. return [4 /*yield*/, getDbPromise()];
  531. case 1:
  532. db = _a.sent();
  533. tx = db.transaction(OBJECT_STORE_NAME, 'readwrite');
  534. store = tx.objectStore(OBJECT_STORE_NAME);
  535. return [4 /*yield*/, store.get(key)];
  536. case 2:
  537. oldValue = (_a.sent());
  538. newValue = updateFn(oldValue);
  539. if (!(newValue === undefined)) return [3 /*break*/, 4];
  540. return [4 /*yield*/, store.delete(key)];
  541. case 3:
  542. _a.sent();
  543. return [3 /*break*/, 6];
  544. case 4: return [4 /*yield*/, store.put(newValue, key)];
  545. case 5:
  546. _a.sent();
  547. _a.label = 6;
  548. case 6: return [4 /*yield*/, tx.done];
  549. case 7:
  550. _a.sent();
  551. if (newValue && (!oldValue || oldValue.fid !== newValue.fid)) {
  552. fidChanged(appConfig, newValue.fid);
  553. }
  554. return [2 /*return*/, newValue];
  555. }
  556. });
  557. });
  558. }
  559. /**
  560. * @license
  561. * Copyright 2019 Google LLC
  562. *
  563. * Licensed under the Apache License, Version 2.0 (the "License");
  564. * you may not use this file except in compliance with the License.
  565. * You may obtain a copy of the License at
  566. *
  567. * http://www.apache.org/licenses/LICENSE-2.0
  568. *
  569. * Unless required by applicable law or agreed to in writing, software
  570. * distributed under the License is distributed on an "AS IS" BASIS,
  571. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  572. * See the License for the specific language governing permissions and
  573. * limitations under the License.
  574. */
  575. /**
  576. * Updates and returns the InstallationEntry from the database.
  577. * Also triggers a registration request if it is necessary and possible.
  578. */
  579. function getInstallationEntry(installations) {
  580. return tslib.__awaiter(this, void 0, void 0, function () {
  581. var registrationPromise, installationEntry;
  582. var _a;
  583. return tslib.__generator(this, function (_b) {
  584. switch (_b.label) {
  585. case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
  586. var installationEntry = updateOrCreateInstallationEntry(oldEntry);
  587. var entryWithPromise = triggerRegistrationIfNecessary(installations, installationEntry);
  588. registrationPromise = entryWithPromise.registrationPromise;
  589. return entryWithPromise.installationEntry;
  590. })];
  591. case 1:
  592. installationEntry = _b.sent();
  593. if (!(installationEntry.fid === INVALID_FID)) return [3 /*break*/, 3];
  594. _a = {};
  595. return [4 /*yield*/, registrationPromise];
  596. case 2:
  597. // FID generation failed. Waiting for the FID from the server.
  598. return [2 /*return*/, (_a.installationEntry = _b.sent(), _a)];
  599. case 3: return [2 /*return*/, {
  600. installationEntry: installationEntry,
  601. registrationPromise: registrationPromise
  602. }];
  603. }
  604. });
  605. });
  606. }
  607. /**
  608. * Creates a new Installation Entry if one does not exist.
  609. * Also clears timed out pending requests.
  610. */
  611. function updateOrCreateInstallationEntry(oldEntry) {
  612. var entry = oldEntry || {
  613. fid: generateFid(),
  614. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  615. };
  616. return clearTimedOutRequest(entry);
  617. }
  618. /**
  619. * If the Firebase Installation is not registered yet, this will trigger the
  620. * registration and return an InProgressInstallationEntry.
  621. *
  622. * If registrationPromise does not exist, the installationEntry is guaranteed
  623. * to be registered.
  624. */
  625. function triggerRegistrationIfNecessary(installations, installationEntry) {
  626. if (installationEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
  627. if (!navigator.onLine) {
  628. // Registration required but app is offline.
  629. var registrationPromiseWithError = Promise.reject(ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */));
  630. return {
  631. installationEntry: installationEntry,
  632. registrationPromise: registrationPromiseWithError
  633. };
  634. }
  635. // Try registering. Change status to IN_PROGRESS.
  636. var inProgressEntry = {
  637. fid: installationEntry.fid,
  638. registrationStatus: 1 /* RequestStatus.IN_PROGRESS */,
  639. registrationTime: Date.now()
  640. };
  641. var registrationPromise = registerInstallation(installations, inProgressEntry);
  642. return { installationEntry: inProgressEntry, registrationPromise: registrationPromise };
  643. }
  644. else if (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */) {
  645. return {
  646. installationEntry: installationEntry,
  647. registrationPromise: waitUntilFidRegistration(installations)
  648. };
  649. }
  650. else {
  651. return { installationEntry: installationEntry };
  652. }
  653. }
  654. /** This will be executed only once for each new Firebase Installation. */
  655. function registerInstallation(installations, installationEntry) {
  656. return tslib.__awaiter(this, void 0, void 0, function () {
  657. var registeredInstallationEntry, e_1;
  658. return tslib.__generator(this, function (_a) {
  659. switch (_a.label) {
  660. case 0:
  661. _a.trys.push([0, 2, , 7]);
  662. return [4 /*yield*/, createInstallationRequest(installations, installationEntry)];
  663. case 1:
  664. registeredInstallationEntry = _a.sent();
  665. return [2 /*return*/, set(installations.appConfig, registeredInstallationEntry)];
  666. case 2:
  667. e_1 = _a.sent();
  668. if (!(isServerError(e_1) && e_1.customData.serverCode === 409)) return [3 /*break*/, 4];
  669. // Server returned a "FID can not be used" error.
  670. // Generate a new ID next time.
  671. return [4 /*yield*/, remove(installations.appConfig)];
  672. case 3:
  673. // Server returned a "FID can not be used" error.
  674. // Generate a new ID next time.
  675. _a.sent();
  676. return [3 /*break*/, 6];
  677. case 4:
  678. // Registration failed. Set FID as not registered.
  679. return [4 /*yield*/, set(installations.appConfig, {
  680. fid: installationEntry.fid,
  681. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  682. })];
  683. case 5:
  684. // Registration failed. Set FID as not registered.
  685. _a.sent();
  686. _a.label = 6;
  687. case 6: throw e_1;
  688. case 7: return [2 /*return*/];
  689. }
  690. });
  691. });
  692. }
  693. /** Call if FID registration is pending in another request. */
  694. function waitUntilFidRegistration(installations) {
  695. return tslib.__awaiter(this, void 0, void 0, function () {
  696. var entry, _a, installationEntry, registrationPromise;
  697. return tslib.__generator(this, function (_b) {
  698. switch (_b.label) {
  699. case 0: return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
  700. case 1:
  701. entry = _b.sent();
  702. _b.label = 2;
  703. case 2:
  704. if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5];
  705. // createInstallation request still in progress.
  706. return [4 /*yield*/, sleep(100)];
  707. case 3:
  708. // createInstallation request still in progress.
  709. _b.sent();
  710. return [4 /*yield*/, updateInstallationRequest(installations.appConfig)];
  711. case 4:
  712. entry = _b.sent();
  713. return [3 /*break*/, 2];
  714. case 5:
  715. if (!(entry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */)) return [3 /*break*/, 7];
  716. return [4 /*yield*/, getInstallationEntry(installations)];
  717. case 6:
  718. _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
  719. if (registrationPromise) {
  720. return [2 /*return*/, registrationPromise];
  721. }
  722. else {
  723. // if there is no registrationPromise, entry is registered.
  724. return [2 /*return*/, installationEntry];
  725. }
  726. case 7: return [2 /*return*/, entry];
  727. }
  728. });
  729. });
  730. }
  731. /**
  732. * Called only if there is a CreateInstallation request in progress.
  733. *
  734. * Updates the InstallationEntry in the DB based on the status of the
  735. * CreateInstallation request.
  736. *
  737. * Returns the updated InstallationEntry.
  738. */
  739. function updateInstallationRequest(appConfig) {
  740. return update(appConfig, function (oldEntry) {
  741. if (!oldEntry) {
  742. throw ERROR_FACTORY.create("installation-not-found" /* ErrorCode.INSTALLATION_NOT_FOUND */);
  743. }
  744. return clearTimedOutRequest(oldEntry);
  745. });
  746. }
  747. function clearTimedOutRequest(entry) {
  748. if (hasInstallationRequestTimedOut(entry)) {
  749. return {
  750. fid: entry.fid,
  751. registrationStatus: 0 /* RequestStatus.NOT_STARTED */
  752. };
  753. }
  754. return entry;
  755. }
  756. function hasInstallationRequestTimedOut(installationEntry) {
  757. return (installationEntry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */ &&
  758. installationEntry.registrationTime + PENDING_TIMEOUT_MS < Date.now());
  759. }
  760. /**
  761. * @license
  762. * Copyright 2019 Google LLC
  763. *
  764. * Licensed under the Apache License, Version 2.0 (the "License");
  765. * you may not use this file except in compliance with the License.
  766. * You may obtain a copy of the License at
  767. *
  768. * http://www.apache.org/licenses/LICENSE-2.0
  769. *
  770. * Unless required by applicable law or agreed to in writing, software
  771. * distributed under the License is distributed on an "AS IS" BASIS,
  772. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  773. * See the License for the specific language governing permissions and
  774. * limitations under the License.
  775. */
  776. function generateAuthTokenRequest(_a, installationEntry) {
  777. var appConfig = _a.appConfig, heartbeatServiceProvider = _a.heartbeatServiceProvider;
  778. return tslib.__awaiter(this, void 0, void 0, function () {
  779. var endpoint, headers, heartbeatService, heartbeatsHeader, body, request, response, responseValue, completedAuthToken;
  780. return tslib.__generator(this, function (_b) {
  781. switch (_b.label) {
  782. case 0:
  783. endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);
  784. headers = getHeadersWithAuth(appConfig, installationEntry);
  785. heartbeatService = heartbeatServiceProvider.getImmediate({
  786. optional: true
  787. });
  788. if (!heartbeatService) return [3 /*break*/, 2];
  789. return [4 /*yield*/, heartbeatService.getHeartbeatsHeader()];
  790. case 1:
  791. heartbeatsHeader = _b.sent();
  792. if (heartbeatsHeader) {
  793. headers.append('x-firebase-client', heartbeatsHeader);
  794. }
  795. _b.label = 2;
  796. case 2:
  797. body = {
  798. installation: {
  799. sdkVersion: PACKAGE_VERSION,
  800. appId: appConfig.appId
  801. }
  802. };
  803. request = {
  804. method: 'POST',
  805. headers: headers,
  806. body: JSON.stringify(body)
  807. };
  808. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  809. case 3:
  810. response = _b.sent();
  811. if (!response.ok) return [3 /*break*/, 5];
  812. return [4 /*yield*/, response.json()];
  813. case 4:
  814. responseValue = _b.sent();
  815. completedAuthToken = extractAuthTokenInfoFromResponse(responseValue);
  816. return [2 /*return*/, completedAuthToken];
  817. case 5: return [4 /*yield*/, getErrorFromResponse('Generate Auth Token', response)];
  818. case 6: throw _b.sent();
  819. }
  820. });
  821. });
  822. }
  823. function getGenerateAuthTokenEndpoint(appConfig, _a) {
  824. var fid = _a.fid;
  825. return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid, "/authTokens:generate");
  826. }
  827. /**
  828. * @license
  829. * Copyright 2019 Google LLC
  830. *
  831. * Licensed under the Apache License, Version 2.0 (the "License");
  832. * you may not use this file except in compliance with the License.
  833. * You may obtain a copy of the License at
  834. *
  835. * http://www.apache.org/licenses/LICENSE-2.0
  836. *
  837. * Unless required by applicable law or agreed to in writing, software
  838. * distributed under the License is distributed on an "AS IS" BASIS,
  839. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  840. * See the License for the specific language governing permissions and
  841. * limitations under the License.
  842. */
  843. /**
  844. * Returns a valid authentication token for the installation. Generates a new
  845. * token if one doesn't exist, is expired or about to expire.
  846. *
  847. * Should only be called if the Firebase Installation is registered.
  848. */
  849. function refreshAuthToken(installations, forceRefresh) {
  850. if (forceRefresh === void 0) { forceRefresh = false; }
  851. return tslib.__awaiter(this, void 0, void 0, function () {
  852. var tokenPromise, entry, authToken, _a;
  853. return tslib.__generator(this, function (_b) {
  854. switch (_b.label) {
  855. case 0: return [4 /*yield*/, update(installations.appConfig, function (oldEntry) {
  856. if (!isEntryRegistered(oldEntry)) {
  857. throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
  858. }
  859. var oldAuthToken = oldEntry.authToken;
  860. if (!forceRefresh && isAuthTokenValid(oldAuthToken)) {
  861. // There is a valid token in the DB.
  862. return oldEntry;
  863. }
  864. else if (oldAuthToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */) {
  865. // There already is a token request in progress.
  866. tokenPromise = waitUntilAuthTokenRequest(installations, forceRefresh);
  867. return oldEntry;
  868. }
  869. else {
  870. // No token or token expired.
  871. if (!navigator.onLine) {
  872. throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
  873. }
  874. var inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);
  875. tokenPromise = fetchAuthTokenFromServer(installations, inProgressEntry);
  876. return inProgressEntry;
  877. }
  878. })];
  879. case 1:
  880. entry = _b.sent();
  881. if (!tokenPromise) return [3 /*break*/, 3];
  882. return [4 /*yield*/, tokenPromise];
  883. case 2:
  884. _a = _b.sent();
  885. return [3 /*break*/, 4];
  886. case 3:
  887. _a = entry.authToken;
  888. _b.label = 4;
  889. case 4:
  890. authToken = _a;
  891. return [2 /*return*/, authToken];
  892. }
  893. });
  894. });
  895. }
  896. /**
  897. * Call only if FID is registered and Auth Token request is in progress.
  898. *
  899. * Waits until the current pending request finishes. If the request times out,
  900. * tries once in this thread as well.
  901. */
  902. function waitUntilAuthTokenRequest(installations, forceRefresh) {
  903. return tslib.__awaiter(this, void 0, void 0, function () {
  904. var entry, authToken;
  905. return tslib.__generator(this, function (_a) {
  906. switch (_a.label) {
  907. case 0: return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
  908. case 1:
  909. entry = _a.sent();
  910. _a.label = 2;
  911. case 2:
  912. if (!(entry.authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 5];
  913. // generateAuthToken still in progress.
  914. return [4 /*yield*/, sleep(100)];
  915. case 3:
  916. // generateAuthToken still in progress.
  917. _a.sent();
  918. return [4 /*yield*/, updateAuthTokenRequest(installations.appConfig)];
  919. case 4:
  920. entry = _a.sent();
  921. return [3 /*break*/, 2];
  922. case 5:
  923. authToken = entry.authToken;
  924. if (authToken.requestStatus === 0 /* RequestStatus.NOT_STARTED */) {
  925. // The request timed out or failed in a different call. Try again.
  926. return [2 /*return*/, refreshAuthToken(installations, forceRefresh)];
  927. }
  928. else {
  929. return [2 /*return*/, authToken];
  930. }
  931. }
  932. });
  933. });
  934. }
  935. /**
  936. * Called only if there is a GenerateAuthToken request in progress.
  937. *
  938. * Updates the InstallationEntry in the DB based on the status of the
  939. * GenerateAuthToken request.
  940. *
  941. * Returns the updated InstallationEntry.
  942. */
  943. function updateAuthTokenRequest(appConfig) {
  944. return update(appConfig, function (oldEntry) {
  945. if (!isEntryRegistered(oldEntry)) {
  946. throw ERROR_FACTORY.create("not-registered" /* ErrorCode.NOT_REGISTERED */);
  947. }
  948. var oldAuthToken = oldEntry.authToken;
  949. if (hasAuthTokenRequestTimedOut(oldAuthToken)) {
  950. return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
  951. }
  952. return oldEntry;
  953. });
  954. }
  955. function fetchAuthTokenFromServer(installations, installationEntry) {
  956. return tslib.__awaiter(this, void 0, void 0, function () {
  957. var authToken, updatedInstallationEntry, e_1, updatedInstallationEntry;
  958. return tslib.__generator(this, function (_a) {
  959. switch (_a.label) {
  960. case 0:
  961. _a.trys.push([0, 3, , 8]);
  962. return [4 /*yield*/, generateAuthTokenRequest(installations, installationEntry)];
  963. case 1:
  964. authToken = _a.sent();
  965. updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: authToken });
  966. return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
  967. case 2:
  968. _a.sent();
  969. return [2 /*return*/, authToken];
  970. case 3:
  971. e_1 = _a.sent();
  972. if (!(isServerError(e_1) &&
  973. (e_1.customData.serverCode === 401 || e_1.customData.serverCode === 404))) return [3 /*break*/, 5];
  974. // Server returned a "FID not found" or a "Invalid authentication" error.
  975. // Generate a new ID next time.
  976. return [4 /*yield*/, remove(installations.appConfig)];
  977. case 4:
  978. // Server returned a "FID not found" or a "Invalid authentication" error.
  979. // Generate a new ID next time.
  980. _a.sent();
  981. return [3 /*break*/, 7];
  982. case 5:
  983. updatedInstallationEntry = tslib.__assign(tslib.__assign({}, installationEntry), { authToken: { requestStatus: 0 /* RequestStatus.NOT_STARTED */ } });
  984. return [4 /*yield*/, set(installations.appConfig, updatedInstallationEntry)];
  985. case 6:
  986. _a.sent();
  987. _a.label = 7;
  988. case 7: throw e_1;
  989. case 8: return [2 /*return*/];
  990. }
  991. });
  992. });
  993. }
  994. function isEntryRegistered(installationEntry) {
  995. return (installationEntry !== undefined &&
  996. installationEntry.registrationStatus === 2 /* RequestStatus.COMPLETED */);
  997. }
  998. function isAuthTokenValid(authToken) {
  999. return (authToken.requestStatus === 2 /* RequestStatus.COMPLETED */ &&
  1000. !isAuthTokenExpired(authToken));
  1001. }
  1002. function isAuthTokenExpired(authToken) {
  1003. var now = Date.now();
  1004. return (now < authToken.creationTime ||
  1005. authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER);
  1006. }
  1007. /** Returns an updated InstallationEntry with an InProgressAuthToken. */
  1008. function makeAuthTokenRequestInProgressEntry(oldEntry) {
  1009. var inProgressAuthToken = {
  1010. requestStatus: 1 /* RequestStatus.IN_PROGRESS */,
  1011. requestTime: Date.now()
  1012. };
  1013. return tslib.__assign(tslib.__assign({}, oldEntry), { authToken: inProgressAuthToken });
  1014. }
  1015. function hasAuthTokenRequestTimedOut(authToken) {
  1016. return (authToken.requestStatus === 1 /* RequestStatus.IN_PROGRESS */ &&
  1017. authToken.requestTime + PENDING_TIMEOUT_MS < Date.now());
  1018. }
  1019. /**
  1020. * @license
  1021. * Copyright 2019 Google LLC
  1022. *
  1023. * Licensed under the Apache License, Version 2.0 (the "License");
  1024. * you may not use this file except in compliance with the License.
  1025. * You may obtain a copy of the License at
  1026. *
  1027. * http://www.apache.org/licenses/LICENSE-2.0
  1028. *
  1029. * Unless required by applicable law or agreed to in writing, software
  1030. * distributed under the License is distributed on an "AS IS" BASIS,
  1031. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1032. * See the License for the specific language governing permissions and
  1033. * limitations under the License.
  1034. */
  1035. /**
  1036. * Creates a Firebase Installation if there isn't one for the app and
  1037. * returns the Installation ID.
  1038. * @param installations - The `Installations` instance.
  1039. *
  1040. * @public
  1041. */
  1042. function getId(installations) {
  1043. return tslib.__awaiter(this, void 0, void 0, function () {
  1044. var installationsImpl, _a, installationEntry, registrationPromise;
  1045. return tslib.__generator(this, function (_b) {
  1046. switch (_b.label) {
  1047. case 0:
  1048. installationsImpl = installations;
  1049. return [4 /*yield*/, getInstallationEntry(installationsImpl)];
  1050. case 1:
  1051. _a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
  1052. if (registrationPromise) {
  1053. registrationPromise.catch(console.error);
  1054. }
  1055. else {
  1056. // If the installation is already registered, update the authentication
  1057. // token if needed.
  1058. refreshAuthToken(installationsImpl).catch(console.error);
  1059. }
  1060. return [2 /*return*/, installationEntry.fid];
  1061. }
  1062. });
  1063. });
  1064. }
  1065. /**
  1066. * @license
  1067. * Copyright 2019 Google LLC
  1068. *
  1069. * Licensed under the Apache License, Version 2.0 (the "License");
  1070. * you may not use this file except in compliance with the License.
  1071. * You may obtain a copy of the License at
  1072. *
  1073. * http://www.apache.org/licenses/LICENSE-2.0
  1074. *
  1075. * Unless required by applicable law or agreed to in writing, software
  1076. * distributed under the License is distributed on an "AS IS" BASIS,
  1077. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1078. * See the License for the specific language governing permissions and
  1079. * limitations under the License.
  1080. */
  1081. /**
  1082. * Returns a Firebase Installations auth token, identifying the current
  1083. * Firebase Installation.
  1084. * @param installations - The `Installations` instance.
  1085. * @param forceRefresh - Force refresh regardless of token expiration.
  1086. *
  1087. * @public
  1088. */
  1089. function getToken(installations, forceRefresh) {
  1090. if (forceRefresh === void 0) { forceRefresh = false; }
  1091. return tslib.__awaiter(this, void 0, void 0, function () {
  1092. var installationsImpl, authToken;
  1093. return tslib.__generator(this, function (_a) {
  1094. switch (_a.label) {
  1095. case 0:
  1096. installationsImpl = installations;
  1097. return [4 /*yield*/, completeInstallationRegistration(installationsImpl)];
  1098. case 1:
  1099. _a.sent();
  1100. return [4 /*yield*/, refreshAuthToken(installationsImpl, forceRefresh)];
  1101. case 2:
  1102. authToken = _a.sent();
  1103. return [2 /*return*/, authToken.token];
  1104. }
  1105. });
  1106. });
  1107. }
  1108. function completeInstallationRegistration(installations) {
  1109. return tslib.__awaiter(this, void 0, void 0, function () {
  1110. var registrationPromise;
  1111. return tslib.__generator(this, function (_a) {
  1112. switch (_a.label) {
  1113. case 0: return [4 /*yield*/, getInstallationEntry(installations)];
  1114. case 1:
  1115. registrationPromise = (_a.sent()).registrationPromise;
  1116. if (!registrationPromise) return [3 /*break*/, 3];
  1117. // A createInstallation request is in progress. Wait until it finishes.
  1118. return [4 /*yield*/, registrationPromise];
  1119. case 2:
  1120. // A createInstallation request is in progress. Wait until it finishes.
  1121. _a.sent();
  1122. _a.label = 3;
  1123. case 3: return [2 /*return*/];
  1124. }
  1125. });
  1126. });
  1127. }
  1128. /**
  1129. * @license
  1130. * Copyright 2019 Google LLC
  1131. *
  1132. * Licensed under the Apache License, Version 2.0 (the "License");
  1133. * you may not use this file except in compliance with the License.
  1134. * You may obtain a copy of the License at
  1135. *
  1136. * http://www.apache.org/licenses/LICENSE-2.0
  1137. *
  1138. * Unless required by applicable law or agreed to in writing, software
  1139. * distributed under the License is distributed on an "AS IS" BASIS,
  1140. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1141. * See the License for the specific language governing permissions and
  1142. * limitations under the License.
  1143. */
  1144. function deleteInstallationRequest(appConfig, installationEntry) {
  1145. return tslib.__awaiter(this, void 0, void 0, function () {
  1146. var endpoint, headers, request, response;
  1147. return tslib.__generator(this, function (_a) {
  1148. switch (_a.label) {
  1149. case 0:
  1150. endpoint = getDeleteEndpoint(appConfig, installationEntry);
  1151. headers = getHeadersWithAuth(appConfig, installationEntry);
  1152. request = {
  1153. method: 'DELETE',
  1154. headers: headers
  1155. };
  1156. return [4 /*yield*/, retryIfServerError(function () { return fetch(endpoint, request); })];
  1157. case 1:
  1158. response = _a.sent();
  1159. if (!!response.ok) return [3 /*break*/, 3];
  1160. return [4 /*yield*/, getErrorFromResponse('Delete Installation', response)];
  1161. case 2: throw _a.sent();
  1162. case 3: return [2 /*return*/];
  1163. }
  1164. });
  1165. });
  1166. }
  1167. function getDeleteEndpoint(appConfig, _a) {
  1168. var fid = _a.fid;
  1169. return "".concat(getInstallationsEndpoint(appConfig), "/").concat(fid);
  1170. }
  1171. /**
  1172. * @license
  1173. * Copyright 2019 Google LLC
  1174. *
  1175. * Licensed under the Apache License, Version 2.0 (the "License");
  1176. * you may not use this file except in compliance with the License.
  1177. * You may obtain a copy of the License at
  1178. *
  1179. * http://www.apache.org/licenses/LICENSE-2.0
  1180. *
  1181. * Unless required by applicable law or agreed to in writing, software
  1182. * distributed under the License is distributed on an "AS IS" BASIS,
  1183. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1184. * See the License for the specific language governing permissions and
  1185. * limitations under the License.
  1186. */
  1187. /**
  1188. * Deletes the Firebase Installation and all associated data.
  1189. * @param installations - The `Installations` instance.
  1190. *
  1191. * @public
  1192. */
  1193. function deleteInstallations(installations) {
  1194. return tslib.__awaiter(this, void 0, void 0, function () {
  1195. var appConfig, entry;
  1196. return tslib.__generator(this, function (_a) {
  1197. switch (_a.label) {
  1198. case 0:
  1199. appConfig = installations.appConfig;
  1200. return [4 /*yield*/, update(appConfig, function (oldEntry) {
  1201. if (oldEntry && oldEntry.registrationStatus === 0 /* RequestStatus.NOT_STARTED */) {
  1202. // Delete the unregistered entry without sending a deleteInstallation request.
  1203. return undefined;
  1204. }
  1205. return oldEntry;
  1206. })];
  1207. case 1:
  1208. entry = _a.sent();
  1209. if (!entry) return [3 /*break*/, 6];
  1210. if (!(entry.registrationStatus === 1 /* RequestStatus.IN_PROGRESS */)) return [3 /*break*/, 2];
  1211. // Can't delete while trying to register.
  1212. throw ERROR_FACTORY.create("delete-pending-registration" /* ErrorCode.DELETE_PENDING_REGISTRATION */);
  1213. case 2:
  1214. if (!(entry.registrationStatus === 2 /* RequestStatus.COMPLETED */)) return [3 /*break*/, 6];
  1215. if (!!navigator.onLine) return [3 /*break*/, 3];
  1216. throw ERROR_FACTORY.create("app-offline" /* ErrorCode.APP_OFFLINE */);
  1217. case 3: return [4 /*yield*/, deleteInstallationRequest(appConfig, entry)];
  1218. case 4:
  1219. _a.sent();
  1220. return [4 /*yield*/, remove(appConfig)];
  1221. case 5:
  1222. _a.sent();
  1223. _a.label = 6;
  1224. case 6: return [2 /*return*/];
  1225. }
  1226. });
  1227. });
  1228. }
  1229. /**
  1230. * @license
  1231. * Copyright 2019 Google LLC
  1232. *
  1233. * Licensed under the Apache License, Version 2.0 (the "License");
  1234. * you may not use this file except in compliance with the License.
  1235. * You may obtain a copy of the License at
  1236. *
  1237. * http://www.apache.org/licenses/LICENSE-2.0
  1238. *
  1239. * Unless required by applicable law or agreed to in writing, software
  1240. * distributed under the License is distributed on an "AS IS" BASIS,
  1241. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1242. * See the License for the specific language governing permissions and
  1243. * limitations under the License.
  1244. */
  1245. /**
  1246. * Sets a new callback that will get called when Installation ID changes.
  1247. * Returns an unsubscribe function that will remove the callback when called.
  1248. * @param installations - The `Installations` instance.
  1249. * @param callback - The callback function that is invoked when FID changes.
  1250. * @returns A function that can be called to unsubscribe.
  1251. *
  1252. * @public
  1253. */
  1254. function onIdChange(installations, callback) {
  1255. var appConfig = installations.appConfig;
  1256. addCallback(appConfig, callback);
  1257. return function () {
  1258. removeCallback(appConfig, callback);
  1259. };
  1260. }
  1261. /**
  1262. * @license
  1263. * Copyright 2020 Google LLC
  1264. *
  1265. * Licensed under the Apache License, Version 2.0 (the "License");
  1266. * you may not use this file except in compliance with the License.
  1267. * You may obtain a copy of the License at
  1268. *
  1269. * http://www.apache.org/licenses/LICENSE-2.0
  1270. *
  1271. * Unless required by applicable law or agreed to in writing, software
  1272. * distributed under the License is distributed on an "AS IS" BASIS,
  1273. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1274. * See the License for the specific language governing permissions and
  1275. * limitations under the License.
  1276. */
  1277. /**
  1278. * Returns an instance of {@link Installations} associated with the given
  1279. * {@link @firebase/app#FirebaseApp} instance.
  1280. * @param app - The {@link @firebase/app#FirebaseApp} instance.
  1281. *
  1282. * @public
  1283. */
  1284. function getInstallations(app$1) {
  1285. if (app$1 === void 0) { app$1 = app.getApp(); }
  1286. var installationsImpl = app._getProvider(app$1, 'installations').getImmediate();
  1287. return installationsImpl;
  1288. }
  1289. /**
  1290. * @license
  1291. * Copyright 2019 Google LLC
  1292. *
  1293. * Licensed under the Apache License, Version 2.0 (the "License");
  1294. * you may not use this file except in compliance with the License.
  1295. * You may obtain a copy of the License at
  1296. *
  1297. * http://www.apache.org/licenses/LICENSE-2.0
  1298. *
  1299. * Unless required by applicable law or agreed to in writing, software
  1300. * distributed under the License is distributed on an "AS IS" BASIS,
  1301. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1302. * See the License for the specific language governing permissions and
  1303. * limitations under the License.
  1304. */
  1305. function extractAppConfig(app) {
  1306. var e_1, _a;
  1307. if (!app || !app.options) {
  1308. throw getMissingValueError('App Configuration');
  1309. }
  1310. if (!app.name) {
  1311. throw getMissingValueError('App Name');
  1312. }
  1313. // Required app config keys
  1314. var configKeys = [
  1315. 'projectId',
  1316. 'apiKey',
  1317. 'appId'
  1318. ];
  1319. try {
  1320. for (var configKeys_1 = tslib.__values(configKeys), configKeys_1_1 = configKeys_1.next(); !configKeys_1_1.done; configKeys_1_1 = configKeys_1.next()) {
  1321. var keyName = configKeys_1_1.value;
  1322. if (!app.options[keyName]) {
  1323. throw getMissingValueError(keyName);
  1324. }
  1325. }
  1326. }
  1327. catch (e_1_1) { e_1 = { error: e_1_1 }; }
  1328. finally {
  1329. try {
  1330. if (configKeys_1_1 && !configKeys_1_1.done && (_a = configKeys_1.return)) _a.call(configKeys_1);
  1331. }
  1332. finally { if (e_1) throw e_1.error; }
  1333. }
  1334. return {
  1335. appName: app.name,
  1336. projectId: app.options.projectId,
  1337. apiKey: app.options.apiKey,
  1338. appId: app.options.appId
  1339. };
  1340. }
  1341. function getMissingValueError(valueName) {
  1342. return ERROR_FACTORY.create("missing-app-config-values" /* ErrorCode.MISSING_APP_CONFIG_VALUES */, {
  1343. valueName: valueName
  1344. });
  1345. }
  1346. /**
  1347. * @license
  1348. * Copyright 2020 Google LLC
  1349. *
  1350. * Licensed under the Apache License, Version 2.0 (the "License");
  1351. * you may not use this file except in compliance with the License.
  1352. * You may obtain a copy of the License at
  1353. *
  1354. * http://www.apache.org/licenses/LICENSE-2.0
  1355. *
  1356. * Unless required by applicable law or agreed to in writing, software
  1357. * distributed under the License is distributed on an "AS IS" BASIS,
  1358. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  1359. * See the License for the specific language governing permissions and
  1360. * limitations under the License.
  1361. */
  1362. var INSTALLATIONS_NAME = 'installations';
  1363. var INSTALLATIONS_NAME_INTERNAL = 'installations-internal';
  1364. var publicFactory = function (container) {
  1365. var app$1 = container.getProvider('app').getImmediate();
  1366. // Throws if app isn't configured properly.
  1367. var appConfig = extractAppConfig(app$1);
  1368. var heartbeatServiceProvider = app._getProvider(app$1, 'heartbeat');
  1369. var installationsImpl = {
  1370. app: app$1,
  1371. appConfig: appConfig,
  1372. heartbeatServiceProvider: heartbeatServiceProvider,
  1373. _delete: function () { return Promise.resolve(); }
  1374. };
  1375. return installationsImpl;
  1376. };
  1377. var internalFactory = function (container) {
  1378. var app$1 = container.getProvider('app').getImmediate();
  1379. // Internal FIS instance relies on public FIS instance.
  1380. var installations = app._getProvider(app$1, INSTALLATIONS_NAME).getImmediate();
  1381. var installationsInternal = {
  1382. getId: function () { return getId(installations); },
  1383. getToken: function (forceRefresh) { return getToken(installations, forceRefresh); }
  1384. };
  1385. return installationsInternal;
  1386. };
  1387. function registerInstallations() {
  1388. app._registerComponent(new component.Component(INSTALLATIONS_NAME, publicFactory, "PUBLIC" /* ComponentType.PUBLIC */));
  1389. app._registerComponent(new component.Component(INSTALLATIONS_NAME_INTERNAL, internalFactory, "PRIVATE" /* ComponentType.PRIVATE */));
  1390. }
  1391. /**
  1392. * Firebase Installations
  1393. *
  1394. * @packageDocumentation
  1395. */
  1396. registerInstallations();
  1397. app.registerVersion(name, version);
  1398. // BUILD_TARGET will be replaced by values like esm5, esm2017, cjs5, etc during the compilation
  1399. app.registerVersion(name, version, 'cjs5');
  1400. exports.deleteInstallations = deleteInstallations;
  1401. exports.getId = getId;
  1402. exports.getInstallations = getInstallations;
  1403. exports.getToken = getToken;
  1404. exports.onIdChange = onIdChange;
  1405. //# sourceMappingURL=index.cjs.js.map