diff --git a/ios/AuthsignalPasskeyModule.m b/ios/AuthsignalPasskeyModule.m index 9f0a8e0..57dce6b 100644 --- a/ios/AuthsignalPasskeyModule.m +++ b/ios/AuthsignalPasskeyModule.m @@ -17,6 +17,7 @@ @interface RCT_EXTERN_MODULE(AuthsignalPasskeyModule, NSObject) RCT_EXTERN_METHOD(signIn:(NSString)action withToken:(NSString)token withAutofill:(BOOL)autofill + withPreferImmediatelyAvailableCredentials:(BOOL)preferImmediatelyAvailableCredentials resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) diff --git a/ios/AuthsignalPasskeyModule.swift b/ios/AuthsignalPasskeyModule.swift index 8ba3510..4be4296 100644 --- a/ios/AuthsignalPasskeyModule.swift +++ b/ios/AuthsignalPasskeyModule.swift @@ -41,7 +41,7 @@ class AuthsignalPasskeyModule: NSObject { let response = await authsignal!.signUp(token: tokenStr, userName: userNameStr, displayName: displayNameStr) if (response.error != nil) { - reject("signUp error", response.error, nil) + reject("signUpError", response.error, nil) } else { let signUpResponse: [String: String?] = [ "token": response.data!.token, @@ -56,6 +56,7 @@ class AuthsignalPasskeyModule: NSObject { _ action: NSString?, withToken token: NSString?, withAutofill autofill: Bool, + withPreferImmediatelyAvailableCredentials preferImmediatelyAvailableCredentials: Bool, resolver resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock ) -> Void { @@ -68,10 +69,17 @@ class AuthsignalPasskeyModule: NSObject { let tokenStr = token as String? Task.init { - let response = await authsignal!.signIn(token: tokenStr, action: actionStr, autofill: autofill) + let response = await authsignal!.signIn( + token: tokenStr, + action: actionStr, + autofill: autofill, + preferImmediatelyAvailableCredentials: preferImmediatelyAvailableCredentials + ) - if (response.error != nil) { - reject("signIn error", response.error, nil) + if (response.errorCode == .canceled) { + reject("signInCanceled", "SIGN_IN_CANCELED", nil) + } else if (response.error != nil) { + reject("signInError", response.error, nil) } else { let signInResponse: [String: Any?] = [ "isVerified": response.data!.isVerified, diff --git a/package.json b/package.json index 271cdd0..48e9278 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-native-authsignal", - "version": "0.4.2", + "version": "0.4.3", "description": "The official Authsignal React Native library.", "main": "lib/commonjs/index", "module": "lib/module/index", diff --git a/react-native-authsignal.podspec b/react-native-authsignal.podspec index 8c91a8d..146323b 100644 --- a/react-native-authsignal.podspec +++ b/react-native-authsignal.podspec @@ -17,7 +17,7 @@ Pod::Spec.new do |s| s.source_files = "ios/**/*.{h,m,mm,swift}" s.dependency "React-Core" - s.dependency 'Authsignal', '0.3.0' + s.dependency 'Authsignal', '0.3.1' # Don't install the dependencies when we run `pod install` in the old architecture. if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then diff --git a/src/error.ts b/src/error.ts index 6b94b1f..6b817c0 100644 --- a/src/error.ts +++ b/src/error.ts @@ -5,3 +5,7 @@ export const LINKING_ERROR = Platform.select({ ios: "- You have run 'pod install'\n", default: '' }) + '- You rebuilt the app after installing the package\n' + '- You are not using Expo Go\n'; + +export enum ErrorCode { + passkeySignInCanceled = 'passkeySignInCanceled', +} diff --git a/src/index.tsx b/src/index.tsx index c1c1c32..7904474 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -4,6 +4,7 @@ import { AuthsignalPasskey } from './passkey'; import { AuthsignalPush } from './push'; export * from './types'; +export { ErrorCode } from './error'; const AuthsignalModule = NativeModules.AuthsignalModule ? NativeModules.AuthsignalModule diff --git a/src/passkey.ts b/src/passkey.ts index c81e6f0..2f62c1f 100644 --- a/src/passkey.ts +++ b/src/passkey.ts @@ -1,5 +1,5 @@ import { NativeModules, Platform } from 'react-native'; -import { LINKING_ERROR } from './error'; +import { LINKING_ERROR, ErrorCode } from './error'; import type { AuthsignalResponse, SignInResponse, @@ -22,6 +22,7 @@ interface PasskeySignInInput { action?: string; token?: string; autofill?: boolean; + preferImmediatelyAvailableCredentials?: boolean; } let initialized = false; @@ -81,6 +82,7 @@ export class AuthsignalPasskey { action, token, autofill = false, + preferImmediatelyAvailableCredentials = true, }: PasskeySignInInput = {}): Promise> { await this.ensureModuleIsInitialized(); @@ -97,7 +99,8 @@ export class AuthsignalPasskey { const data = await AuthsignalPasskeyModule.signIn( action, token, - autofill + autofill, + preferImmediatelyAvailableCredentials ); autofillRequestPending = false; @@ -118,7 +121,12 @@ export class AuthsignalPasskey { autofillRequestPending = false; if (ex instanceof Error) { - return { error: ex.message }; + return ex.message === 'SIGN_IN_CANCELED' + ? { + errorCode: ErrorCode.passkeySignInCanceled, + error: 'Passkey sign-in canceled', + } + : { error: ex.message }; } throw ex; diff --git a/src/types.ts b/src/types.ts index a8d3386..c6620f3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,6 +1,9 @@ +import { ErrorCode } from './error'; + export interface AuthsignalResponse { data?: T; error?: string; + errorCode?: ErrorCode; } export interface TokenPayload {