@pyrocancode/react-native-vk-auth 0.4.1 → 1.0.1
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/README.md +103 -137
- package/android/build.gradle +7 -11
- package/android/src/main/java/com/vkauth/VkAuthModule.kt +18 -16
- package/android/src/main/java/com/vkauth/VkAuthPackage.kt +10 -5
- package/android/src/main/java/com/vkauth/vkid/AuthDelegate.kt +92 -84
- package/android/src/main/java/com/vkauth/vkid/InitDelegate.kt +8 -2
- package/android/src/main/java/com/vkauth/vkid/VkAuthPayload.kt +61 -0
- package/android/src/main/java/com/vkauth/vkid/VkAuthServiceHolder.kt +8 -0
- package/android/src/main/java/com/vkauth/vkid/onetapbutton/OneTapButtonManager.kt +32 -129
- package/ios/Event.swift +3 -19
- package/ios/RCTDomain.swift +17 -13
- package/ios/VkAuth.swift +113 -97
- package/package.json +2 -2
- package/react-native-vk-auth.podspec +17 -10
- package/src/index.tsx +99 -77
- package/android/src/main/java/com/vkauth/vkid/JSSilentTokenExchanger.kt +0 -33
- package/android/src/main/java/com/vkauth/vkid/SuperAppKitInitUtils.kt +0 -75
- package/android/src/main/java/com/vkauth/vkid/dto/AcessToken.kt +0 -19
- package/android/src/main/java/com/vkauth/vkid/dto/DtoExt.kt +0 -24
- package/android/src/main/java/com/vkauth/vkid/dto/SilentAuthInfo.kt +0 -22
- package/android/src/main/java/com/vkauth/vkid/dto/Token.kt +0 -15
- package/android/src/main/java/com/vkauth/vkid/dto/UserSession.kt +0 -28
- package/android/src/main/java/com/vkauth/vkid/jstutils/JsCbSender.kt +0 -16
- package/android/src/main/java/com/vkauth/vkid/jstutils/JsOutputParam.kt +0 -7
package/README.md
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
# @pyrocancode/react-native-vk-auth
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
Форк библиотеки [@devsomersets/react-native-vk-auth](https://www.npmjs.com/package/@devsomersets/react-native-vk-auth) ([исходный репозиторий](https://github.com/somersets/react-native-vk-auth), автор Nikita Likhachev). Разработка ведётся в [pyrocancode/react-native-vk-auth](https://github.com/pyrocancode/react-native-vk-auth).
|
|
3
|
+
Тонкая обёртка над **VK ID SDK** для React Native: **OAuth 2.1**, нативные модули iOS и Android. Репозиторий: [pyrocancode/react-native-vk-auth](https://github.com/pyrocancode/react-native-vk-auth).
|
|
6
4
|
|
|
7
5
|
## Installation
|
|
8
6
|
|
|
9
|
-
Из npm (после публикации пакета):
|
|
10
|
-
|
|
11
7
|
```sh
|
|
12
8
|
npm install @pyrocancode/react-native-vk-auth
|
|
13
9
|
```
|
|
14
10
|
|
|
15
|
-
|
|
11
|
+
Альтернатива — установка из GitHub (конкретная ветка или коммит):
|
|
16
12
|
|
|
17
13
|
```sh
|
|
18
14
|
npm install github:pyrocancode/react-native-vk-auth
|
|
@@ -88,21 +84,25 @@ cd ios && pod install
|
|
|
88
84
|
}
|
|
89
85
|
```
|
|
90
86
|
|
|
91
|
-
|
|
92
|
-
|
|
87
|
+
Подключите `Linking` из React Native и `VK` из этого пакета — в обработчике вызывайте `VK.openURL`, чтобы завершить OAuth-поток после возврата из клиента VK.
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import { Linking } from 'react-native';
|
|
91
|
+
import { VK } from '@pyrocancode/react-native-vk-auth';
|
|
92
|
+
|
|
93
93
|
React.useEffect(() => {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
});
|
|
94
|
+
Linking.getInitialURL()
|
|
95
|
+
.then((url) => {
|
|
96
|
+
if (url) handleOpenURL({ url });
|
|
97
|
+
})
|
|
98
|
+
.catch((err) => console.warn('getInitialURL', err));
|
|
99
|
+
|
|
100
|
+
const sub = Linking.addEventListener('url', handleOpenURL);
|
|
101
|
+
return () => sub.remove();
|
|
102
|
+
}, []);
|
|
103
103
|
|
|
104
104
|
function handleOpenURL(event: { url: string }) {
|
|
105
|
-
|
|
105
|
+
VK.openURL(event.url);
|
|
106
106
|
}
|
|
107
107
|
```
|
|
108
108
|
|
|
@@ -146,148 +146,118 @@ dependencies { }
|
|
|
146
146
|
<string name="vk_account_manager_id" translatable="false">your.package.account</string>
|
|
147
147
|
```
|
|
148
148
|
|
|
149
|
-
##
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
149
|
+
## Минимальный общий сценарий (JS)
|
|
150
|
+
|
|
151
|
+
Инициализация выполняется **один раз** при старте приложения. Используйте `VK`, `VKID` и при необходимости `VKOneTapButton` из `@pyrocancode/react-native-vk-auth`.
|
|
152
|
+
|
|
153
|
+
### 1. Инициализация
|
|
154
|
+
|
|
155
|
+
```tsx
|
|
156
|
+
import { Image } from 'react-native';
|
|
157
|
+
import { VK, VKID } from '@pyrocancode/react-native-vk-auth';
|
|
158
|
+
|
|
159
|
+
const logo = Image.resolveAssetSource(require('./assets/logo.png'));
|
|
160
|
+
|
|
161
|
+
const vkid = new VKID(
|
|
162
|
+
'Моё приложение',
|
|
163
|
+
'1.0.0',
|
|
164
|
+
logo,
|
|
165
|
+
{
|
|
166
|
+
serviceUserAgreement: 'https://example.com/terms',
|
|
167
|
+
servicePrivacyPolicy: 'https://example.com/privacy',
|
|
168
|
+
serviceSupport: null,
|
|
169
|
+
}
|
|
167
170
|
);
|
|
168
171
|
|
|
169
172
|
VK.initialize(
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
},
|
|
175
|
-
mode: VK.Mode.DEBUG,
|
|
173
|
+
{
|
|
174
|
+
credentials: {
|
|
175
|
+
clientId: 'YOUR_CLIENT_ID',
|
|
176
|
+
clientSecret: 'YOUR_CLIENT_SECRET',
|
|
176
177
|
},
|
|
177
|
-
|
|
178
|
+
mode: VK.Mode.DEBUG,
|
|
179
|
+
},
|
|
180
|
+
vkid
|
|
178
181
|
);
|
|
179
182
|
```
|
|
180
183
|
|
|
181
|
-
2.
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
ok: true,
|
|
198
|
-
accessToken: {
|
|
199
|
-
token: new VKID.Token(accessToken),
|
|
200
|
-
userID: new VKID.UserID(userId),
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
return result;
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
}
|
|
184
|
+
### 2. Подписка на авторизацию и выход
|
|
185
|
+
|
|
186
|
+
```tsx
|
|
187
|
+
vkid.setOnAuthChanged({
|
|
188
|
+
onAuthorized(payload) {
|
|
189
|
+
// OAuth 2.1: access token и идентификатор пользователя VK
|
|
190
|
+
console.log(payload.accessToken, payload.userId, payload.profile);
|
|
191
|
+
},
|
|
192
|
+
onLogout() {
|
|
193
|
+
console.log('Пользователь вышел');
|
|
194
|
+
},
|
|
195
|
+
onAuthFailed(message) {
|
|
196
|
+
console.warn(message);
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
```
|
|
207
200
|
|
|
208
|
-
|
|
209
|
-
vkid.setOnAuthChanged(new class implements VKID.AuthChangedCallback {
|
|
210
|
-
onAuth(userSession: VKID.Session.UserSession): void {
|
|
211
|
-
if (userSession instanceof VKID.Session.Authorized) {
|
|
212
|
-
// user was successfuly authorized, so show authorized flow or get user profile info
|
|
213
|
-
userSession.userProfile.then((profileInfo) => {
|
|
214
|
-
setProfileInfo("Profile info: " + profileInfo.userID.value + " " + profileInfo.firstName);
|
|
215
|
-
})
|
|
216
|
-
}
|
|
217
|
-
}
|
|
201
|
+
### 3. Кнопка One Tap или ручной старт
|
|
218
202
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
})
|
|
203
|
+
```tsx
|
|
204
|
+
import { Button } from 'react-native';
|
|
205
|
+
import { VKOneTapButton, VKID } from '@pyrocancode/react-native-vk-auth';
|
|
223
206
|
|
|
224
|
-
//
|
|
225
|
-
import { VKOneTapButton } from 'react-native-superappkit-pub';
|
|
207
|
+
// В разметке
|
|
226
208
|
<VKOneTapButton />
|
|
227
209
|
|
|
228
|
-
//
|
|
229
|
-
<Button title=
|
|
230
|
-
function auth() {
|
|
231
|
-
vkid.startAuth();
|
|
232
|
-
}
|
|
210
|
+
// Или кнопка «Войти через VK»
|
|
211
|
+
<Button title="Войти через VK" onPress={() => vkid.startAuth()} />
|
|
233
212
|
|
|
234
|
-
//
|
|
213
|
+
// Принудительно закрыть экран авторизации
|
|
235
214
|
function forceCloseAuth() {
|
|
236
|
-
|
|
215
|
+
vkid.closeAuth();
|
|
237
216
|
}
|
|
238
217
|
|
|
239
|
-
// Logout
|
|
240
218
|
function logout() {
|
|
241
|
-
|
|
219
|
+
vkid.logout();
|
|
242
220
|
}
|
|
243
221
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
let isLoggedIn = sessions.some((session) => session instanceof VKID.UserSession.Authorized)
|
|
222
|
+
async function checkLoggedIn() {
|
|
223
|
+
const sessions = await vkid.userSessions();
|
|
224
|
+
return sessions.some((s) => s instanceof VKID.Session.Authorized);
|
|
248
225
|
}
|
|
249
226
|
```
|
|
250
227
|
|
|
251
|
-
### One Tap
|
|
252
|
-
|
|
253
|
-
|
|
228
|
+
### Кастомизация One Tap
|
|
229
|
+
|
|
230
|
+
```tsx
|
|
231
|
+
import { VKOneTapButton, VKOneTapButtonSpace } from '@pyrocancode/react-native-vk-auth';
|
|
232
|
+
|
|
254
233
|
<VKOneTapButton
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
actionText: 'Login as {firstName} {lastName}', /* {firstName} and {lastName} are templates that will be replaced by real user names */
|
|
277
|
-
phoneText: 'With phone {phone}', /* {phone} is a template that will be replaced by user phone */
|
|
278
|
-
}}
|
|
279
|
-
oneLineTextSize={ 16 }
|
|
280
|
-
firstLineTextSize={ 16 }
|
|
281
|
-
secondLineTextSize={ 14 }
|
|
282
|
-
avatarSize={ 64 }
|
|
283
|
-
iconSize={ 64 }
|
|
284
|
-
progressSize={ 56 }
|
|
234
|
+
style={styles.vkView}
|
|
235
|
+
backgroundStyle={{
|
|
236
|
+
style: VKOneTapButtonSpace.BgColor.CUSTOM,
|
|
237
|
+
customVkIconColor: '#fff',
|
|
238
|
+
customBackgroundColor: '#0077FF',
|
|
239
|
+
customTextColor: '#fff',
|
|
240
|
+
}}
|
|
241
|
+
iconGravity={VKOneTapButtonSpace.IconGravity.START}
|
|
242
|
+
firstLineFieldType={VKOneTapButtonSpace.LineFieldType.ACTION}
|
|
243
|
+
secondLineFieldType={VKOneTapButtonSpace.LineFieldType.PHONE}
|
|
244
|
+
texts={{
|
|
245
|
+
noUserText: 'Войти через VK',
|
|
246
|
+
actionText: 'Продолжить как {firstName} {lastName}',
|
|
247
|
+
phoneText: 'Телефон {phone}',
|
|
248
|
+
}}
|
|
249
|
+
oneLineTextSize={16}
|
|
250
|
+
firstLineTextSize={16}
|
|
251
|
+
secondLineTextSize={14}
|
|
252
|
+
avatarSize={64}
|
|
253
|
+
iconSize={64}
|
|
254
|
+
progressSize={56}
|
|
285
255
|
/>
|
|
286
256
|
```
|
|
287
257
|
|
|
288
258
|
## Usage
|
|
289
259
|
|
|
290
|
-
|
|
260
|
+
После настройки iOS/Android (см. выше) используйте API из раздела «Минимальный общий сценарий»: `VK.initialize`, `vkid.setOnAuthChanged`, `vkid.startAuth` / `VKOneTapButton`, `VK.openURL` для deep link.
|
|
291
261
|
|
|
292
262
|
## Contributing
|
|
293
263
|
|
|
@@ -295,8 +265,4 @@ See the [contributing guide](CONTRIBUTING.md) to learn how to contribute to the
|
|
|
295
265
|
|
|
296
266
|
## License
|
|
297
267
|
|
|
298
|
-
[MIT](LICENSE).
|
|
299
|
-
|
|
300
|
-
---
|
|
301
|
-
|
|
302
|
-
Made with [create-react-native-library](https://github.com/callstack/react-native-builder-bob)
|
|
268
|
+
[MIT](LICENSE). См. полный текст в файле `LICENSE`.
|
package/android/build.gradle
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
buildscript {
|
|
2
|
-
// Buildscript is evaluated before everything else so we can't use getExtOrDefault
|
|
3
2
|
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : project.properties['VkAuth_kotlinVersion']
|
|
4
3
|
|
|
5
4
|
repositories {
|
|
@@ -9,7 +8,6 @@ buildscript {
|
|
|
9
8
|
|
|
10
9
|
dependencies {
|
|
11
10
|
classpath 'com.android.tools.build:gradle:3.5.3'
|
|
12
|
-
// noinspection DifferentKotlinGradleVersion
|
|
13
11
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
14
12
|
}
|
|
15
13
|
}
|
|
@@ -33,6 +31,7 @@ def getExtOrIntegerDefault(name) {
|
|
|
33
31
|
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties['VkAuth_' + name]).toInteger()
|
|
34
32
|
}
|
|
35
33
|
|
|
34
|
+
def vkidVersion = "2.6.2"
|
|
36
35
|
|
|
37
36
|
android {
|
|
38
37
|
compileSdkVersion getExtOrIntegerDefault('compileSdkVersion')
|
|
@@ -62,9 +61,9 @@ android {
|
|
|
62
61
|
repositories {
|
|
63
62
|
mavenCentral()
|
|
64
63
|
google()
|
|
65
|
-
maven {
|
|
66
|
-
|
|
67
|
-
}
|
|
64
|
+
maven { url = "https://artifactory-external.vkpartner.ru/artifactory/vkid-sdk-android/" }
|
|
65
|
+
maven { url = "https://artifactory-external.vkpartner.ru/artifactory/maven/" }
|
|
66
|
+
maven { url = "https://artifactory-external.vkpartner.ru/artifactory/vk-id-captcha/android/" }
|
|
68
67
|
|
|
69
68
|
def found = false
|
|
70
69
|
def defaultDir = null
|
|
@@ -133,17 +132,14 @@ repositories {
|
|
|
133
132
|
}
|
|
134
133
|
|
|
135
134
|
def kotlin_version = getExtOrDefault('kotlinVersion')
|
|
136
|
-
def vkSdkVersion = "0.104-24412"
|
|
137
135
|
|
|
138
136
|
dependencies {
|
|
139
|
-
//noinspection GradleDynamicVersion
|
|
140
137
|
implementation "com.facebook.react:react-native:+"
|
|
141
|
-
implementation "com.vk:
|
|
142
|
-
implementation "com.vk:
|
|
138
|
+
implementation "com.vk.id:vkid:${vkidVersion}"
|
|
139
|
+
implementation "com.vk.id:onetap-xml:${vkidVersion}"
|
|
143
140
|
implementation "androidx.appcompat:appcompat:1.6.1"
|
|
144
|
-
|
|
141
|
+
implementation "androidx.fragment:fragment-ktx:1.6.2"
|
|
145
142
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
146
|
-
// From node_modules
|
|
147
143
|
}
|
|
148
144
|
|
|
149
145
|
if (isNewArchitectureEnabled()) {
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
package com.vkauth
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.bridge
|
|
3
|
+
import com.facebook.react.bridge.Promise
|
|
4
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
5
|
+
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
|
6
|
+
import com.facebook.react.bridge.ReactMethod
|
|
7
|
+
import com.facebook.react.bridge.ReadableMap
|
|
4
8
|
import com.vkauth.vkid.AuthDelegate
|
|
5
9
|
import com.vkauth.vkid.InitDelegate
|
|
6
10
|
import com.vkauth.vkid.jsinput.App
|
|
7
|
-
import com.vkauth.vkid.jsinput.VKID
|
|
11
|
+
import com.vkauth.vkid.jsinput.VKID as VkIdInput
|
|
8
12
|
|
|
9
13
|
class VkAuthModule(
|
|
10
14
|
reactContext: ReactApplicationContext,
|
|
11
15
|
private val initDelegate: InitDelegate,
|
|
12
|
-
private val authDelegate: AuthDelegate
|
|
13
|
-
) :
|
|
14
|
-
ReactContextBaseJavaModule(reactContext) {
|
|
16
|
+
private val authDelegate: AuthDelegate,
|
|
17
|
+
) : ReactContextBaseJavaModule(reactContext) {
|
|
15
18
|
|
|
16
|
-
override fun getName(): String
|
|
17
|
-
return "VkAuth"
|
|
18
|
-
}
|
|
19
|
+
override fun getName(): String = "VkAuth"
|
|
19
20
|
|
|
20
21
|
@ReactMethod
|
|
21
22
|
fun initialize(app: ReadableMap, vkid: ReadableMap) {
|
|
22
|
-
initDelegate.initialize(App.fromMap(app),
|
|
23
|
+
initDelegate.initialize(App.fromMap(app), VkIdInput.fromMap(vkid))
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
@ReactMethod
|
|
@@ -32,17 +33,18 @@ class VkAuthModule(
|
|
|
32
33
|
authDelegate.closeAuth()
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
// to ignore react warning
|
|
36
36
|
@ReactMethod
|
|
37
|
-
fun addListener(eventName: String) {
|
|
38
|
-
}
|
|
37
|
+
fun addListener(@Suppress("UNUSED_PARAMETER") eventName: String) {}
|
|
39
38
|
|
|
40
39
|
@ReactMethod
|
|
41
|
-
fun removeAllListeners() {
|
|
42
|
-
|
|
40
|
+
fun removeAllListeners() {}
|
|
41
|
+
|
|
42
|
+
@ReactMethod
|
|
43
|
+
fun removeListeners(@Suppress("UNUSED_PARAMETER") type: Int?) {}
|
|
43
44
|
|
|
44
45
|
@ReactMethod
|
|
45
|
-
fun
|
|
46
|
+
fun openURL(@Suppress("UNUSED_PARAMETER") url: String) {
|
|
47
|
+
// Редирект обрабатывает VK ID SDK / система; при необходимости дополните.
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
@ReactMethod
|
|
@@ -51,7 +53,7 @@ class VkAuthModule(
|
|
|
51
53
|
}
|
|
52
54
|
|
|
53
55
|
@ReactMethod
|
|
54
|
-
fun accessTokenChangedFailed(error: ReadableMap) {
|
|
56
|
+
fun accessTokenChangedFailed(@Suppress("UNUSED_PARAMETER") error: ReadableMap) {
|
|
55
57
|
authDelegate.accessTokenChangedFailed()
|
|
56
58
|
}
|
|
57
59
|
|
|
@@ -6,15 +6,20 @@ import com.facebook.react.bridge.ReactApplicationContext
|
|
|
6
6
|
import com.facebook.react.uimanager.ViewManager
|
|
7
7
|
import com.vkauth.vkid.AuthDelegate
|
|
8
8
|
import com.vkauth.vkid.InitDelegate
|
|
9
|
+
import com.vkauth.vkid.VkAuthServiceHolder
|
|
9
10
|
import com.vkauth.vkid.onetapbutton.OneTabButtonManager
|
|
10
11
|
|
|
11
|
-
|
|
12
12
|
class VkAuthPackage : ReactPackage {
|
|
13
13
|
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
14
|
+
val authDelegate = AuthDelegate(reactContext)
|
|
15
|
+
VkAuthServiceHolder.authDelegate = authDelegate
|
|
16
|
+
return listOf(
|
|
17
|
+
VkAuthModule(
|
|
18
|
+
reactContext,
|
|
19
|
+
InitDelegate(reactContext),
|
|
20
|
+
authDelegate,
|
|
21
|
+
),
|
|
22
|
+
)
|
|
18
23
|
}
|
|
19
24
|
|
|
20
25
|
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
@@ -5,119 +5,127 @@ import androidx.fragment.app.FragmentActivity
|
|
|
5
5
|
import com.facebook.react.bridge.Arguments
|
|
6
6
|
import com.facebook.react.bridge.Promise
|
|
7
7
|
import com.facebook.react.bridge.ReactApplicationContext
|
|
8
|
-
import com.
|
|
9
|
-
import com.
|
|
10
|
-
import com.vk.
|
|
11
|
-
import com.vk.
|
|
12
|
-
import com.vk.auth.
|
|
13
|
-
import com.vk.auth.
|
|
14
|
-
import com.vk.auth.
|
|
15
|
-
import com.vk.
|
|
16
|
-
import com.vk.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
private val context: ReactApplicationContext
|
|
24
|
-
) {
|
|
25
|
-
private val jsCallbackSender = JsCbSender()
|
|
8
|
+
import com.facebook.react.bridge.WritableMap
|
|
9
|
+
import com.facebook.react.modules.core.DeviceEventManagerModule
|
|
10
|
+
import com.vk.id.VKID
|
|
11
|
+
import com.vk.id.VKIDAuthFail
|
|
12
|
+
import com.vk.id.auth.AuthCodeData
|
|
13
|
+
import com.vk.id.auth.VKIDAuthCallback
|
|
14
|
+
import com.vk.id.auth.VKIDAuthParams
|
|
15
|
+
import com.vk.id.logout.VKIDLogoutCallback
|
|
16
|
+
import com.vk.id.logout.VKIDLogoutFail
|
|
17
|
+
|
|
18
|
+
class AuthDelegate(private val reactContext: ReactApplicationContext) {
|
|
19
|
+
|
|
20
|
+
companion object {
|
|
21
|
+
private const val TAG = "VkAuth"
|
|
22
|
+
}
|
|
26
23
|
|
|
27
24
|
init {
|
|
28
|
-
|
|
29
|
-
override fun onLogout(logoutReason: LogoutReason) {
|
|
30
|
-
super.onLogout(logoutReason)
|
|
31
|
-
jsCallbackSender.sendCallback(context, ON_LOGOUT_EVENT, null)
|
|
32
|
-
}
|
|
33
|
-
})
|
|
25
|
+
VKID.logsEnabled = true
|
|
34
26
|
}
|
|
35
27
|
|
|
36
28
|
fun startAuth() {
|
|
37
|
-
val activity =
|
|
38
|
-
|
|
39
|
-
|
|
29
|
+
val activity = reactContext.currentActivity as? FragmentActivity
|
|
30
|
+
if (activity == null) {
|
|
31
|
+
Log.e(TAG, "startAuth: no FragmentActivity")
|
|
32
|
+
emitAuthFail("No activity")
|
|
40
33
|
return
|
|
41
34
|
}
|
|
35
|
+
VKID.instance.authorize(
|
|
36
|
+
activity,
|
|
37
|
+
object : VKIDAuthCallback {
|
|
38
|
+
override fun onAuth(accessToken: com.vk.id.AccessToken) {
|
|
39
|
+
Log.d(
|
|
40
|
+
TAG,
|
|
41
|
+
"VKID onAuth: userID=${accessToken.userID} expire=${accessToken.expireTime}",
|
|
42
|
+
)
|
|
43
|
+
emitAuthSuccess(accessToken)
|
|
44
|
+
}
|
|
42
45
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
override fun onAuthCode(data: AuthCodeData, isCompletion: Boolean) {
|
|
47
|
+
Log.d(TAG, "VKID onAuthCode: isCompletion=$isCompletion code=${data.code} deviceId=${data.deviceId}")
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override fun onFail(fail: VKIDAuthFail) {
|
|
51
|
+
Log.e(TAG, "VKID onFail: $fail")
|
|
52
|
+
emitAuthFail(fail.toString())
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
VKIDAuthParams.Builder().build(),
|
|
56
|
+
)
|
|
46
57
|
}
|
|
47
58
|
|
|
48
59
|
fun closeAuth() {
|
|
49
|
-
|
|
50
|
-
(activity.supportFragmentManager.findFragmentByTag(FAST_LOGIN_TAG) as? BottomSheetDialogFragment)
|
|
51
|
-
?.dismissAllowingStateLoss()
|
|
52
|
-
?: run {
|
|
53
|
-
(activity.supportFragmentManager
|
|
54
|
-
.fragments
|
|
55
|
-
.find { it is VkFastLoginBottomSheetFragment } as? BottomSheetDialogFragment)
|
|
56
|
-
?.dismissAllowingStateLoss()
|
|
57
|
-
}
|
|
60
|
+
// VK ID SDK не требует явного закрытия веб-view из нативного модуля.
|
|
58
61
|
}
|
|
59
62
|
|
|
60
|
-
fun
|
|
61
|
-
val
|
|
62
|
-
|
|
63
|
+
fun logout() {
|
|
64
|
+
val activity = reactContext.currentActivity as? FragmentActivity
|
|
65
|
+
if (activity == null) {
|
|
66
|
+
Log.e(TAG, "logout: no FragmentActivity")
|
|
67
|
+
return
|
|
68
|
+
}
|
|
69
|
+
VKID.instance.logout(
|
|
70
|
+
object : VKIDLogoutCallback {
|
|
71
|
+
override fun onSuccess() {
|
|
72
|
+
Log.d(TAG, "VKID logout success")
|
|
73
|
+
sendEvent("onLogout", null)
|
|
74
|
+
}
|
|
63
75
|
|
|
64
|
-
|
|
76
|
+
override fun onFail(fail: VKIDLogoutFail) {
|
|
77
|
+
Log.e(TAG, "VKID logout fail: $fail")
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
activity,
|
|
81
|
+
)
|
|
65
82
|
}
|
|
66
83
|
|
|
67
|
-
fun
|
|
68
|
-
|
|
84
|
+
fun accessTokenChangedSuccess(token: String, userId: Int) {
|
|
85
|
+
// Старый поток silent token; оставлено для совместимости с JS до миграции приложения.
|
|
86
|
+
Log.d(TAG, "accessTokenChangedSuccess (legacy): userId=$userId")
|
|
69
87
|
}
|
|
70
88
|
|
|
71
|
-
fun
|
|
72
|
-
|
|
89
|
+
fun accessTokenChangedFailed() {
|
|
90
|
+
Log.d(TAG, "accessTokenChangedFailed (legacy)")
|
|
73
91
|
}
|
|
74
92
|
|
|
75
93
|
fun getUserSessions(promise: Promise) {
|
|
76
|
-
val
|
|
77
|
-
|
|
78
|
-
|
|
94
|
+
val token = VKID.instance.accessToken
|
|
95
|
+
val arr = com.facebook.react.bridge.Arguments.createArray()
|
|
96
|
+
if (token != null) {
|
|
97
|
+
val m = com.facebook.react.bridge.Arguments.createMap()
|
|
98
|
+
m.putString("type", "authorized")
|
|
99
|
+
arr.pushMap(m)
|
|
79
100
|
}
|
|
80
|
-
|
|
81
|
-
val array = Arguments.createArray().apply {
|
|
82
|
-
pushMap(UserSession.Authorized.toMap())
|
|
83
|
-
}
|
|
84
|
-
promise.resolve(array)
|
|
101
|
+
promise.resolve(arr)
|
|
85
102
|
}
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
val
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
if (byTag) {
|
|
93
|
-
return true
|
|
104
|
+
fun getUserProfile(promise: Promise) {
|
|
105
|
+
val token = VKID.instance.accessToken
|
|
106
|
+
if (token == null) {
|
|
107
|
+
promise.reject("E_VK_NOT_AUTHORIZED", "No VK ID access token")
|
|
108
|
+
return
|
|
94
109
|
}
|
|
110
|
+
promise.resolve(VkAuthPayload.profileForJs(token.userID, token.userData))
|
|
111
|
+
}
|
|
95
112
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
113
|
+
fun emitAuthSuccess(accessToken: com.vk.id.AccessToken) {
|
|
114
|
+
val map = VkAuthPayload.fromAccessToken(accessToken)
|
|
115
|
+
map.putMap("profile", VkAuthPayload.profileForJs(accessToken.userID, accessToken.userData))
|
|
116
|
+
sendEvent("onAuth", map)
|
|
99
117
|
}
|
|
100
118
|
|
|
101
|
-
fun
|
|
102
|
-
val
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
promise.reject(error)
|
|
107
|
-
}
|
|
108
|
-
override fun success(result: ProfileShortInfo) {
|
|
109
|
-
promise.resolve(result.toMap())
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
)
|
|
113
|
-
return
|
|
114
|
-
}
|
|
115
|
-
promise.resolve(profile)
|
|
119
|
+
fun emitAuthFail(message: String) {
|
|
120
|
+
val map = Arguments.createMap()
|
|
121
|
+
map.putString("type", "error")
|
|
122
|
+
map.putString("error", message)
|
|
123
|
+
sendEvent("onAuth", map)
|
|
116
124
|
}
|
|
117
125
|
|
|
118
|
-
private
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
126
|
+
private fun sendEvent(eventName: String, params: WritableMap?) {
|
|
127
|
+
reactContext
|
|
128
|
+
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter::class.java)
|
|
129
|
+
.emit(eventName, params)
|
|
122
130
|
}
|
|
123
131
|
}
|