@@ -2,14 +2,18 @@ import { useEffect } from 'react';
22import {
33 NativeEventEmitter ,
44 NativeModules ,
5+ Platform ,
56 type EmitterSubscription ,
67} from 'react-native' ;
78import {
89 Threat ,
910 type NativeEventEmitterActions ,
11+ type PackageInfo ,
12+ type SuspiciousAppInfo ,
1013 type TalsecConfig ,
1114} from './definitions' ;
1215import { getThreatCount , itemsHaveType } from './utils' ;
16+ import { decode } from 'base-64' ;
1317
1418const { FreeraspReactNative } = NativeModules ;
1519
@@ -31,9 +35,10 @@ const getThreatIdentifiers = async (): Promise<number[]> => {
3135 return identifiers ;
3236} ;
3337
34- const getThreatChannelData = async ( ) : Promise < [ string , string ] > => {
38+ const getThreatChannelData = async ( ) : Promise < [ string , string , string ] > => {
39+ const dataLength = Platform . OS === 'ios' ? 2 : 3 ;
3540 let data = await FreeraspReactNative . getThreatChannelData ( ) ;
36- if ( data . length !== 2 || ! itemsHaveType ( data , 'string' ) ) {
41+ if ( data . length !== dataLength || ! itemsHaveType ( data , 'string' ) ) {
3742 onInvalidCallback ( ) ;
3843 }
3944 return data ;
@@ -48,10 +53,25 @@ const prepareMapping = async (): Promise<void> => {
4853 } ) ;
4954} ;
5055
56+ // parses base64-encoded malware data to SuspiciousAppInfo[]
57+ const parseMalwareData = ( data : string [ ] ) : SuspiciousAppInfo [ ] => {
58+ const result : SuspiciousAppInfo [ ] = [ ] ;
59+ data . forEach ( ( entry ) => {
60+ result . push ( toSuspiciousAppInfo ( entry ) ) ;
61+ } ) ;
62+ return result ;
63+ } ;
64+
65+ const toSuspiciousAppInfo = ( base64Value : string ) : SuspiciousAppInfo => {
66+ const data = JSON . parse ( decode ( base64Value ) ) ;
67+ const packageInfo = data . packageInfo as PackageInfo ;
68+ return { packageInfo, reason : data . reason } as SuspiciousAppInfo ;
69+ } ;
70+
5171export const setThreatListeners = async < T extends NativeEventEmitterActions > (
5272 config : T & Record < Exclude < keyof T , keyof NativeEventEmitterActions > , [ ] >
5373) => {
54- const [ channel , key ] = await getThreatChannelData ( ) ;
74+ const [ channel , key , malwareKey ] = await getThreatChannelData ( ) ;
5575 await prepareMapping ( ) ;
5676
5777 eventsListener = eventEmitter . addListener ( channel , ( event ) => {
@@ -98,6 +118,9 @@ export const setThreatListeners = async <T extends NativeEventEmitterActions>(
98118 case Threat . SystemVPN . value :
99119 config . systemVPN ?.( ) ;
100120 break ;
121+ case Threat . Malware . value :
122+ config . malware ?.( parseMalwareData ( event [ malwareKey ] ) ) ;
123+ break ;
101124 default :
102125 onInvalidCallback ( ) ;
103126 break ;
@@ -138,4 +161,12 @@ export const useFreeRasp = <T extends NativeEventEmitterActions>(
138161 } , [ ] ) ;
139162} ;
140163
164+ export const addToWhitelist = async ( packageName : string ) : Promise < boolean > => {
165+ if ( Platform . OS === 'ios' ) {
166+ return Promise . reject ( 'Malware detection not available on iOS' ) ;
167+ }
168+ return FreeraspReactNative . addToWhitelist ( packageName ) ;
169+ } ;
170+
171+ export * from './definitions' ;
141172export default FreeraspReactNative ;
0 commit comments