@firebase/app-check
Advanced tools
Comparing version 0.0.900-exp.57f19127c to 0.0.900-exp.6ef484a04
@@ -0,2 +1,10 @@ | ||
/** | ||
* Firebase App Check | ||
* | ||
* @packageDocumentation | ||
*/ | ||
import { FirebaseApp } from '@firebase/app'; | ||
import { PartialObserver } from '@firebase/util'; | ||
import { Unsubscribe } from '@firebase/util'; | ||
@@ -59,2 +67,19 @@ /** | ||
/** | ||
* A listener that is called whenever the App Check token changes. | ||
* @public | ||
*/ | ||
export declare type AppCheckTokenListener = (token: AppCheckTokenResult) => void; | ||
/** | ||
* Result returned by `getToken()`. | ||
* @public | ||
*/ | ||
export declare interface AppCheckTokenResult { | ||
/** | ||
* The token string in JWT format. | ||
*/ | ||
readonly token: string; | ||
} | ||
/** | ||
* Custom provider class. | ||
@@ -84,2 +109,14 @@ * @public | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
export declare function getToken(appCheckInstance: AppCheck, forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
/** | ||
* Activate App Check for the given app. Can be called only once per app. | ||
@@ -93,2 +130,39 @@ * @param app - the FirebaseApp to activate App Check for | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param observer - An object with `next`, `error`, and `complete` | ||
* properties. `next` is called with an | ||
* {@link AppCheckTokenResult} | ||
* whenever the token changes. `error` is optional and is called if an | ||
* error is thrown by the listener (the `next` function). `complete` | ||
* is unused, as the token stream is unending. | ||
* | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, observer: PartialObserver<AppCheckTokenResult>): Unsubscribe; | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param onNext - When the token changes, this function is called with aa | ||
* {@link AppCheckTokenResult}. | ||
* @param onError - Optional. Called if there is an error thrown by the | ||
* listener (the `onNext` function). | ||
* @param onCompletion - Currently unused, as the token stream is unending. | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, onNext: (tokenResult: AppCheckTokenResult) => void, onError?: (error: Error) => void, onCompletion?: () => void): Unsubscribe; | ||
export { PartialObserver } | ||
/** | ||
* App Check provider that can obtain a reCAPTCHA V3 token and exchange it | ||
@@ -115,2 +189,3 @@ * for an App Check token. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -121,4 +196,5 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
export declare function setTokenAutoRefreshEnabled(app: FirebaseApp, isTokenAutoRefreshEnabled: boolean): void; | ||
export declare function setTokenAutoRefreshEnabled(appCheckInstance: AppCheck, isTokenAutoRefreshEnabled: boolean): void; | ||
export { Unsubscribe } | ||
export { } |
@@ -0,2 +1,10 @@ | ||
/** | ||
* Firebase App Check | ||
* | ||
* @packageDocumentation | ||
*/ | ||
import { FirebaseApp } from '@firebase/app'; | ||
import { PartialObserver } from '@firebase/util'; | ||
import { Unsubscribe } from '@firebase/util'; | ||
@@ -65,2 +73,19 @@ /** | ||
/** | ||
* A listener that is called whenever the App Check token changes. | ||
* @public | ||
*/ | ||
export declare type AppCheckTokenListener = (token: AppCheckTokenResult) => void; | ||
/** | ||
* Result returned by `getToken()`. | ||
* @public | ||
*/ | ||
export declare interface AppCheckTokenResult { | ||
/** | ||
* The token string in JWT format. | ||
*/ | ||
readonly token: string; | ||
} | ||
/** | ||
* Custom provider class. | ||
@@ -96,2 +121,14 @@ * @public | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
export declare function getToken(appCheckInstance: AppCheck, forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
/** | ||
* Activate App Check for the given app. Can be called only once per app. | ||
@@ -105,2 +142,39 @@ * @param app - the FirebaseApp to activate App Check for | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param observer - An object with `next`, `error`, and `complete` | ||
* properties. `next` is called with an | ||
* {@link AppCheckTokenResult} | ||
* whenever the token changes. `error` is optional and is called if an | ||
* error is thrown by the listener (the `next` function). `complete` | ||
* is unused, as the token stream is unending. | ||
* | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, observer: PartialObserver<AppCheckTokenResult>): Unsubscribe; | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param onNext - When the token changes, this function is called with aa | ||
* {@link AppCheckTokenResult}. | ||
* @param onError - Optional. Called if there is an error thrown by the | ||
* listener (the `onNext` function). | ||
* @param onCompletion - Currently unused, as the token stream is unending. | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, onNext: (tokenResult: AppCheckTokenResult) => void, onError?: (error: Error) => void, onCompletion?: () => void): Unsubscribe; | ||
export { PartialObserver } | ||
/** | ||
* App Check provider that can obtain a reCAPTCHA V3 token and exchange it | ||
@@ -134,2 +208,3 @@ * for an App Check token. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -140,4 +215,5 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
export declare function setTokenAutoRefreshEnabled(app: FirebaseApp, isTokenAutoRefreshEnabled: boolean): void; | ||
export declare function setTokenAutoRefreshEnabled(appCheckInstance: AppCheck, isTokenAutoRefreshEnabled: boolean): void; | ||
export { Unsubscribe } | ||
export { } |
@@ -30,3 +30,3 @@ 'use strict'; | ||
activated: false, | ||
tokenListeners: [] | ||
tokenObservers: [] | ||
}; | ||
@@ -603,3 +603,3 @@ var DEBUG_STATE = { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var existingDebugToken, _e_1, newToken; | ||
var existingDebugToken, newToken; | ||
return tslib.__generator(this, function (_a) { | ||
@@ -617,3 +617,3 @@ switch (_a.label) { | ||
case 3: | ||
_e_1 = _a.sent(); | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
@@ -729,26 +729,17 @@ case 4: | ||
*/ | ||
function getToken(app, platformLoggerProvider, forceRefresh) { | ||
function getToken$2(appCheck, forceRefresh) { | ||
if (forceRefresh === void 0) { forceRefresh = false; } | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var tokenFromDebugExchange, _a, _b, _c, state, token, error, cachedToken, e_1, interopTokenResult; | ||
var app, state, token, error, cachedToken, tokenFromDebugExchange, _a, _b, _c, e_1, interopTokenResult; | ||
return tslib.__generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
app = appCheck.app; | ||
ensureActivated(app); | ||
if (!isDebugMode()) return [3 /*break*/, 3]; | ||
_a = exchangeToken; | ||
_b = getExchangeDebugTokenRequest; | ||
_c = [app]; | ||
return [4 /*yield*/, getDebugToken()]; | ||
case 1: return [4 /*yield*/, _a.apply(void 0, [_b.apply(void 0, _c.concat([_d.sent()])), platformLoggerProvider])]; | ||
case 2: | ||
tokenFromDebugExchange = _d.sent(); | ||
return [2 /*return*/, { token: tokenFromDebugExchange.token }]; | ||
case 3: | ||
state = getState(app); | ||
token = state.token; | ||
error = undefined; | ||
if (!!token) return [3 /*break*/, 5]; | ||
if (!!token) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, readTokenFromStorage(app)]; | ||
case 4: | ||
case 1: | ||
cachedToken = _d.sent(); | ||
@@ -761,5 +752,5 @@ if (cachedToken && isValid(cachedToken)) { | ||
} | ||
_d.label = 5; | ||
case 5: | ||
// return the cached token if it's valid | ||
_d.label = 2; | ||
case 2: | ||
// Return the cached token (from either memory or indexedDB) if it's valid | ||
if (!forceRefresh && token && isValid(token)) { | ||
@@ -770,3 +761,18 @@ return [2 /*return*/, { | ||
} | ||
_d.label = 6; | ||
if (!isDebugMode()) return [3 /*break*/, 6]; | ||
_a = exchangeToken; | ||
_b = getExchangeDebugTokenRequest; | ||
_c = [app]; | ||
return [4 /*yield*/, getDebugToken()]; | ||
case 3: return [4 /*yield*/, _a.apply(void 0, [_b.apply(void 0, _c.concat([_d.sent()])), appCheck.platformLoggerProvider])]; | ||
case 4: | ||
tokenFromDebugExchange = _d.sent(); | ||
// Write debug token to indexedDB. | ||
return [4 /*yield*/, writeTokenToStorage(app, tokenFromDebugExchange)]; | ||
case 5: | ||
// Write debug token to indexedDB. | ||
_d.sent(); | ||
// Write debug token to state. | ||
setState(app, tslib.__assign(tslib.__assign({}, state), { token: tokenFromDebugExchange })); | ||
return [2 /*return*/, { token: tokenFromDebugExchange.token }]; | ||
case 6: | ||
@@ -797,3 +803,3 @@ _d.trys.push([6, 8, , 9]); | ||
}; | ||
// write the new token to the memory state as well ashe persistent storage. | ||
// write the new token to the memory state as well as the persistent storage. | ||
// Only do it if we got a valid new token | ||
@@ -812,46 +818,33 @@ setState(app, tslib.__assign(tslib.__assign({}, state), { token: token })); | ||
} | ||
function addTokenListener(app, platformLoggerProvider, listener) { | ||
function addTokenListener(appCheck, type, listener, onError) { | ||
var app = appCheck.app; | ||
var state = getState(app); | ||
var newState = tslib.__assign(tslib.__assign({}, state), { tokenListeners: tslib.__spreadArray(tslib.__spreadArray([], state.tokenListeners), [listener]) }); | ||
var tokenObserver = { | ||
next: listener, | ||
error: onError, | ||
type: type | ||
}; | ||
var newState = tslib.__assign(tslib.__assign({}, state), { tokenObservers: tslib.__spreadArray(tslib.__spreadArray([], state.tokenObservers), [tokenObserver]) }); | ||
/** | ||
* DEBUG MODE | ||
* | ||
* invoke the listener once with the debug token. | ||
* Invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (isDebugMode()) { | ||
var debugState = getDebugState(); | ||
if (debugState.enabled && debugState.token) { | ||
debugState.token.promise | ||
.then(function (token) { return listener({ token: token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
if (!newState.tokenRefresher) { | ||
var tokenRefresher = createTokenRefresher(appCheck); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
else { | ||
/** | ||
* PROD MODE | ||
* | ||
* invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (!newState.tokenRefresher) { | ||
var tokenRefresher = createTokenRefresher(app, platformLoggerProvider); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled === true) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
var validToken_1 = state.token; | ||
Promise.resolve() | ||
.then(function () { return listener({ token: validToken_1.token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
var validToken_1 = state.token; | ||
Promise.resolve() | ||
.then(function () { return listener({ token: validToken_1.token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
setState(app, newState); | ||
@@ -861,4 +854,4 @@ } | ||
var state = getState(app); | ||
var newListeners = state.tokenListeners.filter(function (l) { return l !== listener; }); | ||
if (newListeners.length === 0 && | ||
var newObservers = state.tokenObservers.filter(function (tokenObserver) { return tokenObserver.next !== listener; }); | ||
if (newObservers.length === 0 && | ||
state.tokenRefresher && | ||
@@ -868,6 +861,7 @@ state.tokenRefresher.isRunning()) { | ||
} | ||
setState(app, tslib.__assign(tslib.__assign({}, state), { tokenListeners: newListeners })); | ||
setState(app, tslib.__assign(tslib.__assign({}, state), { tokenObservers: newObservers })); | ||
} | ||
function createTokenRefresher(app, platformLoggerProvider) { | ||
function createTokenRefresher(appCheck) { | ||
var _this = this; | ||
var app = appCheck.app; | ||
return new Refresher( | ||
@@ -883,7 +877,7 @@ // Keep in mind when this fails for any reason other than the ones | ||
if (!!state.token) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, getToken(app, platformLoggerProvider)]; | ||
return [4 /*yield*/, getToken$2(appCheck)]; | ||
case 1: | ||
result = _a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 2: return [4 /*yield*/, getToken(app, platformLoggerProvider, true)]; | ||
case 2: return [4 /*yield*/, getToken$2(appCheck, true)]; | ||
case 3: | ||
@@ -922,10 +916,21 @@ result = _a.sent(); | ||
function notifyTokenListeners(app, token) { | ||
var listeners = getState(app).tokenListeners; | ||
for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { | ||
var listener = listeners_1[_i]; | ||
var observers = getState(app).tokenObservers; | ||
for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) { | ||
var observer = observers_1[_i]; | ||
try { | ||
listener(token); | ||
if (observer.type === "EXTERNAL" /* EXTERNAL */ && token.error != null) { | ||
// If this listener was added by a 3P call, send any token error to | ||
// the supplied error handler. A 3P observer always has an error | ||
// handler. | ||
observer.error(token.error); | ||
} | ||
else { | ||
// If the token has no error field, always return the token. | ||
// If this is a 2P listener, return the token, whether or not it | ||
// has an error field. | ||
observer.next(token); | ||
} | ||
} | ||
catch (e) { | ||
// If any handler fails, ignore and run next handler. | ||
// Errors in the listener function itself are always ignored. | ||
} | ||
@@ -964,6 +969,12 @@ } | ||
var AppCheckService = /** @class */ (function () { | ||
function AppCheckService(app) { | ||
function AppCheckService(app, platformLoggerProvider) { | ||
this.app = app; | ||
this.platformLoggerProvider = platformLoggerProvider; | ||
} | ||
AppCheckService.prototype._delete = function () { | ||
var tokenObservers = getState(this.app).tokenObservers; | ||
for (var _i = 0, tokenObservers_1 = tokenObservers; _i < tokenObservers_1.length; _i++) { | ||
var tokenObserver = tokenObservers_1[_i]; | ||
removeTokenListener(this.app, tokenObserver.next); | ||
} | ||
return Promise.resolve(); | ||
@@ -973,14 +984,12 @@ }; | ||
}()); | ||
function factory(app) { | ||
return new AppCheckService(app); | ||
function factory(app, platformLoggerProvider) { | ||
return new AppCheckService(app, platformLoggerProvider); | ||
} | ||
function internalFactory(app, platformLoggerProvider) { | ||
function internalFactory(appCheck) { | ||
return { | ||
getToken: function (forceRefresh) { | ||
return getToken(app, platformLoggerProvider, forceRefresh); | ||
}, | ||
getToken: function (forceRefresh) { return getToken$2(appCheck, forceRefresh); }, | ||
addTokenListener: function (listener) { | ||
return addTokenListener(app, platformLoggerProvider, listener); | ||
return addTokenListener(appCheck, "INTERNAL" /* INTERNAL */, listener); | ||
}, | ||
removeTokenListener: function (listener) { return removeTokenListener(app, listener); } | ||
removeTokenListener: function (listener) { return removeTokenListener(appCheck.app, listener); } | ||
}; | ||
@@ -990,3 +999,3 @@ } | ||
var name = "@firebase/app-check-exp"; | ||
var version = "0.0.900-exp.57f19127c"; | ||
var version = "0.0.900-exp.6ef484a04"; | ||
@@ -1270,2 +1279,3 @@ /** | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -1276,3 +1286,4 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
function setTokenAutoRefreshEnabled(app, isTokenAutoRefreshEnabled) { | ||
function setTokenAutoRefreshEnabled(appCheckInstance, isTokenAutoRefreshEnabled) { | ||
var app = appCheckInstance.app; | ||
var state = getState(app); | ||
@@ -1291,18 +1302,63 @@ // This will exist if any product libraries have called | ||
} | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
function getToken(appCheckInstance, forceRefresh) { | ||
return tslib.__awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return tslib.__generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, getToken$2(appCheckInstance, forceRefresh)]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.error) { | ||
throw result.error; | ||
} | ||
return [2 /*return*/, { token: result.token }]; | ||
} | ||
}); | ||
}); | ||
} | ||
/** | ||
* Wraps addTokenListener/removeTokenListener methods in an Observer | ||
* pattern for public use. | ||
*/ | ||
function onTokenChanged(appCheckInstance, onNextOrObserver, onError, | ||
/** | ||
* NOTE: Although an `onCompletion` callback can be provided, it will | ||
* never be called because the token stream is never-ending. | ||
* It is added only for API consistency with the observer pattern, which | ||
* we follow in JS APIs. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
onCompletion) { | ||
var nextFn = function () { }; | ||
var errorFn = function () { }; | ||
if (onNextOrObserver.next != null) { | ||
nextFn = onNextOrObserver.next.bind(onNextOrObserver); | ||
} | ||
else { | ||
nextFn = onNextOrObserver; | ||
} | ||
if (onNextOrObserver.error != null) { | ||
errorFn = onNextOrObserver.error.bind(onNextOrObserver); | ||
} | ||
else if (onError) { | ||
errorFn = onError; | ||
} | ||
addTokenListener(appCheckInstance, "EXTERNAL" /* EXTERNAL */, nextFn, errorFn); | ||
return function () { return removeTokenListener(appCheckInstance.app, nextFn); }; | ||
} | ||
/** | ||
* @license | ||
* Copyright 2017 Google LLC | ||
* Firebase App Check | ||
* | ||
* 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. | ||
* @packageDocumentation | ||
*/ | ||
@@ -1316,11 +1372,18 @@ var APP_CHECK_NAME = 'app-check-exp'; | ||
var app = container.getProvider('app-exp').getImmediate(); | ||
return factory(app); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
var platformLoggerProvider = container.getProvider('platform-logger'); | ||
return factory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */) | ||
.setInstantiationMode("EXPLICIT" /* EXPLICIT */) | ||
/** | ||
* Initialize app-check-internal after app-check is initialized to make AppCheck available to | ||
* other Firebase SDKs | ||
*/ | ||
.setInstanceCreatedCallback(function (container, _identifier, _appcheckService) { | ||
container.getProvider(APP_CHECK_NAME_INTERNAL).initialize(); | ||
})); | ||
// The internal interface used by other Firebase products | ||
app._registerComponent(new component.Component(APP_CHECK_NAME_INTERNAL, function (container) { | ||
// getImmediate for FirebaseApp will always succeed | ||
var app = container.getProvider('app-exp').getImmediate(); | ||
var platformLoggerProvider = container.getProvider('platform-logger'); | ||
return internalFactory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
var appCheck = container.getProvider('app-check-exp').getImmediate(); | ||
return internalFactory(appCheck); | ||
}, "PUBLIC" /* PUBLIC */).setInstantiationMode("EXPLICIT" /* EXPLICIT */)); | ||
app.registerVersion(name, version); | ||
@@ -1333,4 +1396,6 @@ } | ||
exports.ReCaptchaV3Provider = ReCaptchaV3Provider; | ||
exports.getToken = getToken; | ||
exports.initializeAppCheck = initializeAppCheck; | ||
exports.onTokenChanged = onTokenChanged; | ||
exports.setTokenAutoRefreshEnabled = setTokenAutoRefreshEnabled; | ||
//# sourceMappingURL=index.cjs.js.map |
@@ -26,3 +26,3 @@ import { _getProvider, getApp, _registerComponent, registerVersion } from '@firebase/app'; | ||
activated: false, | ||
tokenListeners: [] | ||
tokenObservers: [] | ||
}; | ||
@@ -599,3 +599,3 @@ var DEBUG_STATE = { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var existingDebugToken, _e_1, newToken; | ||
var existingDebugToken, newToken; | ||
return __generator(this, function (_a) { | ||
@@ -613,3 +613,3 @@ switch (_a.label) { | ||
case 3: | ||
_e_1 = _a.sent(); | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
@@ -725,26 +725,17 @@ case 4: | ||
*/ | ||
function getToken(app, platformLoggerProvider, forceRefresh) { | ||
function getToken$2(appCheck, forceRefresh) { | ||
if (forceRefresh === void 0) { forceRefresh = false; } | ||
return __awaiter(this, void 0, void 0, function () { | ||
var tokenFromDebugExchange, _a, _b, _c, state, token, error, cachedToken, e_1, interopTokenResult; | ||
var app, state, token, error, cachedToken, tokenFromDebugExchange, _a, _b, _c, e_1, interopTokenResult; | ||
return __generator(this, function (_d) { | ||
switch (_d.label) { | ||
case 0: | ||
app = appCheck.app; | ||
ensureActivated(app); | ||
if (!isDebugMode()) return [3 /*break*/, 3]; | ||
_a = exchangeToken; | ||
_b = getExchangeDebugTokenRequest; | ||
_c = [app]; | ||
return [4 /*yield*/, getDebugToken()]; | ||
case 1: return [4 /*yield*/, _a.apply(void 0, [_b.apply(void 0, _c.concat([_d.sent()])), platformLoggerProvider])]; | ||
case 2: | ||
tokenFromDebugExchange = _d.sent(); | ||
return [2 /*return*/, { token: tokenFromDebugExchange.token }]; | ||
case 3: | ||
state = getState(app); | ||
token = state.token; | ||
error = undefined; | ||
if (!!token) return [3 /*break*/, 5]; | ||
if (!!token) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, readTokenFromStorage(app)]; | ||
case 4: | ||
case 1: | ||
cachedToken = _d.sent(); | ||
@@ -757,5 +748,5 @@ if (cachedToken && isValid(cachedToken)) { | ||
} | ||
_d.label = 5; | ||
case 5: | ||
// return the cached token if it's valid | ||
_d.label = 2; | ||
case 2: | ||
// Return the cached token (from either memory or indexedDB) if it's valid | ||
if (!forceRefresh && token && isValid(token)) { | ||
@@ -766,3 +757,18 @@ return [2 /*return*/, { | ||
} | ||
_d.label = 6; | ||
if (!isDebugMode()) return [3 /*break*/, 6]; | ||
_a = exchangeToken; | ||
_b = getExchangeDebugTokenRequest; | ||
_c = [app]; | ||
return [4 /*yield*/, getDebugToken()]; | ||
case 3: return [4 /*yield*/, _a.apply(void 0, [_b.apply(void 0, _c.concat([_d.sent()])), appCheck.platformLoggerProvider])]; | ||
case 4: | ||
tokenFromDebugExchange = _d.sent(); | ||
// Write debug token to indexedDB. | ||
return [4 /*yield*/, writeTokenToStorage(app, tokenFromDebugExchange)]; | ||
case 5: | ||
// Write debug token to indexedDB. | ||
_d.sent(); | ||
// Write debug token to state. | ||
setState(app, __assign(__assign({}, state), { token: tokenFromDebugExchange })); | ||
return [2 /*return*/, { token: tokenFromDebugExchange.token }]; | ||
case 6: | ||
@@ -793,3 +799,3 @@ _d.trys.push([6, 8, , 9]); | ||
}; | ||
// write the new token to the memory state as well ashe persistent storage. | ||
// write the new token to the memory state as well as the persistent storage. | ||
// Only do it if we got a valid new token | ||
@@ -808,46 +814,33 @@ setState(app, __assign(__assign({}, state), { token: token })); | ||
} | ||
function addTokenListener(app, platformLoggerProvider, listener) { | ||
function addTokenListener(appCheck, type, listener, onError) { | ||
var app = appCheck.app; | ||
var state = getState(app); | ||
var newState = __assign(__assign({}, state), { tokenListeners: __spreadArray(__spreadArray([], state.tokenListeners), [listener]) }); | ||
var tokenObserver = { | ||
next: listener, | ||
error: onError, | ||
type: type | ||
}; | ||
var newState = __assign(__assign({}, state), { tokenObservers: __spreadArray(__spreadArray([], state.tokenObservers), [tokenObserver]) }); | ||
/** | ||
* DEBUG MODE | ||
* | ||
* invoke the listener once with the debug token. | ||
* Invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (isDebugMode()) { | ||
var debugState = getDebugState(); | ||
if (debugState.enabled && debugState.token) { | ||
debugState.token.promise | ||
.then(function (token) { return listener({ token: token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
if (!newState.tokenRefresher) { | ||
var tokenRefresher = createTokenRefresher(appCheck); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
else { | ||
/** | ||
* PROD MODE | ||
* | ||
* invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (!newState.tokenRefresher) { | ||
var tokenRefresher = createTokenRefresher(app, platformLoggerProvider); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled === true) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
var validToken_1 = state.token; | ||
Promise.resolve() | ||
.then(function () { return listener({ token: validToken_1.token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
var validToken_1 = state.token; | ||
Promise.resolve() | ||
.then(function () { return listener({ token: validToken_1.token }); }) | ||
.catch(function () { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
setState(app, newState); | ||
@@ -857,4 +850,4 @@ } | ||
var state = getState(app); | ||
var newListeners = state.tokenListeners.filter(function (l) { return l !== listener; }); | ||
if (newListeners.length === 0 && | ||
var newObservers = state.tokenObservers.filter(function (tokenObserver) { return tokenObserver.next !== listener; }); | ||
if (newObservers.length === 0 && | ||
state.tokenRefresher && | ||
@@ -864,6 +857,7 @@ state.tokenRefresher.isRunning()) { | ||
} | ||
setState(app, __assign(__assign({}, state), { tokenListeners: newListeners })); | ||
setState(app, __assign(__assign({}, state), { tokenObservers: newObservers })); | ||
} | ||
function createTokenRefresher(app, platformLoggerProvider) { | ||
function createTokenRefresher(appCheck) { | ||
var _this = this; | ||
var app = appCheck.app; | ||
return new Refresher( | ||
@@ -879,7 +873,7 @@ // Keep in mind when this fails for any reason other than the ones | ||
if (!!state.token) return [3 /*break*/, 2]; | ||
return [4 /*yield*/, getToken(app, platformLoggerProvider)]; | ||
return [4 /*yield*/, getToken$2(appCheck)]; | ||
case 1: | ||
result = _a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 2: return [4 /*yield*/, getToken(app, platformLoggerProvider, true)]; | ||
case 2: return [4 /*yield*/, getToken$2(appCheck, true)]; | ||
case 3: | ||
@@ -918,10 +912,21 @@ result = _a.sent(); | ||
function notifyTokenListeners(app, token) { | ||
var listeners = getState(app).tokenListeners; | ||
for (var _i = 0, listeners_1 = listeners; _i < listeners_1.length; _i++) { | ||
var listener = listeners_1[_i]; | ||
var observers = getState(app).tokenObservers; | ||
for (var _i = 0, observers_1 = observers; _i < observers_1.length; _i++) { | ||
var observer = observers_1[_i]; | ||
try { | ||
listener(token); | ||
if (observer.type === "EXTERNAL" /* EXTERNAL */ && token.error != null) { | ||
// If this listener was added by a 3P call, send any token error to | ||
// the supplied error handler. A 3P observer always has an error | ||
// handler. | ||
observer.error(token.error); | ||
} | ||
else { | ||
// If the token has no error field, always return the token. | ||
// If this is a 2P listener, return the token, whether or not it | ||
// has an error field. | ||
observer.next(token); | ||
} | ||
} | ||
catch (e) { | ||
// If any handler fails, ignore and run next handler. | ||
// Errors in the listener function itself are always ignored. | ||
} | ||
@@ -960,6 +965,12 @@ } | ||
var AppCheckService = /** @class */ (function () { | ||
function AppCheckService(app) { | ||
function AppCheckService(app, platformLoggerProvider) { | ||
this.app = app; | ||
this.platformLoggerProvider = platformLoggerProvider; | ||
} | ||
AppCheckService.prototype._delete = function () { | ||
var tokenObservers = getState(this.app).tokenObservers; | ||
for (var _i = 0, tokenObservers_1 = tokenObservers; _i < tokenObservers_1.length; _i++) { | ||
var tokenObserver = tokenObservers_1[_i]; | ||
removeTokenListener(this.app, tokenObserver.next); | ||
} | ||
return Promise.resolve(); | ||
@@ -969,14 +980,12 @@ }; | ||
}()); | ||
function factory(app) { | ||
return new AppCheckService(app); | ||
function factory(app, platformLoggerProvider) { | ||
return new AppCheckService(app, platformLoggerProvider); | ||
} | ||
function internalFactory(app, platformLoggerProvider) { | ||
function internalFactory(appCheck) { | ||
return { | ||
getToken: function (forceRefresh) { | ||
return getToken(app, platformLoggerProvider, forceRefresh); | ||
}, | ||
getToken: function (forceRefresh) { return getToken$2(appCheck, forceRefresh); }, | ||
addTokenListener: function (listener) { | ||
return addTokenListener(app, platformLoggerProvider, listener); | ||
return addTokenListener(appCheck, "INTERNAL" /* INTERNAL */, listener); | ||
}, | ||
removeTokenListener: function (listener) { return removeTokenListener(app, listener); } | ||
removeTokenListener: function (listener) { return removeTokenListener(appCheck.app, listener); } | ||
}; | ||
@@ -986,3 +995,3 @@ } | ||
var name = "@firebase/app-check-exp"; | ||
var version = "0.0.900-exp.57f19127c"; | ||
var version = "0.0.900-exp.6ef484a04"; | ||
@@ -1266,2 +1275,3 @@ /** | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -1272,3 +1282,4 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
function setTokenAutoRefreshEnabled(app, isTokenAutoRefreshEnabled) { | ||
function setTokenAutoRefreshEnabled(appCheckInstance, isTokenAutoRefreshEnabled) { | ||
var app = appCheckInstance.app; | ||
var state = getState(app); | ||
@@ -1287,18 +1298,63 @@ // This will exist if any product libraries have called | ||
} | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
function getToken(appCheckInstance, forceRefresh) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var result; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: return [4 /*yield*/, getToken$2(appCheckInstance, forceRefresh)]; | ||
case 1: | ||
result = _a.sent(); | ||
if (result.error) { | ||
throw result.error; | ||
} | ||
return [2 /*return*/, { token: result.token }]; | ||
} | ||
}); | ||
}); | ||
} | ||
/** | ||
* Wraps addTokenListener/removeTokenListener methods in an Observer | ||
* pattern for public use. | ||
*/ | ||
function onTokenChanged(appCheckInstance, onNextOrObserver, onError, | ||
/** | ||
* NOTE: Although an `onCompletion` callback can be provided, it will | ||
* never be called because the token stream is never-ending. | ||
* It is added only for API consistency with the observer pattern, which | ||
* we follow in JS APIs. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
onCompletion) { | ||
var nextFn = function () { }; | ||
var errorFn = function () { }; | ||
if (onNextOrObserver.next != null) { | ||
nextFn = onNextOrObserver.next.bind(onNextOrObserver); | ||
} | ||
else { | ||
nextFn = onNextOrObserver; | ||
} | ||
if (onNextOrObserver.error != null) { | ||
errorFn = onNextOrObserver.error.bind(onNextOrObserver); | ||
} | ||
else if (onError) { | ||
errorFn = onError; | ||
} | ||
addTokenListener(appCheckInstance, "EXTERNAL" /* EXTERNAL */, nextFn, errorFn); | ||
return function () { return removeTokenListener(appCheckInstance.app, nextFn); }; | ||
} | ||
/** | ||
* @license | ||
* Copyright 2017 Google LLC | ||
* Firebase App Check | ||
* | ||
* 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. | ||
* @packageDocumentation | ||
*/ | ||
@@ -1312,11 +1368,18 @@ var APP_CHECK_NAME = 'app-check-exp'; | ||
var app = container.getProvider('app-exp').getImmediate(); | ||
return factory(app); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
var platformLoggerProvider = container.getProvider('platform-logger'); | ||
return factory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */) | ||
.setInstantiationMode("EXPLICIT" /* EXPLICIT */) | ||
/** | ||
* Initialize app-check-internal after app-check is initialized to make AppCheck available to | ||
* other Firebase SDKs | ||
*/ | ||
.setInstanceCreatedCallback(function (container, _identifier, _appcheckService) { | ||
container.getProvider(APP_CHECK_NAME_INTERNAL).initialize(); | ||
})); | ||
// The internal interface used by other Firebase products | ||
_registerComponent(new Component(APP_CHECK_NAME_INTERNAL, function (container) { | ||
// getImmediate for FirebaseApp will always succeed | ||
var app = container.getProvider('app-exp').getImmediate(); | ||
var platformLoggerProvider = container.getProvider('platform-logger'); | ||
return internalFactory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
var appCheck = container.getProvider('app-check-exp').getImmediate(); | ||
return internalFactory(appCheck); | ||
}, "PUBLIC" /* PUBLIC */).setInstantiationMode("EXPLICIT" /* EXPLICIT */)); | ||
registerVersion(name, version); | ||
@@ -1327,3 +1390,3 @@ } | ||
export { CustomProvider, ReCaptchaV3Provider, initializeAppCheck, setTokenAutoRefreshEnabled }; | ||
export { CustomProvider, ReCaptchaV3Provider, getToken, initializeAppCheck, onTokenChanged, setTokenAutoRefreshEnabled }; | ||
//# sourceMappingURL=index.esm.js.map |
@@ -25,3 +25,3 @@ import { _getProvider, getApp, _registerComponent, registerVersion } from '@firebase/app'; | ||
activated: false, | ||
tokenListeners: [] | ||
tokenObservers: [] | ||
}; | ||
@@ -643,17 +643,13 @@ const DEBUG_STATE = { | ||
*/ | ||
async function getToken(app, platformLoggerProvider, forceRefresh = false) { | ||
async function getToken$2(appCheck, forceRefresh = false) { | ||
const app = appCheck.app; | ||
ensureActivated(app); | ||
const state = getState(app); | ||
/** | ||
* DEBUG MODE | ||
* return the debug token directly | ||
* First check if there is a token in memory from a previous `getToken()` call. | ||
*/ | ||
if (isDebugMode()) { | ||
const tokenFromDebugExchange = await exchangeToken(getExchangeDebugTokenRequest(app, await getDebugToken()), platformLoggerProvider); | ||
return { token: tokenFromDebugExchange.token }; | ||
} | ||
const state = getState(app); | ||
let token = state.token; | ||
let error = undefined; | ||
/** | ||
* try to load token from indexedDB if it's the first time this function is called | ||
* If there is no token in memory, try to load token from indexedDB. | ||
*/ | ||
@@ -670,3 +666,3 @@ if (!token) { | ||
} | ||
// return the cached token if it's valid | ||
// Return the cached token (from either memory or indexedDB) if it's valid | ||
if (!forceRefresh && token && isValid(token)) { | ||
@@ -678,2 +674,15 @@ return { | ||
/** | ||
* DEBUG MODE | ||
* If debug mode is set, and there is no cached token, fetch a new App | ||
* Check token using the debug token, and return it directly. | ||
*/ | ||
if (isDebugMode()) { | ||
const tokenFromDebugExchange = await exchangeToken(getExchangeDebugTokenRequest(app, await getDebugToken()), appCheck.platformLoggerProvider); | ||
// Write debug token to indexedDB. | ||
await writeTokenToStorage(app, tokenFromDebugExchange); | ||
// Write debug token to state. | ||
setState(app, Object.assign(Object.assign({}, state), { token: tokenFromDebugExchange })); | ||
return { token: tokenFromDebugExchange.token }; | ||
} | ||
/** | ||
* request a new token | ||
@@ -702,3 +711,3 @@ */ | ||
}; | ||
// write the new token to the memory state as well ashe persistent storage. | ||
// write the new token to the memory state as well as the persistent storage. | ||
// Only do it if we got a valid new token | ||
@@ -711,46 +720,33 @@ setState(app, Object.assign(Object.assign({}, state), { token })); | ||
} | ||
function addTokenListener(app, platformLoggerProvider, listener) { | ||
function addTokenListener(appCheck, type, listener, onError) { | ||
const { app } = appCheck; | ||
const state = getState(app); | ||
const newState = Object.assign(Object.assign({}, state), { tokenListeners: [...state.tokenListeners, listener] }); | ||
const tokenObserver = { | ||
next: listener, | ||
error: onError, | ||
type | ||
}; | ||
const newState = Object.assign(Object.assign({}, state), { tokenObservers: [...state.tokenObservers, tokenObserver] }); | ||
/** | ||
* DEBUG MODE | ||
* | ||
* invoke the listener once with the debug token. | ||
* Invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (isDebugMode()) { | ||
const debugState = getDebugState(); | ||
if (debugState.enabled && debugState.token) { | ||
debugState.token.promise | ||
.then(token => listener({ token })) | ||
.catch(() => { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
if (!newState.tokenRefresher) { | ||
const tokenRefresher = createTokenRefresher(appCheck); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
else { | ||
/** | ||
* PROD MODE | ||
* | ||
* invoke the listener with the valid token, then start the token refresher | ||
*/ | ||
if (!newState.tokenRefresher) { | ||
const tokenRefresher = createTokenRefresher(app, platformLoggerProvider); | ||
newState.tokenRefresher = tokenRefresher; | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled === true) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
const validToken = state.token; | ||
Promise.resolve() | ||
.then(() => listener({ token: validToken.token })) | ||
.catch(() => { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
// Create the refresher but don't start it if `isTokenAutoRefreshEnabled` | ||
// is not true. | ||
if (!newState.tokenRefresher.isRunning() && | ||
state.isTokenAutoRefreshEnabled) { | ||
newState.tokenRefresher.start(); | ||
} | ||
// invoke the listener async immediately if there is a valid token | ||
if (state.token && isValid(state.token)) { | ||
const validToken = state.token; | ||
Promise.resolve() | ||
.then(() => listener({ token: validToken.token })) | ||
.catch(() => { | ||
/* we don't care about exceptions thrown in listeners */ | ||
}); | ||
} | ||
setState(app, newState); | ||
@@ -760,4 +756,4 @@ } | ||
const state = getState(app); | ||
const newListeners = state.tokenListeners.filter(l => l !== listener); | ||
if (newListeners.length === 0 && | ||
const newObservers = state.tokenObservers.filter(tokenObserver => tokenObserver.next !== listener); | ||
if (newObservers.length === 0 && | ||
state.tokenRefresher && | ||
@@ -767,5 +763,6 @@ state.tokenRefresher.isRunning()) { | ||
} | ||
setState(app, Object.assign(Object.assign({}, state), { tokenListeners: newListeners })); | ||
setState(app, Object.assign(Object.assign({}, state), { tokenObservers: newObservers })); | ||
} | ||
function createTokenRefresher(app, platformLoggerProvider) { | ||
function createTokenRefresher(appCheck) { | ||
const { app } = appCheck; | ||
return new Refresher( | ||
@@ -780,6 +777,6 @@ // Keep in mind when this fails for any reason other than the ones | ||
if (!state.token) { | ||
result = await getToken(app, platformLoggerProvider); | ||
result = await getToken$2(appCheck); | ||
} | ||
else { | ||
result = await getToken(app, platformLoggerProvider, true); | ||
result = await getToken$2(appCheck, true); | ||
} | ||
@@ -812,9 +809,20 @@ // getToken() always resolves. In case the result has an error field defined, it means the operation failed, and we should retry. | ||
function notifyTokenListeners(app, token) { | ||
const listeners = getState(app).tokenListeners; | ||
for (const listener of listeners) { | ||
const observers = getState(app).tokenObservers; | ||
for (const observer of observers) { | ||
try { | ||
listener(token); | ||
if (observer.type === "EXTERNAL" /* EXTERNAL */ && token.error != null) { | ||
// If this listener was added by a 3P call, send any token error to | ||
// the supplied error handler. A 3P observer always has an error | ||
// handler. | ||
observer.error(token.error); | ||
} | ||
else { | ||
// If the token has no error field, always return the token. | ||
// If this is a 2P listener, return the token, whether or not it | ||
// has an error field. | ||
observer.next(token); | ||
} | ||
} | ||
catch (e) { | ||
// If any handler fails, ignore and run next handler. | ||
// Errors in the listener function itself are always ignored. | ||
} | ||
@@ -853,17 +861,22 @@ } | ||
class AppCheckService { | ||
constructor(app) { | ||
constructor(app, platformLoggerProvider) { | ||
this.app = app; | ||
this.platformLoggerProvider = platformLoggerProvider; | ||
} | ||
_delete() { | ||
const { tokenObservers } = getState(this.app); | ||
for (const tokenObserver of tokenObservers) { | ||
removeTokenListener(this.app, tokenObserver.next); | ||
} | ||
return Promise.resolve(); | ||
} | ||
} | ||
function factory(app) { | ||
return new AppCheckService(app); | ||
function factory(app, platformLoggerProvider) { | ||
return new AppCheckService(app, platformLoggerProvider); | ||
} | ||
function internalFactory(app, platformLoggerProvider) { | ||
function internalFactory(appCheck) { | ||
return { | ||
getToken: forceRefresh => getToken(app, platformLoggerProvider, forceRefresh), | ||
addTokenListener: listener => addTokenListener(app, platformLoggerProvider, listener), | ||
removeTokenListener: listener => removeTokenListener(app, listener) | ||
getToken: forceRefresh => getToken$2(appCheck, forceRefresh), | ||
addTokenListener: listener => addTokenListener(appCheck, "INTERNAL" /* INTERNAL */, listener), | ||
removeTokenListener: listener => removeTokenListener(appCheck.app, listener) | ||
}; | ||
@@ -873,3 +886,3 @@ } | ||
const name = "@firebase/app-check-exp"; | ||
const version = "0.0.900-exp.57f19127c"; | ||
const version = "0.0.900-exp.6ef484a04"; | ||
@@ -1126,2 +1139,3 @@ /** | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -1132,3 +1146,4 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
function setTokenAutoRefreshEnabled(app, isTokenAutoRefreshEnabled) { | ||
function setTokenAutoRefreshEnabled(appCheckInstance, isTokenAutoRefreshEnabled) { | ||
const app = appCheckInstance.app; | ||
const state = getState(app); | ||
@@ -1147,18 +1162,54 @@ // This will exist if any product libraries have called | ||
} | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
async function getToken(appCheckInstance, forceRefresh) { | ||
const result = await getToken$2(appCheckInstance, forceRefresh); | ||
if (result.error) { | ||
throw result.error; | ||
} | ||
return { token: result.token }; | ||
} | ||
/** | ||
* Wraps addTokenListener/removeTokenListener methods in an Observer | ||
* pattern for public use. | ||
*/ | ||
function onTokenChanged(appCheckInstance, onNextOrObserver, onError, | ||
/** | ||
* NOTE: Although an `onCompletion` callback can be provided, it will | ||
* never be called because the token stream is never-ending. | ||
* It is added only for API consistency with the observer pattern, which | ||
* we follow in JS APIs. | ||
*/ | ||
// eslint-disable-next-line @typescript-eslint/no-unused-vars | ||
onCompletion) { | ||
let nextFn = () => { }; | ||
let errorFn = () => { }; | ||
if (onNextOrObserver.next != null) { | ||
nextFn = onNextOrObserver.next.bind(onNextOrObserver); | ||
} | ||
else { | ||
nextFn = onNextOrObserver; | ||
} | ||
if (onNextOrObserver.error != null) { | ||
errorFn = onNextOrObserver.error.bind(onNextOrObserver); | ||
} | ||
else if (onError) { | ||
errorFn = onError; | ||
} | ||
addTokenListener(appCheckInstance, "EXTERNAL" /* EXTERNAL */, nextFn, errorFn); | ||
return () => removeTokenListener(appCheckInstance.app, nextFn); | ||
} | ||
/** | ||
* @license | ||
* Copyright 2017 Google LLC | ||
* Firebase App Check | ||
* | ||
* 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. | ||
* @packageDocumentation | ||
*/ | ||
@@ -1172,11 +1223,18 @@ const APP_CHECK_NAME = 'app-check-exp'; | ||
const app = container.getProvider('app-exp').getImmediate(); | ||
return factory(app); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
const platformLoggerProvider = container.getProvider('platform-logger'); | ||
return factory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */) | ||
.setInstantiationMode("EXPLICIT" /* EXPLICIT */) | ||
/** | ||
* Initialize app-check-internal after app-check is initialized to make AppCheck available to | ||
* other Firebase SDKs | ||
*/ | ||
.setInstanceCreatedCallback((container, _identifier, _appcheckService) => { | ||
container.getProvider(APP_CHECK_NAME_INTERNAL).initialize(); | ||
})); | ||
// The internal interface used by other Firebase products | ||
_registerComponent(new Component(APP_CHECK_NAME_INTERNAL, container => { | ||
// getImmediate for FirebaseApp will always succeed | ||
const app = container.getProvider('app-exp').getImmediate(); | ||
const platformLoggerProvider = container.getProvider('platform-logger'); | ||
return internalFactory(app, platformLoggerProvider); | ||
}, "PUBLIC" /* PUBLIC */)); | ||
const appCheck = container.getProvider('app-check-exp').getImmediate(); | ||
return internalFactory(appCheck); | ||
}, "PUBLIC" /* PUBLIC */).setInstantiationMode("EXPLICIT" /* EXPLICIT */)); | ||
registerVersion(name, version); | ||
@@ -1187,3 +1245,3 @@ } | ||
export { CustomProvider, ReCaptchaV3Provider, initializeAppCheck, setTokenAutoRefreshEnabled }; | ||
export { CustomProvider, ReCaptchaV3Provider, getToken, initializeAppCheck, onTokenChanged, setTokenAutoRefreshEnabled }; | ||
//# sourceMappingURL=index.esm2017.js.map |
@@ -17,3 +17,3 @@ /** | ||
*/ | ||
import { AppCheck, AppCheckOptions } from './public-types'; | ||
import { AppCheck, AppCheckOptions, AppCheckTokenResult, Unsubscribe, PartialObserver } from './public-types'; | ||
import { FirebaseApp } from "@firebase/app"; | ||
@@ -37,2 +37,3 @@ import { AppCheckService } from './factory'; | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param isTokenAutoRefreshEnabled - If true, the SDK automatically | ||
@@ -43,2 +44,47 @@ * refreshes App Check tokens as needed. This overrides any value set | ||
*/ | ||
export declare function setTokenAutoRefreshEnabled(app: FirebaseApp, isTokenAutoRefreshEnabled: boolean): void; | ||
export declare function setTokenAutoRefreshEnabled(appCheckInstance: AppCheck, isTokenAutoRefreshEnabled: boolean): void; | ||
/** | ||
* Get the current App Check token. Attaches to the most recent | ||
* in-flight request if one is present. Returns null if no token | ||
* is present and no token requests are in-flight. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param forceRefresh - If true, will always try to fetch a fresh token. | ||
* If false, will use a cached token if found in storage. | ||
* @public | ||
*/ | ||
export declare function getToken(appCheckInstance: AppCheck, forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param observer - An object with `next`, `error`, and `complete` | ||
* properties. `next` is called with an | ||
* {@link AppCheckTokenResult} | ||
* whenever the token changes. `error` is optional and is called if an | ||
* error is thrown by the listener (the `next` function). `complete` | ||
* is unused, as the token stream is unending. | ||
* | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, observer: PartialObserver<AppCheckTokenResult>): Unsubscribe; | ||
/** | ||
* Registers a listener to changes in the token state. There can be more | ||
* than one listener registered at the same time for one or more | ||
* App Check instances. The listeners call back on the UI thread whenever | ||
* the current token associated with this App Check instance changes. | ||
* | ||
* @param appCheckInstance - The App Check service instance. | ||
* @param onNext - When the token changes, this function is called with aa | ||
* {@link AppCheckTokenResult}. | ||
* @param onError - Optional. Called if there is an error thrown by the | ||
* listener (the `onNext` function). | ||
* @param onCompletion - Currently unused, as the token stream is unending. | ||
* @returns A function that unsubscribes this listener. | ||
* @public | ||
*/ | ||
export declare function onTokenChanged(appCheckInstance: AppCheck, onNext: (tokenResult: AppCheckTokenResult) => void, onError?: (error: Error) => void, onCompletion?: () => void): Unsubscribe; |
@@ -26,6 +26,7 @@ /** | ||
app: FirebaseApp; | ||
constructor(app: FirebaseApp); | ||
platformLoggerProvider: Provider<'platform-logger'>; | ||
constructor(app: FirebaseApp, platformLoggerProvider: Provider<'platform-logger'>); | ||
_delete(): Promise<void>; | ||
} | ||
export declare function factory(app: FirebaseApp): AppCheckService; | ||
export declare function internalFactory(app: FirebaseApp, platformLoggerProvider: Provider<'platform-logger'>): FirebaseAppCheckInternal; | ||
export declare function factory(app: FirebaseApp, platformLoggerProvider: Provider<'platform-logger'>): AppCheckService; | ||
export declare function internalFactory(appCheck: AppCheckService): FirebaseAppCheckInternal; |
@@ -0,1 +1,6 @@ | ||
/** | ||
* Firebase App Check | ||
* | ||
* @packageDocumentation | ||
*/ | ||
import { _AppCheckInternalComponentName } from './types'; | ||
@@ -2,0 +7,0 @@ export { _AppCheckInternalComponentName }; |
@@ -18,4 +18,5 @@ /** | ||
import { FirebaseApp } from "@firebase/app"; | ||
import { AppCheckTokenResult, AppCheckTokenListener } from './types'; | ||
import { Provider } from '@firebase/component'; | ||
import { AppCheckTokenResult, ListenerType } from './types'; | ||
import { AppCheckTokenListener } from './public-types'; | ||
import { AppCheckService } from './factory'; | ||
export declare const defaultTokenErrorData: { | ||
@@ -35,4 +36,4 @@ error: string; | ||
*/ | ||
export declare function getToken(app: FirebaseApp, platformLoggerProvider: Provider<'platform-logger'>, forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
export declare function addTokenListener(app: FirebaseApp, platformLoggerProvider: Provider<'platform-logger'>, listener: AppCheckTokenListener): void; | ||
export declare function getToken(appCheck: AppCheckService, forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
export declare function addTokenListener(appCheck: AppCheckService, type: ListenerType, listener: AppCheckTokenListener, onError?: (error: Error) => void): void; | ||
export declare function removeTokenListener(app: FirebaseApp, listener: AppCheckTokenListener): void; |
@@ -19,2 +19,3 @@ /** | ||
import { CustomProvider, ReCaptchaV3Provider } from './providers'; | ||
export { Unsubscribe, PartialObserver } from '@firebase/util'; | ||
/** | ||
@@ -71,1 +72,16 @@ * The Firebase App Check service interface. | ||
} | ||
/** | ||
* Result returned by `getToken()`. | ||
* @public | ||
*/ | ||
export interface AppCheckTokenResult { | ||
/** | ||
* The token string in JWT format. | ||
*/ | ||
readonly token: string; | ||
} | ||
/** | ||
* A listener that is called whenever the App Check token changes. | ||
* @public | ||
*/ | ||
export declare type AppCheckTokenListener = (token: AppCheckTokenResult) => void; |
@@ -18,3 +18,3 @@ /** | ||
import { FirebaseApp } from "@firebase/app"; | ||
import { AppCheckProvider, AppCheckTokenInternal, AppCheckTokenListener } from './types'; | ||
import { AppCheckProvider, AppCheckTokenInternal, AppCheckTokenObserver } from './types'; | ||
import { Refresher } from './proactive-refresh'; | ||
@@ -25,3 +25,3 @@ import { Deferred } from '@firebase/util'; | ||
activated: boolean; | ||
tokenListeners: AppCheckTokenListener[]; | ||
tokenObservers: AppCheckTokenObserver[]; | ||
provider?: AppCheckProvider; | ||
@@ -28,0 +28,0 @@ token?: AppCheckTokenInternal; |
@@ -18,3 +18,4 @@ /** | ||
import { FirebaseApp } from "@firebase/app"; | ||
import { AppCheckToken } from './public-types'; | ||
import { PartialObserver } from '@firebase/util'; | ||
import { AppCheckToken, AppCheckTokenListener } from './public-types'; | ||
export interface FirebaseAppCheckInternal { | ||
@@ -25,3 +26,10 @@ getToken(forceRefresh?: boolean): Promise<AppCheckTokenResult>; | ||
} | ||
export declare type AppCheckTokenListener = (token: AppCheckTokenResult) => void; | ||
export interface AppCheckTokenObserver extends PartialObserver<AppCheckTokenResult> { | ||
next: AppCheckTokenListener; | ||
type: ListenerType; | ||
} | ||
export declare const enum ListenerType { | ||
'INTERNAL' = "INTERNAL", | ||
'EXTERNAL' = "EXTERNAL" | ||
} | ||
export interface AppCheckTokenResult { | ||
@@ -28,0 +36,0 @@ readonly token: string; |
@@ -20,5 +20,6 @@ /** | ||
import { Provider } from '@firebase/component'; | ||
import { CustomProvider } from '../src'; | ||
import { AppCheck, CustomProvider } from '../src'; | ||
export declare const FAKE_SITE_KEY = "fake-site-key"; | ||
export declare function getFakeApp(overrides?: Record<string, any>): FirebaseApp; | ||
export declare function getFakeAppCheck(app: FirebaseApp): AppCheck; | ||
export declare function getFullApp(): FirebaseApp; | ||
@@ -25,0 +26,0 @@ export declare function getFakeCustomTokenProvider(): CustomProvider; |
{ | ||
"name": "@firebase/app-check", | ||
"version": "0.0.900-exp.57f19127c", | ||
"version": "0.0.900-exp.6ef484a04", | ||
"private": false, | ||
@@ -30,3 +30,3 @@ "description": "An App Check package for new firebase packages", | ||
"peerDependencies": { | ||
"@firebase/app": "0.0.900-exp.57f19127c" | ||
"@firebase/app": "0.0.900-exp.6ef484a04" | ||
}, | ||
@@ -36,3 +36,3 @@ "dependencies": { | ||
"@firebase/util": "1.1.0", | ||
"@firebase/component": "0.5.3", | ||
"@firebase/component": "0.5.4", | ||
"tslib": "^2.1.0" | ||
@@ -43,7 +43,7 @@ }, | ||
"@firebase/app-exp": "0.0.900", | ||
"rollup": "2.33.2", | ||
"rollup": "2.52.2", | ||
"@rollup/plugin-commonjs": "17.1.0", | ||
"@rollup/plugin-json": "4.1.0", | ||
"@rollup/plugin-node-resolve": "11.2.0", | ||
"rollup-plugin-typescript2": "0.29.0", | ||
"rollup-plugin-typescript2": "0.30.0", | ||
"typescript": "4.2.2" | ||
@@ -50,0 +50,0 @@ }, |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
452004
39
5202
17
0
+ Added@firebase/app@0.0.900-exp.6ef484a04(transitive)
+ Added@firebase/component@0.5.4(transitive)
- Removed@firebase/app@0.0.900-exp.57f19127c(transitive)
- Removed@firebase/component@0.5.3(transitive)
Updated@firebase/component@0.5.4