@norcy/react-native-toolkit 0.3.30 → 0.3.31
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/Auth.js +3 -3
- package/lib/commonjs/Auth.js.map +1 -1
- package/lib/commonjs/CloudBaseAuth.js +90 -148
- package/lib/commonjs/CloudBaseAuth.js.map +1 -1
- package/lib/commonjs/LeanCloudAuth.js +2 -6
- package/lib/commonjs/LeanCloudAuth.js.map +1 -1
- package/lib/commonjs/LoginManager.js +1 -1
- package/lib/commonjs/LoginManager.js.map +1 -1
- package/lib/module/Auth.js +3 -3
- package/lib/module/Auth.js.map +1 -1
- package/lib/module/CloudBaseAuth.js +90 -148
- package/lib/module/CloudBaseAuth.js.map +1 -1
- package/lib/module/LeanCloudAuth.js +2 -6
- package/lib/module/LeanCloudAuth.js.map +1 -1
- package/lib/module/LoginManager.js +1 -1
- package/lib/module/LoginManager.js.map +1 -1
- package/lib/typescript/Auth.d.ts +1 -1
- package/lib/typescript/Auth.d.ts.map +1 -1
- package/lib/typescript/CloudBaseAuth.d.ts +3 -3
- package/lib/typescript/CloudBaseAuth.d.ts.map +1 -1
- package/lib/typescript/LeanCloudAuth.d.ts +2 -2
- package/lib/typescript/LeanCloudAuth.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/Auth.ts +3 -3
- package/src/CloudBaseAuth.ts +112 -153
- package/src/LeanCloudAuth.ts +2 -6
- package/src/LoginManager.ts +1 -1
package/src/CloudBaseAuth.ts
CHANGED
|
@@ -1,36 +1,63 @@
|
|
|
1
|
-
import cloudbase from '@cloudbase/js-sdk';
|
|
2
1
|
import adapter from '@cloudbase/adapter-rn';
|
|
3
|
-
import
|
|
2
|
+
import cloudbase from '@cloudbase/js-sdk';
|
|
4
3
|
import {
|
|
5
4
|
LoginAuthDataType,
|
|
6
5
|
LoginType,
|
|
7
6
|
LoginUserDataType,
|
|
8
7
|
UserType,
|
|
9
8
|
} from './constant';
|
|
9
|
+
import { SyncPrefData } from './SyncPrefData';
|
|
10
10
|
import { ToolkitConfig } from './Tool';
|
|
11
11
|
|
|
12
12
|
cloudbase.useAdapters(adapter);
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* CloudBase 自定义登录所需的云函数约定(需部署到 CloudBase 并开启 HTTP 访问服务):
|
|
16
|
-
*
|
|
17
|
-
* ### loginWithAuthData(通过 ToolkitConfig.CloudBaseAuthUrl HTTP 调用)
|
|
18
|
-
* 请求体: { action, authData: { openid, unionid?, loginType }, userData?: { nickname, headimgurl, email }, source? }
|
|
19
|
-
* 响应体: { ticket: string, user: UserProfile, isNew: boolean }
|
|
20
|
-
* 逻辑: 根据 openid+loginType 查找 user_profile,不存在则创建用户(CreateUser API + user_profile 文档),
|
|
21
|
-
* 用 app.auth().createTicket(uid) 签发 ticket 并连同 user_profile 一起返回。
|
|
22
|
-
*
|
|
23
|
-
* ### destroyUser(已登录态下通过 callFunction 调用,云函数名 "auth")
|
|
24
|
-
* event: { action: 'destroyUser' }
|
|
25
|
-
* 逻辑: 从 context.auth 获取 uid,删除用户系统记录(DeleteUsers API)及 user_profile 文档。
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
14
|
let app: cloudbase.app.App | null = null;
|
|
29
|
-
let cachedProfile: any = null;
|
|
30
15
|
let authUrl = '';
|
|
16
|
+
const CACHED_PROFILE_KEY = 'CloudBaseAuth_CachedProfile_v1';
|
|
17
|
+
const LOGIN_TYPE_MAP: Record<string, number> = {
|
|
18
|
+
wechat: LoginType.LoginTypeWeChat,
|
|
19
|
+
visitor: LoginType.LoginTypeVisitor,
|
|
20
|
+
huawei: LoginType.LoginTypeHuawei,
|
|
21
|
+
apple: LoginType.LoginTypeApple,
|
|
22
|
+
};
|
|
31
23
|
|
|
32
|
-
|
|
24
|
+
interface CloudBaseProfile {
|
|
25
|
+
_id: string;
|
|
26
|
+
nickname: string;
|
|
27
|
+
email: string;
|
|
28
|
+
headimgurl: string;
|
|
29
|
+
loginType: string;
|
|
30
|
+
vipType?: string;
|
|
31
|
+
vipEndTime?: string | number | Date;
|
|
32
|
+
createdAt?: string | number | Date;
|
|
33
|
+
attr?: unknown;
|
|
34
|
+
webdav?: unknown;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
interface AuthResponse {
|
|
38
|
+
ticket: string;
|
|
39
|
+
user: CloudBaseProfile;
|
|
40
|
+
isNew?: boolean;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const toLocalUser = (profile: CloudBaseProfile): UserType => {
|
|
44
|
+
return {
|
|
45
|
+
id: profile._id,
|
|
46
|
+
nickname: profile.nickname,
|
|
47
|
+
email: profile.email,
|
|
48
|
+
headimgurl: profile.headimgurl,
|
|
49
|
+
type: LOGIN_TYPE_MAP[profile.loginType],
|
|
50
|
+
vipType: profile.vipType,
|
|
51
|
+
vipEndTime: profile.vipEndTime ? new Date(profile.vipEndTime) : undefined,
|
|
52
|
+
createdAt: profile.createdAt ? new Date(profile.createdAt) : undefined,
|
|
53
|
+
attr: profile.attr,
|
|
54
|
+
webdav: profile.webdav,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const getApp = () => {
|
|
33
59
|
if (app) return app;
|
|
60
|
+
|
|
34
61
|
const {
|
|
35
62
|
CloudBaseEnv,
|
|
36
63
|
CloudBaseAccessKey,
|
|
@@ -42,6 +69,7 @@ const ensureInit = () => {
|
|
|
42
69
|
'CloudBase config missing. Set CloudBaseEnv / CloudBaseAccessKey / CloudBaseAuthUrl in ToolkitConfig.'
|
|
43
70
|
);
|
|
44
71
|
}
|
|
72
|
+
|
|
45
73
|
app = cloudbase.init({
|
|
46
74
|
env: CloudBaseEnv,
|
|
47
75
|
region: CloudBaseRegion || 'ap-shanghai',
|
|
@@ -52,174 +80,105 @@ const ensureInit = () => {
|
|
|
52
80
|
return app;
|
|
53
81
|
};
|
|
54
82
|
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
|
|
83
|
+
const setCachedProfile = (profile?: CloudBaseProfile) => {
|
|
84
|
+
if (!profile) {
|
|
85
|
+
SyncPrefData.delete(CACHED_PROFILE_KEY);
|
|
86
|
+
} else {
|
|
87
|
+
SyncPrefData.set(CACHED_PROFILE_KEY, JSON.stringify(profile));
|
|
58
88
|
}
|
|
59
|
-
if (loginType === 'visitor') {
|
|
60
|
-
return LoginType.LoginTypeVisitor;
|
|
61
|
-
}
|
|
62
|
-
if (loginType === 'huawei') {
|
|
63
|
-
return LoginType.LoginTypeHuawei;
|
|
64
|
-
}
|
|
65
|
-
return LoginType.LoginTypeApple;
|
|
66
89
|
};
|
|
67
90
|
|
|
68
|
-
const
|
|
69
|
-
return
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
91
|
+
const getUid = () => {
|
|
92
|
+
return getApp().auth.hasLoginState()?.user.uid;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
const requestAuth = async (body: Record<string, unknown>) => {
|
|
96
|
+
getApp();
|
|
97
|
+
const response = await fetch(authUrl, {
|
|
98
|
+
method: 'POST',
|
|
99
|
+
headers: { 'Content-Type': 'application/json' },
|
|
100
|
+
body: JSON.stringify(body),
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
if (!response.ok) {
|
|
104
|
+
throw new Error(`CloudBase auth failed: ${response.status}`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return response.json() as Promise<AuthResponse>;
|
|
81
108
|
};
|
|
82
109
|
|
|
83
110
|
export const CloudBaseAuth = {
|
|
84
|
-
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
cachedProfile = null;
|
|
111
|
+
getLocalUser: async (): Promise<UserType | null> => {
|
|
112
|
+
const uid = getUid();
|
|
113
|
+
if (!uid) {
|
|
114
|
+
setCachedProfile();
|
|
89
115
|
return null;
|
|
90
116
|
}
|
|
91
117
|
|
|
92
|
-
|
|
93
|
-
|
|
118
|
+
const raw = SyncPrefData.getString(CACHED_PROFILE_KEY);
|
|
119
|
+
const profile = raw ? (JSON.parse(raw) as CloudBaseProfile) : null;
|
|
120
|
+
if (profile?._id === uid) {
|
|
121
|
+
return toLocalUser(profile);
|
|
94
122
|
}
|
|
95
123
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
const db = cbApp.database();
|
|
101
|
-
const { data } = await db.collection('user-profile').doc(uid).get();
|
|
102
|
-
if (!data || (Array.isArray(data) && data.length === 0)) return null;
|
|
103
|
-
cachedProfile = Array.isArray(data) ? data[0] : data;
|
|
104
|
-
return profileToLocalUser(cachedProfile);
|
|
105
|
-
} catch (error) {
|
|
106
|
-
console.log('CloudBase getCurrentUser error', error);
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
124
|
+
await CloudBaseAuth.logout();
|
|
125
|
+
return null;
|
|
109
126
|
},
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
login: async (
|
|
112
129
|
authData: LoginAuthDataType,
|
|
113
130
|
userData?: LoginUserDataType
|
|
114
131
|
): Promise<UserType> => {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
userData: userData
|
|
130
|
-
? {
|
|
131
|
-
nickname: userData.nickname,
|
|
132
|
-
headimgurl: userData.headimgurl,
|
|
133
|
-
email: userData.email,
|
|
134
|
-
}
|
|
135
|
-
: undefined,
|
|
136
|
-
source: Platform.OS === 'android' ? 2 : undefined,
|
|
137
|
-
}),
|
|
132
|
+
const { ticket, user, isNew } = await requestAuth({
|
|
133
|
+
action: 'login',
|
|
134
|
+
authData: {
|
|
135
|
+
openid: authData.openid,
|
|
136
|
+
unionid: authData.unionid,
|
|
137
|
+
loginType: authData.loginType,
|
|
138
|
+
},
|
|
139
|
+
userData: userData
|
|
140
|
+
? {
|
|
141
|
+
nickname: userData.nickname,
|
|
142
|
+
headimgurl: userData.headimgurl,
|
|
143
|
+
email: userData.email,
|
|
144
|
+
}
|
|
145
|
+
: undefined,
|
|
138
146
|
});
|
|
139
147
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const result = await response.json();
|
|
147
|
-
const { ticket, user, isNew } = result;
|
|
148
|
-
|
|
149
|
-
if (!ticket) {
|
|
150
|
-
console.log('CloudBase 登录失败: no ticket returned');
|
|
151
|
-
throw new Error('CloudBase auth: server did not return a ticket');
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
if (!user) {
|
|
155
|
-
console.log('CloudBase 登录失败: no user returned', result);
|
|
156
|
-
throw new Error('CloudBase auth: server did not return a user profile');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
const signInResult: any = await cbApp.auth.signInWithCustomTicket(() =>
|
|
160
|
-
Promise.resolve(ticket)
|
|
161
|
-
);
|
|
162
|
-
if (signInResult?.error) {
|
|
163
|
-
console.log('CloudBase 登录失败', signInResult.error);
|
|
164
|
-
throw signInResult.error;
|
|
165
|
-
}
|
|
166
|
-
console.log('CloudBase 登录成功');
|
|
167
|
-
|
|
168
|
-
cachedProfile = user;
|
|
169
|
-
const localUser = profileToLocalUser(user);
|
|
170
|
-
localUser.isNew = isNew ?? false;
|
|
148
|
+
await getApp().auth.signInWithCustomTicket(() => Promise.resolve(ticket));
|
|
149
|
+
setCachedProfile(user);
|
|
150
|
+
const localUser = toLocalUser(user);
|
|
151
|
+
localUser.isNew = isNew;
|
|
171
152
|
return localUser;
|
|
172
153
|
},
|
|
173
154
|
|
|
174
|
-
logout: () => {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
console.log('CloudBase signOut error', e);
|
|
178
|
-
});
|
|
179
|
-
cachedProfile = null;
|
|
155
|
+
logout: async () => {
|
|
156
|
+
await getApp().auth.signOut();
|
|
157
|
+
setCachedProfile();
|
|
180
158
|
},
|
|
181
159
|
|
|
182
160
|
updateUser: async (keys: string[], values: any[]): Promise<UserType> => {
|
|
183
|
-
const
|
|
184
|
-
const uid = cbApp.auth.currentUser?.uid;
|
|
161
|
+
const uid = getUid();
|
|
185
162
|
if (!uid) throw new Error('User Not Login Yet');
|
|
186
163
|
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
try {
|
|
197
|
-
await db.collection('user-profile').doc(uid).update(updateData);
|
|
198
|
-
const { data } = await db.collection('user-profile').doc(uid).get();
|
|
199
|
-
cachedProfile = Array.isArray(data) ? data[0] : data;
|
|
200
|
-
return profileToLocalUser(cachedProfile);
|
|
201
|
-
} catch (error) {
|
|
202
|
-
if (cachedProfile) {
|
|
203
|
-
for (let i = 0; i < keys.length; i++) {
|
|
204
|
-
cachedProfile[keys[i]] = oldValues[i];
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
throw error;
|
|
208
|
-
}
|
|
164
|
+
const { user } = await requestAuth({
|
|
165
|
+
action: 'updateUser',
|
|
166
|
+
uid,
|
|
167
|
+
keys,
|
|
168
|
+
values,
|
|
169
|
+
});
|
|
170
|
+
setCachedProfile(user);
|
|
171
|
+
return toLocalUser(user);
|
|
209
172
|
},
|
|
210
173
|
|
|
211
174
|
destroyUser: async () => {
|
|
212
|
-
const
|
|
213
|
-
const uid = cbApp.auth.currentUser?.uid;
|
|
175
|
+
const uid = getUid();
|
|
214
176
|
if (!uid) throw new Error('User Not Login Yet');
|
|
215
177
|
|
|
216
|
-
|
|
217
|
-
await cbApp.callFunction({
|
|
178
|
+
await getApp().callFunction({
|
|
218
179
|
name: 'auth',
|
|
219
180
|
data: { action: 'destroyUser' },
|
|
220
181
|
});
|
|
221
|
-
|
|
222
|
-
await cbApp.auth.signOut();
|
|
223
|
-
cachedProfile = null;
|
|
182
|
+
await CloudBaseAuth.logout();
|
|
224
183
|
},
|
|
225
184
|
};
|
package/src/LeanCloudAuth.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { User } from 'leancloud-storage';
|
|
2
|
-
import { Platform } from 'react-native';
|
|
3
2
|
import {
|
|
4
3
|
LoginAuthDataType,
|
|
5
4
|
LoginType,
|
|
@@ -38,12 +37,12 @@ const getLoginTypeNum = (loginType?: string) => {
|
|
|
38
37
|
};
|
|
39
38
|
|
|
40
39
|
export const LeanCloudAuth = {
|
|
41
|
-
|
|
40
|
+
getLocalUser: async (): Promise<UserType | null> => {
|
|
42
41
|
const user = await AV.User.currentAsync();
|
|
43
42
|
return user ? AVUserToLocalUser(user) : null;
|
|
44
43
|
},
|
|
45
44
|
|
|
46
|
-
|
|
45
|
+
login: async (
|
|
47
46
|
authData: LoginAuthDataType,
|
|
48
47
|
userData?: LoginUserDataType
|
|
49
48
|
): Promise<UserType> => {
|
|
@@ -80,9 +79,6 @@ export const LeanCloudAuth = {
|
|
|
80
79
|
newUser.set('nickname', userData?.nickname);
|
|
81
80
|
newUser.set('headimgurl', userData?.headimgurl);
|
|
82
81
|
newUser.set('type', getLoginTypeNum(loginType));
|
|
83
|
-
if (Platform.OS === 'android') {
|
|
84
|
-
newUser.set('source', 2);
|
|
85
|
-
}
|
|
86
82
|
try {
|
|
87
83
|
const user: User = await newUser.loginWithAuthData(authData, loginType);
|
|
88
84
|
console.log('Lean Cloud 注册成功');
|
package/src/LoginManager.ts
CHANGED
|
@@ -55,7 +55,7 @@ const doLogin = async (
|
|
|
55
55
|
userData?: LoginUserDataType
|
|
56
56
|
) => {
|
|
57
57
|
try {
|
|
58
|
-
const user = await Auth.
|
|
58
|
+
const user = await Auth.login(authData, userData);
|
|
59
59
|
onLoginFinish({ user });
|
|
60
60
|
} catch (error: any) {
|
|
61
61
|
onLoginFinish({ error });
|