diff --git a/packages/ai/lib/models/utils.ts b/packages/ai/lib/models/utils.ts index 0f2dba4923..1ac7cc4a08 100644 --- a/packages/ai/lib/models/utils.ts +++ b/packages/ai/lib/models/utils.ts @@ -14,7 +14,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - +import type { FirebaseAppCheckTypes } from '@react-native-firebase/app-check'; import { AIError } from '../errors'; import { AI, AIErrorCode } from '../public-types'; import { AIService } from '../service'; @@ -52,12 +52,10 @@ export function initApiSettings(ai: AI): ApiSettings { backend: ai.backend, }; - if ((ai as AIService).appCheck) { - if (ai.options?.useLimitedUseAppCheckTokens) { - apiSettings.getAppCheckToken = () => (ai as AIService).appCheck!.getLimitedUseToken(); - } else { - apiSettings.getAppCheckToken = () => (ai as AIService).appCheck!.getToken(); - } + const appCheck = ai.appCheck as FirebaseAppCheckTypes.Module; + if (appCheck) { + apiSettings.getAppCheckToken = () => + ai.options?.useLimitedUseAppCheckTokens ? appCheck.getLimitedUseToken() : appCheck.getToken(); } if ((ai as AIService).auth?.currentUser) { diff --git a/packages/app-check/lib/ReactNativeFirebaseAppCheckProvider.ts b/packages/app-check/lib/ReactNativeFirebaseAppCheckProvider.ts deleted file mode 100644 index bdc9887082..0000000000 --- a/packages/app-check/lib/ReactNativeFirebaseAppCheckProvider.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { - AppCheckProvider, - AppCheckToken, - ReactNativeFirebaseAppCheckProviderOptionsMap as ProviderOptions, -} from './types/appcheck'; - -export default class ReactNativeFirebaseAppCheckProvider implements AppCheckProvider { - providerOptions?: ProviderOptions; - - constructor() {} - - configure(options: ProviderOptions): void { - this.providerOptions = options; - } - - async getToken(): Promise { - // This is a placeholder - the actual implementation is handled by the native modules - // This method exists to satisfy the AppCheckProvider interface - throw new Error('getToken() must be called after configure() and is handled by native modules'); - } -} diff --git a/packages/app-check/lib/index.ts b/packages/app-check/lib/index.ts index 6aaaf4f702..4b9fd720da 100644 --- a/packages/app-check/lib/index.ts +++ b/packages/app-check/lib/index.ts @@ -16,31 +16,12 @@ */ // Export types from types/appcheck -export type { - AppCheckProvider, - CustomProviderOptions, - AppCheckOptions, - AppCheckToken, - AppCheckTokenResult, - AppCheckListenerResult, - PartialObserver, - Observer, - NextFn, - ErrorFn, - CompleteFn, - Unsubscribe, - ReactNativeFirebaseAppCheckProviderOptions, - ReactNativeFirebaseAppCheckProviderWebOptions, - ReactNativeFirebaseAppCheckProviderAppleOptions, - ReactNativeFirebaseAppCheckProviderAndroidOptions, - ReactNativeFirebaseAppCheckProvider, - AppCheck, - FirebaseAppCheckTypes, -} from './types/appcheck'; +export type * from './types/appcheck'; // Export modular API functions export * from './modular'; // Export namespaced API +export type { FirebaseAppCheckTypes } from './types/namespaced'; export * from './namespaced'; export { default } from './namespaced'; diff --git a/packages/app-check/lib/modular.ts b/packages/app-check/lib/modular.ts index 9c867f5f70..eebc3d844a 100644 --- a/packages/app-check/lib/modular.ts +++ b/packages/app-check/lib/modular.ts @@ -15,9 +15,8 @@ * */ -import { getApp, type ReactNativeFirebase } from '@react-native-firebase/app'; +import { getApp, type FirebaseApp } from '@react-native-firebase/app'; import { MODULAR_DEPRECATION_ARG } from '@react-native-firebase/app/dist/module/common'; -import ReactNativeFirebaseAppCheckProvider from './ReactNativeFirebaseAppCheckProvider'; import type { AppCheck, @@ -25,8 +24,14 @@ import type { AppCheckTokenResult, PartialObserver, Unsubscribe, - AppCheckListenerResult, } from './types/appcheck'; +import type { AppCheckInternal } from './types/internal'; + +export { CustomProvider, ReactNativeFirebaseAppCheckProvider } from './providers'; + +type WithModularDeprecationArg = F extends (...args: infer P) => infer R + ? (...args: [...P, typeof MODULAR_DEPRECATION_ARG]) => R + : never; /** * Activate App Check for the given app. Can be called only once per app. @@ -35,20 +40,16 @@ import type { * @returns Promise */ export async function initializeAppCheck( - app?: ReactNativeFirebase.FirebaseApp, + app?: FirebaseApp, options?: AppCheckOptions, ): Promise { - if (app) { - const appInstance = getApp(app.name) as ReactNativeFirebase.FirebaseApp; - const appCheck = appInstance.appCheck(); - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls - await appCheck.initializeAppCheck.call(appCheck, options, MODULAR_DEPRECATION_ARG); - return appCheck; - } - const appInstance = getApp() as ReactNativeFirebase.FirebaseApp; + const appInstance = app ? (getApp(app.name) as FirebaseApp) : (getApp() as FirebaseApp); const appCheck = appInstance.appCheck(); - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls - await appCheck.initializeAppCheck.call(appCheck, options, MODULAR_DEPRECATION_ARG); + await ( + (appCheck as AppCheckInternal).initializeAppCheck as WithModularDeprecationArg< + AppCheckInternal['initializeAppCheck'] + > + ).call(appCheck, options as AppCheckOptions, MODULAR_DEPRECATION_ARG); return appCheck; } @@ -63,12 +64,11 @@ export function getToken( appCheckInstance: AppCheck, forceRefresh?: boolean, ): Promise { - return appCheckInstance.getToken.call( - appCheckInstance, - forceRefresh, - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls - MODULAR_DEPRECATION_ARG, - ) as Promise; + return ( + (appCheckInstance as AppCheckInternal).getToken as WithModularDeprecationArg< + AppCheckInternal['getToken'] + > + ).call(appCheckInstance, forceRefresh, MODULAR_DEPRECATION_ARG) as Promise; } /** @@ -78,11 +78,11 @@ export function getToken( * @returns Promise */ export function getLimitedUseToken(appCheckInstance: AppCheck): Promise { - return appCheckInstance.getLimitedUseToken.call( - appCheckInstance, - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls - MODULAR_DEPRECATION_ARG, - ) as Promise; + return ( + (appCheckInstance as AppCheckInternal).getLimitedUseToken as WithModularDeprecationArg< + AppCheckInternal['getLimitedUseToken'] + > + ).call(appCheckInstance, MODULAR_DEPRECATION_ARG) as Promise; } /** @@ -94,12 +94,11 @@ export function setTokenAutoRefreshEnabled( appCheckInstance: AppCheck, isAutoRefreshEnabled: boolean, ): void { - appCheckInstance.setTokenAutoRefreshEnabled.call( - appCheckInstance, - isAutoRefreshEnabled, - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls - MODULAR_DEPRECATION_ARG, - ); + ( + (appCheckInstance as AppCheckInternal).setTokenAutoRefreshEnabled as WithModularDeprecationArg< + AppCheckInternal['setTokenAutoRefreshEnabled'] + > + ).call(appCheckInstance, isAutoRefreshEnabled, MODULAR_DEPRECATION_ARG); } /** @@ -114,7 +113,7 @@ export function setTokenAutoRefreshEnabled( */ export function onTokenChanged( appCheckInstance: AppCheck, - listener: PartialObserver, + observer: PartialObserver, ): Unsubscribe; /** @@ -131,7 +130,7 @@ export function onTokenChanged( */ export function onTokenChanged( appCheckInstance: AppCheck, - onNext: (tokenResult: AppCheckListenerResult) => void, + onNext: (tokenResult: AppCheckTokenResult) => void, onError?: (error: Error) => void, onCompletion?: () => void, ): Unsubscribe; @@ -140,18 +139,19 @@ export function onTokenChanged( appCheckInstance: AppCheck, onNextOrObserver: | PartialObserver - | ((tokenResult: AppCheckListenerResult) => void), + | ((tokenResult: AppCheckTokenResult) => void), onError?: (error: Error) => void, onCompletion?: () => void, ): Unsubscribe { - return appCheckInstance.onTokenChanged.call( + return ( + (appCheckInstance as AppCheckInternal).onTokenChanged as WithModularDeprecationArg< + AppCheckInternal['onTokenChanged'] + > + ).call( appCheckInstance, onNextOrObserver, onError, onCompletion, - // @ts-ignore - Extra arg used by deprecation proxy to detect modular calls MODULAR_DEPRECATION_ARG, ) as Unsubscribe; } - -export { ReactNativeFirebaseAppCheckProvider }; diff --git a/packages/app-check/lib/namespaced.ts b/packages/app-check/lib/namespaced.ts index ff9998cfd1..678773adcc 100644 --- a/packages/app-check/lib/namespaced.ts +++ b/packages/app-check/lib/namespaced.ts @@ -20,7 +20,6 @@ import { isIOS, isString, isObject, - isFunction, isUndefined, isOther, parseListenerOrObserver, @@ -32,45 +31,24 @@ import { } from '@react-native-firebase/app/dist/module/internal'; import type { ModuleConfig } from '@react-native-firebase/app/dist/module/internal'; import { Platform } from 'react-native'; -import ReactNativeFirebaseAppCheckProvider from './ReactNativeFirebaseAppCheckProvider'; import { setReactNativeModule } from '@react-native-firebase/app/dist/module/internal/nativeModule'; import fallBackModule from './web/RNFBAppCheckModule'; import { version } from './version'; import type { - CustomProviderOptions, + AppCheckOptions, AppCheckProvider, AppCheckTokenResult, - AppCheckOptions, - AppCheckListenerResult, PartialObserver, - AppCheck, - AppCheckStatics, - ProviderWithOptions, } from './types/appcheck'; +import type { ProviderWithOptions } from './types/internal'; +import type { FirebaseAppCheckTypes } from './types/namespaced'; import type { ReactNativeFirebase } from '@react-native-firebase/app'; +import { CustomProvider, ReactNativeFirebaseAppCheckProvider } from './providers'; const namespace = 'appCheck'; const nativeModuleName = 'RNFBAppCheckModule'; -export class CustomProvider implements AppCheckProvider { - private _customProviderOptions: CustomProviderOptions; - - constructor(_customProviderOptions: CustomProviderOptions) { - if (!isObject(_customProviderOptions)) { - throw new Error('Invalid configuration: no provider options defined.'); - } - if (!isFunction(_customProviderOptions.getToken)) { - throw new Error('Invalid configuration: no getToken function defined.'); - } - this._customProviderOptions = _customProviderOptions; - } - - async getToken() { - return this._customProviderOptions.getToken(); - } -} - const statics = { CustomProvider, }; @@ -89,7 +67,7 @@ function hasProviderOptions( ); } -class FirebaseAppCheckModule extends FirebaseModule { +class FirebaseAppCheckModule extends FirebaseModule { _listenerCount: number; constructor( @@ -226,8 +204,8 @@ class FirebaseAppCheckModule extends FirebaseModule { onTokenChanged( onNextOrObserver: - | PartialObserver - | ((tokenResult: AppCheckListenerResult) => void), + | PartialObserver + | ((tokenResult: FirebaseAppCheckTypes.AppCheckListenerResult) => void), _onError?: (error: Error) => void, _onCompletion?: () => void, ): () => void { @@ -239,8 +217,8 @@ class FirebaseAppCheckModule extends FirebaseModule { } const nextFn = parseListenerOrObserver( onNextOrObserver as - | ((value: AppCheckListenerResult) => void) - | { next: (value: AppCheckListenerResult) => void }, + | ((value: FirebaseAppCheckTypes.AppCheckListenerResult) => void) + | { next: (value: FirebaseAppCheckTypes.AppCheckListenerResult) => void }, ); // let errorFn = function () { }; // if (onNextOrObserver.error != null) { @@ -278,10 +256,13 @@ const appCheckNamespace = createModuleNamespace({ }); type AppCheckNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< - AppCheck, - AppCheckStatics + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics > & { - appCheck: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; + appCheck: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics + >; firebase: ReactNativeFirebase.Module; app(name?: string): ReactNativeFirebase.FirebaseApp; }; @@ -296,8 +277,8 @@ export default appCheckNamespace as unknown as AppCheckNamespace; export const firebase = getFirebaseRoot() as unknown as ReactNativeFirebase.FirebaseNamespacedExport< 'appCheck', - AppCheck, - AppCheckStatics, + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics, false >; diff --git a/packages/app-check/lib/providers.ts b/packages/app-check/lib/providers.ts new file mode 100644 index 0000000000..508f43e84a --- /dev/null +++ b/packages/app-check/lib/providers.ts @@ -0,0 +1,49 @@ +import type { + AppCheckProvider, + AppCheckToken, + CustomProviderOptions, + ReactNativeFirebaseAppCheckProviderOptionsMap as ProviderOptions, +} from './types/appcheck'; +import { isFunction, isObject } from '@react-native-firebase/app/dist/module/common'; + +/** + * @public Use this to configure providers for android, iOS and "other" platforms. + */ +export class ReactNativeFirebaseAppCheckProvider implements AppCheckProvider { + providerOptions?: ProviderOptions; + + constructor(options?: ProviderOptions) { + this.providerOptions = options; + } + + configure(options: ProviderOptions): void { + this.providerOptions = options; + } + + async getToken(): Promise { + // This is a placeholder - the actual implementation is handled by the native modules + // This method exists to satisfy the AppCheckProvider interface + throw new Error('getToken() must be called after configure() and is handled by native modules'); + } +} + +/** + * @public Use this to configure a Custom Provider on "other" platform. This will not work on iOS and android. + */ +export class CustomProvider implements AppCheckProvider { + private _customProviderOptions: CustomProviderOptions; + + constructor(_customProviderOptions: CustomProviderOptions) { + if (!isObject(_customProviderOptions)) { + throw new Error('Invalid configuration: no provider options defined.'); + } + if (!isFunction(_customProviderOptions.getToken)) { + throw new Error('Invalid configuration: no getToken function defined.'); + } + this._customProviderOptions = _customProviderOptions; + } + + async getToken() { + return this._customProviderOptions.getToken(); + } +} diff --git a/packages/app-check/lib/types/appcheck.ts b/packages/app-check/lib/types/appcheck.ts index e26c72bb29..71b2683762 100644 --- a/packages/app-check/lib/types/appcheck.ts +++ b/packages/app-check/lib/types/appcheck.ts @@ -15,42 +15,43 @@ * */ -import type { ReactNativeFirebase } from '@react-native-firebase/app'; - -// ============ Provider Types ============ +import type { FirebaseApp } from '@react-native-firebase/app'; +import type { CustomProvider, ReactNativeFirebaseAppCheckProvider } from '../providers'; +export type { + Unsubscribe, + PartialObserver, +} from '@react-native-firebase/app/dist/module/types/common'; /** - * An App Check provider. This can be either the built-in reCAPTCHA provider - * or a custom provider. For more on custom providers, see - * https://firebase.google.com/docs/app-check/web-custom-provider + * The Firebase App Check service interface. + * + * @public */ -export interface AppCheckProvider { +export interface AppCheck { /** - * Returns an AppCheck token. + * this `AppCheck` instance is associated with this FirebaseApp. */ - getToken(): Promise; -} - -/** - * Function to get an App Check token through a custom provider service. - */ -export interface CustomProviderOptions { - getToken: () => Promise; + app: FirebaseApp; } -// ============ Options & Result Types ============ - /** - * Custom provider class. + * The token returned from an `AppCheckProvider`. * @public */ -export declare class CustomProvider implements AppCheckProvider { - constructor(customProviderOptions: CustomProviderOptions); - getToken(): Promise; +export interface AppCheckToken { + /** + * The token string in JWT format. + */ + readonly token: string; + /** + * The local timestamp after which the token will expire. + */ + readonly expireTimeMillis: number; } /** * Options for App Check initialization. + * @public */ export interface AppCheckOptions { /** @@ -73,21 +74,21 @@ export interface AppCheckOptions { } /** - * The token returned from an `AppCheckProvider`. + * Function to get an App Check token through a custom provider service. This is for + * "other" platform only, this is not supported on iOS and android. + * @public */ -export interface AppCheckToken { - /** - * The token string in JWT format. - */ - readonly token: string; +export interface CustomProviderOptions { /** - * The local timestamp after which the token will expire. + * Function to get an App Check token through a custom provider + * service. */ - readonly expireTimeMillis: number; + getToken: () => Promise; } /** * Result returned by `getToken()`. + * @public */ export interface AppCheckTokenResult { /** @@ -97,31 +98,22 @@ export interface AppCheckTokenResult { } /** - * The result return from `onTokenChanged` + * An App Check provider. This can be either the built-in reCAPTCHA provider + * or a custom provider. For more on custom providers, see + * https://firebase.google.com/docs/app-check/web-custom-provider + * @public */ -export type AppCheckListenerResult = AppCheckToken & { readonly appName: string }; - -// ============ Observer Types ============ - -export type NextFn = (value: T) => void; -export type ErrorFn = (error: Error) => void; -export type CompleteFn = () => void; - -export interface Observer { - next: NextFn; - error: ErrorFn; - complete: CompleteFn; +export interface AppCheckProvider { + /** + * Returns an AppCheck token. + */ + getToken(): Promise; } -export type PartialObserver = Partial>; - /** - * A function that unsubscribes from token changes. + * Options for ReactNativeFirebaseAppCheckProvider. + * @public */ -export type Unsubscribe = () => void; - -// ============ ReactNativeFirebaseAppCheckProvider Types ============ - export interface ReactNativeFirebaseAppCheckProviderOptions { /** * debug token to use, if any. Defaults to undefined, pre-configure tokens in firebase web console if needed @@ -129,6 +121,10 @@ export interface ReactNativeFirebaseAppCheckProviderOptions { debugToken?: string; } +/** + * Options for ReactNativeFirebaseAppCheckProvider on web. + * @public + */ export interface ReactNativeFirebaseAppCheckProviderWebOptions extends ReactNativeFirebaseAppCheckProviderOptions { /** * The web provider to use, either `reCaptchaV3` or `reCaptchaEnterprise`, defaults to `reCaptchaV3` @@ -141,6 +137,10 @@ export interface ReactNativeFirebaseAppCheckProviderWebOptions extends ReactNati siteKey?: string; } +/** + * Options for ReactNativeFirebaseAppCheckProvider on apple. + * @public + */ export interface ReactNativeFirebaseAppCheckProviderAppleOptions extends ReactNativeFirebaseAppCheckProviderOptions { /** * The apple provider to use, either `deviceCheck` or `appAttest`, or `appAttestWithDeviceCheckFallback`, @@ -150,6 +150,10 @@ export interface ReactNativeFirebaseAppCheckProviderAppleOptions extends ReactNa provider?: 'debug' | 'deviceCheck' | 'appAttest' | 'appAttestWithDeviceCheckFallback'; } +/** + * Options for ReactNativeFirebaseAppCheckProvider on android. + * @public + */ export interface ReactNativeFirebaseAppCheckProviderAndroidOptions extends ReactNativeFirebaseAppCheckProviderOptions { /** * The android provider to use, either `debug` or `playIntegrity`. default is `playIntegrity`. @@ -159,6 +163,7 @@ export interface ReactNativeFirebaseAppCheckProviderAndroidOptions extends React /** * Platform-specific provider options configuration. + * @public */ export type ReactNativeFirebaseAppCheckProviderOptionsMap = { web?: ReactNativeFirebaseAppCheckProviderWebOptions; @@ -172,215 +177,8 @@ export type ReactNativeFirebaseAppCheckProviderOptionsMap = { * that can be passed directly with providerOptions (for convenience in initialization). * The runtime accepts objects with providerOptions even if they don't have * getToken() and configure() methods. + * @public */ export interface ReactNativeFirebaseAppCheckProviderConfig { providerOptions: ReactNativeFirebaseAppCheckProviderOptionsMap; } - -export interface ReactNativeFirebaseAppCheckProvider extends AppCheckProvider { - /** - * Provider options for platform-specific configuration. - * This is set when configure() is called. - */ - providerOptions?: ReactNativeFirebaseAppCheckProviderOptionsMap; - - /** - * Specify how the app check provider should be configured. The new configuration is - * in effect when this call returns. You must call `getToken()` - * after this call to get a token using the new configuration. - * This custom provider allows for delayed configuration and re-configuration on all platforms - * so AppCheck has the same experience across all platforms, with the only difference being the native - * providers you choose to use on each platform. - */ - configure(options: ReactNativeFirebaseAppCheckProviderOptionsMap): void; -} - -/** - * Type representing providers that have providerOptions. - * Used for type narrowing in runtime code. - */ -export type ProviderWithOptions = - | ReactNativeFirebaseAppCheckProvider - | ReactNativeFirebaseAppCheckProviderConfig; - -// ============ Module Interface ============ - -/** - * App Check module instance - returned from firebase.appCheck() or firebase.app().appCheck() - */ -export interface AppCheck extends ReactNativeFirebase.FirebaseModule { - /** The FirebaseApp this module is associated with */ - app: ReactNativeFirebase.FirebaseApp; - - /** - * Create a ReactNativeFirebaseAppCheckProvider option for use in react-native-firebase - */ - newReactNativeFirebaseAppCheckProvider(): ReactNativeFirebaseAppCheckProvider; - - /** - * Initialize the AppCheck module. Note that in react-native-firebase AppCheckOptions must always - * be an object with a `provider` member containing `ReactNativeFirebaseAppCheckProvider` that has returned successfully - * from a call to the `configure` method, with sub-providers for the various platforms configured to meet your project - * requirements. This must be called prior to interacting with any firebase services protected by AppCheck - * - * @param options an AppCheckOptions with a configured ReactNativeFirebaseAppCheckProvider as the provider - */ - initializeAppCheck(options: AppCheckOptions): Promise; - - /** - * Activate App Check - * On iOS App Check is activated with DeviceCheck provider simply by including the module, using the token auto refresh default or - * the specific value (if configured) in firebase.json, but calling this does no harm. - * On Android if you call this it will install the PlayIntegrity provider in release builds, the Debug provider if debuggable. - * On both platforms you may use this method to alter the token refresh setting after startup. - * On iOS if you want to set a specific AppCheckProviderFactory (for instance to FIRAppCheckDebugProviderFactory or - * FIRAppAttestProvider) you must manually do that in your AppDelegate.m prior to calling [FIRApp configure] - * - * @deprecated use initializeAppCheck to gain access to all platform providers and firebase-js-sdk v9 compatibility - * @param siteKeyOrProvider - This is ignored, Android uses DebugProviderFactory if the app is debuggable (https://firebase.google.com/docs/app-check/android/debug-provider) - * Android uses PlayIntegrityProviderFactory for release builds. - * iOS uses DeviceCheckProviderFactory by default unless altered in AppDelegate.m manually - * @param isTokenAutoRefreshEnabled - If true, enables SDK to automatically - * refresh AppCheck token as needed. If undefined, the value will default - * to the value of `app.automaticDataCollectionEnabled`. That property - * defaults to false and can be set in the app config. - */ - activate( - siteKeyOrProvider: string | AppCheckProvider, - isTokenAutoRefreshEnabled?: boolean, - ): Promise; - - /** - * Alter the token auto refresh setting. By default it will take the value of automaticDataCollectionEnabled from Info.plist / AndroidManifest.xml - * @param isTokenAutoRefreshEnabled - If true, the SDK automatically - * refreshes App Check tokens as needed. This overrides any value set - * during `activate()` or taken by default from automaticDataCollectionEnabled in plist / android manifest - */ - setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled: boolean): void; - - /** - * Requests Firebase App Check token. - * This method should only be used if you need to authorize requests to a non-Firebase backend. - * Requests to Firebase backend are authorized automatically if configured. - * - * @param forceRefresh - If true, a new Firebase App Check token is requested and the token cache is ignored. - * If false, the cached token is used if it exists and has not expired yet. - * In most cases, false should be used. True should only be used if the server explicitly returns an error, indicating a revoked token. - */ - getToken(forceRefresh?: boolean): Promise; - - /** - * Requests a Firebase App Check token. This method should be used only if you need to authorize requests - * to a non-Firebase backend. Returns limited-use tokens that are intended for use with your non-Firebase - * backend endpoints that are protected with Replay Protection (https://firebase.google.com/docs/app-check/custom-resource-backend#replay-protection). - * This method does not affect the token generation behavior of the getAppCheckToken() method. - */ - getLimitedUseToken(): Promise; - - /** - * 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. - * - * @returns A function that unsubscribes this listener. - */ - onTokenChanged(observer: PartialObserver): () => void; - - /** - * 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. - * - * Token listeners do not exist in the native SDK for iOS, no token change events will be emitted on that platform. - * This is not yet implemented on Android, no token change events will be emitted until implemented. - * - * NOTE: Although an `onError` callback can be provided, it will - * never be called, Android sdk code doesn't provide handling for onError function - * - * NOTE: Although an `onCompletion` callback can be provided, it will - * never be called because the token stream is never-ending. - * - * @returns A function that unsubscribes this listener. - */ - onTokenChanged( - onNext: (tokenResult: AppCheckListenerResult) => void, - onError?: (error: Error) => void, - onCompletion?: () => void, - ): () => void; -} - -// ============ Statics Interface ============ - -/** - * Static properties available on firebase.appCheck - */ -export interface AppCheckStatics { - CustomProvider: new (customProviderOptions: CustomProviderOptions) => CustomProvider; - SDK_VERSION: string; -} - -/** - * FirebaseApp type with appCheck() method. - * @deprecated Import FirebaseApp from '@react-native-firebase/app' instead. - * The appCheck() method is added via module augmentation. - */ -export type FirebaseApp = ReactNativeFirebase.FirebaseApp; - -// ============ Module Augmentation ============ - -/* eslint-disable @typescript-eslint/no-namespace */ -declare module '@react-native-firebase/app' { - namespace ReactNativeFirebase { - interface Module { - appCheck: FirebaseModuleWithStaticsAndApp; - } - interface FirebaseApp { - appCheck(): AppCheck; - } - } -} -/* eslint-enable @typescript-eslint/no-namespace */ - -// ============ Backwards Compatibility Namespace ============ - -// Helper types to reference outer scope types within the namespace -// These are needed because TypeScript can't directly alias types with the same name -type _AppCheckProvider = AppCheckProvider; -type _CustomProviderOptions = CustomProviderOptions; -type _AppCheckOptions = AppCheckOptions; -type _AppCheckToken = AppCheckToken; -type _AppCheckTokenResult = AppCheckTokenResult; -type _AppCheckListenerResult = AppCheckListenerResult; -type _AppCheck = AppCheck; -type _AppCheckStatics = AppCheckStatics; - -/** - * @deprecated Use the exported types directly instead. - * FirebaseAppCheckTypes namespace is kept for backwards compatibility. - */ -/* eslint-disable @typescript-eslint/no-namespace */ -export namespace FirebaseAppCheckTypes { - // Short name aliases referencing top-level types - export type Provider = AppCheckProvider; - export type ProviderOptions = CustomProviderOptions; - export type Options = AppCheckOptions; - export type Token = AppCheckToken; - export type TokenResult = AppCheckTokenResult; - export type ListenerResult = AppCheckListenerResult; - export type Statics = AppCheckStatics; - export type Module = AppCheck; - - // AppCheck* aliases that reference the exported types above via helper types - // These provide backwards compatibility for code using FirebaseAppCheckTypes.AppCheckProvider - export type AppCheckProvider = _AppCheckProvider; - export type CustomProviderOptions = _CustomProviderOptions; - export type AppCheckOptions = _AppCheckOptions; - export type AppCheckToken = _AppCheckToken; - export type AppCheckTokenResult = _AppCheckTokenResult; - export type AppCheckListenerResult = _AppCheckListenerResult; - export type AppCheck = _AppCheck; - export type AppCheckStatics = _AppCheckStatics; -} -/* eslint-enable @typescript-eslint/no-namespace */ diff --git a/packages/app-check/lib/types/internal.ts b/packages/app-check/lib/types/internal.ts new file mode 100644 index 0000000000..8c24672710 --- /dev/null +++ b/packages/app-check/lib/types/internal.ts @@ -0,0 +1,162 @@ +import type { FirebaseApp } from '@react-native-firebase/app'; +import type { + AppCheck, + AppCheckOptions, + AppCheckProvider, + AppCheckTokenResult, + PartialObserver, + ReactNativeFirebaseAppCheckProviderConfig, + Unsubscribe, +} from './appcheck'; +import type { ReactNativeFirebaseAppCheckProvider } from '../providers'; + +type AppCheckListenerResult = AppCheckTokenResult & { readonly appName: string }; + +export type AppCheckInternal = AppCheck & { + /** The FirebaseApp this module is associated with */ + app: FirebaseApp; + + /** + * Create a ReactNativeFirebaseAppCheckProvider option for use in react-native-firebase + */ + newReactNativeFirebaseAppCheckProvider(): ReactNativeFirebaseAppCheckProvider; + + /** + * Initialize the AppCheck module. Note that in react-native-firebase AppCheckOptions must always + * be an object with a `provider` member containing `ReactNativeFirebaseAppCheckProvider` that has returned successfully + * from a call to the `configure` method, with sub-providers for the various platforms configured to meet your project + * requirements. This must be called prior to interacting with any firebase services protected by AppCheck + * + * @param options an AppCheckOptions with a configured ReactNativeFirebaseAppCheckProvider as the provider + */ + initializeAppCheck(options: AppCheckOptions): Promise; + + /** + * Activate App Check + * On iOS App Check is activated with DeviceCheck provider simply by including the module, using the token auto refresh default or + * the specific value (if configured) in firebase.json, but calling this does no harm. + * On Android if you call this it will install the PlayIntegrity provider in release builds, the Debug provider if debuggable. + * On both platforms you may use this method to alter the token refresh setting after startup. + * On iOS if you want to set a specific AppCheckProviderFactory (for instance to FIRAppCheckDebugProviderFactory or + * FIRAppAttestProvider) you must manually do that in your AppDelegate.m prior to calling [FIRApp configure] + * + * @deprecated use initializeAppCheck to gain access to all platform providers and firebase-js-sdk v9 compatibility + * @param siteKeyOrProvider - This is ignored, Android uses DebugProviderFactory if the app is debuggable (https://firebase.google.com/docs/app-check/android/debug-provider) + * Android uses PlayIntegrityProviderFactory for release builds. + * iOS uses DeviceCheckProviderFactory by default unless altered in AppDelegate.m manually + * @param isTokenAutoRefreshEnabled - If true, enables SDK to automatically + * refresh AppCheck token as needed. If undefined, the value will default + * to the value of `app.automaticDataCollectionEnabled`. That property + * defaults to false and can be set in the app config. + */ + activate( + siteKeyOrProvider: string | AppCheckProvider, + isTokenAutoRefreshEnabled?: boolean, + ): Promise; + + /** + * Alter the token auto refresh setting. By default it will take the value of automaticDataCollectionEnabled from Info.plist / AndroidManifest.xml + * @param isTokenAutoRefreshEnabled - If true, the SDK automatically + * refreshes App Check tokens as needed. This overrides any value set + * during `activate()` or taken by default from automaticDataCollectionEnabled in plist / android manifest + */ + setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled: boolean): void; + + /** + * Requests Firebase App Check token. + * This method should only be used if you need to authorize requests to a non-Firebase backend. + * Requests to Firebase backend are authorized automatically if configured. + * + * @param forceRefresh - If true, a new Firebase App Check token is requested and the token cache is ignored. + * If false, the cached token is used if it exists and has not expired yet. + * In most cases, false should be used. True should only be used if the server explicitly returns an error, indicating a revoked token. + */ + getToken(forceRefresh?: boolean): Promise; + + /** + * Requests a Firebase App Check token. This method should be used only if you need to authorize requests + * to a non-Firebase backend. Returns limited-use tokens that are intended for use with your non-Firebase + * backend endpoints that are protected with Replay Protection (https://firebase.google.com/docs/app-check/custom-resource-backend#replay-protection). + * This method does not affect the token generation behavior of the getAppCheckToken() method. + */ + getLimitedUseToken(): Promise; + + /** + * 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. + * + * @returns A function that unsubscribes this listener. + */ + onTokenChanged(observer: PartialObserver): () => void; + + /** + * 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. + * + * Token listeners do not exist in the native SDK for iOS, no token change events will be emitted on that platform. + * This is not yet implemented on Android, no token change events will be emitted until implemented. + * + * NOTE: Although an `onError` callback can be provided, it will + * never be called, Android sdk code doesn't provide handling for onError function + * + * NOTE: Although an `onCompletion` callback can be provided, it will + * never be called because the token stream is never-ending. + * + * @returns A function that unsubscribes this listener. + */ + onTokenChanged( + onNext: (tokenResult: AppCheckListenerResult) => void, + onError?: (error: Error) => void, + onCompletion?: () => void, + ): Unsubscribe; + + /** + * Implementation signature used by modular wrappers. + */ + onTokenChanged( + onNextOrObserver: + | PartialObserver + | ((tokenResult: AppCheckTokenResult) => void), + onError?: (error: Error) => void, + onCompletion?: () => void, + ): Unsubscribe; +}; + +/** + * Type representing providers that have providerOptions. + * Used for type narrowing in runtime code. + */ +export type ProviderWithOptions = + | ReactNativeFirebaseAppCheckProvider + | ReactNativeFirebaseAppCheckProviderConfig; + +/** + * Wrapped native module interface for App Check. + * + * Note: React Native Firebase internally wraps native methods and auto-prepends the app name + * when `hasMultiAppSupport` is enabled. This interface represents the *wrapped* module shape + * that is exposed as `this.native` within FirebaseModule subclasses. + */ +export interface RNFBAppCheckModule { + initializeAppCheck(options: AppCheckOptions): Promise; + + setTokenAutoRefreshEnabled(enabled: boolean): void | Promise; + + configureProvider(provider: string, debugToken?: string): Promise; + + getToken(forceRefresh: boolean): Promise; + getLimitedUseToken(): Promise; + + addAppCheckListener(): void | Promise; + removeAppCheckListener(): void | Promise; +} + +declare module '@react-native-firebase/app/dist/module/internal/NativeModules' { + interface ReactNativeFirebaseNativeModules { + RNFBAppCheckModule: RNFBAppCheckModule; + } +} diff --git a/packages/app-check/lib/types/namespaced.ts b/packages/app-check/lib/types/namespaced.ts new file mode 100644 index 0000000000..71f7d0c442 --- /dev/null +++ b/packages/app-check/lib/types/namespaced.ts @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +import type { ReactNativeFirebase } from '@react-native-firebase/app'; + +/** + * Firebase App Check package for React Native. + * + * #### Example 1 + * + * Access the firebase export from the `appCheck` package: + * + * ```js + * import { firebase } from '@react-native-firebase/app-check'; + * + * // firebase.appCheck().X + * ``` + * + * #### Example 2 + * + * Using the default export from the `appCheck` package: + * + * ```js + * import appCheck from '@react-native-firebase/app-check'; + * + * // appCheck().X + * ``` + * + * #### Example 3 + * + * Using the default export from the `app` package: + * + * ```js + * import firebase from '@react-native-firebase/app'; + * import '@react-native-firebase/app-check'; + * + * // firebase.appCheck().X + * ``` + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + * @firebase app-check + */ +/* eslint-disable @typescript-eslint/no-namespace */ +export namespace FirebaseAppCheckTypes { + type FirebaseModule = ReactNativeFirebase.FirebaseModule; + + /** + * An App Check provider. This can be either the built-in reCAPTCHA provider + * or a custom provider. For more on custom providers, see + * https://firebase.google.com/docs/app-check/web-custom-provider + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface AppCheckProvider { + /** + * Returns an AppCheck token. + */ + getToken(): Promise; + } + + /** + * Custom provider class. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + * @public + */ + export declare class CustomProvider implements AppCheckProvider { + constructor(customProviderOptions: CustomProviderOptions); + getToken(): Promise; + } + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface CustomProviderOptions { + /** + * Function to get an App Check token through a custom provider + * service. + */ + getToken: () => Promise; + } + /** + * Options for App Check initialization. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface AppCheckOptions { + /** + * The App Check provider to use. This can be either the built-in reCAPTCHA provider + * or a custom provider. + */ + provider: CustomProvider | ReactNativeFirebaseAppCheckProvider; + + /** + * If true, enables SDK to automatically + * refresh AppCheck token as needed. If undefined, the value will default + * to the value of `app.automaticDataCollectionEnabled`. That property + * defaults to false and can be set in the app config. + */ + isTokenAutoRefreshEnabled?: boolean; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export type NextFn = (value: T) => void; + export type ErrorFn = (error: Error) => void; + export type CompleteFn = () => void; + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface Observer { + next: NextFn; + error: ErrorFn; + complete: CompleteFn; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export type PartialObserver = Partial>; + + /** + * A function that unsubscribes from token changes. + */ + export type Unsubscribe = () => void; + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface ReactNativeFirebaseAppCheckProviderOptions { + /** + * debug token to use, if any. Defaults to undefined, pre-configure tokens in firebase web console if needed + */ + debugToken?: string; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface ReactNativeFirebaseAppCheckProviderWebOptions extends ReactNativeFirebaseAppCheckProviderOptions { + /** + * The web provider to use, either `reCaptchaV3` or `reCaptchaEnterprise`, defaults to `reCaptchaV3` + */ + provider?: 'debug' | 'reCaptchaV3' | 'reCaptchaEnterprise'; + + /** + * siteKey for use in web queries, defaults to `none` + */ + siteKey?: string; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface ReactNativeFirebaseAppCheckProviderAppleOptions extends ReactNativeFirebaseAppCheckProviderOptions { + /** + * The apple provider to use, either `deviceCheck` or `appAttest`, or `appAttestWithDeviceCheckFallback`, + * defaults to `DeviceCheck`. `appAttest` requires iOS 14+ or will fail, `appAttestWithDeviceCheckFallback` + * will use `appAttest` for iOS14+ and fallback to `deviceCheck` on devices with ios13 and lower + */ + provider?: 'debug' | 'deviceCheck' | 'appAttest' | 'appAttestWithDeviceCheckFallback'; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface ReactNativeFirebaseAppCheckProviderAndroidOptions extends ReactNativeFirebaseAppCheckProviderOptions { + /** + * The android provider to use, either `debug` or `playIntegrity`. default is `playIntegrity`. + */ + provider?: 'debug' | 'playIntegrity'; + } + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface ReactNativeFirebaseAppCheckProvider extends AppCheckProvider { + /** + * Specify how the app check provider should be configured. The new configuration is + * in effect when this call returns. You must call `getToken()` + * after this call to get a token using the new configuration. + * This custom provider allows for delayed configuration and re-configuration on all platforms + * so AppCheck has the same experience across all platforms, with the only difference being the native + * providers you choose to use on each platform. + */ + configure(options: { + web?: ReactNativeFirebaseAppCheckProviderWebOptions; + android?: ReactNativeFirebaseAppCheckProviderAndroidOptions; + apple?: ReactNativeFirebaseAppCheckProviderAppleOptions; + isTokenAutoRefreshEnabled?: boolean; + }): void; + } + + /** + * Result returned by `getToken()`. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface AppCheckTokenResult { + /** + * The token string in JWT format. + */ + readonly token: string; + } + /** + * The token returned from an `AppCheckProvider`. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface AppCheckToken { + /** + * The token string in JWT format. + */ + readonly token: string; + /** + * The local timestamp after which the token will expire. + */ + readonly expireTimeMillis: number; + } + /** + * The result return from `onTokenChanged` + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export type AppCheckListenerResult = AppCheckToken & { readonly appName: string }; + + /** + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface Statics { + // firebase.appCheck.* static props go here + CustomProvider: typeof CustomProvider; + SDK_VERSION: string; + } + + /** + * The Firebase App Check service is available for the default app or a given app. + * + * #### Example 1 + * + * Get the appCheck instance for the **default app**: + * + * ```js + * const appCheckForDefaultApp = firebase.appCheck(); + * ``` + * + * #### Example 2 + * + * Get the appCheck instance for a **secondary app**: + *˚ + * ```js + * const otherApp = firebase.app('otherApp'); + * const appCheckForOtherApp = firebase.appCheck(otherApp); + * ``` + * + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + export interface Module extends FirebaseModule { + /** + * The current `FirebaseApp` instance for this Firebase service. + */ + app: ReactNativeFirebase.FirebaseApp; + + /** + * Create a ReactNativeFirebaseAppCheckProvider option for use in react-native-firebase + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + newReactNativeFirebaseAppCheckProvider(): ReactNativeFirebaseAppCheckProvider; + + /** + * Initialize the AppCheck module. Note that in react-native-firebase AppCheckOptions must always + * be an object with a `provider` member containing `ReactNativeFirebaseAppCheckProvider` that has returned successfully + * from a call to the `configure` method, with sub-providers for the various platforms configured to meet your project + * requirements. This must be called prior to interacting with any firebase services protected by AppCheck + * + * @param options an AppCheckOptions with a configured ReactNativeFirebaseAppCheckProvider as the provider + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + // TODO wrong types + initializeAppCheck(options: AppCheckOptions): Promise; + + /** + * Activate App Check + * On iOS App Check is activated with DeviceCheck provider simply by including the module, using the token auto refresh default or + * the specific value (if configured) in firebase.json, but calling this does no harm. + * On Android if you call this it will install the PlayIntegrity provider in release builds, the Debug provider if debuggable. + * On both platforms you may use this method to alter the token refresh setting after startup. + * On iOS if you want to set a specific AppCheckProviderFactory (for instance to FIRAppCheckDebugProviderFactory or + * FIRAppAttestProvider) you must manually do that in your AppDelegate.m prior to calling [FIRApp configure] + * + * @deprecated use initializeAppCheck to gain access to all platform providers and firebase-js-sdk v9 compatibility + * @param siteKeyOrProvider - This is ignored, Android uses DebugProviderFactory if the app is debuggable (https://firebase.google.com/docs/app-check/android/debug-provider) + * Android uses PlayIntegrityProviderFactory for release builds. + * iOS uses DeviceCheckProviderFactory by default unless altered in AppDelegate.m manually + * @param isTokenAutoRefreshEnabled - If true, enables SDK to automatically + * refresh AppCheck token as needed. If undefined, the value will default + * to the value of `app.automaticDataCollectionEnabled`. That property + * defaults to false and can be set in the app config. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + activate( + siteKeyOrProvider: string | AppCheckProvider, + isTokenAutoRefreshEnabled?: boolean, + ): Promise; + + /** + * Alter the token auto refresh setting. By default it will take the value of automaticDataCollectionEnabled from Info.plist / AndroidManifest.xml + * @param isTokenAutoRefreshEnabled - If true, the SDK automatically + * refreshes App Check tokens as needed. This overrides any value set + * during `activate()` or taken by default from automaticDataCollectionEnabled in plist / android manifest + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + setTokenAutoRefreshEnabled(isTokenAutoRefreshEnabled: boolean): void; + + /** + * Requests Firebase App Check token. + * This method should only be used if you need to authorize requests to a non-Firebase backend. + * Requests to Firebase backend are authorized automatically if configured. + * + * @param forceRefresh - If true, a new Firebase App Check token is requested and the token cache is ignored. + * If false, the cached token is used if it exists and has not expired yet. + * In most cases, false should be used. True should only be used if the server explicitly returns an error, indicating a revoked token. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + getToken(forceRefresh?: boolean): Promise; + + /** + * Requests a Firebase App Check token. This method should be used only if you need to authorize requests + * to a non-Firebase backend. Returns limited-use tokens that are intended for use with your non-Firebase + * backend endpoints that are protected with Replay Protection (https://firebase.google.com/docs/app-check/custom-resource-backend#replay-protection). + * This method does not affect the token generation behavior of the getAppCheckToken() method. + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + */ + getLimitedUseToken(): Promise; + + /** + * 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. + * + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + * @returns A function that unsubscribes this listener. + */ + // TODO wrong types + onTokenChanged(observer: PartialObserver): () => void; + + /** + * 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. + * + * Token listeners do not exist in the native SDK for iOS, no token change events will be emitted on that platform. + * This is not yet implemented on Android, no token change events will be emitted until implemented. + * + * NOTE: Although an `onError` callback can be provided, it will + * never be called, Android sdk code doesn't provide handling for onError function + * + * NOTE: Although an `onCompletion` callback can be provided, it will + * never be called because the token stream is never-ending. + * + * @deprecated Use the exported types directly instead. FirebaseAppCheckTypes namespace is kept for backwards compatibility. + * @returns A function that unsubscribes this listener. + */ + // TODO wrong types + onTokenChanged( + onNext: (tokenResult: AppCheckListenerResult) => void, + onError?: (error: Error) => void, + onCompletion?: () => void, + ): () => void; + } +} + +type AppCheckNamespace = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics +> & { + appCheck: ReactNativeFirebase.FirebaseModuleWithStaticsAndApp< + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics + >; + firebase: ReactNativeFirebase.Module; + app(name?: string): ReactNativeFirebase.FirebaseApp; +}; + +declare const defaultExport: AppCheckNamespace; + +export declare const firebase: ReactNativeFirebase.Module & { + appCheck: typeof defaultExport; + app( + name?: string, + ): ReactNativeFirebase.FirebaseApp & { appCheck(): FirebaseAppCheckTypes.Module }; +}; + +export default defaultExport; + +/** + * Attach namespace to `firebase.` and `FirebaseApp.`. + */ +declare module '@react-native-firebase/app' { + namespace ReactNativeFirebase { + import FirebaseModuleWithStaticsAndApp = ReactNativeFirebase.FirebaseModuleWithStaticsAndApp; + interface Module { + appCheck: FirebaseModuleWithStaticsAndApp< + FirebaseAppCheckTypes.Module, + FirebaseAppCheckTypes.Statics + >; + } + interface FirebaseApp { + appCheck(): FirebaseAppCheckTypes.Module; + } + } +} diff --git a/packages/app-check/lib/web/RNFBAppCheckModule.ts b/packages/app-check/lib/web/RNFBAppCheckModule.ts index 1ad79e5daa..b6bd76edd5 100644 --- a/packages/app-check/lib/web/RNFBAppCheckModule.ts +++ b/packages/app-check/lib/web/RNFBAppCheckModule.ts @@ -7,9 +7,10 @@ import { CustomProvider, onTokenChanged, makeIDBAvailable, + type AppCheckOptions, + type AppCheckTokenResult, } from '@react-native-firebase/app/dist/module/internal/web/firebaseAppCheck'; import { guard, emitEvent } from '@react-native-firebase/app/dist/module/internal/web/utils'; -import type { FirebaseAppCheckTypes } from '../types/appcheck'; let appCheckInstances: Record = {}; let listenersForApp: Record void> = {}; @@ -24,16 +25,10 @@ function getAppCheckInstanceForApp(appName: string): any { } interface AppCheckModule { - initializeAppCheck( - appName: string, - options: FirebaseAppCheckTypes.AppCheckOptions, - ): Promise; + initializeAppCheck(appName: string, options: AppCheckOptions): Promise; setTokenAutoRefreshEnabled(appName: string, isTokenAutoRefreshEnabled: boolean): Promise; - getLimitedUseToken(appName: string): Promise; - getToken( - appName: string, - forceRefresh: boolean, - ): Promise; + getLimitedUseToken(appName: string): Promise; + getToken(appName: string, forceRefresh: boolean): Promise; addAppCheckListener(appName: string): Promise; removeAppCheckListener(appName: string): Promise; } @@ -45,7 +40,7 @@ interface AppCheckModule { * java methods on Android. */ const module: AppCheckModule = { - initializeAppCheck(appName: string, options: FirebaseAppCheckTypes.AppCheckOptions) { + initializeAppCheck(appName: string, options: AppCheckOptions) { makeIDBAvailable(); return guard(async () => { if (appCheckInstances[appName]) { @@ -90,15 +85,12 @@ const module: AppCheckModule = { return; } const instance = getAppCheckInstanceForApp(appName); - listenersForApp[appName] = onTokenChanged( - instance, - (tokenResult: FirebaseAppCheckTypes.AppCheckTokenResult) => { - emitEvent('appCheck_token_changed', { - appName, - ...tokenResult, - }); - }, - ); + listenersForApp[appName] = onTokenChanged(instance, (tokenResult: AppCheckTokenResult) => { + emitEvent('appCheck_token_changed', { + appName, + ...tokenResult, + }); + }); }); }, removeAppCheckListener(appName: string) { diff --git a/packages/app-check/tsconfig.json b/packages/app-check/tsconfig.json index d23f0c8b5a..d3c1ec5ac4 100644 --- a/packages/app-check/tsconfig.json +++ b/packages/app-check/tsconfig.json @@ -13,7 +13,8 @@ "../app/dist/typescript/lib/internal/*" ], "@react-native-firebase/app/dist/module/internal": ["../app/dist/typescript/lib/internal"], - "@react-native-firebase/app": ["../app/dist/typescript/lib"] + "@react-native-firebase/app": ["../app/dist/typescript/lib"], + "@react-native-firebase/app/dist/module/types/common": ["../app/dist/typescript/lib/types/common"] } }, "include": ["lib/**/*", "../app/lib/internal/global.d.ts"], diff --git a/packages/app-check/type-test.ts b/packages/app-check/type-test.ts index 3314f4ca9d..d1d92a051d 100644 --- a/packages/app-check/type-test.ts +++ b/packages/app-check/type-test.ts @@ -7,6 +7,8 @@ import appCheck, { setTokenAutoRefreshEnabled, onTokenChanged, CustomProvider, + AppCheck, + AppCheckTokenResult, } from '.'; console.log(appCheck().app); @@ -113,33 +115,33 @@ modularProvider.configure({ initializeAppCheck(firebase.app(), { provider: modularProvider, isTokenAutoRefreshEnabled: true, -}).then((appCheckModular: FirebaseAppCheckTypes.Module) => { +}).then((appCheckModular: AppCheck) => { console.log(appCheckModular.app.name); }); initializeAppCheck(undefined, { provider: modularProvider, isTokenAutoRefreshEnabled: true, -}).then((appCheckModular: FirebaseAppCheckTypes.Module) => { +}).then((appCheckModular: AppCheck) => { console.log(appCheckModular.app.name); }); -getToken(appCheckInstance).then((result: FirebaseAppCheckTypes.AppCheckTokenResult) => { +getToken(appCheckInstance).then((result: AppCheckTokenResult) => { console.log(result.token); }); -getToken(appCheckInstance, true).then((result: FirebaseAppCheckTypes.AppCheckTokenResult) => { +getToken(appCheckInstance, true).then((result: AppCheckTokenResult) => { console.log(result.token); }); -getLimitedUseToken(appCheckInstance).then((result: FirebaseAppCheckTypes.AppCheckTokenResult) => { +getLimitedUseToken(appCheckInstance).then((result: AppCheckTokenResult) => { console.log(result.token); }); setTokenAutoRefreshEnabled(appCheckInstance, true); const modularUnsubscribe1 = onTokenChanged(appCheckInstance, { - next: (tokenResult: FirebaseAppCheckTypes.AppCheckTokenResult) => { + next: (tokenResult: AppCheckTokenResult) => { console.log(tokenResult.token); }, error: (error: Error) => { @@ -152,9 +154,8 @@ const modularUnsubscribe1 = onTokenChanged(appCheckInstance, { const modularUnsubscribe2 = onTokenChanged( appCheckInstance, - (tokenResult: FirebaseAppCheckTypes.AppCheckListenerResult) => { + (tokenResult: AppCheckTokenResult) => { console.log(tokenResult.token); - console.log(tokenResult.appName); }, (error: Error) => { console.log(error.message); diff --git a/packages/app/lib/types/common.ts b/packages/app/lib/types/common.ts new file mode 100644 index 0000000000..8eae14d815 --- /dev/null +++ b/packages/app/lib/types/common.ts @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016-present Invertase Limited & Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this library except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +export type NextFn = (value: T) => void; +export type ErrorFn = (error: Error) => void; +export type CompleteFn = () => void; + +export interface Observer { + next: NextFn; + error: ErrorFn; + complete: CompleteFn; +} + +export type PartialObserver = Partial>; + +/** + * A function that unsubscribes from an event listener. + */ +export type Unsubscribe = () => void;