From 6aa1fcae086505d5cf9b90774f3e52fba906f38f Mon Sep 17 00:00:00 2001 From: Tomas Psota Date: Wed, 11 Nov 2026 19:03:32 +0100 Subject: [PATCH 1/3] feat!: unify the public API with the other freeRASP plugins - TalsecIosConfig.appBundleId (string) -> appBundleIds (string[]), as in the iOS SDK - methods that resolved with status strings or constants resolve to void - all methods reject with TalsecError carrying a stable code, including Android-only methods called on iOS - onInvalidCallback and removeListenerForEvent are no longer exported; abortApp is the only exported internal helper Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 4 + example/src/App.tsx | 8 +- example/src/DemoApp.tsx | 3 +- example/src/MalwareItem.tsx | 6 +- ios/FreeraspReactNative.swift | 6 +- src/api/listeners/raspExecutionState.ts | 2 +- src/api/listeners/threat.ts | 2 +- src/api/methods/internal.ts | 13 +++ src/api/methods/native.ts | 108 ++++++++++++++++-------- src/api/methods/reactNative.ts | 6 +- src/channels/raspExecutionState.ts | 2 +- src/channels/threat.ts | 2 +- src/index.tsx | 2 + src/types/errors.ts | 57 +++++++++++++ src/types/types.ts | 2 +- 15 files changed, 163 insertions(+), 60 deletions(-) create mode 100644 src/api/methods/internal.ts create mode 100644 src/types/errors.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index c729030..fae3ca3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Breaking - `allChecksFinished` RASP execution state action renamed to `fastChecksFinished`. On Android, it is triggered when the fast checks are completed, while the postponed checks may still run; on iOS, when all checks are completed +- `TalsecIosConfig.appBundleId` (string) replaced by `appBundleIds` (string[]), matching the iOS SDK +- Methods that resolved with a status string or a constant now resolve to `void`: `talsecStart`, `addToWhitelist`, `blockScreenCapture`, `blockScreenControl`, `startOngoingCallDetection`, `stopOngoingCallDetection`, `storeExternalId`, `removeExternalId` +- All methods now reject with `TalsecError` (`code`: `talsec-failure`, `unsupported-platform`, `configuration-exception`, `external-id-failure`, `malware-failure`) instead of native errors or plain strings +- `onInvalidCallback` and `removeListenerForEvent` are no longer exported; use `abortApp` to terminate the app ### React Native diff --git a/example/src/App.tsx b/example/src/App.tsx index 9f7c23e..d91d304 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -67,7 +67,7 @@ const App = () => { }, }, iosConfig: { - appBundleId: 'org.reactjs.native.example.FreeraspReactNativeExample', + appBundleIds: ['org.reactjs.native.example.FreeraspReactNativeExample'], appTeamId: 'your_team_ID', }, watcherMail: 'your_email_address@example.com', @@ -351,10 +351,8 @@ const App = () => { await Promise.all( appsToWhitelist.map(async (app) => { try { - const whitelistResponse = await addToWhitelist(app); - console.info( - `${app} stored to Malware Whitelist: ${whitelistResponse}` - ); + await addToWhitelist(app); + console.info(`${app} stored to Malware Whitelist`); } catch (error) { console.info('Malware whitelist failed: ', error); } diff --git a/example/src/DemoApp.tsx b/example/src/DemoApp.tsx index 599f8f2..3e70a4a 100644 --- a/example/src/DemoApp.tsx +++ b/example/src/DemoApp.tsx @@ -75,8 +75,7 @@ export const DemoApp: React.FC<{ const toggleScreenCaptureBlock = async () => { try { - const response = await blockScreenCapture(!hasScreenCaptureBlocked); - console.info('Changing Screen Capture Status:', response); + await blockScreenCapture(!hasScreenCaptureBlocked); await updateScreenCaptureStatus(); } catch (error: any) { console.error('Screen capture Error:', error.message); diff --git a/example/src/MalwareItem.tsx b/example/src/MalwareItem.tsx index ce7c311..20d5190 100644 --- a/example/src/MalwareItem.tsx +++ b/example/src/MalwareItem.tsx @@ -28,10 +28,8 @@ export const MalwareItem: React.FC<{ app: SuspiciousAppInfo }> = ({ app }) => { const whitelistApp = async (packageName: string) => { try { - const whitelistResponse = await addToWhitelist(packageName); - console.info( - `Malware Whitelist response for ${app}: ${whitelistResponse}` - ); + await addToWhitelist(packageName); + console.info(`${app.packageInfo.packageName} added to Malware Whitelist`); alert('Restart app for whitelist to take effect'); } catch (error: any) { console.info('Error while adding app to malware whitelist: ', error); diff --git a/ios/FreeraspReactNative.swift b/ios/FreeraspReactNative.swift index 0667c28..e625ddf 100644 --- a/ios/FreeraspReactNative.swift +++ b/ios/FreeraspReactNative.swift @@ -51,8 +51,8 @@ class FreeraspReactNative: RCTEventEmitter { guard let iosConfig = talsecConfig["iosConfig"] as? NSDictionary else { throw NSError(domain: "Missing iosConfig parameter in Talsec Native Plugin", code: 1) } - guard let appBundleIds = iosConfig["appBundleId"] as? String else { - throw NSError(domain: "Missing appBundleId parameter in Talsec Native Plugin", code: 2) + guard let appBundleIds = iosConfig["appBundleIds"] as? [String] else { + throw NSError(domain: "Missing appBundleIds parameter in Talsec Native Plugin", code: 2) } guard let appTeamId = iosConfig["appTeamId"] as? String else { throw NSError(domain: "Missing appTeamId parameter in Talsec Native Plugin", code: 3) @@ -62,7 +62,7 @@ class FreeraspReactNative: RCTEventEmitter { } let isProd = talsecConfig["isProd"] as? Bool ?? true - let config = TalsecConfig(appBundleIds: [appBundleIds], appTeamId: appTeamId, watcherMailAddress: watcherMailAddress, isProd: isProd) + let config = TalsecConfig(appBundleIds: appBundleIds, appTeamId: appTeamId, watcherMailAddress: watcherMailAddress, isProd: isProd) Talsec.start(config: config) } diff --git a/src/api/listeners/raspExecutionState.ts b/src/api/listeners/raspExecutionState.ts index 2e8bb8b..9552852 100644 --- a/src/api/listeners/raspExecutionState.ts +++ b/src/api/listeners/raspExecutionState.ts @@ -1,6 +1,6 @@ import { NativeEventEmitter, type EmitterSubscription } from 'react-native'; import { FreeraspReactNative } from '../nativeModules'; -import { onInvalidCallback, removeListenerForEvent } from '../methods/native'; +import { onInvalidCallback, removeListenerForEvent } from '../methods/internal'; import type { NativeEvent, RaspExecutionStateEventActions, diff --git a/src/api/listeners/threat.ts b/src/api/listeners/threat.ts index 6e859c6..99b1e6b 100644 --- a/src/api/listeners/threat.ts +++ b/src/api/listeners/threat.ts @@ -1,6 +1,6 @@ import { NativeEventEmitter, type EmitterSubscription } from 'react-native'; import { FreeraspReactNative } from '../nativeModules'; -import { onInvalidCallback, removeListenerForEvent } from '../methods/native'; +import { onInvalidCallback, removeListenerForEvent } from '../methods/internal'; import { Threat } from '../../models/threat'; import type { CallState, diff --git a/src/api/methods/internal.ts b/src/api/methods/internal.ts new file mode 100644 index 0000000..7b4fb32 --- /dev/null +++ b/src/api/methods/internal.ts @@ -0,0 +1,13 @@ +import { FreeraspReactNative } from '../nativeModules'; + +/** + * Terminates the app. Called when the native side sends data that freeRASP + * never sends, which indicates tampering. Exported publicly as `abortApp`. + */ +export const onInvalidCallback = (): void => { + FreeraspReactNative.onInvalidCallback(); +}; + +export const removeListenerForEvent = (channel: string): Promise => { + return FreeraspReactNative.removeListenerForEvent(channel); +}; diff --git a/src/api/methods/native.ts b/src/api/methods/native.ts index 7efa748..ef77da3 100644 --- a/src/api/methods/native.ts +++ b/src/api/methods/native.ts @@ -1,39 +1,60 @@ import { Platform } from 'react-native'; import { FreeraspReactNative } from '../nativeModules'; import type { TalsecConfig } from '../../types/types'; +import { androidOnly, wrapNative } from '../../types/errors'; import { withDefaults } from '../../utils/config'; -export const talsecStart = async (options: TalsecConfig): Promise => { - return FreeraspReactNative.talsecStart(withDefaults(options)); +/** + * Starts freeRASP. Prefer the `useFreeRasp` hook, which also registers the + * listeners. + */ +export const talsecStart = async (options: TalsecConfig): Promise => { + await wrapNative('talsec-failure', () => + FreeraspReactNative.talsecStart(withDefaults(options)) + ); }; -export const addToWhitelist = async (packageName: string): Promise => { +/** + * Android only. Adds an app to the malware whitelist so it is not reported. + */ +export const addToWhitelist = async (packageName: string): Promise => { if (Platform.OS === 'ios') { - return Promise.reject('Malware detection not available on iOS'); + return androidOnly('Malware detection'); } - return FreeraspReactNative.addToWhitelist(packageName); + await wrapNative('malware-failure', () => + FreeraspReactNative.addToWhitelist(packageName) + ); }; -export const blockScreenCapture = (enable: boolean): Promise => { - return FreeraspReactNative.blockScreenCapture(enable); +/** + * Blocks or unblocks screenshots and screen recording of the app screen. + */ +export const blockScreenCapture = async (enable: boolean): Promise => { + await wrapNative('talsec-failure', () => + FreeraspReactNative.blockScreenCapture(enable) + ); }; +/** + * Returns whether screen capture is blocked for the current screen. + */ export const isScreenCaptureBlocked = (): Promise => { - return FreeraspReactNative.isScreenCaptureBlocked(); + return wrapNative('talsec-failure', () => + FreeraspReactNative.isScreenCaptureBlocked() + ); }; -const androidOnly = (feature: string): Promise => - Promise.reject(`${feature} not available on iOS`); - /** * Android only. Prevents accessibility services from reading or controlling * the app screen. */ -export const blockScreenControl = (enable: boolean): Promise => { +export const blockScreenControl = async (enable: boolean): Promise => { if (Platform.OS === 'ios') { return androidOnly('Screen control blocking'); } - return FreeraspReactNative.blockScreenControl(enable); + await wrapNative('talsec-failure', () => + FreeraspReactNative.blockScreenControl(enable) + ); }; /** @@ -43,7 +64,9 @@ export const isScreenControlBlocked = (): Promise => { if (Platform.OS === 'ios') { return androidOnly('Screen control blocking'); } - return FreeraspReactNative.isScreenControlBlocked(); + return wrapNative('talsec-failure', () => + FreeraspReactNative.isScreenControlBlocked() + ); }; /** @@ -56,7 +79,9 @@ export const blockOverlayWindows = (enable: boolean): Promise => { if (Platform.OS === 'ios') { return androidOnly('Overlay windows blocking'); } - return FreeraspReactNative.blockOverlayWindows(enable); + return wrapNative('talsec-failure', () => + FreeraspReactNative.blockOverlayWindows(enable) + ); }; /** @@ -66,51 +91,62 @@ export const isOverlayWindowsBlocked = (): Promise => { if (Platform.OS === 'ios') { return androidOnly('Overlay windows blocking'); } - return FreeraspReactNative.isOverlayWindowsBlocked(); + return wrapNative('talsec-failure', () => + FreeraspReactNative.isOverlayWindowsBlocked() + ); }; /** * Android only. Starts the ongoing call (cellular and VoIP) detection. * Call states are reported through the `ongoingCall` threat action. */ -export const startOngoingCallDetection = (): Promise => { +export const startOngoingCallDetection = async (): Promise => { if (Platform.OS === 'ios') { return androidOnly('Ongoing call detection'); } - return FreeraspReactNative.startOngoingCallDetection(); + await wrapNative('talsec-failure', () => + FreeraspReactNative.startOngoingCallDetection() + ); }; /** * Android only. Stops the ongoing call detection. */ -export const stopOngoingCallDetection = (): Promise => { +export const stopOngoingCallDetection = async (): Promise => { if (Platform.OS === 'ios') { return androidOnly('Ongoing call detection'); } - return FreeraspReactNative.stopOngoingCallDetection(); + await wrapNative('talsec-failure', () => + FreeraspReactNative.stopOngoingCallDetection() + ); }; -export const storeExternalId = (data: string): Promise => { - return FreeraspReactNative.storeExternalId(data); +/** + * Stores an external ID sent with freeRASP logs. + */ +export const storeExternalId = async (data: string): Promise => { + await wrapNative('external-id-failure', () => + FreeraspReactNative.storeExternalId(data) + ); }; -export const removeExternalId = (): Promise => { - return FreeraspReactNative.removeExternalId(); +/** + * Removes the stored external ID. + */ +export const removeExternalId = async (): Promise => { + await wrapNative('external-id-failure', () => + FreeraspReactNative.removeExternalId() + ); }; +/** + * Android only. Returns the icon of the given app as a base64-encoded PNG. + */ export const getAppIcon = (packageName: string): Promise => { if (Platform.OS === 'ios') { - return Promise.reject( - 'App icon retrieval for Malware detection not available on iOS' - ); + return androidOnly('App icon retrieval for malware detection'); } - return FreeraspReactNative.getAppIcon(packageName); -}; - -export const onInvalidCallback = (): void => { - FreeraspReactNative.onInvalidCallback(); -}; - -export const removeListenerForEvent = (channel: string): Promise => { - return FreeraspReactNative.removeListenerForEvent(channel); + return wrapNative('malware-failure', () => + FreeraspReactNative.getAppIcon(packageName) + ); }; diff --git a/src/api/methods/reactNative.ts b/src/api/methods/reactNative.ts index 4379446..14c9c65 100644 --- a/src/api/methods/reactNative.ts +++ b/src/api/methods/reactNative.ts @@ -10,7 +10,6 @@ import type { TalsecConfig, RaspExecutionStateEventActions, } from '../../types/types'; -import { onInvalidCallback } from './native'; let isRaspStarted = false; @@ -30,10 +29,7 @@ export const useFreeRasp = ( } try { - const response = await talsecStart(config); - if (response !== 'freeRASP started') { - onInvalidCallback(); - } + await talsecStart(config); isRaspStarted = true; } catch (e: any) { console.error(`${e.code}: ${e.message}`); diff --git a/src/channels/raspExecutionState.ts b/src/channels/raspExecutionState.ts index 7196f20..82a1f51 100644 --- a/src/channels/raspExecutionState.ts +++ b/src/channels/raspExecutionState.ts @@ -1,6 +1,6 @@ import { getRaspExecutionStateCount, itemsHaveType } from '../utils/utils'; import { FreeraspReactNative } from '../api/nativeModules'; -import { onInvalidCallback } from '../api/methods/native'; +import { onInvalidCallback } from '../api/methods/internal'; import { RaspExecutionState } from '../models/raspExecutionState'; export const getRaspExecutionStateIdentifiers = async (): Promise => { diff --git a/src/channels/threat.ts b/src/channels/threat.ts index 9942ac8..8c62230 100644 --- a/src/channels/threat.ts +++ b/src/channels/threat.ts @@ -1,7 +1,7 @@ import { getThreatCount, itemsHaveType } from '../utils/utils'; import { FreeraspReactNative } from '../api/nativeModules'; import { Threat } from '../models/threat'; -import { onInvalidCallback } from '../api/methods/native'; +import { onInvalidCallback } from '../api/methods/internal'; export const getThreatIdentifiers = async (): Promise => { const identifiers = await FreeraspReactNative.getThreatIdentifiers(); diff --git a/src/index.tsx b/src/index.tsx index 70f0246..b063c57 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,5 +1,7 @@ export * from './types/types'; +export { TalsecError, type TalsecErrorCode } from './types/errors'; export * from './api/methods/native'; export * from './api/methods/reactNative'; export * from './api/listeners/threat'; export * from './api/listeners/raspExecutionState'; +export { onInvalidCallback as abortApp } from './api/methods/internal'; diff --git a/src/types/errors.ts b/src/types/errors.ts new file mode 100644 index 0000000..0dd2270 --- /dev/null +++ b/src/types/errors.ts @@ -0,0 +1,57 @@ +/** + * Stable error codes shared with the other freeRASP plugins. + * + * - `talsec-failure` - a native call failed + * - `unsupported-platform` - the feature is not available on this platform + * - `configuration-exception` - the configuration is invalid + * - `external-id-failure` - storing or removing the external ID failed + * - `malware-failure` - a malware-detection call failed + */ +export type TalsecErrorCode = + | 'talsec-failure' + | 'unsupported-platform' + | 'configuration-exception' + | 'external-id-failure' + | 'malware-failure'; + +/** + * The only error freeRASP methods reject with. + */ +export class TalsecError extends Error { + readonly code: TalsecErrorCode; + + constructor(code: TalsecErrorCode, message?: string) { + super(message); + this.name = 'TalsecError'; + this.code = code; + Object.setPrototypeOf(this, TalsecError.prototype); + } +} + +/** + * Runs a native call and rethrows any failure as a {@link TalsecError}. + */ +export const wrapNative = async ( + code: TalsecErrorCode, + fn: () => Promise +): Promise => { + try { + return await fn(); + } catch (e: any) { + if (e instanceof TalsecError) { + throw e; + } + throw new TalsecError(code, e?.message ?? String(e)); + } +}; + +/** + * Rejects with an `unsupported-platform` error for Android-only features. + */ +export const androidOnly = (feature: string): Promise => + Promise.reject( + new TalsecError( + 'unsupported-platform', + `${feature} is not available on iOS` + ) + ); diff --git a/src/types/types.ts b/src/types/types.ts index ddda6d8..120302c 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -37,7 +37,7 @@ export type TalsecAndroidConfig = { }; export type TalsecIosConfig = { - appBundleId: string; + appBundleIds: string[]; appTeamId: string; }; From 9dee43221c00a93443c88670fe2ab0d3be6e28d2 Mon Sep 17 00:00:00 2001 From: Tomas Psota Date: Wed, 11 Nov 2026 19:21:01 +0100 Subject: [PATCH 2/3] feat: return start status and errors from useFreeRasp useFreeRasp returns { started, error } instead of only logging failures, so apps can react when the listeners can't be registered or freeRASP fails to start. Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + example/src/App.tsx | 14 +++++++- src/api/methods/reactNative.ts | 60 ++++++++++++++++++++++++++-------- src/types/types.ts | 12 +++++++ 4 files changed, 73 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fae3ca3..ffb368a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #### Added +- `useFreeRasp` returns `{ started, error }`; `error` is the `TalsecError` that prevented the listeners from being registered or freeRASP from starting, which was previously only logged to the console - `ongoingCall` threat action with the new `CallState` type (`'STARTED' | 'ONGOING' | 'STOPPED'`), driven by `startOngoingCallDetection()` and `stopOngoingCallDetection()` (Android only) - `blockScreenControl()` and `isScreenControlBlocked()` to prevent accessibility services from reading or controlling the app screen (Android only) - `blockOverlayWindows()` and `isOverlayWindowsBlocked()` to hide overlay windows of other apps (Android 12+ only, requires the `HIDE_OVERLAY_WINDOWS` permission) diff --git a/example/src/App.tsx b/example/src/App.tsx index d91d304..78661a5 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -360,7 +360,19 @@ const App = () => { ); }; - useFreeRasp(config, actions, raspExecutionStateActions); + const { error: raspError } = useFreeRasp( + config, + actions, + raspExecutionStateActions + ); + + useEffect(() => { + if (raspError) { + console.error( + `freeRASP failed to start: ${raspError.code}: ${raspError.message}` + ); + } + }, [raspError]); return ( + e instanceof TalsecError + ? e + : new TalsecError( + 'talsec-failure', + e instanceof Error ? e.message : String(e) + ); + +/** + * Registers the threat and RASP execution state listeners and starts freeRASP. + * + * freeRASP is started only once per app run; later mounts only re-register + * the listeners. + * + * @returns `started` once freeRASP runs, or the `TalsecError` that prevented + * the listeners from being registered or freeRASP from starting. + */ export const useFreeRasp = ( config: TalsecConfig, actions: ThreatEventActions, raspExecutionStateActions?: RaspExecutionStateEventActions -) => { +): FreeRaspStatus => { + const [status, setStatus] = useState({ + started: isRaspStarted, + error: null, + }); + useEffect(() => { + let isMounted = true; + (async () => { - await setThreatListeners(actions); - raspExecutionStateActions && - (await setRaspExecutionStateListener(raspExecutionStateActions)); + try { + await setThreatListeners(actions); + if (raspExecutionStateActions) { + await setRaspExecutionStateListener(raspExecutionStateActions); + } - if (isRaspStarted) { - return; - } + if (!isRaspStarted) { + await talsecStart(config); + isRaspStarted = true; + } - try { - await talsecStart(config); - isRaspStarted = true; - } catch (e: any) { - console.error(`${e.code}: ${e.message}`); + if (isMounted) { + setStatus({ started: true, error: null }); + } + } catch (e) { + if (isMounted) { + setStatus({ started: isRaspStarted, error: toTalsecError(e) }); + } } })(); return () => { + isMounted = false; (async () => { await removeThreatListener(); await removeRaspExecutionStateEventListener(); @@ -44,4 +76,6 @@ export const useFreeRasp = ( }; // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + + return status; }; diff --git a/src/types/types.ts b/src/types/types.ts index 120302c..ba4d02f 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -1,3 +1,5 @@ +import type { TalsecError } from './errors'; + export type TalsecConfig = { androidConfig?: TalsecAndroidConfig; iosConfig?: TalsecIosConfig; @@ -116,3 +118,13 @@ export type RaspExecutionStateEventActions = { */ postponedChecksFinished?: () => any; }; + +/** + * State returned by `useFreeRasp`. + */ +export type FreeRaspStatus = { + /** `true` once freeRASP has been started. */ + started: boolean; + /** Error that prevented the listeners from being registered or freeRASP from starting. */ + error: TalsecError | null; +}; From 577e1afdf0129be0a1891dde80b92d8500e51cc8 Mon Sep 17 00:00:00 2001 From: Tomas Psota Date: Thu, 12 Nov 2026 09:05:16 +0100 Subject: [PATCH 3/3] refactor(types): type threat and execution state actions as returning void Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + src/types/types.ts | 54 +++++++++++++++++++++++----------------------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffb368a..e36f2ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Android package (namespace) of the plugin renamed from `com.freeraspreactnative` to `app.talsec.rasp.reactnative`, following the Android SDK's `app.talsec.rasp` (update the import if you register `FreeraspReactNativePackage` manually) - On Android, `isScreenCaptureBlocked()` reports the protection state of the current activity +- Threat and RASP execution state actions are typed as returning `void` instead of `any` ### Android diff --git a/src/types/types.ts b/src/types/types.ts index ba4d02f..a0c8d51 100644 --- a/src/types/types.ts +++ b/src/types/types.ts @@ -67,33 +67,33 @@ export type PackageInfo = { export type CallState = 'STARTED' | 'ONGOING' | 'STOPPED'; export type ThreatEventActions = { - privilegedAccess?: () => any; - debug?: () => any; - simulator?: () => any; - appIntegrity?: () => any; - unofficialStore?: () => any; - hooks?: () => any; - deviceBinding?: () => any; - deviceID?: () => any; - passcode?: () => any; - secureHardwareNotAvailable?: () => any; - obfuscationIssues?: () => any; - devMode?: () => any; - systemVPN?: () => any; - malware?: (suspiciousApps: SuspiciousAppInfo[]) => any; - adbEnabled?: () => any; - screenshot?: () => any; - screenRecording?: () => any; - multiInstance?: () => any; - timeSpoofing?: () => any; - locationSpoofing?: () => any; - unsecureWifi?: () => any; - automation?: () => any; - bootloader?: () => any; + privilegedAccess?: () => void; + debug?: () => void; + simulator?: () => void; + appIntegrity?: () => void; + unofficialStore?: () => void; + hooks?: () => void; + deviceBinding?: () => void; + deviceID?: () => void; + passcode?: () => void; + secureHardwareNotAvailable?: () => void; + obfuscationIssues?: () => void; + devMode?: () => void; + systemVPN?: () => void; + malware?: (suspiciousApps: SuspiciousAppInfo[]) => void; + adbEnabled?: () => void; + screenshot?: () => void; + screenRecording?: () => void; + multiInstance?: () => void; + timeSpoofing?: () => void; + locationSpoofing?: () => void; + unsecureWifi?: () => void; + automation?: () => void; + bootloader?: () => void; /** * Android only. Requires `startOngoingCallDetection()`. */ - ongoingCall?: (state: CallState) => any; + ongoingCall?: (state: CallState) => void; }; export type NativeEvent = { @@ -106,17 +106,17 @@ export type RaspExecutionStateEventActions = { * checks may still run afterwards. On iOS, triggered when all checks have * been completed. */ - fastChecksFinished?: () => any; + fastChecksFinished?: () => void; /** * Android only. The critical checks have been completed, before the * non-critical checks. */ - criticalChecksFinished?: () => any; + criticalChecksFinished?: () => void; /** * Android only. The postponed checks have been completed, which ends the * initial evaluation. */ - postponedChecksFinished?: () => any; + postponedChecksFinished?: () => void; }; /**