Skip to content

Commit

Permalink
feat: better handling of platform specific functions
Browse files Browse the repository at this point in the history
  • Loading branch information
LazyAfternoons committed May 16, 2024
1 parent a4c7921 commit 4e3ef0a
Showing 1 changed file with 49 additions and 30 deletions.
79 changes: 49 additions & 30 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,12 @@ type IntegrityErrorCodesIOS =
| 'CLIENT_DATA_ENCODING_ERROR'
| 'GENERATION_ASSERTION_FAILED';

type IntegrityErrorCodesCommon = 'PLATFORM_NOT_SUPPORTED';

export type IntegrityErrorCodes =
| IntegrityErrorCodesIOS
| IntegrityErrorCodesAndroid;
| IntegrityErrorCodesAndroid
| IntegrityErrorCodesCommon;

/**
* Error type returned by a rejected promise.
Expand All @@ -41,6 +44,14 @@ export type IntegrityError = {
userInfo: Record<string, string>;
};

/**
* Error when the platform is not supported.
*/
const IntegrityErrorUnsupportedError: IntegrityError = {
message: 'PLATFORM_NOT_SUPPORTED',
userInfo: {},
};

const LINKING_ERROR =
`The package '@pagopa/io-react-native-integrity' doesn't seem to be linked. Make sure: \n\n` +
Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) +
Expand All @@ -59,6 +70,7 @@ const IoReactNativeIntegrity = NativeModules.IoReactNativeIntegrity
);

/**
* iOS ONLY
* This function checks if the attestation service is available on the device.
*
* If it is not possible to retrive the key, the promise is rejected providing an
Expand All @@ -67,9 +79,10 @@ const IoReactNativeIntegrity = NativeModules.IoReactNativeIntegrity
* @returns a promise that resolves to a boolean.
*/
export function isAttestationServiceAvailable(): Promise<boolean> {
return Platform.OS === 'ios'
? IoReactNativeIntegrity.isAttestationServiceAvailable()
: Promise.resolve(false); // TODO: implement for Android
return Platform.select({
ios: () => IoReactNativeIntegrity.isAttestationServiceAvailable(),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
Expand All @@ -81,10 +94,15 @@ export function isAttestationServiceAvailable(): Promise<boolean> {
* @returns a promise that resolves to a string.
*/
export function generateHardwareKey(): Promise<string> {
return IoReactNativeIntegrity.generateHardwareKey();
return Platform.select({
ios: () => IoReactNativeIntegrity.generateHardwareKey(),
android: () => Promise.reject(IntegrityErrorUnsupportedError),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
* iOS ONLY
* This function generates an attestation for the given challenge and hardware key.
*
* If it is not possible to retrive the attestation, the promise is rejected providing an
Expand All @@ -98,10 +116,14 @@ export function getAttestation(
challenge: string,
hardwareKeyTag: string
): Promise<string> {
return IoReactNativeIntegrity.getAttestation(challenge, hardwareKeyTag);
return Platform.select({
ios: () => IoReactNativeIntegrity.getAttestation(challenge, hardwareKeyTag),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
* iOS ONLY
* This function generates a signature for the given client data given an hardware key.
*
* If it is not possible to retrive the signature, the promise is rejected providing an
Expand All @@ -115,32 +137,26 @@ export function generateHardwareSignatureWithAssertion(
clientData: string,
hardwareKeyTag: string
): Promise<string> {
return IoReactNativeIntegrity.generateHardwareSignatureWithAssertion(
clientData,
hardwareKeyTag
);
return Platform.select({
ios: () =>
IoReactNativeIntegrity.generateHardwareSignatureWithAssertion(
clientData,
hardwareKeyTag
),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
* Checks whether the current platform is Android or not.
* @returns true if the current platform is Android, false otherwise.
*/
const isAndroid = () => Platform.OS === 'android';

/**
* Error message for functions available only on Android.
*/
const NOT_ANDROID_ERROR = 'This function is available only on Android';

/**
* ANDROID ONLY
* Checks whether Google Play Services is available on the device or not.
* @return a promise resolved to true if Google Play Services is available, to false otherwise.
*/
export function isPlayServicesAvailable(): Promise<boolean> {
return isAndroid()
? IoReactNativeIntegrity.isPlayServicesAvailable()
: Promise.resolve(false);
return Platform.select({
android: () => IoReactNativeIntegrity.isPlayServicesAvailable(),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
Expand All @@ -160,9 +176,11 @@ export function isPlayServicesAvailable(): Promise<boolean> {
export function prepareIntegrityToken(
cloudProjectNumber: string
): Promise<void> {
return isAndroid()
? IoReactNativeIntegrity.prepareIntegrityToken(cloudProjectNumber)
: Promise.reject(NOT_ANDROID_ERROR);
return Platform.select({
android: () =>
IoReactNativeIntegrity.prepareIntegrityToken(cloudProjectNumber),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

/**
Expand All @@ -178,7 +196,8 @@ export function prepareIntegrityToken(
* - The {@link prepareIntegrityToken} function hasn't been called previously.
*/
export function requestIntegrityToken(requestHash?: string): Promise<string> {
return isAndroid()
? IoReactNativeIntegrity.requestIntegrityToken(requestHash)
: Promise.reject(NOT_ANDROID_ERROR);
return Platform.select({
android: () => IoReactNativeIntegrity.requestIntegrityToken(requestHash),
default: () => Promise.reject(IntegrityErrorUnsupportedError),
})();
}

0 comments on commit 4e3ef0a

Please sign in to comment.