@norcy/react-native-toolkit 0.1.11 → 0.1.13
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/lib/commonjs/LoginManager.js +354 -0
- package/lib/commonjs/LoginManager.js.map +1 -0
- package/lib/commonjs/Notification.js.map +1 -1
- package/lib/commonjs/constant.js.map +1 -1
- package/lib/commonjs/index.js +12 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/module/LoginManager.js +348 -0
- package/lib/module/LoginManager.js.map +1 -0
- package/lib/module/Notification.js.map +1 -1
- package/lib/module/constant.js.map +1 -1
- package/lib/module/index.js +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/typescript/LoginManager.d.ts +16 -0
- package/lib/typescript/Notification.d.ts +1 -1
- package/lib/typescript/constant.d.ts +15 -0
- package/lib/typescript/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/LoginManager.ts +355 -0
- package/src/Notification.ts +1 -1
- package/src/constant.ts +17 -0
- package/src/index.tsx +1 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AppleLoginUtil,
|
|
3
|
+
BuildInPrefs,
|
|
4
|
+
LoginType,
|
|
5
|
+
Notification,
|
|
6
|
+
PrefData,
|
|
7
|
+
WeChatLoginUtil,
|
|
8
|
+
} from '@norcy/react-native-toolkit';
|
|
9
|
+
import { User } from 'leancloud-storage';
|
|
10
|
+
import { Platform } from 'react-native';
|
|
11
|
+
import { getUniqueIdSync } from 'react-native-device-info';
|
|
12
|
+
import {
|
|
13
|
+
LoginAuthDataType,
|
|
14
|
+
LoginState,
|
|
15
|
+
LoginUserDataType,
|
|
16
|
+
UserType,
|
|
17
|
+
} from './constant';
|
|
18
|
+
import { i18n } from './i18n';
|
|
19
|
+
|
|
20
|
+
const AV = require('leancloud-storage');
|
|
21
|
+
|
|
22
|
+
let CURRENT_USER: UserType | null = null;
|
|
23
|
+
|
|
24
|
+
let WeiXinId = '';
|
|
25
|
+
let WeiXinSecret = '';
|
|
26
|
+
|
|
27
|
+
const AVUserToLocalUser = (user: User) => {
|
|
28
|
+
return {
|
|
29
|
+
nickname: user.get('nickname'),
|
|
30
|
+
email: user.get('email'),
|
|
31
|
+
headimgurl: user.get('headimgurl'),
|
|
32
|
+
type: user.get('type'),
|
|
33
|
+
AVUser: user,
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const onLoginFinish = ({
|
|
38
|
+
isAuto = false,
|
|
39
|
+
user,
|
|
40
|
+
error,
|
|
41
|
+
code,
|
|
42
|
+
}: {
|
|
43
|
+
isAuto?: boolean;
|
|
44
|
+
user?: UserType;
|
|
45
|
+
error?: string | object;
|
|
46
|
+
code?: number;
|
|
47
|
+
}) => {
|
|
48
|
+
const data = { isAuto, user, error, code };
|
|
49
|
+
if (user) {
|
|
50
|
+
PrefData.setValue(BuildInPrefs.LastLoginType, user.type);
|
|
51
|
+
}
|
|
52
|
+
Notification.postNotification('onLogin', data);
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const doLeanCloudLogin = async (
|
|
56
|
+
authData: LoginAuthDataType,
|
|
57
|
+
userData: LoginUserDataType | undefined,
|
|
58
|
+
callback: ({ user, error }: { user?: UserType; error?: any }) => void
|
|
59
|
+
) => {
|
|
60
|
+
console.log('Lean Cloud 开始登录', userData);
|
|
61
|
+
// loginType 空说明是老用户
|
|
62
|
+
const loginType = authData.loginType ? authData.loginType : 'apple';
|
|
63
|
+
let loginTypeNum = LoginType.LoginTypeApple;
|
|
64
|
+
if (loginType === 'wechat') {
|
|
65
|
+
loginTypeNum = LoginType.LoginTypeWeChat;
|
|
66
|
+
} else if (loginType === 'visitor') {
|
|
67
|
+
loginTypeNum = LoginType.LoginTypeVisitor;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
AV.User.loginWithAuthData(authData, loginType, { failOnNotExist: true }).then(
|
|
71
|
+
(user: User) => {
|
|
72
|
+
// 登录成功
|
|
73
|
+
console.log('Lean Cloud 登录成功');
|
|
74
|
+
// 每次重新鉴权都更新头像和昵称,避免微信头像过期
|
|
75
|
+
// if (userData?.nickname) {
|
|
76
|
+
// user.set('nickname', userData?.nickname);
|
|
77
|
+
// }
|
|
78
|
+
// if (userData?.headimgurl) {
|
|
79
|
+
// user.set('headimgurl', userData?.headimgurl);
|
|
80
|
+
// }
|
|
81
|
+
// user.save();
|
|
82
|
+
CURRENT_USER = AVUserToLocalUser(user);
|
|
83
|
+
callback({ user: CURRENT_USER });
|
|
84
|
+
},
|
|
85
|
+
(error: any) => {
|
|
86
|
+
if (error.code === 211) {
|
|
87
|
+
// 创建用户,并补充资料
|
|
88
|
+
console.log('创建用户,并补充资料');
|
|
89
|
+
const newUser = new AV.User();
|
|
90
|
+
const email = userData?.email;
|
|
91
|
+
if (email) {
|
|
92
|
+
newUser.setEmail(email);
|
|
93
|
+
}
|
|
94
|
+
newUser.set('nickname', userData?.nickname);
|
|
95
|
+
newUser.set('headimgurl', userData?.headimgurl);
|
|
96
|
+
newUser.set('type', loginTypeNum);
|
|
97
|
+
if (Platform.OS === 'android') {
|
|
98
|
+
newUser.set('source', 2);
|
|
99
|
+
}
|
|
100
|
+
newUser.set('toLDB', 1);
|
|
101
|
+
newUser.loginWithAuthData(authData, loginType).then(
|
|
102
|
+
(user: User) => {
|
|
103
|
+
// 登录成功
|
|
104
|
+
console.log('Lean Cloud 注册成功');
|
|
105
|
+
CURRENT_USER = AVUserToLocalUser(user);
|
|
106
|
+
CURRENT_USER.isNew = true;
|
|
107
|
+
// 标记为当前用户是在本机注册的 TODO
|
|
108
|
+
// PrefData.setValue(Prefs.RegisterInThisDevice, true);
|
|
109
|
+
callback({ user: CURRENT_USER });
|
|
110
|
+
},
|
|
111
|
+
(error2: any) => {
|
|
112
|
+
// 登录失败
|
|
113
|
+
console.log('Lean Cloud 登录失败', error2);
|
|
114
|
+
callback({ error: error2 });
|
|
115
|
+
}
|
|
116
|
+
);
|
|
117
|
+
} else {
|
|
118
|
+
// 登录失败
|
|
119
|
+
console.log('Lean Cloud 登录失败', error);
|
|
120
|
+
callback({ error: error });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
);
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
export const LoginManager = {
|
|
127
|
+
setup: (WeChatId: string, WeChatSecret: string) => {
|
|
128
|
+
WeiXinId = WeChatId;
|
|
129
|
+
WeChatSecret = WeChatSecret;
|
|
130
|
+
},
|
|
131
|
+
|
|
132
|
+
// 自动根据已有的 User 信息进行登录鉴权,如果 User 为空则失败
|
|
133
|
+
autoLogin: async () => {
|
|
134
|
+
const user = await AV.User.currentAsync();
|
|
135
|
+
if (user) {
|
|
136
|
+
console.log('自动登录成功');
|
|
137
|
+
CURRENT_USER = AVUserToLocalUser(user);
|
|
138
|
+
onLoginFinish({ isAuto: true, user: CURRENT_USER });
|
|
139
|
+
} else {
|
|
140
|
+
onLoginFinish({ isAuto: true, error: 'User Not Login Yet' });
|
|
141
|
+
}
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
// 如果 User 为空,则唤起苹果登录框;如果 User 不为空,直接鉴权
|
|
145
|
+
login: async (
|
|
146
|
+
type: LoginType,
|
|
147
|
+
devAuthData: LoginAuthDataType | null = null,
|
|
148
|
+
loadingCallback: Function
|
|
149
|
+
) => {
|
|
150
|
+
// 如果之前已经鉴权过,则直接使用上次鉴权的 AuthData
|
|
151
|
+
const cuurentUser = await AV.User.currentAsync();
|
|
152
|
+
if (cuurentUser) {
|
|
153
|
+
await LoginManager.autoLogin();
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// 改为注入 delegate
|
|
158
|
+
if (__DEV__) {
|
|
159
|
+
if (devAuthData) {
|
|
160
|
+
doLeanCloudLogin(devAuthData, undefined, ({ user, error }) => {
|
|
161
|
+
onLoginFinish({ user, error });
|
|
162
|
+
});
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (type === LoginType.LoginTypeApple) {
|
|
168
|
+
const { user, email, identityToken, error, code } =
|
|
169
|
+
await AppleLoginUtil.requestAppleUserForLogin();
|
|
170
|
+
if (!user || error) {
|
|
171
|
+
onLoginFinish({ error, code });
|
|
172
|
+
return;
|
|
173
|
+
} else {
|
|
174
|
+
let userData = {
|
|
175
|
+
userId: user,
|
|
176
|
+
email: email,
|
|
177
|
+
authData: {
|
|
178
|
+
openid: user,
|
|
179
|
+
access_token: identityToken,
|
|
180
|
+
expires_in: 99999999,
|
|
181
|
+
loginType: 'apple',
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
AppleLoginUtil.fetchAndUpdateCredentialState(
|
|
186
|
+
userData.userId,
|
|
187
|
+
({ result, error: error2 }: { result: number; error: any }) => {
|
|
188
|
+
if (error || result !== LoginState.AUTHORIZED) {
|
|
189
|
+
onLoginFinish({ error: error2 });
|
|
190
|
+
} else {
|
|
191
|
+
loadingCallback && loadingCallback();
|
|
192
|
+
doLeanCloudLogin(
|
|
193
|
+
userData.authData,
|
|
194
|
+
userData,
|
|
195
|
+
({ user: loginUser, error: error3 }) => {
|
|
196
|
+
onLoginFinish({ user: loginUser, error: error3 });
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
} else if (type === LoginType.LoginTypeWeChat) {
|
|
204
|
+
WeChatLoginUtil.doLogin(
|
|
205
|
+
WeiXinId,
|
|
206
|
+
WeiXinSecret,
|
|
207
|
+
({
|
|
208
|
+
nickname,
|
|
209
|
+
headimgurl,
|
|
210
|
+
openid,
|
|
211
|
+
unionid,
|
|
212
|
+
error,
|
|
213
|
+
}: {
|
|
214
|
+
nickname: string;
|
|
215
|
+
headimgurl: string;
|
|
216
|
+
openid: string;
|
|
217
|
+
unionid: string;
|
|
218
|
+
error: any;
|
|
219
|
+
}) => {
|
|
220
|
+
if (error) {
|
|
221
|
+
onLoginFinish({ error });
|
|
222
|
+
} else {
|
|
223
|
+
let userData = {
|
|
224
|
+
nickname: nickname,
|
|
225
|
+
headimgurl: headimgurl,
|
|
226
|
+
authData: {
|
|
227
|
+
openid: openid,
|
|
228
|
+
unionid: unionid,
|
|
229
|
+
access_token: openid,
|
|
230
|
+
expires_in: 99999999,
|
|
231
|
+
loginType: 'wechat',
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
loadingCallback && loadingCallback();
|
|
235
|
+
doLeanCloudLogin(
|
|
236
|
+
userData.authData,
|
|
237
|
+
userData,
|
|
238
|
+
({ user, error: error2 }) => {
|
|
239
|
+
onLoginFinish({ user, error: error2 });
|
|
240
|
+
}
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
);
|
|
245
|
+
} else if (type === LoginType.LoginTypeVisitor) {
|
|
246
|
+
const uniqueId = getUniqueIdSync();
|
|
247
|
+
console.log(uniqueId);
|
|
248
|
+
let userData = {
|
|
249
|
+
nickname: i18n.t('游客'),
|
|
250
|
+
authData: {
|
|
251
|
+
openid: uniqueId,
|
|
252
|
+
access_token: uniqueId,
|
|
253
|
+
expires_in: 99999999,
|
|
254
|
+
loginType: 'visitor',
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
loadingCallback && loadingCallback();
|
|
258
|
+
doLeanCloudLogin(userData.authData, userData, ({ user, error }) => {
|
|
259
|
+
onLoginFinish({ user, error });
|
|
260
|
+
});
|
|
261
|
+
} else {
|
|
262
|
+
onLoginFinish({ error: i18n.t('未知登录类型,不应该走到这') });
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
|
|
266
|
+
logOut: (callback: Function) => {
|
|
267
|
+
console.log('onLogout');
|
|
268
|
+
AV.User.logOut();
|
|
269
|
+
CURRENT_USER = null;
|
|
270
|
+
callback && callback();
|
|
271
|
+
Notification.postNotification('onLogout');
|
|
272
|
+
},
|
|
273
|
+
|
|
274
|
+
isLogin: () => {
|
|
275
|
+
return LoginManager.currentUser() != null;
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
isVisitor: () => {
|
|
279
|
+
return (
|
|
280
|
+
LoginManager.isLogin() &&
|
|
281
|
+
LoginManager.currentUser()?.type === LoginType.LoginTypeVisitor
|
|
282
|
+
);
|
|
283
|
+
},
|
|
284
|
+
|
|
285
|
+
currentUser: () => {
|
|
286
|
+
// console.log('current user is ', CURRENT_USER);
|
|
287
|
+
return CURRENT_USER;
|
|
288
|
+
},
|
|
289
|
+
|
|
290
|
+
batchUpdateUser: async (
|
|
291
|
+
keys: string[],
|
|
292
|
+
values: string[],
|
|
293
|
+
callback: Function
|
|
294
|
+
) => {
|
|
295
|
+
console.log('Batch Update User Begin: ' + keys + ' ' + values);
|
|
296
|
+
const user = await AV.User.currentAsync();
|
|
297
|
+
if (!user) {
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const oldValues = [];
|
|
301
|
+
for (let i = 0; i < keys.length; i++) {
|
|
302
|
+
oldValues.push(user.get(keys[i]));
|
|
303
|
+
user.set(keys[i], values[i]);
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
const newUser = await user.save();
|
|
307
|
+
CURRENT_USER = AVUserToLocalUser(newUser);
|
|
308
|
+
console.log('Batch Update User End', user);
|
|
309
|
+
callback && callback();
|
|
310
|
+
} catch (e) {
|
|
311
|
+
console.error(e);
|
|
312
|
+
for (let i = 0; i < keys.length; i++) {
|
|
313
|
+
user.set(keys[i], oldValues[i]);
|
|
314
|
+
}
|
|
315
|
+
callback && callback(e);
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
|
|
319
|
+
updateUser: (key: string, value: string, callback: Function) => {
|
|
320
|
+
LoginManager.batchUpdateUser([key], [value], callback);
|
|
321
|
+
},
|
|
322
|
+
|
|
323
|
+
deleteUser: async (callback: Function) => {
|
|
324
|
+
try {
|
|
325
|
+
if (!CURRENT_USER) {
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
if (CURRENT_USER.type === LoginType.LoginTypeApple) {
|
|
329
|
+
await AppleLoginUtil.requestDeleteAccount();
|
|
330
|
+
}
|
|
331
|
+
const user = await AV.User.currentAsync();
|
|
332
|
+
console.log('get user success');
|
|
333
|
+
await user.destroy();
|
|
334
|
+
console.log('delete user success');
|
|
335
|
+
callback();
|
|
336
|
+
} catch (error) {
|
|
337
|
+
console.error(error);
|
|
338
|
+
callback(error);
|
|
339
|
+
}
|
|
340
|
+
},
|
|
341
|
+
|
|
342
|
+
lastLoginType: () => {
|
|
343
|
+
return PrefData.getValue(BuildInPrefs.LastLoginType);
|
|
344
|
+
},
|
|
345
|
+
|
|
346
|
+
fetchWeChatAvatar: (callback: Function) => {
|
|
347
|
+
WeChatLoginUtil.doLogin(
|
|
348
|
+
WeiXinId,
|
|
349
|
+
WeiXinSecret,
|
|
350
|
+
({ headimgurl }: { headimgurl: string }) => {
|
|
351
|
+
callback({ headimgurl });
|
|
352
|
+
}
|
|
353
|
+
);
|
|
354
|
+
},
|
|
355
|
+
};
|
package/src/Notification.ts
CHANGED
package/src/constant.ts
CHANGED
|
@@ -5,9 +5,26 @@ export interface UserType {
|
|
|
5
5
|
email: string;
|
|
6
6
|
headimgurl: string;
|
|
7
7
|
type: number;
|
|
8
|
+
isNew?: boolean;
|
|
8
9
|
AVUser: User;
|
|
9
10
|
}
|
|
10
11
|
|
|
12
|
+
export interface LoginAuthDataType {
|
|
13
|
+
openid: string;
|
|
14
|
+
unionid?: string;
|
|
15
|
+
access_token: string | null;
|
|
16
|
+
expires_in: number;
|
|
17
|
+
loginType: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface LoginUserDataType {
|
|
21
|
+
userId?: string;
|
|
22
|
+
nickname?: string;
|
|
23
|
+
headimgurl?: string;
|
|
24
|
+
email?: string | null;
|
|
25
|
+
authData: LoginAuthDataType;
|
|
26
|
+
}
|
|
27
|
+
|
|
11
28
|
export enum LoginState {
|
|
12
29
|
NOTLOGIN,
|
|
13
30
|
AUTHORIZED,
|
package/src/index.tsx
CHANGED
|
@@ -8,6 +8,7 @@ const { ReactNativeToolkit } = NativeModules;
|
|
|
8
8
|
|
|
9
9
|
export default ReactNativeToolkit as ReactNativeToolkitType;
|
|
10
10
|
export * from './AppleLoginUtil';
|
|
11
|
+
export * from './LoginManager';
|
|
11
12
|
export * from './Notification';
|
|
12
13
|
export * from './PrefData';
|
|
13
14
|
export * from './ReportUtil';
|