otpless-headless-rn 2.2.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "otpless-headless-rn",
3
- "version": "2.2.0",
3
+ "version": "3.0.0",
4
4
  "description": "react native plugin for otpless headless android and ios",
5
5
  "main": "lib/commonjs/index",
6
6
  "module": "lib/module/index",
@@ -41,7 +41,10 @@
41
41
  "ios",
42
42
  "android"
43
43
  ],
44
- "repository": "https://github.com/otpless-tech/react-native-headless-sdk",
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/otpless-tech/react-native-headless-sdk.git"
47
+ },
45
48
  "author": "https://github.com/sparsh-otpless",
46
49
  "license": "MIT",
47
50
  "bugs": {
package/src/index.tsx CHANGED
@@ -3,7 +3,11 @@ import type {
3
3
  OtplessTruecallerRequest,
4
4
  OtplessAuthEvent,
5
5
  OtplessProviderType,
6
+ OtplessRequestInput,
7
+ OtplessBackgroundAuthConfig,
8
+ OtplessInitOptions,
6
9
  } from './models';
10
+ import { otplessRnVersion } from './version';
7
11
 
8
12
  const LINKING_ERROR =
9
13
  `The package 'otpless-headless-rn' doesn't seem to be linked. Make sure: \n\n` +
@@ -22,6 +26,23 @@ const OtplessHeadlessRN = NativeModules.OtplessHeadlessRN
22
26
  }
23
27
  );
24
28
 
29
+ /**
30
+ * Wrapper-attribution token sent to the native SDKs at `initialize`.
31
+ *
32
+ * Computed here, in JS, so `otplessRnVersion` is the single source of truth:
33
+ * the Kotlin and Swift bridges only forward whatever arrives over the bridge,
34
+ * instead of each hardcoding a version that would drift on every release.
35
+ *
36
+ * Emitted by the native device-telemetry event as:
37
+ * - Android - `otpless-headless-sdk(react-native-android-<version>)`
38
+ * - iOS - `otpless-headless(react-native-ios-<version>)`
39
+ *
40
+ * The `react-native-` prefix distinguishes this package from the sibling
41
+ * wrappers (`react-native-lite-*`, `react-native-turbo-*`), which share the
42
+ * same iOS telemetry prefix.
43
+ */
44
+ const BUILD_PLATFORM = `react-native-${Platform.OS}-${otplessRnVersion}`;
45
+
25
46
  interface OtplessResultCallback {
26
47
  (result: any): void;
27
48
  }
@@ -37,19 +58,31 @@ class OtplessHeadlessModule {
37
58
  this.eventEmitter?.removeAllListeners('OTPlessEventResult');
38
59
  }
39
60
 
40
- initialize(appId: String, loginUri: string | null = null) {
61
+ initialize(
62
+ appId: string,
63
+ loginUri: string | null = null,
64
+ options: OtplessInitOptions | null = null
65
+ ) {
41
66
  if (this.eventEmitter == null) {
42
67
  this.eventEmitter = new NativeEventEmitter(OtplessHeadlessRN);
43
68
  }
44
- // call the native method
45
- OtplessHeadlessRN.initialize(appId, loginUri);
69
+ // call the native method; sslPinning is a plain string so an older
70
+ // native module degrades to pinning disabled. buildPlatform is internal
71
+ // wrapper attribution, not a merchant-facing parameter; the native bridges
72
+ // fall back to a bare "react-native-<platform>" if it ever arrives blank.
73
+ OtplessHeadlessRN.initialize(
74
+ appId,
75
+ loginUri,
76
+ options?.sslPinning ?? 'disabled',
77
+ BUILD_PLATFORM
78
+ );
46
79
  }
47
80
 
48
81
  setResponseCallback(callback: OtplessResultCallback) {
49
82
  this.eventEmitter?.addListener('OTPlessEventResult', callback);
50
83
  }
51
84
 
52
- start(input: any) {
85
+ start(input: OtplessRequestInput) {
53
86
  OtplessHeadlessRN.start(input);
54
87
  }
55
88
 
@@ -81,6 +114,41 @@ class OtplessHeadlessModule {
81
114
  OtplessHeadlessRN.setDevLogging(enable);
82
115
  }
83
116
 
117
+ setMfaEnabled(enabled: boolean) {
118
+ OtplessHeadlessRN.setMfaEnabled(enabled);
119
+ }
120
+
121
+ async startBackgroundAuth(
122
+ config: OtplessBackgroundAuthConfig
123
+ ): Promise<boolean> {
124
+ return await OtplessHeadlessRN.startBackgroundAuth(config);
125
+ }
126
+
127
+ startInBackground(input: OtplessRequestInput) {
128
+ if (Platform.OS === 'android') {
129
+ OtplessHeadlessRN.startInBackground(input);
130
+ }
131
+ }
132
+
133
+ setSimBindingEnabled(enabled: boolean) {
134
+ if (Platform.OS === 'android') {
135
+ OtplessHeadlessRN.setSimBindingEnabled(enabled);
136
+ }
137
+ }
138
+
139
+ async checkSimBindingStatus(): Promise<boolean> {
140
+ if (Platform.OS === 'android') {
141
+ return await OtplessHeadlessRN.checkSimBindingStatus();
142
+ }
143
+ return false;
144
+ }
145
+
146
+ async clearSimBinding(): Promise<void> {
147
+ if (Platform.OS === 'android') {
148
+ await OtplessHeadlessRN.clearSimBinding();
149
+ }
150
+ }
151
+
84
152
  async isSdkReady(): Promise<boolean> {
85
153
  return await OtplessHeadlessRN.isSdkReady();
86
154
  }
@@ -92,22 +160,18 @@ class OtplessHeadlessModule {
92
160
  return false;
93
161
  }
94
162
 
95
- // Android only — OtplessBM (iOS) has no equivalent.
96
163
  userAuthEvent(
97
164
  event: OtplessAuthEvent,
98
165
  providerType: OtplessProviderType,
99
166
  fallback: boolean = false,
100
- providerInfo: any = {} // `any` avoids Record<string,string> conflicts across RN versions
167
+ providerInfo: any = {}
101
168
  ) {
102
- if (Platform.OS === 'android') {
103
- // args reordered to match Kotlin bridge: (event, fallback, providerType, providerInfo)
104
- OtplessHeadlessRN.userAuthEvent(
105
- event,
106
- fallback,
107
- providerType,
108
- providerInfo
109
- );
110
- }
169
+ OtplessHeadlessRN.userAuthEvent(
170
+ event,
171
+ fallback,
172
+ providerType,
173
+ providerInfo
174
+ );
111
175
  }
112
176
  }
113
177
 
package/src/models.tsx CHANGED
@@ -1,10 +1,8 @@
1
-
2
1
  export interface OtplessTruecallerRequest {
3
- trueCallerRequest?: OtplessTruecallerConfig;
4
- scope: Array<OTScope>;
2
+ trueCallerRequest?: OtplessTruecallerConfig;
3
+ scope: Array<OTScope>;
5
4
  }
6
5
 
7
-
8
6
  export interface OtplessTruecallerConfig {
9
7
  footerType?: OTFooterType;
10
8
  shape?: OTButtonShape;
@@ -17,78 +15,142 @@ export interface OtplessTruecallerConfig {
17
15
  buttonTextColor?: number;
18
16
  }
19
17
 
20
- export type OTScope = "profile" | "phone" | "open_id" | "offline_access" | "email" | "address";
18
+ export type OTScope =
19
+ | 'profile'
20
+ | 'phone'
21
+ | 'open_id'
22
+ | 'offline_access'
23
+ | 'email'
24
+ | 'address';
21
25
 
22
26
  export type OTFooterType =
23
- | 'footer_type_skip'
24
- | 'footer_type_another_mobile_no'
25
- | 'footer_type_another_method'
26
- | 'footer_type_manually'
27
- | 'footer_type_later';
28
-
29
- export type OTButtonShape =
30
- | 'button_shape_rounded'
31
- | 'button_shape_rectangle';
27
+ | 'footer_type_skip'
28
+ | 'footer_type_another_mobile_no'
29
+ | 'footer_type_another_method'
30
+ | 'footer_type_manually'
31
+ | 'footer_type_later';
32
32
 
33
+ export type OTButtonShape = 'button_shape_rounded' | 'button_shape_rectangle';
33
34
 
34
35
  export type OTVerifyOption =
35
- | 'option_verify_only_tc_users'
36
- | 'option_verify_all_users';
37
-
36
+ | 'option_verify_only_tc_users'
37
+ | 'option_verify_all_users';
38
38
 
39
39
  export type OTHeadingConsent =
40
- | 'sdk_consent_heading_log_in_to'
41
- | 'sdk_consent_heading_sign_up_with'
42
- | 'sdk_consent_heading_sign_in_to'
43
- | 'sdk_consent_heading_verify_number_with'
44
- | 'sdk_consent_heading_register_with'
45
- | 'sdk_consent_heading_get_started_with'
46
- | 'sdk_consent_heading_proceed_with'
47
- | 'sdk_consent_heading_verify_with'
48
- | 'sdk_consent_heading_verify_profile_with'
49
- | 'sdk_consent_heading_verify_your_profile_with'
50
- | 'sdk_consent_heading_verify_phone_no_with'
51
- | 'sdk_consent_heading_verify_your_no_with'
52
- | 'sdk_consent_heading_continue_with'
53
- | 'sdk_consent_heading_complete_order_with'
54
- | 'sdk_consent_heading_place_order_with'
55
- | 'sdk_consent_heading_complete_booking_with'
56
- | 'sdk_consent_heading_checkout_with'
57
- | 'sdk_consent_heading_manage_details_with'
58
- | 'sdk_consent_heading_manage_your_details_with'
59
- | 'sdk_consent_heading_login_to_with_one_tap'
60
- | 'sdk_consent_heading_subscribe_to'
61
- | 'sdk_consent_heading_get_updates_from'
62
- | 'sdk_consent_heading_continue_reading_on'
63
- | 'sdk_consent_heading_get_new_updates_from'
64
- | 'sdk_consent_heading_login_signup_with';
65
-
40
+ | 'sdk_consent_heading_log_in_to'
41
+ | 'sdk_consent_heading_sign_up_with'
42
+ | 'sdk_consent_heading_sign_in_to'
43
+ | 'sdk_consent_heading_verify_number_with'
44
+ | 'sdk_consent_heading_register_with'
45
+ | 'sdk_consent_heading_get_started_with'
46
+ | 'sdk_consent_heading_proceed_with'
47
+ | 'sdk_consent_heading_verify_with'
48
+ | 'sdk_consent_heading_verify_profile_with'
49
+ | 'sdk_consent_heading_verify_your_profile_with'
50
+ | 'sdk_consent_heading_verify_phone_no_with'
51
+ | 'sdk_consent_heading_verify_your_no_with'
52
+ | 'sdk_consent_heading_continue_with'
53
+ | 'sdk_consent_heading_complete_order_with'
54
+ | 'sdk_consent_heading_place_order_with'
55
+ | 'sdk_consent_heading_complete_booking_with'
56
+ | 'sdk_consent_heading_checkout_with'
57
+ | 'sdk_consent_heading_manage_details_with'
58
+ | 'sdk_consent_heading_manage_your_details_with'
59
+ | 'sdk_consent_heading_login_to_with_one_tap'
60
+ | 'sdk_consent_heading_subscribe_to'
61
+ | 'sdk_consent_heading_get_updates_from'
62
+ | 'sdk_consent_heading_continue_reading_on'
63
+ | 'sdk_consent_heading_get_new_updates_from'
64
+ | 'sdk_consent_heading_login_signup_with';
66
65
 
67
66
  export type OTLoginPrefixText =
68
- | 'login_text_prefix_to_get_started'
69
- | 'login_text_prefix_to_continue'
70
- | 'login_text_prefix_to_place_order'
71
- | 'login_text_prefix_to_complete_your_purchase'
72
- | 'login_text_prefix_to_checkout'
73
- | 'login_text_prefix_to_complete_your_booking'
74
- | 'login_text_prefix_to_proceed_with_your_booking'
75
- | 'login_text_prefix_to_continue_with_your_booking'
76
- | 'login_text_prefix_to_get_details'
77
- | 'login_text_prefix_to_view_more'
78
- | 'login_text_prefix_to_continue_reading'
79
- | 'login_text_prefix_to_proceed'
80
- | 'login_text_prefix_for_new_updates'
81
- | 'login_text_prefix_to_get_updates'
82
- | 'login_text_prefix_to_subscribe'
83
- | 'login_text_prefix_to_subscribe_and_get_updates';
84
-
67
+ | 'login_text_prefix_to_get_started'
68
+ | 'login_text_prefix_to_continue'
69
+ | 'login_text_prefix_to_place_order'
70
+ | 'login_text_prefix_to_complete_your_purchase'
71
+ | 'login_text_prefix_to_checkout'
72
+ | 'login_text_prefix_to_complete_your_booking'
73
+ | 'login_text_prefix_to_proceed_with_your_booking'
74
+ | 'login_text_prefix_to_continue_with_your_booking'
75
+ | 'login_text_prefix_to_get_details'
76
+ | 'login_text_prefix_to_view_more'
77
+ | 'login_text_prefix_to_continue_reading'
78
+ | 'login_text_prefix_to_proceed'
79
+ | 'login_text_prefix_for_new_updates'
80
+ | 'login_text_prefix_to_get_updates'
81
+ | 'login_text_prefix_to_subscribe'
82
+ | 'login_text_prefix_to_subscribe_and_get_updates';
85
83
 
86
84
  export type OTCtaText =
87
- | 'cta_text_proceed'
88
- | 'cta_text_continue'
89
- | 'cta_text_accept'
90
- | 'cta_text_confirm';
85
+ | 'cta_text_proceed'
86
+ | 'cta_text_continue'
87
+ | 'cta_text_accept'
88
+ | 'cta_text_confirm';
91
89
 
92
- export type OtplessAuthEvent = 'AUTH_INITIATED' | 'AUTH_SUCCESS' | 'AUTH_FAILED';
90
+ export type OtplessAuthEvent =
91
+ | 'AUTH_INITIATED'
92
+ | 'AUTH_SUCCESS'
93
+ | 'AUTH_FAILED';
93
94
 
94
95
  export type OtplessProviderType = 'CLIENT' | 'OTPLESS';
96
+
97
+ export interface OtplessRequestInput {
98
+ phone?: string;
99
+ /** Required together with `phone`. */
100
+ countryCode?: string;
101
+ email?: string;
102
+ channelType?: OtplessChannelType;
103
+ otp?: string;
104
+ expiry?: string;
105
+ otpLength?: string;
106
+ deliveryChannel?: string;
107
+ tid?: string;
108
+ /** Backend-generated or WebAuthn request ID. */
109
+ requestId?: string;
110
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
111
+ }
112
+
113
+ export interface OtplessBackgroundAuthConfig {
114
+ /** Defaults to `true` — presents the OneTap bottom sheet. `false` runs in background when possible. */
115
+ isForeground?: boolean;
116
+ otp?: string;
117
+ tid?: string;
118
+ deviceFingerprintMode?: OtplessDeviceFingerprintMode;
119
+ }
120
+
121
+ export type OtplessChannelType =
122
+ | 'WHATSAPP'
123
+ | 'GOOGLE_SDK'
124
+ | 'FACEBOOK_SDK'
125
+ | 'APPLE'
126
+ | 'APPLE_SDK'
127
+ | 'GMAIL'
128
+ | 'TWITTER'
129
+ | 'DISCORD'
130
+ | 'SLACK'
131
+ | 'FACEBOOK'
132
+ | 'LINKEDIN'
133
+ | 'MICROSOFT'
134
+ | 'LINE'
135
+ | 'LINEAR'
136
+ | 'NOTION'
137
+ | 'TWITCH'
138
+ | 'GITHUB'
139
+ | 'BITBUCKET'
140
+ | 'ATLASSIAN'
141
+ | 'GITLAB'
142
+ | 'TRUE_CALLER';
143
+
144
+ export type OtplessDeviceFingerprintMode = 'NONE' | 'ASYNC' | 'SYNC';
145
+
146
+ /**
147
+ * SSL pinning mode for `initialize`. `'disabled'` (default) keeps the
148
+ * 2.3.x behaviour. `'enabled'` pins `sigma.otpless.app`; a pin mismatch
149
+ * (e.g. an intercepting proxy) fails closed with `FAILED` / statusCode `5004`.
150
+ */
151
+ export type OtplessSslPinning = 'enabled' | 'disabled';
152
+
153
+ export interface OtplessInitOptions {
154
+ /** Defaults to `'disabled'`. */
155
+ sslPinning?: OtplessSslPinning;
156
+ }
package/src/version.ts ADDED
@@ -0,0 +1,17 @@
1
+ /**
2
+ * This package's own version, kept in lock-step with `version` in
3
+ * `package.json`.
4
+ *
5
+ * Internal only: this module is deliberately **not** re-exported from
6
+ * `src/index.tsx` (which exports `OtplessHeadlessModule` and `./models`), so it
7
+ * never becomes merchant-facing API. It exists so the wrapper-attribution token
8
+ * sent to the native SDKs at `initialize`
9
+ * (`react-native-android-<version>` / `react-native-ios-<version>`) has a
10
+ * single source of truth in TypeScript instead of being duplicated in Kotlin
11
+ * and Swift, where it would silently drift on every release.
12
+ *
13
+ * `src/__tests__/version.test.ts` reads `package.json` and fails if this
14
+ * constant falls out of sync, so a forgotten bump breaks CI rather than
15
+ * shipping a wrong token.
16
+ */
17
+ export const otplessRnVersion = '3.0.0';