Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,35 @@ try {
}
```

**Platform agnostic errors:**

You can access the platform agnostic generic error codes as below :

```js
try {
const credentials = await auth0.credentialsManager.getCredentials();
} catch (error) {
console.log(e.type);
}
```

_Note_ : We have platform agnostic error codes available only for `CredentialsManagerError` as of now.

| Generic Error Code | Corresponding Error Code in Android | Corresponding Error Code in iOS |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------- |
| `INVALID_CREDENTIALS` | `INVALID_CREDENTIALS` | |
| `NO_CREDENTIALS` | `NO_CREDENTIALS` | `noCredentials` |
| `NO_REFRESH_TOKEN` | `NO_REFRESH_TOKEN` | `noRefreshToken` |
| `RENEW_FAILED` | `RENEW_FAILED` | `renewFailed` |
| `STORE_FAILED` | `STORE_FAILED` | `storeFailed` |
| `REVOKE_FAILED` | `REVOKE_FAILED` | `revokeFailed` |
| `LARGE_MIN_TTL` | `LARGE_MIN_TTL` | `largeMinTTL` |
| `INCOMPATIBLE_DEVICE` | `INCOMPATIBLE_DEVICE` | |
| `CRYPTO_EXCEPTION` | `CRYPTO_EXCEPTION` | |
| `BIOMETRICS_FAILED` | OneOf <br>`BIOMETRIC_NO_ACTIVITY`,`BIOMETRIC_ERROR_STATUS_UNKNOWN`,`BIOMETRIC_ERROR_UNSUPPORTED`,<br>`BIOMETRIC_ERROR_HW_UNAVAILABLE`,`BIOMETRIC_ERROR_NONE_ENROLLED`,`BIOMETRIC_ERROR_NO_HARDWARE`,<br>`BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED`,`BIOMETRIC_AUTHENTICATION_CHECK_FAILED`,<br>`BIOMETRIC_ERROR_DEVICE_CREDENTIAL_NOT_AVAILABLE` | `biometricsFailed` |
| `NO_NETWORK` | `NO_NETWORK` | |
| `API_ERROR` | `API_ERROR` | |

## Feedback

### Contributing
Expand Down
47 changes: 45 additions & 2 deletions android/src/main/java/com/auth0/react/A0Auth0Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,43 @@

public class A0Auth0Module extends ReactContextBaseJavaModule implements ActivityEventListener {

private final Map<CredentialsManagerException, String> ERROR_CODE_MAP = new HashMap<>() {{
put(CredentialsManagerException.Companion.getINVALID_CREDENTIALS(), "INVALID_CREDENTIALS");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is Enum.name field provided by Enums in Kotlin, can we use that to simplify the code? I haven't fired up my IDE to test this but looks like there is an opportunity to clean this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Enums are internal in the underlying android SDK right now and we cannot access them.
We are leveraging the Public fields exposed via the Companion class.
However, we have a plan to migrate this .java code to .kt. Once that is done, we can leverage kotlin semantics and clean this snippet (tracked as part of SDK-5699)

put(CredentialsManagerException.Companion.getNO_CREDENTIALS(), "NO_CREDENTIALS");
put(CredentialsManagerException.Companion.getNO_REFRESH_TOKEN(), "NO_REFRESH_TOKEN");
put(CredentialsManagerException.Companion.getRENEW_FAILED(), "RENEW_FAILED");
put(CredentialsManagerException.Companion.getSTORE_FAILED(), "STORE_FAILED");
put(CredentialsManagerException.Companion.getREVOKE_FAILED(), "REVOKE_FAILED");
put(CredentialsManagerException.Companion.getLARGE_MIN_TTL(), "LARGE_MIN_TTL");
put(CredentialsManagerException.Companion.getINCOMPATIBLE_DEVICE(), "INCOMPATIBLE_DEVICE");
put(CredentialsManagerException.Companion.getCRYPTO_EXCEPTION(), "CRYPTO_EXCEPTION");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NO_ACTIVITY(), "BIOMETRIC_NO_ACTIVITY");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_STATUS_UNKNOWN(), "BIOMETRIC_ERROR_STATUS_UNKNOWN");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_UNSUPPORTED(), "BIOMETRIC_ERROR_UNSUPPORTED");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_HW_UNAVAILABLE(), "BIOMETRIC_ERROR_HW_UNAVAILABLE");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NONE_ENROLLED(), "BIOMETRIC_ERROR_NONE_ENROLLED");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NO_HARDWARE(), "BIOMETRIC_ERROR_NO_HARDWARE");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED(), "BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED");
put(CredentialsManagerException.Companion.getBIOMETRIC_AUTHENTICATION_CHECK_FAILED(), "BIOMETRIC_AUTHENTICATION_CHECK_FAILED");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_DEVICE_CREDENTIAL_NOT_AVAILABLE(), "BIOMETRIC_ERROR_DEVICE_CREDENTIAL_NOT_AVAILABLE");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_STRONG_AND_DEVICE_CREDENTIAL_NOT_AVAILABLE(), "BIOMETRIC_ERROR_STRONG_AND_DEVICE_CREDENTIAL_NOT_AVAILABLE");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL(), "BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NEGATIVE_BUTTON(), "BIOMETRIC_ERROR_NEGATIVE_BUTTON");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_HW_NOT_PRESENT(), "BIOMETRIC_ERROR_HW_NOT_PRESENT");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NO_BIOMETRICS(), "BIOMETRIC_ERROR_NO_BIOMETRICS");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_USER_CANCELED(), "BIOMETRIC_ERROR_USER_CANCELED");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_LOCKOUT_PERMANENT(), "BIOMETRIC_ERROR_LOCKOUT_PERMANENT");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_VENDOR(), "BIOMETRIC_ERROR_VENDOR");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_LOCKOUT(), "BIOMETRIC_ERROR_LOCKOUT");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_CANCELED(), "BIOMETRIC_ERROR_CANCELED");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_NO_SPACE(), "BIOMETRIC_ERROR_NO_SPACE");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_TIMEOUT(), "BIOMETRIC_ERROR_TIMEOUT");
put(CredentialsManagerException.Companion.getBIOMETRIC_ERROR_UNABLE_TO_PROCESS(), "BIOMETRIC_ERROR_UNABLE_TO_PROCESS");
put(CredentialsManagerException.Companion.getBIOMETRICS_INVALID_USER(), "BIOMETRICS_INVALID_USER");
put(CredentialsManagerException.Companion.getBIOMETRIC_AUTHENTICATION_FAILED(), "BIOMETRIC_AUTHENTICATION_FAILED");
put(CredentialsManagerException.Companion.getAPI_ERROR(), "API_ERROR");
put(CredentialsManagerException.Companion.getNO_NETWORK(), "NO_NETWORK");
}};
private static final String CREDENTIAL_MANAGER_ERROR_CODE = "a0.invalid_state.credential_manager_exception";
private static final String INVALID_DOMAIN_URL_ERROR_CODE = "a0.invalid_domain_url";
private static final String BIOMETRICS_AUTHENTICATION_ERROR_CODE = "a0.invalid_options_biometrics_authentication";
Expand Down Expand Up @@ -122,18 +159,24 @@ public void onSuccess(Credentials credentials) {

@Override
public void onFailure(@NonNull CredentialsManagerException e) {
promise.reject(CREDENTIAL_MANAGER_ERROR_CODE, e.getMessage(), e);
String errorCode = deduceErrorCode(e);
promise.reject(errorCode, e.getMessage(), e);
}
}));
}

private String deduceErrorCode(@NonNull CredentialsManagerException e) {
return ERROR_CODE_MAP.getOrDefault(e, CREDENTIAL_MANAGER_ERROR_CODE);
}

@ReactMethod
public void saveCredentials(ReadableMap credentials, Promise promise) {
try {
this.secureCredentialsManager.saveCredentials(CredentialsParser.fromMap(credentials));
promise.resolve(true);
} catch (CredentialsManagerException e) {
promise.reject(CREDENTIAL_MANAGER_ERROR_CODE, e.getMessage(), e);
String errorCode = deduceErrorCode(e);
promise.reject(errorCode, e.getMessage(), e);
}
}

Expand Down
138 changes: 138 additions & 0 deletions src/credentials-manager/__tests__/credentials-manager.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import CredentialsManager from '../index';
import CredentialsManagerError from '../credentialsManagerError';
import { Platform } from 'react-native';

describe('credentials manager tests', () => {
Expand Down Expand Up @@ -168,4 +169,141 @@ describe('credentials manager tests', () => {
newNativeModule.mockRestore();
});
});

describe('CredentialsManagerError', () => {
describe('convertToCommonErrorCode', () => {
it('should return the correct common error code for known error codes', () => {
const error = new CredentialsManagerError({
status: 400,
json: {},
text: '',
});

expect(error.convertToCommonErrorCode('INVALID_CREDENTIALS')).toBe(
'INVALID_CREDENTIALS'
);
expect(error.convertToCommonErrorCode('NO_CREDENTIALS')).toBe(
'NO_CREDENTIALS'
);
expect(error.convertToCommonErrorCode('NO_REFRESH_TOKEN')).toBe(
'NO_REFRESH_TOKEN'
);
expect(error.convertToCommonErrorCode('RENEW_FAILED')).toBe(
'RENEW_FAILED'
);
expect(error.convertToCommonErrorCode('STORE_FAILED')).toBe(
'STORE_FAILED'
);
expect(error.convertToCommonErrorCode('REVOKE_FAILED')).toBe(
'REVOKE_FAILED'
);
expect(error.convertToCommonErrorCode('LARGE_MIN_TTL')).toBe(
'LARGE_MIN_TTL'
);
expect(error.convertToCommonErrorCode('INCOMPATIBLE_DEVICE')).toBe(
'INCOMPATIBLE_DEVICE'
);
expect(error.convertToCommonErrorCode('CRYPTO_EXCEPTION')).toBe(
'CRYPTO_EXCEPTION'
);
expect(error.convertToCommonErrorCode('BIOMETRIC_NO_ACTIVITY')).toBe(
'BIOMETRICS_FAILED'
);
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_STATUS_UNKNOWN')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_UNSUPPORTED')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_HW_UNAVAILABLE')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_NONE_ENROLLED')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_NO_HARDWARE')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode(
'BIOMETRIC_ERROR_SECURITY_UPDATE_REQUIRED'
)
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode(
'BIOMETRIC_AUTHENTICATION_CHECK_FAILED'
)
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode(
'BIOMETRIC_ERROR_DEVICE_CREDENTIAL_NOT_AVAILABLE'
)
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode(
'BIOMETRIC_ERROR_STRONG_AND_DEVICE_CREDENTIAL_NOT_AVAILABLE'
)
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_NEGATIVE_BUTTON')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_HW_NOT_PRESENT')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_NO_BIOMETRICS')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_USER_CANCELED')
).toBe('BIOMETRICS_FAILED');
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_LOCKOUT_PERMANENT')
).toBe('BIOMETRICS_FAILED');
expect(error.convertToCommonErrorCode('BIOMETRIC_ERROR_VENDOR')).toBe(
'BIOMETRICS_FAILED'
);
expect(error.convertToCommonErrorCode('BIOMETRIC_ERROR_LOCKOUT')).toBe(
'BIOMETRICS_FAILED'
);
expect(error.convertToCommonErrorCode('BIOMETRIC_ERROR_CANCELED')).toBe(
'BIOMETRICS_FAILED'
);
expect(error.convertToCommonErrorCode('BIOMETRIC_ERROR_NO_SPACE')).toBe(
'BIOMETRICS_FAILED'
);
expect(error.convertToCommonErrorCode('BIOMETRIC_ERROR_TIMEOUT')).toBe(
'BIOMETRICS_FAILED'
);
expect(
error.convertToCommonErrorCode('BIOMETRIC_ERROR_UNABLE_TO_PROCESS')
).toBe('BIOMETRICS_FAILED');
expect(error.convertToCommonErrorCode('BIOMETRICS_INVALID_USER')).toBe(
'BIOMETRICS_FAILED'
);
expect(
error.convertToCommonErrorCode('BIOMETRIC_AUTHENTICATION_FAILED')
).toBe('BIOMETRICS_FAILED');
expect(error.convertToCommonErrorCode('BIOMETRICS_FAILED')).toBe(
'BIOMETRICS_FAILED'
);
expect(error.convertToCommonErrorCode('NO_NETWORK')).toBe('NO_NETWORK');
expect(error.convertToCommonErrorCode('API_ERROR')).toBe('API_ERROR');
});

it('should return UNKNOWN_ERROR for unknown error codes', () => {
const error = new CredentialsManagerError({
status: 400,
json: {},
text: '',
});

expect(error.convertToCommonErrorCode('UNKNOWN_CODE')).toBe(
'UNKNOWN_ERROR'
);
});
});
});
});
Loading