@octopus-community/react-native 1.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/LICENSE.md +143 -0
- package/OctopusReactNativeSdk.podspec +33 -0
- package/README.md +161 -0
- package/android/build.gradle +92 -0
- package/android/gradle.properties +9 -0
- package/android/src/main/AndroidManifest.xml +9 -0
- package/android/src/main/AndroidManifestNew.xml +8 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusEventEmitter.kt +48 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusReactNativeSdkModule.kt +73 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusReactNativeSdkPackage.kt +17 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSDKInitializer.kt +55 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSSOAuthenticator.kt +124 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIActivity.kt +71 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusUIController.kt +34 -0
- package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/ProfileFieldMapper.kt +39 -0
- package/ios/OctopusEventManager.swift +44 -0
- package/ios/OctopusReactNativeSdk-Bridging-Header.h +3 -0
- package/ios/OctopusReactNativeSdk.mm +37 -0
- package/ios/OctopusReactNativeSdk.swift +148 -0
- package/ios/OctopusSDKInitializer.swift +62 -0
- package/ios/OctopusSSOAuthenticator.swift +157 -0
- package/ios/OctopusUIManager.swift +40 -0
- package/ios/ProfileFieldMapper.swift +43 -0
- package/lib/module/addEditUserListener.js +13 -0
- package/lib/module/addEditUserListener.js.map +1 -0
- package/lib/module/addLoginRequiredListener.js +14 -0
- package/lib/module/addLoginRequiredListener.js.map +1 -0
- package/lib/module/addUserTokenRequestListener.js +26 -0
- package/lib/module/addUserTokenRequestListener.js.map +1 -0
- package/lib/module/closeUI.js +11 -0
- package/lib/module/closeUI.js.map +1 -0
- package/lib/module/connectUser.js +14 -0
- package/lib/module/connectUser.js.map +1 -0
- package/lib/module/disconnectUser.js +7 -0
- package/lib/module/disconnectUser.js.map +1 -0
- package/lib/module/enums/LogLevel.enum.js +13 -0
- package/lib/module/enums/LogLevel.enum.js.map +1 -0
- package/lib/module/index.js +15 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/initialize.js +38 -0
- package/lib/module/initialize.js.map +1 -0
- package/lib/module/internals/eventEmitter.js +6 -0
- package/lib/module/internals/eventEmitter.js.map +1 -0
- package/lib/module/internals/logger.js +42 -0
- package/lib/module/internals/logger.js.map +1 -0
- package/lib/module/internals/nativeModule.js +13 -0
- package/lib/module/internals/nativeModule.js.map +1 -0
- package/lib/module/logger.js +4 -0
- package/lib/module/logger.js.map +1 -0
- package/lib/module/openUI.js +11 -0
- package/lib/module/openUI.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types/userProfileField.js +2 -0
- package/lib/module/types/userProfileField.js.map +1 -0
- package/lib/module/useUserTokenProvider.js +33 -0
- package/lib/module/useUserTokenProvider.js.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/addEditUserListener.d.ts +14 -0
- package/lib/typescript/src/addEditUserListener.d.ts.map +1 -0
- package/lib/typescript/src/addLoginRequiredListener.d.ts +10 -0
- package/lib/typescript/src/addLoginRequiredListener.d.ts.map +1 -0
- package/lib/typescript/src/addUserTokenRequestListener.d.ts +10 -0
- package/lib/typescript/src/addUserTokenRequestListener.d.ts.map +1 -0
- package/lib/typescript/src/closeUI.d.ts +5 -0
- package/lib/typescript/src/closeUI.d.ts.map +1 -0
- package/lib/typescript/src/connectUser.d.ts +30 -0
- package/lib/typescript/src/connectUser.d.ts.map +1 -0
- package/lib/typescript/src/disconnectUser.d.ts +2 -0
- package/lib/typescript/src/disconnectUser.d.ts.map +1 -0
- package/lib/typescript/src/enums/LogLevel.enum.d.ts +10 -0
- package/lib/typescript/src/enums/LogLevel.enum.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +13 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/initialize.d.ts +50 -0
- package/lib/typescript/src/initialize.d.ts.map +1 -0
- package/lib/typescript/src/internals/eventEmitter.d.ts +3 -0
- package/lib/typescript/src/internals/eventEmitter.d.ts.map +1 -0
- package/lib/typescript/src/internals/logger.d.ts +20 -0
- package/lib/typescript/src/internals/logger.d.ts.map +1 -0
- package/lib/typescript/src/internals/nativeModule.d.ts +2 -0
- package/lib/typescript/src/internals/nativeModule.d.ts.map +1 -0
- package/lib/typescript/src/logger.d.ts +3 -0
- package/lib/typescript/src/logger.d.ts.map +1 -0
- package/lib/typescript/src/openUI.d.ts +5 -0
- package/lib/typescript/src/openUI.d.ts.map +1 -0
- package/lib/typescript/src/types/userProfileField.d.ts +14 -0
- package/lib/typescript/src/types/userProfileField.d.ts.map +1 -0
- package/lib/typescript/src/useUserTokenProvider.d.ts +17 -0
- package/lib/typescript/src/useUserTokenProvider.d.ts.map +1 -0
- package/package.json +136 -0
- package/src/addEditUserListener.ts +19 -0
- package/src/addLoginRequiredListener.ts +16 -0
- package/src/addUserTokenRequestListener.ts +32 -0
- package/src/closeUI.ts +8 -0
- package/src/connectUser.ts +34 -0
- package/src/disconnectUser.ts +5 -0
- package/src/enums/LogLevel.enum.ts +9 -0
- package/src/index.ts +12 -0
- package/src/initialize.ts +56 -0
- package/src/internals/eventEmitter.ts +4 -0
- package/src/internals/logger.ts +60 -0
- package/src/internals/nativeModule.ts +18 -0
- package/src/logger.ts +7 -0
- package/src/openUI.ts +8 -0
- package/src/types/userProfileField.ts +13 -0
- package/src/useUserTokenProvider.ts +36 -0
package/LICENSE.md
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Octopus Community Mobile SDK License Agreement
|
|
2
|
+
|
|
3
|
+
**By downloading, installing, accessing, or otherwise using the SDK, Licensee acknowledges that it has read this Agreement, understands it, and agrees to be bound by its terms.**
|
|
4
|
+
|
|
5
|
+
This Mobile SDK License Agreement (the “**Agreement**”) is entered into by and between Octopus Community SAS (“**Licensor**”) and you or the entity you represent (“**Licensee**”). By downloading, accessing, or using the Octopus Community Mobile SDK (“**SDK**”), Licensee agrees to be bound by this Agreement.
|
|
6
|
+
|
|
7
|
+
## 1. Definitions
|
|
8
|
+
|
|
9
|
+
1.1 **“API”** means the application programming interface made available by Licensor, including any accompanying or related documentation, source code, executable applications, and other materials provided by Licensor for use in conjunction with the SDK.
|
|
10
|
+
|
|
11
|
+
1.2 **“SaaS Service”** means the proprietary software-as-a-service platform provided by Licensor, which is accessed via the API.
|
|
12
|
+
|
|
13
|
+
1.3 **“Authorized Application”** means a software application developed by Licensee using the SDK solely for interacting with the SaaS Service.
|
|
14
|
+
|
|
15
|
+
1.4 **“Confidential Information”** means any information disclosed by Licensor to Licensee that is identified as confidential or proprietary, or that would otherwise reasonably be understood to be confidential in nature, including but not limited to source code, trade secrets, and non-public business information.
|
|
16
|
+
|
|
17
|
+
## 2. Grant of License
|
|
18
|
+
|
|
19
|
+
2.1 **License Grant**
|
|
20
|
+
|
|
21
|
+
Subject to Licensee’s compliance with this Agreement, Licensor grants Licensee a limited, non-exclusive, non-transferable, non-sublicensable, revocable license to:
|
|
22
|
+
|
|
23
|
+
- Download, install, and use the SDK in source or binary form **solely** to develop and test Authorized Applications that interface with and depend on Licensor’s SaaS Service via the API.
|
|
24
|
+
|
|
25
|
+
2.2 **Access to Source Code**
|
|
26
|
+
|
|
27
|
+
Licensor may provide the SDK source code for reference, debugging, and integration purposes. **This provision does not constitute an open-source license**; rather, it grants Licensee the right to view and compile the provided source code only as necessary for development of Authorized Applications in conjunction with the SaaS Service.
|
|
28
|
+
|
|
29
|
+
## 3. License Restrictions
|
|
30
|
+
|
|
31
|
+
3.1 **Permitted Use**
|
|
32
|
+
|
|
33
|
+
Licensee may use the SDK **only** to develop Authorized Applications that exclusively interact with the SaaS Service via the API. Any other use, including use with any third-party services or products, is prohibited unless expressly authorized in writing by Licensor.
|
|
34
|
+
|
|
35
|
+
3.2 **Modifications**
|
|
36
|
+
|
|
37
|
+
Licensee shall not modify, translate, adapt, arrange, or create derivative works of the SDK, in whole or in part, for any purpose other than (a) debug or integration efforts necessary for the Authorized Application to properly interface with the SaaS Service, and (b) as otherwise expressly permitted by Licensor in writing. **Under no circumstances** shall any modifications be used independently of the SaaS Service or for any other commercial or non-commercial use.
|
|
38
|
+
|
|
39
|
+
3.3 **Distribution**
|
|
40
|
+
|
|
41
|
+
Licensee may distribute the SDK (in compiled or other form) **only** as embedded or integrated in the Authorized Application, **solely** for the purpose of enabling end users to connect to and use the SaaS Service. Licensee is prohibited from redistributing the SDK as a standalone product or library.
|
|
42
|
+
|
|
43
|
+
3.4 **Prohibitions**
|
|
44
|
+
|
|
45
|
+
Licensee shall not:
|
|
46
|
+
|
|
47
|
+
- Sell, license, lease, rent, loan, resell, or otherwise distribute the SDK except as expressly set forth herein.
|
|
48
|
+
- Remove, alter, or obscure any copyright notices, trademarks, or other proprietary notices or legends from the SDK.
|
|
49
|
+
- Use the SDK in any manner that infringes, misappropriates, or violates any intellectual property, publicity, privacy, or other right of any third party.
|
|
50
|
+
- Disassemble, decompile, or reverse engineer the SDK, or attempt to discover any source code therein (except to the extent that the SDK is provided in source form or as otherwise permitted under applicable law).
|
|
51
|
+
|
|
52
|
+
3.5 **No Competitive Use**
|
|
53
|
+
|
|
54
|
+
Licensee shall not use the SDK (in whole or in part) to develop or assist in the development of any product or service that competes with Licensor’s SaaS Service or any other product or service offered by Licensor. Additionally, Licensee shall not use the SDK to replicate or replace the core functionality of the SaaS Service.
|
|
55
|
+
|
|
56
|
+
## 4. Intellectual Property Rights
|
|
57
|
+
|
|
58
|
+
4.1 **Reservation of Rights**
|
|
59
|
+
|
|
60
|
+
All rights not expressly granted in this Agreement are reserved by Licensor. Licensor retains all right, title, and interest, including all intellectual property rights, in and to the SDK, the SaaS Service, the API, and any associated documentation or materials.
|
|
61
|
+
|
|
62
|
+
4.2 **Feedback**
|
|
63
|
+
|
|
64
|
+
If Licensee provides any suggestions, feedback, or comments regarding the SDK or the SaaS Service (collectively, “**Feedback**”), Licensor shall be free to use, disclose, reproduce, license, or otherwise distribute and exploit the Feedback without any obligation or restriction, provided that such Feedback does not include Licensee’s Confidential Information.
|
|
65
|
+
|
|
66
|
+
## 5. Confidentiality
|
|
67
|
+
|
|
68
|
+
5.1 **Obligation**
|
|
69
|
+
|
|
70
|
+
Licensee shall maintain the Confidential Information in strict confidence and shall use the same standard of care used to protect its own confidential or proprietary information of a similar nature, but not less than a reasonable standard of care, to prevent unauthorized access to or disclosure of the Confidential Information.
|
|
71
|
+
|
|
72
|
+
5.2 **Exceptions**
|
|
73
|
+
|
|
74
|
+
Licensee’s obligations under Section 5.1 do not apply to information that:
|
|
75
|
+
|
|
76
|
+
- Is already known to Licensee without obligation of confidentiality.
|
|
77
|
+
- Becomes publicly available without Licensee’s breach of any obligation owed to Licensor.
|
|
78
|
+
- Is rightfully received from a third party without breach of any obligation owed to Licensor.
|
|
79
|
+
- Is independently developed by Licensee without use of or reference to the Confidential Information.
|
|
80
|
+
|
|
81
|
+
## 6. Term and Termination
|
|
82
|
+
|
|
83
|
+
6.1 **Term**
|
|
84
|
+
|
|
85
|
+
This Agreement is effective as of the Effective Date and will continue until terminated as provided herein.
|
|
86
|
+
|
|
87
|
+
6.2 **Termination by Licensor**
|
|
88
|
+
|
|
89
|
+
Licensor may terminate this Agreement immediately if Licensee breaches any provision of this Agreement and fails to cure such breach within ten (10) days after receiving written notice.
|
|
90
|
+
|
|
91
|
+
6.3 **Effect of Termination**
|
|
92
|
+
|
|
93
|
+
Upon termination of this Agreement for any reason:
|
|
94
|
+
|
|
95
|
+
- All licenses granted hereunder shall immediately terminate, and Licensee shall cease using the SDK.
|
|
96
|
+
- Licensee shall return or destroy (at Licensor’s option) all copies of the SDK, including any Confidential Information.
|
|
97
|
+
- Sections 3, 4, 5, 7, 8, and 9 shall survive termination.
|
|
98
|
+
|
|
99
|
+
## 7. Disclaimer of Warranties
|
|
100
|
+
|
|
101
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THE SDK IS PROVIDED “AS IS” AND “AS AVAILABLE,” WITH ALL FAULTS AND WITHOUT WARRANTY OF ANY KIND. LICENSOR EXPRESSLY DISCLAIMS ALL WARRANTIES, WHETHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. LICENSOR DOES NOT WARRANT THAT THE SDK OR THE SAAS SERVICE WILL MEET LICENSEE’S REQUIREMENTS, THAT THE OPERATION OF THE SDK OR THE SAAS SERVICE WILL BE UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE SDK CAN OR WILL BE CORRECTED.
|
|
102
|
+
|
|
103
|
+
## 8. Limitation of Liability
|
|
104
|
+
|
|
105
|
+
TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL LICENSOR BE LIABLE FOR ANY INDIRECT, INCIDENTAL, SPECIAL, CONSEQUENTIAL, OR EXEMPLARY DAMAGES (INCLUDING, BUT NOT LIMITED TO, DAMAGES FOR LOSS OF PROFITS, GOODWILL, OR DATA) ARISING OUT OF OR IN CONNECTION WITH THIS AGREEMENT, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN NO EVENT SHALL LICENSOR’S TOTAL CUMULATIVE LIABILITY FOR ALL CLAIMS ARISING FROM OR RELATING TO THIS AGREEMENT EXCEED THE GREATER OF (A) ONE HUNDRED U.S. DOLLARS ($100), OR (B) THE AMOUNT ACTUALLY PAID BY LICENSEE TO LICENSOR UNDER THIS AGREEMENT IN THE SIX (6) MONTH PERIOD PRECEDING THE CLAIM.
|
|
106
|
+
|
|
107
|
+
## 9. General Provisions
|
|
108
|
+
|
|
109
|
+
9.1 **Governing Law**
|
|
110
|
+
|
|
111
|
+
This Agreement shall be governed by and construed in accordance with the laws of France, without regard to its conflict-of-laws principles. Any dispute arising out of or relating to this Agreement shall be brought exclusively in the courts of France, and the parties hereby consent to the personal jurisdiction and venue therein.
|
|
112
|
+
|
|
113
|
+
9.2 **Entire Agreement**
|
|
114
|
+
|
|
115
|
+
This Agreement constitutes the entire agreement between the parties with respect to the subject matter hereof and supersedes all prior understandings and agreements, whether written or oral, regarding such subject matter.
|
|
116
|
+
|
|
117
|
+
9.3 **Amendment**
|
|
118
|
+
|
|
119
|
+
No amendment, modification, or supplement to this Agreement shall be binding unless it is in writing and signed by both parties.
|
|
120
|
+
|
|
121
|
+
9.4 **Assignment**
|
|
122
|
+
|
|
123
|
+
Licensee may not assign or transfer this Agreement, in whole or in part, without Licensor’s prior written consent. Any attempt to assign or transfer in violation of this Section shall be null and void.
|
|
124
|
+
|
|
125
|
+
9.5 **Severability**
|
|
126
|
+
|
|
127
|
+
If any provision of this Agreement is held to be invalid or unenforceable, that provision shall be deemed modified to the least extent necessary to make it valid or enforceable, and the remaining provisions of this Agreement shall remain in full force and effect.
|
|
128
|
+
|
|
129
|
+
9.6 **Waiver**
|
|
130
|
+
|
|
131
|
+
No waiver of any provision of this Agreement shall be effective unless it is in writing and signed by the party granting the waiver. The failure of Licensor to enforce any provision of this Agreement shall not be construed as a waiver of such provision or any other provision hereof.
|
|
132
|
+
|
|
133
|
+
9.7 **Independent Contractors**
|
|
134
|
+
|
|
135
|
+
The parties are independent contractors. Nothing in this Agreement shall be construed to create a partnership, joint venture, agency, or any other relationship between the parties.
|
|
136
|
+
|
|
137
|
+
9.8 **Notices**
|
|
138
|
+
|
|
139
|
+
All notices under this Agreement shall be in writing and sent to the addresses designated by the parties from time to time.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
**By downloading, installing, accessing, or otherwise using the SDK, Licensee acknowledges that it has read this Agreement, understands it, and agrees to be bound by its terms.**
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
octopus_version = '~> 1.5.1'
|
|
5
|
+
|
|
6
|
+
Pod::Spec.new do |s|
|
|
7
|
+
s.name = "OctopusReactNativeSdk"
|
|
8
|
+
s.version = package["version"]
|
|
9
|
+
s.summary = package["description"]
|
|
10
|
+
s.homepage = package["homepage"]
|
|
11
|
+
s.license = package["license"]
|
|
12
|
+
s.authors = package["author"]
|
|
13
|
+
|
|
14
|
+
s.platforms = { :ios => min_ios_version_supported }
|
|
15
|
+
s.source = { :git => "https://github.com/Octopus-Community/octopus-sdk-react-native.git", :tag => "#{s.version}" }
|
|
16
|
+
|
|
17
|
+
s.source_files = "ios/**/*.{h,m,mm,swift}"
|
|
18
|
+
|
|
19
|
+
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
|
|
20
|
+
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
|
|
21
|
+
if respond_to?(:install_modules_dependencies, true)
|
|
22
|
+
install_modules_dependencies(s)
|
|
23
|
+
else
|
|
24
|
+
s.dependency "React-Core"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
s.dependency 'OctopusCommunity', octopus_version
|
|
28
|
+
s.dependency 'OctopusCommunityUI', octopus_version
|
|
29
|
+
s.dependency 'OctopusCommunityCore', octopus_version
|
|
30
|
+
s.dependency 'OctopusCommunityRemoteClient', octopus_version
|
|
31
|
+
s.dependency 'OctopusCommunityGrpcModels', octopus_version
|
|
32
|
+
s.dependency 'OctopusCommunityDependencyInjection', octopus_version
|
|
33
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# @octopus-community/react-native
|
|
2
|
+
|
|
3
|
+
React Native module for the Octopus Community [Android](https://github.com/Octopus-Community/octopus-sdk-android) and [Swift](https://github.com/Octopus-Community/octopus-sdk-swift) SDKs
|
|
4
|
+
|
|
5
|
+
- [Installation](#installation)
|
|
6
|
+
- [iOS setup](#ios-setup)
|
|
7
|
+
- [Compatibility table](#compatibility-table)
|
|
8
|
+
- [Usage](#usage)
|
|
9
|
+
- [Initialization](#initialization)
|
|
10
|
+
- [Show the UI](#show-the-ui)
|
|
11
|
+
- [API docs](./docs/api/README.md)
|
|
12
|
+
- [Example app](./example)
|
|
13
|
+
- [Troubleshooting](#troubleshooting)
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
npm install @octopus-community/react-native
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### iOS setup
|
|
22
|
+
|
|
23
|
+
Make sure to `use_frameworks` in your `Podfile`.
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
# Podfile
|
|
27
|
+
linkage = :static # or :dynamic
|
|
28
|
+
if linkage != nil
|
|
29
|
+
Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
|
|
30
|
+
use_frameworks! :linkage => linkage.to_sym
|
|
31
|
+
end
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Due to a bug in XCode 15, you might need to set `ENABLE_USER_SCRIPT_SANDBOXING` to YES and then to NO in order to compile (see [this issue](https://github.com/CocoaPods/CocoaPods/issues/11946#issuecomment-1948423786)).
|
|
35
|
+
|
|
36
|
+
### Compatibility table
|
|
37
|
+
|
|
38
|
+
| React Native version(s) | Android | iOS | Old arch | New arch | Supporting version(s) |
|
|
39
|
+
|-------------------------| ------- |-------| -------- | ------------- | --------------------- |
|
|
40
|
+
| v0.78+ | 5.0+ | 14.0+ | ✅ | Interop layer | v1+ |
|
|
41
|
+
|
|
42
|
+
* Older React Native versions might be supported but were untested
|
|
43
|
+
* New arch is currently supported with the interoperability layer
|
|
44
|
+
* Other requirements for current version:
|
|
45
|
+
* Android
|
|
46
|
+
* Kotlin version 2
|
|
47
|
+
* iOS
|
|
48
|
+
* XCode 16.0+
|
|
49
|
+
|
|
50
|
+
### Expo
|
|
51
|
+
|
|
52
|
+
An expo plugin will be available shortly.
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
### Initialization
|
|
57
|
+
|
|
58
|
+
Initialize the SDK with your API key with [`initialize`](./docs/api/functions/initialize.md).
|
|
59
|
+
|
|
60
|
+
Choose whether your app or Octopus handles user authentification:
|
|
61
|
+
|
|
62
|
+
#### Octopus-handled authentification
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { initialize } from '@octopus-community/react-native';
|
|
66
|
+
|
|
67
|
+
await initialize({
|
|
68
|
+
apiKey: 'YOUR_OCTOPUS_API_KEY',
|
|
69
|
+
connectionMode: { type: 'octopus' }
|
|
70
|
+
});
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
#### Single Sign-On (SSO)
|
|
74
|
+
|
|
75
|
+
For SSO mode:
|
|
76
|
+
|
|
77
|
+
* your app manages user authentication and certain profile fields. You specify which profile fields your app will handle directly
|
|
78
|
+
* you need to provide a token provider function that returns a valid JWT token for the authenticated user.
|
|
79
|
+
* use the `useUserTokenProvider` hook in React components:
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
import {
|
|
83
|
+
initialize,
|
|
84
|
+
addEditUserListener,
|
|
85
|
+
addLoginRequiredListener,
|
|
86
|
+
connectUser,
|
|
87
|
+
disconnectUser,
|
|
88
|
+
useUserTokenProvider,
|
|
89
|
+
closeUI,
|
|
90
|
+
} from '@octopus-community/react-native';
|
|
91
|
+
|
|
92
|
+
// Initialize with SSO mode
|
|
93
|
+
await initialize({
|
|
94
|
+
apiKey: 'YOUR_OCTOPUS_API_KEY',
|
|
95
|
+
connectionMode: {
|
|
96
|
+
type: 'sso',
|
|
97
|
+
appManagedFields: ['username', 'profilePicture', 'biography']
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// Listen for when authentication is required
|
|
102
|
+
const loginRequiredSubscription = addLoginRequiredListener(() => {
|
|
103
|
+
// Navigate to your app's login screen
|
|
104
|
+
console.log('User needs to log in');
|
|
105
|
+
closeUI();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// Listen for when users want to edit their profile
|
|
109
|
+
const editUserSubscription = addEditUserListener(({ fieldToEdit }) => {
|
|
110
|
+
// Navigate to your app's profile editing screen
|
|
111
|
+
// for the specific field (username, profilePicture, etc.)
|
|
112
|
+
console.log(`User wants to edit: ${fieldToEdit}`);
|
|
113
|
+
closeUI();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
// Set up token provider (in a React component)
|
|
117
|
+
useUserTokenProvider(async () => {
|
|
118
|
+
const token = await refreshUserToken();
|
|
119
|
+
return token;
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
// Connect a user after they log in
|
|
123
|
+
await connectUser({
|
|
124
|
+
userId: 'unique-user-id',
|
|
125
|
+
profile: {
|
|
126
|
+
username: 'john_doe',
|
|
127
|
+
profilePicture: 'https://example.com/avatar.jpg',
|
|
128
|
+
biography: 'Software developer',
|
|
129
|
+
legalAgeReached: true,
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// Disconnect the user when they log out
|
|
134
|
+
await disconnectUser();
|
|
135
|
+
|
|
136
|
+
// Cleanup listeners when appropriate (eg. in return of a useEffect)
|
|
137
|
+
loginRequiredSubscription.remove();
|
|
138
|
+
editUserSubscription.remove();
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Show the UI
|
|
142
|
+
|
|
143
|
+
Show the Octopus home screen with the [`openUI()`](./docs/api/functions/openUI.md) method.
|
|
144
|
+
|
|
145
|
+
Future versions of this React Native module will let you show the UI in your React components. Please reach out if you need this prioritized.
|
|
146
|
+
|
|
147
|
+
### API docs
|
|
148
|
+
|
|
149
|
+
For details about the Typescript API, head to the [API docs](./docs/api/README.md).
|
|
150
|
+
|
|
151
|
+
### Example app
|
|
152
|
+
|
|
153
|
+
Take a look at our [example app](./example/src/App.tsx).
|
|
154
|
+
|
|
155
|
+
## Troubleshooting
|
|
156
|
+
|
|
157
|
+
Any error that might be intercepted by the React Native module will be rejected in the methods you call. If it cannot be intercepted, you may see the underlying SDK's logs in your native logs.
|
|
158
|
+
|
|
159
|
+
## Contributing
|
|
160
|
+
|
|
161
|
+
See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the repository and the development workflow.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.getExtOrDefault = {name ->
|
|
3
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties['OctopusReactNativeSdk_' + name]
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
repositories {
|
|
7
|
+
google()
|
|
8
|
+
mavenCentral()
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
dependencies {
|
|
12
|
+
classpath "com.android.tools.build:gradle:8.7.2"
|
|
13
|
+
// noinspection DifferentKotlinGradleVersion
|
|
14
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
15
|
+
classpath "org.jetbrains.kotlin:compose-compiler-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
apply plugin: "com.android.library"
|
|
20
|
+
apply plugin: "kotlin-android"
|
|
21
|
+
apply plugin: "org.jetbrains.kotlin.plugin.compose"
|
|
22
|
+
|
|
23
|
+
def getExtOrIntegerDefault(name) {
|
|
24
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["OctopusReactNativeSdk_" + name]).toInteger()
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
def supportsNamespace() {
|
|
28
|
+
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
|
29
|
+
def major = parsed[0].toInteger()
|
|
30
|
+
def minor = parsed[1].toInteger()
|
|
31
|
+
|
|
32
|
+
// Namespace support was added in 7.3.0
|
|
33
|
+
return (major == 7 && minor >= 3) || major >= 8
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
android {
|
|
37
|
+
if (supportsNamespace()) {
|
|
38
|
+
namespace "com.octopuscommunity.octopusreactnativesdk"
|
|
39
|
+
|
|
40
|
+
sourceSets {
|
|
41
|
+
main {
|
|
42
|
+
manifest.srcFile "src/main/AndroidManifestNew.xml"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
48
|
+
|
|
49
|
+
defaultConfig {
|
|
50
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
51
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
buildTypes {
|
|
55
|
+
release {
|
|
56
|
+
minifyEnabled false
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
lintOptions {
|
|
61
|
+
disable "GradleCompatible"
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
buildFeatures {
|
|
65
|
+
compose true
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
compileOptions {
|
|
69
|
+
sourceCompatibility JavaVersion.VERSION_1_8
|
|
70
|
+
targetCompatibility JavaVersion.VERSION_1_8
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
repositories {
|
|
75
|
+
mavenCentral()
|
|
76
|
+
google()
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
def kotlin_version = getExtOrDefault("kotlinVersion")
|
|
80
|
+
def octopus_community_version = getExtOrDefault("octopusCommunityVersion")
|
|
81
|
+
def compose_bom_version = getExtOrDefault("composeBomVersion")
|
|
82
|
+
def android_x_navigation_version = getExtOrDefault("androidXNavigationVersion")
|
|
83
|
+
|
|
84
|
+
dependencies {
|
|
85
|
+
implementation "com.facebook.react:react-android"
|
|
86
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
87
|
+
implementation platform("androidx.compose:compose-bom:$compose_bom_version")
|
|
88
|
+
implementation "androidx.navigation:navigation-compose:$android_x_navigation_version"
|
|
89
|
+
|
|
90
|
+
api "com.octopuscommunity:octopus-sdk:$octopus_community_version"
|
|
91
|
+
api "com.octopuscommunity:octopus-sdk-ui:$octopus_community_version"
|
|
92
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
OctopusReactNativeSdk_kotlinVersion=2.1.10
|
|
2
|
+
OctopusReactNativeSdk_minSdkVersion=24
|
|
3
|
+
OctopusReactNativeSdk_targetSdkVersion=34
|
|
4
|
+
OctopusReactNativeSdk_compileSdkVersion=35
|
|
5
|
+
OctopusReactNativeSdk_ndkVersion=27.1.12297006
|
|
6
|
+
OctopusReactNativeSdk_composeBomVersion=2025.06.01
|
|
7
|
+
OctopusReactNativeSdk_androidXNavigationVersion=2.9.0
|
|
8
|
+
|
|
9
|
+
OctopusReactNativeSdk_octopusCommunityVersion=1.5.0
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
package="com.octopuscommunity.octopusreactnativesdk">
|
|
3
|
+
<application>
|
|
4
|
+
<activity
|
|
5
|
+
android:name=".OctopusUIActivity"
|
|
6
|
+
android:exported="false"
|
|
7
|
+
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"/>
|
|
8
|
+
</application>
|
|
9
|
+
</manifest>
|
package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusEventEmitter.kt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
package com.octopuscommunity.octopusreactnativesdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Arguments
|
|
4
|
+
import com.facebook.react.bridge.ReactContext
|
|
5
|
+
import com.facebook.react.bridge.WritableMap
|
|
6
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
7
|
+
import com.octopuscommunity.sdk.domain.model.ProfileField
|
|
8
|
+
|
|
9
|
+
class OctopusEventEmitter(private val reactContext: ReactContext) {
|
|
10
|
+
|
|
11
|
+
private var listenerCount = 0
|
|
12
|
+
|
|
13
|
+
fun addListener(eventName: String) {
|
|
14
|
+
listenerCount += 1
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
fun removeListeners(count: Int) {
|
|
18
|
+
listenerCount -= count
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fun emitLoginRequired() {
|
|
22
|
+
sendEvent("loginRequired", null)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
fun emitEditUser(profileField: ProfileField?) {
|
|
26
|
+
val params = Arguments.createMap()
|
|
27
|
+
params.putString("fieldToEdit", ProfileFieldMapper.toReactNativeString(profileField))
|
|
28
|
+
sendEvent("editUser", params)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fun emitUserTokenRequest(requestId: String) {
|
|
32
|
+
val params = Arguments.createMap()
|
|
33
|
+
params.putString("requestId", requestId)
|
|
34
|
+
sendEvent("userTokenRequest", params)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
private fun sendEvent(eventName: String, params: WritableMap?) {
|
|
38
|
+
if (listenerCount > 0) {
|
|
39
|
+
reactContext
|
|
40
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
41
|
+
.emit(eventName, params)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
companion object {
|
|
46
|
+
var instance: OctopusEventEmitter? = null
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
package com.octopuscommunity.octopusreactnativesdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
4
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
5
|
+
import com.facebook.react.bridge.ReactMethod
|
|
6
|
+
import com.facebook.react.bridge.Promise
|
|
7
|
+
import com.facebook.react.bridge.ReadableMap
|
|
8
|
+
|
|
9
|
+
class OctopusReactNativeSdkModule(reactContext: ReactApplicationContext) :
|
|
10
|
+
ReactContextBaseJavaModule(reactContext) {
|
|
11
|
+
|
|
12
|
+
private val sdkInitializer = OctopusSDKInitializer()
|
|
13
|
+
private val eventEmitter = OctopusEventEmitter(reactContext)
|
|
14
|
+
private val uiController = OctopusUIController(reactContext)
|
|
15
|
+
private val ssoAuthenticator = OctopusSSOAuthenticator(eventEmitter)
|
|
16
|
+
|
|
17
|
+
override fun getName(): String = NAME
|
|
18
|
+
|
|
19
|
+
@ReactMethod
|
|
20
|
+
fun initialize(options: ReadableMap, promise: Promise) {
|
|
21
|
+
sdkInitializer.initialize(reactApplicationContext, options, promise)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@ReactMethod
|
|
25
|
+
fun openUI(promise: Promise) {
|
|
26
|
+
uiController.openUI(promise)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@ReactMethod
|
|
30
|
+
fun closeUI(promise: Promise) {
|
|
31
|
+
uiController.closeUI(promise)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
@ReactMethod
|
|
35
|
+
fun connectUser(params: ReadableMap, promise: Promise) {
|
|
36
|
+
ssoAuthenticator.connectUser(params, promise)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
@ReactMethod
|
|
40
|
+
fun disconnectUser(promise: Promise) {
|
|
41
|
+
ssoAuthenticator.disconnectUser(promise)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
@ReactMethod
|
|
45
|
+
fun completeUserTokenRequest(requestId: String, token: String, promise: Promise) {
|
|
46
|
+
ssoAuthenticator.completeTokenRequest(requestId, token)
|
|
47
|
+
promise.resolve(null)
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
@ReactMethod
|
|
51
|
+
fun cancelUserTokenRequest(requestId: String, promise: Promise) {
|
|
52
|
+
ssoAuthenticator.cancelTokenRequest(requestId)
|
|
53
|
+
promise.resolve(null)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
@ReactMethod
|
|
57
|
+
fun addListener(eventName: String) {
|
|
58
|
+
eventEmitter.addListener(eventName)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactMethod
|
|
62
|
+
fun removeListeners(count: Int) {
|
|
63
|
+
eventEmitter.removeListeners(count)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
companion object {
|
|
67
|
+
const val NAME = "OctopusReactNativeSdk"
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
init {
|
|
71
|
+
OctopusEventEmitter.instance = eventEmitter
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.octopuscommunity.octopusreactnativesdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OctopusReactNativeSdkPackage : ReactPackage {
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
+
return listOf(OctopusReactNativeSdkModule(reactContext))
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
+
return emptyList()
|
|
16
|
+
}
|
|
17
|
+
}
|
package/android/src/main/java/com/octopuscommunity/octopusreactnativesdk/OctopusSDKInitializer.kt
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
package com.octopuscommunity.octopusreactnativesdk
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.ReadableMap
|
|
6
|
+
import com.octopuscommunity.sdk.OctopusSDK
|
|
7
|
+
import com.octopuscommunity.sdk.domain.model.ConnectionMode
|
|
8
|
+
|
|
9
|
+
class OctopusSDKInitializer {
|
|
10
|
+
|
|
11
|
+
fun initialize(context: ReactApplicationContext, options: ReadableMap, promise: Promise) {
|
|
12
|
+
val apiKey = options.getString("apiKey")
|
|
13
|
+
if (apiKey == null) {
|
|
14
|
+
promise.reject("INITIALIZE_ERROR", "Missing API key")
|
|
15
|
+
return
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
val connectionMode = parseConnectionMode(options)
|
|
20
|
+
OctopusSDK.initialize(
|
|
21
|
+
context = context,
|
|
22
|
+
apiKey = apiKey,
|
|
23
|
+
connectionMode = connectionMode
|
|
24
|
+
)
|
|
25
|
+
promise.resolve(null)
|
|
26
|
+
} catch (e: InvalidConnectionModeException) {
|
|
27
|
+
promise.reject("INITIALIZE_ERROR", e.message, e)
|
|
28
|
+
} catch (e: Exception) {
|
|
29
|
+
promise.reject("INITIALIZE_ERROR", "Failed to initialize Octopus SDK", e)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private fun parseConnectionMode(options: ReadableMap): ConnectionMode {
|
|
34
|
+
val connectionModeMap = options.getMap("connectionMode")
|
|
35
|
+
return when (val connectionModeType = connectionModeMap?.getString("type")) {
|
|
36
|
+
"sso" -> {
|
|
37
|
+
ConnectionMode.SSO(
|
|
38
|
+
appManagedFields = ProfileFieldMapper.fromReactNativeArray(
|
|
39
|
+
connectionModeMap.getArray("appManagedFields")
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
"octopus" -> {
|
|
45
|
+
ConnectionMode.Octopus
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
else -> {
|
|
49
|
+
throw InvalidConnectionModeException("Invalid connection mode type: $connectionModeType")
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
private class InvalidConnectionModeException(message: String) : Exception(message)
|
|
55
|
+
}
|