diff --git a/pages/fraud-prevention/mobile-app-setup.mdx b/pages/fraud-prevention/mobile-app-setup.mdx index 4b143f1..d69e0e7 100644 --- a/pages/fraud-prevention/mobile-app-setup.mdx +++ b/pages/fraud-prevention/mobile-app-setup.mdx @@ -152,6 +152,7 @@ interface AuthApiService { @Body fingerprint: FingerprintEventRequest, ): Response } + ``` @@ -251,7 +252,6 @@ function registerUser(username: string) { // Account already registered, suggest to the user to log in with that existing account // Keyri.login(username) }); - } function sendFingerprintToBackend(body: string): Promise { @@ -295,6 +295,7 @@ recommend explicitly setting the attribute in your manifest as shown below: ... + ``` [](https://github.com/Keyri-Co/keyri-android-whitelabel-sdk/blob/master/keyrisdk/src/main/java/com/keyrico/keyrisdk/backup/BACKUP.md#control-backup-on-android-11-and-lower)**Control @@ -311,6 +312,7 @@ on devices running Android 11 (API level 30) or lower. ... + ``` 2. Create an XML file called `@xml/backup_rules` in the `res/xml/` directory. @@ -323,6 +325,7 @@ on devices running Android 11 (API level 30) or lower. + ``` If you have more granular control over sharedPref backups, make sure you have @@ -344,6 +347,7 @@ running Android 12 or higher. ... + ``` 2. Create an XML file called `backup_rules.xml` in the `res/xml/` directory. @@ -358,6 +362,7 @@ running Android 12 or higher. + ``` If you have more granular control over sharedPref backups, make sure you have @@ -453,6 +458,7 @@ After it just add your `MyBackupAgent` to `AndroidManifest.xml`: + ``` Or you can just use @@ -468,6 +474,7 @@ implements the necessary logic under the hood as shown below: + ``` ### Testing backup @@ -487,4 +494,3 @@ sure to disclose the following data collection practice: An analogous disclosure is not required for iOS apps, since the device data is not used by Keyri for cross-app tracking. - diff --git a/pages/mobile-app-security.mdx b/pages/mobile-app-security.mdx index 4d17f46..2056517 100644 --- a/pages/mobile-app-security.mdx +++ b/pages/mobile-app-security.mdx @@ -31,6 +31,8 @@ Please be sure to install Keyri mobile SDKs as outlined in our documentation: ### Enabling Emulator Detection +// TODO: Change impl + The SDK constructor has `blockEmulatorDetection` set to `true` by default. This is to allow for local development of your application on an emulator without the SDK terminating the application. If you would like to deny the running of your diff --git a/pages/mobile-app-security/tamper-detection.mdx b/pages/mobile-app-security/tamper-detection.mdx index 44821bc..5727e84 100644 --- a/pages/mobile-app-security/tamper-detection.mdx +++ b/pages/mobile-app-security/tamper-detection.mdx @@ -18,6 +18,8 @@ performed by the SDK at initialization automatically. ## Checksum Registration +// TODO: Add impl + // iOS instructions // Android instructions diff --git a/pages/mobile-sdks/api-reference/android.mdx b/pages/mobile-sdks/api-reference/android.mdx index fae9204..6ab1ee5 100644 --- a/pages/mobile-sdks/api-reference/android.mdx +++ b/pages/mobile-sdks/api-reference/android.mdx @@ -247,9 +247,8 @@ override fun onCreate(savedInstanceState: Bundle?) { appKey, publicApiKey, serviceEncryptionKey, - true, // blockEmulatorDetection payload, - publicUserId + publicUserId, ) // Or with on activityResult: @@ -262,9 +261,8 @@ override fun onCreate(savedInstanceState: Bundle?) { appKey, publicApiKey, serviceEncryptionKey, - true, // blockEmulatorDetection payload, - publicUserId + publicUserId, ) } } @@ -319,9 +317,8 @@ private void processLink(Uri intentData) { appKey, publicApiKey, serviceEncryptionKey, - true, // blockEmulatorDetection payload, - publicUserId + publicUserId, ); // Or with on activityResult: @@ -334,9 +331,8 @@ private void processLink(Uri intentData) { appKey, publicApiKey, serviceEncryptionKey, - true, // blockEmulatorDetection payload, - publicUserId + publicUserId, ); }); } @@ -420,6 +416,8 @@ The following methods are available to interact with the Keyri SDK API, which ca - `suspend fun Keyri.register(publicUserId: String?): Result` - call this method to generate object for register which includes publicKey and userId +- `suspend fun Keyri.getCorrectedTimestampSeconds(): Long` - call this method to get timestamp (in seconds) synchronized with NTP + - `suspend fun Session.confirm(payload: String, context: Context, trustNewBrowser: Boolean = false): Result` - call this function if user confirmed the dialog. Returns authentication result or Throwable error - `suspend fun Session.deny(payload: String, context: Context): Result` - call if the user denied the dialog. Returns denial result or Throwable error @@ -442,9 +440,9 @@ The following methods are available to interact with the Keyri SDK API, which ca - `suspend fun Keyri.removeAssociationKey(publicUserId: String): Result` - removes association public key for the specified publicUserId -- `fun easyKeyriAuth(content: Context, easyKeyriAuthLauncher: ActivityResultLauncher, appKey: String, publicApiKey: String?, serviceEncryptionKey: String?, blockEmulatorDetection: Boolean = true, payload: String, publicUserId: String?)` - launches scanner activity with default confirmation screen for ActivityResultLauncher +- `fun easyKeyriAuth(content: Context, easyKeyriAuthLauncher: ActivityResultLauncher, appKey: String, publicApiKey: String?, serviceEncryptionKey: String?, payload: String, publicUserId: String?, detectionsConfig: KeyriDetectionsConfig = KeyriDetectionsConfig())` - launches scanner activity with default confirmation screen for ActivityResultLauncher -- `fun easyKeyriAuth(activity: Activity, requestCode: Int, appKey: String, publicApiKey: String?, serviceEncryptionKey: String?, blockEmulatorDetection: Boolean = true, payload: String, publicUserId: String?)` - launches scanner activity for result with default confirmation screen for onActivityResult +- `fun easyKeyriAuth(activity: Activity, requestCode: Int, appKey: String, publicApiKey: String?, serviceEncryptionKey: String?, payload: String, publicUserId: String?, detectionsConfig: KeyriDetectionsConfig = KeyriDetectionsConfig())` - launches scanner activity for result with default confirmation screen for onActivityResult - `@Composable fun EasyKeyriAuth(sheetState: ModalBottomSheetState, coroutineScope: CoroutineScope, keyri: Keyri, sessionId: String, payload: String, publicUserId: String?, result: (Result) -> Unit)` - handle process flow with passed scanned url and showing default confirmation screen. Easiest way to process session from deeplink @@ -465,6 +463,8 @@ Payload can be anything (session token or a stringified JSON containing multiple - `void KeyriSdk.register(@Nullable String publicUserId, KeyriCallback callback)` - call this method to generate object for register which includes publicKey and userId +- `void KeyriSdk.getCorrectedTimestampSeconds(KeyriCallback callback)` - call this method to get timestamp (in seconds) synchronized with NTP + - `void KeyriSession.confirm(String payload, Context context, boolean trustNewBrowser, KeyriCallback callback)` - call this function if user confirmed the dialog. Returns authentication result or Throwable error - `void KeyriSession.deny(String payload, Context context, KeyriCallback callback)` - call if the user denied the dialog. Returns denial result or Throwable error @@ -487,9 +487,9 @@ Payload can be anything (session token or a stringified JSON containing multiple - `void KeyriSdk.removeAssociationKey(String publicUserId, KeyriCallback callback)` - removes association public key for the specified publicUserId -- `void EasyKeyriAuth.easyKeyriAuth(Context content, ActivityResultLauncher easyKeyriAuthLauncher, String appKey, @Nullable String publicApiKey, @Nullable String serviceEncryptionKey, String payload, boolean blockEmulatorDetection, String payload, @Nullable String publicUserId)` - launches scanner activity with default confirmation screen for ActivityResultLauncher +- `void EasyKeyriAuth.easyKeyriAuth(Context content, ActivityResultLauncher easyKeyriAuthLauncher, String appKey, @Nullable String publicApiKey, @Nullable String serviceEncryptionKey, String payload, String payload, @Nullable String publicUserId, KeyriDetectionsConfig detectionsConfig)` - launches scanner activity with default confirmation screen for ActivityResultLauncher -- `void EasyKeyriAuth.easyKeyriAuth(Activity activity, int requestCode, String appKey, @Nullable String publicApiKey, @Nullable String serviceEncryptionKey, String payload, boolean blockEmulatorDetection, String payload, @Nullable String publicUserId)` - launches scanner activity for result with default confirmation screen for onActivityResult +- `void EasyKeyriAuth.easyKeyriAuth(Activity activity, int requestCode, String appKey, @Nullable String publicApiKey, @Nullable String serviceEncryptionKey, String payload, String payload, @Nullable String publicUserId, KeyriDetectionsConfig detectionsConfig)` - launches scanner activity for result with default confirmation screen for onActivityResult ### Session Object diff --git a/pages/mobile-sdks/api-reference/cordova.mdx b/pages/mobile-sdks/api-reference/cordova.mdx index b50badc..8c32194 100644 --- a/pages/mobile-sdks/api-reference/cordova.mdx +++ b/pages/mobile-sdks/api-reference/cordova.mdx @@ -38,8 +38,7 @@ the Keyri dashboard Keyri.initialize({ appKey: appKey, publicApiKey: publicApiKey, - serviceEncryptionKey: serviceEncryptionKey, - blockEmulatorDetection: true + serviceEncryptionKey: serviceEncryptionKey }) .then((isSuccess) => { console.log('CordovaKeyri.initialize', isSuccess); @@ -142,12 +141,14 @@ The following methods are available to interact with the Keyri SDK API, which ca - `initiateQrSession(sessionId: string, publicUserId?: string): Promise` - call it after obtaining the sessionId from QR code or deep link. Returns Session object with Risk attributes (needed to show confirmation screen) or Exception -- `initializeDefaultConfirmationScreen(payload: string): Promise` - to show Confirmation with default UI. Returns Boolean result. Also, you can implement your custom Confirmation Screen, just inherit from BaseConfirmationDialog.kt +- `initializeDefaultConfirmationScreen(payload: string): Promise` - to show Confirmation with default UI. Returns Boolean result - `login(publicUserId?: string): Promise` - call this method to generate object for login which includes timestampNonce, signature, publicKey and userId - `register(publicUserId?: string): Promise` - call this method to generate object for register which includes publicKey and userId +- `getCorrectedTimestampSeconds(): Promise` - call this method to get timestamp (in seconds) synchronized with NTP + - `confirmSession(payload: string, trustNewBrowser?: boolean): Promise` - call this function if user confirmed the dialog, trustNewBrowser is false by default. Returns Boolean authentication result - `denySession(payload: string): Promise` - call if the user denied the dialog. Returns Boolean authentication result diff --git a/pages/mobile-sdks/api-reference/flutter.mdx b/pages/mobile-sdks/api-reference/flutter.mdx index d0fa7d8..7c2be8d 100644 --- a/pages/mobile-sdks/api-reference/flutter.mdx +++ b/pages/mobile-sdks/api-reference/flutter.mdx @@ -67,7 +67,6 @@ void main() { const String appKey = "[Your app key here]"; // Change it before launch const String? publicApiKey = null; // Change it before launch, optional const String? serviceEncryptionKey = null; // Change it before launch, optional -const bool blockEmulatorDetection = true; const String? publicUserId = null; // Change it before launch, optional class MyApp extends StatelessWidget { @@ -92,7 +91,7 @@ class KeyriHomePage extends StatefulWidget { } class _KeyriHomePageState extends State { - Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey, blockEmulatorDetection: true); + Keyri keyri = Keyri.primary(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey); @override Widget build(BuildContext context) { @@ -160,7 +159,7 @@ class KeyriScannerAuthPage extends StatefulWidget { class _KeyriScannerAuthPageState extends State { bool _isLoading = false; - Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey, blockEmulatorDetection: true); + Keyri keyri = Keyri.primary(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey); void onMobileScannerDetect(BarcodeCapture barcodes) { if (barcodes.barcodes.isNotEmpty && !_isLoading) { @@ -244,6 +243,7 @@ class _KeyriScannerAuthPageState extends State { }); } } + ``` ## Deep linking @@ -263,6 +263,7 @@ To handle Universal Links (e.g., for QR login straight from the user's built-in + ``` This will handle all links with the following scheme: `https://{yourCompany}.onekey.to?sessionId={sessionId}` @@ -278,11 +279,14 @@ func application(_ application: UIApplication, continue userActivity: NSUserActi else { return false } + let keyri = KeyriInterface(appKey: appKey) - keyri.processLink(url: incomingURL, payload: 'Custom', publicUserId: 'username') + + keyri.processLink(url: incomingURL, payload: 'Custom', publicUserId: 'example@mail.com') return true } + ``` **Note:** Keyri will set up the required `/.well-known/apple-app-site-association` JSON at your `https://{yourSubdomain}.onekey.to` page as required by Apple to handle Universal Link handling. Details on this mechanism are described here: https://developer.apple.com/documentation/Xcode/supporting-associated-domains @@ -306,6 +310,7 @@ To handle Android App Links \(e.g., for QR login straight from the user's built- + ``` In the activity where the processing of links is declared, you need to add handlers in the `onNewIntent()` and `onCreate()` methods, and pass \`sessionId\` to \`easyKeyriAuth\` method: @@ -337,13 +342,13 @@ private fun processLink(data: Uri?) { "[Your appKey]", // Get this value from the Keyri dashboard "[Your publicApiKey]", // Get this value from the Keyri dashboard, optional, "[Your serviceEncryptionKey]", // Get this value from the Keyri dashboard, optional - true, // blockEmulatorDetection "Custom payload here", "public-User-ID", // publicUserId is optional ) } } ?: Log.e("Keyri", "Failed to process link") } + ``` ## Interacting with the API @@ -354,12 +359,14 @@ The following methods are available to interact with the Keyri SDK API, which ca - `Future easyKeyriAuth(String payload, {String? publicUserId})` - handle process flow with passed scanned url and showing default confirmation screen. Easiest way to process session from deeplink -- `Future initializeDefaultConfirmationScreen(String payload)` - to show Confirmation with default UI. Returns Boolean result. Also, you can implement your custom Confirmation Screen, just inherit from BaseConfirmationDialog.kt +- `Future initializeDefaultConfirmationScreen(String payload)` - to show Confirmation with default UI. Returns Boolean result - `Future login({String? publicUserId})` - call this method to generate object for login which includes timestampNonce, signature, publicKey and userId - `Future register({String? publicUserId})` - call this method to generate object for register which includes publicKey and userId +- `Future getCorrectedTimestampSeconds() ` - call this method to get timestamp (in seconds) synchronized with NTP + - `Future confirmSession(String payload, bool trustNewBrowser)` - call this function if user confirmed the dialog, trustNewBrowser is false by default. Returns Boolean authentication result - `Future denySession(String payload)` - call if the user denied the dialog. Returns Boolean authentication result diff --git a/pages/mobile-sdks/api-reference/ios.mdx b/pages/mobile-sdks/api-reference/ios.mdx index 85f93a7..c4d8dd1 100644 --- a/pages/mobile-sdks/api-reference/ios.mdx +++ b/pages/mobile-sdks/api-reference/ios.mdx @@ -52,6 +52,7 @@ match this example: + ``` This will handle all links with the following scheme: @@ -109,7 +110,6 @@ func processLink(url: URL) { // On error } } - } ```` @@ -127,7 +127,7 @@ func processLink(url: URL) { NSString *publicUserId = @"public-User-Id"; // publicUserId is optional NSString *payload = @"Custom payload here"; - [self.keyri initializeKeyriWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey blockEmulatorDetection:YES]; + [self.keyri initializeKeyriWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey]; if (self != nil) { NSString *stringUrl = url; @@ -213,7 +213,7 @@ func openEasyKeyriAuth() { NSString *publicUserId = @"public-User-Id"; // publicUserId is optional NSString *payload = @"Custom payload here"; - [self.keyri initializeKeyriWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey blockEmulatorDetection:YES]; + [self.keyri initializeKeyriWithAppKey:appKey publicApiKey:publicApiKey serviceEncryptionKey:serviceEncryptionKey]; [self.keyri easyKeyriAuthWithPayload:payload publicUserId:publicUserId completion:^(BOOL success, NSError * _Nullable error) { if (success) { @@ -223,6 +223,7 @@ func openEasyKeyriAuth() { } }]; } + ``` @@ -233,9 +234,6 @@ The following methods are available to interact with the Keyri SDK API, which ca ### Swift - -- `public init(appKey: String, publicApiKey: String? = nil, serviceEncryptionKey: String? = nil, blockEmulatorDetection: Bool? = true)`- Initialize the Keyri object with the keys retrieved from the dashboard. If you're using sendEvent() to take advantage of our fraud dashboard, the publicApiKey and serviceEncryptionKey are required - - `func sendEvent(publicUserId: String = Constants.ANON_USER, eventType: EventType = .visits, success: Bool = true, completion: @escaping (Result) -> ())` - Sends an event to our dashboard containing a device snapshot to our dashboard. The response you receive will be sent, as is, to your own backend, where you can utilize our scripts to help you decrypt. See the code sample below and https://docs.keyri.com/fraud-prevention for more - `func KeyriInterface.easyKeyriAuth(payload: String, publicUserId: String?, completion: @escaping (Result) -> ())` - @@ -261,6 +259,8 @@ The following methods are available to interact with the Keyri SDK API, which ca call this method to generate object for register which includes publicKey and userId +- `func KeyriInterface.getCorrectedTimestampSeconds(completion: @escaping (Int) -> ())` - call this method to get timestamp (in seconds) synchronized with NTP + - `func KeyriInterface.processLink(url: URL, payload: String, publicUserId: String?, completion: @escaping (Result) -> ())` - process flow with passed uri with showing default confirmation screen. Easiest way to process session from deeplink. Returns result of authentication or @@ -304,35 +304,37 @@ Payload can be anything (session token or a stringified JSON containing multiple ### Objective-C -- `- (void)initializeKeyriWithAppKey:(NSString * _Nonnull)appKey publicApiKey:(NSString * _Nullable)publicApiKey serviceEncryptionKey:(NSString * _Nullable)serviceEncryptionKey blockEmulatorDetection:(BOOL)blockEmulatorDetection` - Initialize the Keyri object with the keys retrieved from the dashboard. If you're using sendEvent() to take advantage of our fraud dashboard, the publicApiKey and serviceEncryptionKey are required +- `- (void) KeyriObjC.initializeKeyriWithAppKey:(NSString * _Nonnull)appKey publicApiKey:(NSString * _Nullable)publicApiKey serviceEncryptionKey:(NSString * _Nullable)serviceEncryptionKey blockEmulatorDetection:(BOOL)blockEmulatorDetection` - Initialize the Keyri object with the keys retrieved from the dashboard. If you're using sendEvent() to take advantage of our fraud dashboard, the publicApiKey and serviceEncryptionKey are required + +- `- (void) KeyriObjC.easyKeyriAuthWithPayload:(NSString * _Nonnull)payload publicUserId:(NSString * _Nonnull)publicUserId completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - call to have Keyri drive you through the entire process - we display the scanner, scan the QR code, handle user confirmation and fire off the result to the browser - all with one line of code in your app -- `- (void)easyKeyriAuthWithPayload:(NSString * _Nonnull)payload publicUserId:(NSString * _Nonnull)publicUserId completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - call to have Keyri drive you through the entire process - we display the scanner, scan the QR code, handle user confirmation and fire off the result to the browser - all with one line of code in your app +- `- (void) KeyriObjC.generateAssociationKeyWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - creates a persistent ECDSA keypair for the given public user ID (example: email address) and return public key -- `- (void)generateAssociationKeyWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - creates a persistent ECDSA keypair for the given public user ID (example: email address) and return public key +- `- (void) KeyriObjC.generateUserSignatureWithPublicUserId:(NSString * _Nullable)publicUserId data:(NSData * _Nonnull)data completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - returns an ECDSA signature of the timestamp and optional customSignedData with the publicUserId's privateKey (or, if not provided, anonymous privateKey), data can be anything -- `- (void)generateUserSignatureWithPublicUserId:(NSString * _Nullable)publicUserId data:(NSData * _Nonnull)data completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - returns an ECDSA signature of the timestamp and optional customSignedData with the publicUserId's privateKey (or, if not provided, anonymous privateKey), data can be anything +- `- (void) KeyriObjC.listAssociationKeysWithCompletion:(void (^ _Nonnull)(NSDictionary * _Nullable, NSError * _Nullable))completion` - returns a dictionary of "association keys" and ECDSA Base64 public keys -- `- (void)listAssociationKeysWithCompletion:(void (^ _Nonnull)(NSDictionary * _Nullable, NSError * _Nullable))completion` - returns a dictionary of "association keys" and ECDSA Base64 public keys +- `- (void) KeyriObjC.listUniqueAccountsWithCompletion:(void (^ _Nonnull)(NSDictionary * _Nullable, NSError * _Nullable))completion` - returns a dictionary of unique "association keys" and ECDSA Base64 public keys -- `- (void)listUniqueAccountsWithCompletion:(void (^ _Nonnull)(NSDictionary * _Nullable, NSError * _Nullable))completion` - returns a dictionary of unique "association keys" and ECDSA Base64 public keys +- `- (void) KeyriObjC.getAssociationKeyWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - returns Base64 public key for the specified publicUserId -- `- (void)getAssociationKeyWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(NSString * _Nullable, NSError * _Nullable))completion` - returns Base64 public key for the specified publicUserId +- `- (void) KeyriObjC.removeAssociationKeyWithPublicUserId:(NSString * _Nonnull)publicUserId completion:(void (^ _Nonnull)(NSError * _Nullable))completion` - removes association public key for the specified publicUserId -- `- (void)removeAssociationKeyWithPublicUserId:(NSString * _Nonnull)publicUserId completion:(void (^ _Nonnull)(NSError * _Nullable))completion` - removes association public key for the specified publicUserId +- `- (void) KeyriObjC.initiateQrSessionWithSessionId:(NSString * _Nonnull)sessionId publicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(Session * _Nullable, NSError * _Nullable))completion` - call after obtaining the sessionId from QR-code or deep link. Returns Session object with Risk attributes (needed to show confirmation screen) or Exception -- `- (void)initiateQrSessionWithSessionId:(NSString * _Nonnull)sessionId publicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(Session * _Nullable, NSError * _Nullable))completion` - call after obtaining the sessionId from QR-code or deep link. Returns Session object with Risk attributes (needed to show confirmation screen) or Exception +- `- (void) KeyriObjC.loginWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(LoginObject * _Nullable, NSError * _Nullable))completion` - call this method to generate object for login which includes timestampNonce, signature, publicKey and userId -- `- (void)loginWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(LoginObject * _Nullable, NSError * _Nullable))completion` - call this method to generate object for login which includes timestampNonce, signature, publicKey and userId +- `- (void) KeyriObjC.registerWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(RegisterObject * _Nullable, NSError * _Nullable))completion` - call this method to generate object for register which includes publicKey and userId -- `- (void)registerWithPublicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(RegisterObject * _Nullable, NSError * _Nullable))completion` - call this method to generate object for register which includes publicKey and userId +- `- (void) KeyriObjC.getCorrectedTimestampSecondsWithCompletion:(void (^ _Nonnull)(NSInteger))completion` - call this method to get timestamp (in seconds) synchronized with NTP -- `- (void)initializeDefaultConfirmationScreenWithSession:(Session * _Nonnull)session payload:(NSString * _Nonnull)payload completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - to show Confirmation with default UI. Alternatively, you can implement a custom Confirmation Screen. The Default screen is built using SwiftUI, however the session object is designed to work seamlessly with UIKit as well should you prefer that route +- `- (void) KeyriObjC.initializeDefaultConfirmationScreenWithSession:(Session * _Nonnull)session payload:(NSString * _Nonnull)payload completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - to show Confirmation with default UI. Alternatively, you can implement a custom Confirmation Screen. The Default screen is built using SwiftUI, however the session object is designed to work seamlessly with UIKit as well should you prefer that route -- `- (void)processLinkWithUrl:(NSURL * _Nonnull)url payload:(NSString * _Nonnull)payload publicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - process flow with passed uri with showing default confirmation screen. Easiest way to process session from deeplink. Returns result of authentication or error +- `- (void) KeyriObjC.processLinkWithUrl:(NSURL * _Nonnull)url payload:(NSString * _Nonnull)payload publicUserId:(NSString * _Nullable)publicUserId completion:(void (^ _Nonnull)(BOOL, NSError * _Nullable))completion` - process flow with passed uri with showing default confirmation screen. Easiest way to process session from deeplink. Returns result of authentication or error -- `- (void)sendEventWithPublicUserId:(NSString * _Nullable)publicUserId eventType:(NSString * _Nonnull)eventType success:(BOOL)success completion:(void (^ _Nonnull)(FingerprintResponse * _Nullable, NSError * _Nullable))completion` - sends fingerprint event and event result for specified publicUserId's +- `- (void) KeyriObjC.sendEventWithPublicUserId:(NSString * _Nullable)publicUserId eventType:(NSString * _Nonnull)eventType success:(BOOL)success completion:(void (^ _Nonnull)(FingerprintResponse * _Nullable, NSError * _Nullable))completion` - sends fingerprint event and event result for specified publicUserId's -- `- (void)createFingerprintWithCompletion:(void (^ _Nonnull)(FingerprintEventRequest * _Nullable, NSError * _Nullable))completion` - creates and returns fingerprint event object +- `- (void) KeyriObjC.createFingerprintWithCompletion:(void (^ _Nonnull)(FingerprintEventRequest * _Nullable, NSError * _Nullable))completion` - creates and returns fingerprint event object ### Session Object diff --git a/pages/mobile-sdks/api-reference/react-native.mdx b/pages/mobile-sdks/api-reference/react-native.mdx index bccedc8..abf70ca 100644 --- a/pages/mobile-sdks/api-reference/react-native.mdx +++ b/pages/mobile-sdks/api-reference/react-native.mdx @@ -47,6 +47,7 @@ To handle Universal Links (e.g., for QR login straight from the user's built-in + ``` This will handle all links with the following scheme: `https://{yourCompany}.onekey.to?sessionId={sessionId}` @@ -72,6 +73,7 @@ To handle Android App Links (e.g., for QR login straight from the user's built-i + ``` This will handle all links with the following scheme: `https://{yourCompany}.onekey.to?sessionId={sessionId}` @@ -98,6 +100,7 @@ const getInitialUrl = async () => { } }; getInitialUrl(); + ``` **Note:** Keyri will create your `https://{yourCompany}.onekey.to` page automatically once you configure it in the [dashboard](https://app.keyri.com) @@ -115,7 +118,7 @@ const InitialScreen: React.FC = ({ route }) => { const sessionId: string = params?.sessionId ?? ''; const options = { sessionId: sessionId, - publicUserId: '' + publicUserId: 'example@mail.com' }; await Keyri.initiateQrSession(options); await Keyri.initializeDefaultConfirmationScreen('payload'); @@ -206,11 +209,13 @@ The following methods are available to interact with the Keyri SDK API, which ca - `register: (publicUserId?: string) => Promise` - call this method to generate object for register which includes publicKey and userId +- `getCorrectedTimestampSeconds(): Promise` - call this method to get timestamp (in seconds) synchronized with NTP + - `processLink: (options: ProcessLinkOptions) => Promise` - process flow with passed uri with showing default confirmation screen. Easiest way to process session from deeplink. Returns result of authentication or error - `initiateQrSession: (sessionId: string, publicUserId?: string) => Promise` - call it after obtaining the sessionId from QR code or deep link. Returns Session object with Risk attributes (needed to show confirmation screen) or Exception -- `initializeDefaultConfirmationScreen: (payload: string) => Promise` - to show Confirmation with default UI. Returns Boolean result. Also, you can implement your custom Confirmation Screen, just inherit from BaseConfirmationDialog.kt +- `initializeDefaultConfirmationScreen: (payload: string) => Promise` - to show Confirmation with default UI. Returns Boolean result - `confirmSession: (payload: string, trustNewBrowser?: boolean) => Promise` - call this function if user confirmed the dialog, trustNewBrowser is false by default. Returns Boolean authentication result diff --git a/pages/mobile-sdks/installation.mdx b/pages/mobile-sdks/installation.mdx index cafa551..ee694e0 100644 --- a/pages/mobile-sdks/installation.mdx +++ b/pages/mobile-sdks/installation.mdx @@ -116,38 +116,124 @@ Below are the installation instructions for each platform. ## Initialization -Initialize the Keyri object with keys from the dashboard. If you're using fraud +Initialize the Keyri object with `appKey` from the dashboard. If you're using fraud prevention, the `publicApiKey` and `serviceEncryptionKey` are required. - +Also, you can optionally configure and provide `KeyriDetectionsConfig` object with next params: + +- `blockEmulatorDetection` - set this param to false if you want to deny run your app on emulators, **true** by default. +- `blockRootDetection` - set this param to true if you want to allow running your app without rooted device check, **false** by default. +- `blockDangerousAppsDetection` - set this param to true if you want to allow running your app without dangerous apps check, **false** by default. +- `blockTamperDetection` - set this param to true if you want to allow running your app without tamper detection check, **false** by default. +- `blockSwizzleDetection` - set this param to true if you want to allow running your app without swizzle detection check, **false** by default. + + ```swift copy - public init(appKey: String, publicApiKey: String? = nil, serviceEncryptionKey: String? = nil, blockEmulatorDetection: Bool? = true) + let detectionsConfig = KeyriDetectionsConfig( + // Configure desired checks + ) + + let keyri = KeyriInterface( + appKey: String, + publicApiKey: publicApiKey, + serviceEncryptionKey: serviceEncryptionKey, + detectionsConfig: detectionsConfig // Optional + ) + + ``` + + + ```objective-c copy + KeyriDetectionsConfig *detectionsConfig = [[KeyriDetectionsConfig alloc] + // initWith... + // Configure desired checks + ]; + + KeyriObjC *keyri = [[KeyriObjC alloc] + initWithAppKey:appKey + publicApiKey:publicApiKey + serviceEncryptionKey:serviceEncryptionKey + detectionsConfig:detectionsConfig // Optional + ]; + ``` ```kotlin copy - val keyri = Keyri(this@MainActivity, appKey, publicApiKey, serviceEncryptionKey) + val detectionsConfig = KeyriDetectionsConfig( + // Configure desired checks + ) + + val keyri = Keyri( + context = context, + appKey = appKey, + publicApiKey = publicApiKey, + serviceEncryptionKey = serviceEncryptionKey, + detectionsConfig = detectionsConfig // Optional + ) + ``` ```java copy - KeyriSdk keyri = new KeyriSdk(this, appKey, publicApiKey, serviceEncryptionKey); + KeyriDetectionsConfig detectionsConfig = new KeyriDetectionsConfig( + // Configure desired checks + ); + + KeyriSdk keyri = new KeyriSdk( + this, + appKey, + publicApiKey, + serviceEncryptionKey, + detectionsConfig // Optional + ); + ``` ```javascript copy - Keyri.initialize({appKey: appKey, publicApiKey: publicApiKey,serviceEncryptionKey: serviceEncryptionKey}) + let detectionsConfig: KeyriDetectionsConfig = { + // Configure desired checks + }; + + Keyri.initialize({ + appKey: appKey, + publicApiKey: publicApiKey, + serviceEncryptionKey: serviceEncryptionKey, + detectionsConfig: detectionsConfig // Optional + }); + ``` ```dart copy - Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey, blockEmulatorDetection: true); + KeyriDetectionsConfig detectionsConfig = KeyriDetectionsConfig( + // Configure desired checks + ); + + Keyri keyri = Keyri( + appKey, + publicApiKey: publicApiKey, + serviceEncryptionKey: serviceEncryptionKey, + detectionsConfig: detectionsConfig // Optional + ); + ``` ```javascript copy - Keyri.initialize({appKey: appKey, publicApiKey: publicApiKey,serviceEncryptionKey: serviceEncryptionKey}) + let detectionsConfig: KeyriDetectionsConfig = { + // Configure desired checks + }; + + Keyri.initialize({ + appKey: appKey, + publicApiKey: publicApiKey, + serviceEncryptionKey: serviceEncryptionKey, + detectionsConfig: detectionsConfig // Optional + }); + ``` diff --git a/pages/passwordless-authentication/mobile-app-authentication.mdx b/pages/passwordless-authentication/mobile-app-authentication.mdx index 5da7bfe..e074df3 100644 --- a/pages/passwordless-authentication/mobile-app-authentication.mdx +++ b/pages/passwordless-authentication/mobile-app-authentication.mdx @@ -38,14 +38,14 @@ key. ```swift copy let keyri = KeyriInterface(appKey: appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey) -func login(username: String) async throws { let loginObject = - keyri.login(publicUserId: username) +func login(username: String) async throws { + let loginObject = keyri.login(publicUserId: username) authService.login(urlSuffix: "api/login", body: loginObject) } -func register(username: String) async throws { let registerObject = - keyri.register(publicUserId: username) +func register(username: String) async throws { + let registerObject = keyri.register(publicUserId: username) authService.register(urlSuffix: "api/register", body: registerObject) } @@ -110,11 +110,12 @@ interface AuthApiService { @Body registerObject: RegisterObject, ): Response } + ``` ```dart copy -late Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey, blockEmulatorDetection: true); +late Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey); void login(String username) { keyri.login(publicUserId: username) @@ -147,8 +148,7 @@ Future makeAuthApiCall(String urlSuffix, Map bod Keyri.initialize({ appKey: appKey, publicApiKey: publicApiKey, - serviceEncryptionKey: serviceEncryptionKey, - blockEmulatorDetection: true, + serviceEncryptionKey: serviceEncryptionKey }); const login = useCallback(async (username: string) => { @@ -173,6 +173,7 @@ function makeAuthApiCall(urlSuffix: string, body: string): Promise { body: body, }); } + ``` diff --git a/pages/passwordless-authentication/qr-authentication.mdx b/pages/passwordless-authentication/qr-authentication.mdx index 49499ec..7e91623 100644 --- a/pages/passwordless-authentication/qr-authentication.mdx +++ b/pages/passwordless-authentication/qr-authentication.mdx @@ -102,10 +102,11 @@ func qrLogin(username: String) throws { let jsonLoginObject = try JSONSerialization.data(withJSONObject: loginObject, options: .prettyPrinted) - keyri.easyKeyriAuth(payload: jsonLoginObject,publicUserId: username) { res in + keyri.easyKeyriAuth(payload: jsonLoginObject, publicUserId: username) { res in // Process result } } + ``` @@ -130,7 +131,6 @@ fun qrLogin(username: String) { appKey, publicApiKey, serviceEncryptionKey, - true, jsonLoginObject, username, ) @@ -142,7 +142,7 @@ fun qrLogin(username: String) { ```dart copy -late Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey, blockEmulatorDetection: true); +late Keyri keyri = Keyri(appKey, publicApiKey: publicApiKey, serviceEncryptionKey: serviceEncryptionKey); void qrLogin(String username) async { var loginObject = await keyri.login(publicUserId: username); @@ -153,6 +153,7 @@ void qrLogin(String username) async { // Process result }); } + ``` @@ -162,7 +163,6 @@ async function qrLogin(username: string) { appKey: KEYRI_APP_KEY, publicApiKey: KEYRI_PUBLIC_API_KEY, serviceEncryptionKey: SERVICE_ENCRYPTION_KEY, - blockEmulatorDetection: true, }); const loginObject = await Keyri.login(username); @@ -170,6 +170,7 @@ async function qrLogin(username: string) { // Process result } + ```