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

@firebase/installations

Package Overview
Dependencies
Maintainers
5
Versions
2807
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@firebase/installations - npm Package Compare versions

Comparing version

to
0.1.5-canary.fd5a31a

.rpt2_cache/rpt2_5643af4650fc9b9968741f7d3be90e13f8cfcb1e/code/cache/011f65162f121c1aafb5173275d479529cef0a2e

190

dist/index.cjs.js

@@ -12,3 +12,3 @@ 'use strict';

var version = "0.1.5-canary.d164cac";
var version = "0.1.5-canary.fd5a31a";

@@ -640,38 +640,2 @@ /**

*/
function getId(app) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var appConfig, _a, installationEntry, registrationPromise;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(function () { });
}
return [2 /*return*/, installationEntry.fid];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function generateAuthToken(appConfig, installationEntry) {

@@ -731,47 +695,10 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

*/
function getToken(app) {
/**
* Returns a valid authentication token for the installation. Generates a new
* token if one doesn't exist, is expired or about to expire.
*
* Should only be called if the Firebase Installation is registered.
*/
function refreshAuthToken(appConfig) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var appConfig;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, completeInstallationRegistration(appConfig)];
case 1:
_a.sent();
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return [2 /*return*/, fetchAuthToken(appConfig)];
}
});
});
}
function completeInstallationRegistration(appConfig) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, installationEntry, registrationPromise;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (!registrationPromise) return [3 /*break*/, 3];
// A createInstallation request is in progress. Wait until it finishes.
return [4 /*yield*/, registrationPromise];
case 2:
// A createInstallation request is in progress. Wait until it finishes.
_b.sent();
return [3 /*break*/, 4];
case 3:
if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
_b.label = 4;
case 4: return [2 /*return*/];
}
});
});
}
function fetchAuthToken(appConfig) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var tokenPromise, entry, authToken, _a;

@@ -957,2 +884,103 @@ return tslib_1.__generator(this, function (_b) {

*/
function getId(app) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var appConfig, _a, installationEntry, registrationPromise;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(function () { });
}
if (installationEntry.registrationStatus === 2 /* COMPLETED */) {
// If the installation is already registered, update the authentication
// token if needed. Suppress errors as they are not relevant to getId.
refreshAuthToken(appConfig).catch(function () { });
}
return [2 /*return*/, installationEntry.fid];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function getToken(app) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var appConfig;
return tslib_1.__generator(this, function (_a) {
switch (_a.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, completeInstallationRegistration(appConfig)];
case 1:
_a.sent();
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return [2 /*return*/, refreshAuthToken(appConfig)];
}
});
});
}
function completeInstallationRegistration(appConfig) {
return tslib_1.__awaiter(this, void 0, void 0, function () {
var _a, installationEntry, registrationPromise;
return tslib_1.__generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (!registrationPromise) return [3 /*break*/, 3];
// A createInstallation request is in progress. Wait until it finishes.
return [4 /*yield*/, registrationPromise];
case 2:
// A createInstallation request is in progress. Wait until it finishes.
_b.sent();
return [3 /*break*/, 4];
case 3:
if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
_b.label = 4;
case 4: return [2 /*return*/];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function deleteInstallation(appConfig, installationEntry) {

@@ -959,0 +987,0 @@ return tslib_1.__awaiter(this, void 0, void 0, function () {

@@ -7,3 +7,3 @@ import firebase from '@firebase/app';

var version = "0.1.5-canary.d164cac";
var version = "0.1.5-canary.fd5a31a";

@@ -635,38 +635,2 @@ /**

*/
function getId(app) {
return __awaiter(this, void 0, void 0, function () {
var appConfig, _a, installationEntry, registrationPromise;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(function () { });
}
return [2 /*return*/, installationEntry.fid];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function generateAuthToken(appConfig, installationEntry) {

@@ -726,47 +690,10 @@ return __awaiter(this, void 0, void 0, function () {

*/
function getToken(app) {
/**
* Returns a valid authentication token for the installation. Generates a new
* token if one doesn't exist, is expired or about to expire.
*
* Should only be called if the Firebase Installation is registered.
*/
function refreshAuthToken(appConfig) {
return __awaiter(this, void 0, void 0, function () {
var appConfig;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, completeInstallationRegistration(appConfig)];
case 1:
_a.sent();
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return [2 /*return*/, fetchAuthToken(appConfig)];
}
});
});
}
function completeInstallationRegistration(appConfig) {
return __awaiter(this, void 0, void 0, function () {
var _a, installationEntry, registrationPromise;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (!registrationPromise) return [3 /*break*/, 3];
// A createInstallation request is in progress. Wait until it finishes.
return [4 /*yield*/, registrationPromise];
case 2:
// A createInstallation request is in progress. Wait until it finishes.
_b.sent();
return [3 /*break*/, 4];
case 3:
if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
_b.label = 4;
case 4: return [2 /*return*/];
}
});
});
}
function fetchAuthToken(appConfig) {
return __awaiter(this, void 0, void 0, function () {
var tokenPromise, entry, authToken, _a;

@@ -952,2 +879,103 @@ return __generator(this, function (_b) {

*/
function getId(app) {
return __awaiter(this, void 0, void 0, function () {
var appConfig, _a, installationEntry, registrationPromise;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(function () { });
}
if (installationEntry.registrationStatus === 2 /* COMPLETED */) {
// If the installation is already registered, update the authentication
// token if needed. Suppress errors as they are not relevant to getId.
refreshAuthToken(appConfig).catch(function () { });
}
return [2 /*return*/, installationEntry.fid];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function getToken(app) {
return __awaiter(this, void 0, void 0, function () {
var appConfig;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
appConfig = extractAppConfig(app);
return [4 /*yield*/, completeInstallationRegistration(appConfig)];
case 1:
_a.sent();
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return [2 /*return*/, refreshAuthToken(appConfig)];
}
});
});
}
function completeInstallationRegistration(appConfig) {
return __awaiter(this, void 0, void 0, function () {
var _a, installationEntry, registrationPromise;
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, getInstallationEntry(appConfig)];
case 1:
_a = _b.sent(), installationEntry = _a.installationEntry, registrationPromise = _a.registrationPromise;
if (!registrationPromise) return [3 /*break*/, 3];
// A createInstallation request is in progress. Wait until it finishes.
return [4 /*yield*/, registrationPromise];
case 2:
// A createInstallation request is in progress. Wait until it finishes.
_b.sent();
return [3 /*break*/, 4];
case 3:
if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
_b.label = 4;
case 4: return [2 /*return*/];
}
});
});
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
function deleteInstallation(appConfig, installationEntry) {

@@ -954,0 +982,0 @@ return __awaiter(this, void 0, void 0, function () {

@@ -5,3 +5,3 @@ import firebase from '@firebase/app';

const version = "0.1.5-canary.d164cac";
const version = "0.1.5-canary.fd5a31a";

@@ -521,28 +521,2 @@ /**

*/
async function getId(app) {
const appConfig = extractAppConfig(app);
const { installationEntry, registrationPromise } = await getInstallationEntry(appConfig);
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(() => { });
}
return installationEntry.fid;
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function generateAuthToken(appConfig, installationEntry) {

@@ -591,21 +565,9 @@ const endpoint = getGenerateAuthTokenEndpoint(appConfig, installationEntry);

*/
async function getToken(app) {
const appConfig = extractAppConfig(app);
await completeInstallationRegistration(appConfig);
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return fetchAuthToken(appConfig);
}
async function completeInstallationRegistration(appConfig) {
const { installationEntry, registrationPromise } = await getInstallationEntry(appConfig);
if (registrationPromise) {
// A createInstallation request is in progress. Wait until it finishes.
await registrationPromise;
}
else if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
}
async function fetchAuthToken(appConfig) {
/**
* Returns a valid authentication token for the installation. Generates a new
* token if one doesn't exist, is expired or about to expire.
*
* Should only be called if the Firebase Installation is registered.
*/
async function refreshAuthToken(appConfig) {
let tokenPromise;

@@ -744,2 +706,68 @@ const entry = await update(appConfig, (oldEntry) => {

*/
async function getId(app) {
const appConfig = extractAppConfig(app);
const { installationEntry, registrationPromise } = await getInstallationEntry(appConfig);
if (registrationPromise) {
// Suppress registration errors as they are not a problem for getId.
registrationPromise.catch(() => { });
}
if (installationEntry.registrationStatus === 2 /* COMPLETED */) {
// If the installation is already registered, update the authentication
// token if needed. Suppress errors as they are not relevant to getId.
refreshAuthToken(appConfig).catch(() => { });
}
return installationEntry.fid;
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function getToken(app) {
const appConfig = extractAppConfig(app);
await completeInstallationRegistration(appConfig);
// At this point we either have a Registered Installation in the DB, or we've
// already thrown an error.
return refreshAuthToken(appConfig);
}
async function completeInstallationRegistration(appConfig) {
const { installationEntry, registrationPromise } = await getInstallationEntry(appConfig);
if (registrationPromise) {
// A createInstallation request is in progress. Wait until it finishes.
await registrationPromise;
}
else if (installationEntry.registrationStatus !== 2 /* COMPLETED */) {
// Installation ID can't be registered.
throw ERROR_FACTORY.create("create-installation-failed" /* CREATE_INSTALLATION_FAILED */);
}
}
/**
* @license
* Copyright 2019 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
async function deleteInstallation(appConfig, installationEntry) {

@@ -746,0 +774,0 @@ const endpoint = getDeleteEndpoint(appConfig, installationEntry);

{
"name": "@firebase/installations",
"version": "0.1.5-canary.d164cac",
"version": "0.1.5-canary.fd5a31a",
"main": "dist/index.cjs.js",

@@ -48,8 +48,8 @@ "module": "dist/index.esm.js",

"peerDependencies": {
"@firebase/app": "0.4.4-canary.d164cac",
"@firebase/app-types": "0.4.0-canary.d164cac"
"@firebase/app": "0.4.4-canary.fd5a31a",
"@firebase/app-types": "0.4.0-canary.fd5a31a"
},
"dependencies": {
"@firebase/installations-types": "0.1.1-canary.d164cac",
"@firebase/util": "0.2.18-canary.d164cac",
"@firebase/installations-types": "0.1.1-canary.fd5a31a",
"@firebase/util": "0.2.18-canary.fd5a31a",
"idb": "3.0.2",

@@ -56,0 +56,0 @@ "tslib": "1.9.3"

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

import * as getInstallationEntryModule from '../helpers/get-installation-entry';
import * as refreshAuthTokenModule from '../helpers/refresh-auth-token';
import { AppConfig } from '../interfaces/app-config';

@@ -40,3 +41,7 @@ import { RequestStatus } from '../interfaces/installation-entry';

'getInstallationEntry'
).resolves({
);
});
it('returns the FID in InstallationEntry returned by getInstallationEntry', async () => {
getInstallationEntrySpy.resolves({
installationEntry: {

@@ -47,5 +52,3 @@ fid: FID,

});
});
it('returns the FID in InstallationEntry returned by getInstallationEntry', async () => {
const firebaseApp = getFakeApp();

@@ -56,2 +59,24 @@ const fid = await getId(firebaseApp);

});
it('calls refreshAuthToken if the installation is registered', async () => {
getInstallationEntrySpy.resolves({
installationEntry: {
fid: FID,
registrationStatus: RequestStatus.COMPLETED,
refreshToken: 'refreshToken',
authToken: {
requestStatus: RequestStatus.NOT_STARTED
}
}
});
const refreshAuthTokenSpy = stub(
refreshAuthTokenModule,
'refreshAuthToken'
).resolves('authToken');
const firebaseApp = getFakeApp();
await getId(firebaseApp);
expect(refreshAuthTokenSpy).to.be.calledOnce;
});
});

@@ -21,2 +21,4 @@ /**

import { getInstallationEntry } from '../helpers/get-installation-entry';
import { refreshAuthToken } from '../helpers/refresh-auth-token';
import { RequestStatus } from '../interfaces/installation-entry';

@@ -28,2 +30,3 @@ export async function getId(app: FirebaseApp): Promise<string> {

);
if (registrationPromise) {

@@ -33,3 +36,10 @@ // Suppress registration errors as they are not a problem for getId.

}
if (installationEntry.registrationStatus === RequestStatus.COMPLETED) {
// If the installation is already registered, update the authentication
// token if needed. Suppress errors as they are not relevant to getId.
refreshAuthToken(appConfig).catch(() => {});
}
return installationEntry.fid;
}

@@ -297,3 +297,3 @@ /**

it('does not call generateAuthToken on subsequent calls', async () => {
it('does not call generateAuthToken twice on subsequent calls', async () => {
await getToken(app);

@@ -304,2 +304,7 @@ await getToken(app);

it('does not call generateAuthToken twice on simultaneous calls', async () => {
await Promise.all([getToken(app), getToken(app)]);
expect(generateAuthTokenSpy).to.be.calledOnce;
});
it('throws if the app is offline', async () => {

@@ -306,0 +311,0 @@ stub(navigator, 'onLine').value(false);

@@ -19,18 +19,8 @@ /**

import { FirebaseApp } from '@firebase/app-types';
import { generateAuthToken } from '../api/generate-auth-token';
import { extractAppConfig } from '../helpers/extract-app-config';
import { getInstallationEntry } from '../helpers/get-installation-entry';
import { remove, set, update } from '../helpers/idb-manager';
import { refreshAuthToken } from '../helpers/refresh-auth-token';
import { AppConfig } from '../interfaces/app-config';
import {
AuthToken,
CompletedAuthToken,
InProgressAuthToken,
InstallationEntry,
RegisteredInstallationEntry,
RequestStatus
} from '../interfaces/installation-entry';
import { PENDING_TIMEOUT_MS, TOKEN_EXPIRATION_BUFFER } from '../util/constants';
import { ERROR_FACTORY, ErrorCode, isServerError } from '../util/errors';
import { sleep } from '../util/sleep';
import { RequestStatus } from '../interfaces/installation-entry';
import { ERROR_FACTORY, ErrorCode } from '../util/errors';

@@ -44,3 +34,3 @@ export async function getToken(app: FirebaseApp): Promise<string> {

// already thrown an error.
return fetchAuthToken(appConfig);
return refreshAuthToken(appConfig);
}

@@ -63,167 +53,1 @@

}
async function fetchAuthToken(appConfig: AppConfig): Promise<string> {
let tokenPromise: Promise<CompletedAuthToken> | undefined;
const entry = await update(
appConfig,
(oldEntry?: InstallationEntry): RegisteredInstallationEntry => {
if (!isEntryRegistered(oldEntry)) {
throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);
}
const oldAuthToken = oldEntry.authToken;
if (isAuthTokenValid(oldAuthToken)) {
// There is a valid token in the DB.
return oldEntry;
} else if (oldAuthToken.requestStatus === RequestStatus.IN_PROGRESS) {
// There already is a token request in progress.
tokenPromise = waitUntilAuthTokenRequest(appConfig);
return oldEntry;
} else {
// No token or token expired.
if (!navigator.onLine) {
throw ERROR_FACTORY.create(ErrorCode.APP_OFFLINE);
}
const inProgressEntry = makeAuthTokenRequestInProgressEntry(oldEntry);
tokenPromise = fetchAuthTokenFromServer(appConfig, inProgressEntry);
return inProgressEntry;
}
}
);
const authToken: CompletedAuthToken = tokenPromise
? await tokenPromise
: (entry.authToken as CompletedAuthToken);
return authToken.token;
}
/**
* Call only if FID is registered and Auth Token request is in progress.
*/
async function waitUntilAuthTokenRequest(
appConfig: AppConfig
): Promise<CompletedAuthToken> {
// Unfortunately, there is no way of reliably observing when a value in
// IndexedDB changes (yet, see https://github.com/WICG/indexed-db-observers),
// so we need to poll.
let entry = await updateAuthTokenRequest(appConfig);
while (entry.authToken.requestStatus === RequestStatus.IN_PROGRESS) {
// generateAuthToken still in progress.
await sleep(100);
entry = await updateAuthTokenRequest(appConfig);
}
const authToken = entry.authToken;
if (authToken.requestStatus === RequestStatus.NOT_STARTED) {
throw ERROR_FACTORY.create(ErrorCode.GENERATE_TOKEN_FAILED);
} else {
return authToken;
}
}
/**
* Called only if there is a GenerateAuthToken request in progress.
*
* Updates the InstallationEntry in the DB based on the status of the
* GenerateAuthToken request.
*
* Returns the updated InstallationEntry.
*/
function updateAuthTokenRequest(
appConfig: AppConfig
): Promise<RegisteredInstallationEntry> {
return update(
appConfig,
(oldEntry?: InstallationEntry): RegisteredInstallationEntry => {
if (!isEntryRegistered(oldEntry)) {
throw ERROR_FACTORY.create(ErrorCode.NOT_REGISTERED);
}
const oldAuthToken = oldEntry.authToken;
if (hasAuthTokenRequestTimedOut(oldAuthToken)) {
return {
...oldEntry,
authToken: { requestStatus: RequestStatus.NOT_STARTED }
};
}
return oldEntry;
}
);
}
async function fetchAuthTokenFromServer(
appConfig: AppConfig,
installationEntry: RegisteredInstallationEntry
): Promise<CompletedAuthToken> {
try {
const authToken = await generateAuthToken(appConfig, installationEntry);
const updatedInstallationEntry: RegisteredInstallationEntry = {
...installationEntry,
authToken
};
await set(appConfig, updatedInstallationEntry);
return authToken;
} catch (e) {
if (isServerError(e) && (e.serverCode === 401 || e.serverCode === 404)) {
// Server returned a "FID not found" or a "Invalid authentication" error.
// Generate a new ID next time.
await remove(appConfig);
} else {
const updatedInstallationEntry: RegisteredInstallationEntry = {
...installationEntry,
authToken: { requestStatus: RequestStatus.NOT_STARTED }
};
await set(appConfig, updatedInstallationEntry);
}
throw e;
}
}
function isEntryRegistered(
installationEntry: InstallationEntry | undefined
): installationEntry is RegisteredInstallationEntry {
return (
installationEntry !== undefined &&
installationEntry.registrationStatus === RequestStatus.COMPLETED
);
}
function isAuthTokenValid(authToken: AuthToken): boolean {
return (
authToken.requestStatus === RequestStatus.COMPLETED &&
!isAuthTokenExpired(authToken)
);
}
function isAuthTokenExpired(authToken: CompletedAuthToken): boolean {
const now = Date.now();
return (
now < authToken.creationTime ||
authToken.creationTime + authToken.expiresIn < now + TOKEN_EXPIRATION_BUFFER
);
}
/** Returns an updated InstallationEntry with an InProgressAuthToken. */
function makeAuthTokenRequestInProgressEntry(
oldEntry: RegisteredInstallationEntry
): RegisteredInstallationEntry {
const inProgressAuthToken: InProgressAuthToken = {
requestStatus: RequestStatus.IN_PROGRESS,
requestTime: Date.now()
};
return {
...oldEntry,
authToken: inProgressAuthToken
};
}
function hasAuthTokenRequestTimedOut(authToken: AuthToken): boolean {
return (
authToken.requestStatus === RequestStatus.IN_PROGRESS &&
authToken.requestTime + PENDING_TIMEOUT_MS < Date.now()
);
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet