@cloudbase/auth 1.7.3-alpha.0 → 2.0.0-alpha.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.
Files changed (56) hide show
  1. package/dist/cjs/index.d.ts +50 -101
  2. package/dist/cjs/index.js +415 -778
  3. package/dist/esm/index.d.ts +50 -101
  4. package/dist/esm/index.js +416 -775
  5. package/package.json +52 -54
  6. package/src/index.ts +401 -766
  7. package/dist/cjs/common.d.ts +0 -8
  8. package/dist/cjs/common.js +0 -64
  9. package/dist/cjs/constants.d.ts +0 -12
  10. package/dist/cjs/constants.js +0 -17
  11. package/dist/cjs/providers/anonymousAuthProvider.d.ts +0 -15
  12. package/dist/cjs/providers/anonymousAuthProvider.js +0 -256
  13. package/dist/cjs/providers/base.d.ts +0 -21
  14. package/dist/cjs/providers/base.js +0 -152
  15. package/dist/cjs/providers/customAuthProvider.d.ts +0 -5
  16. package/dist/cjs/providers/customAuthProvider.js +0 -150
  17. package/dist/cjs/providers/emailAuthProvider.d.ts +0 -9
  18. package/dist/cjs/providers/emailAuthProvider.js +0 -250
  19. package/dist/cjs/providers/oauth2AuthProvider.d.ts +0 -61
  20. package/dist/cjs/providers/oauth2AuthProvider.js +0 -404
  21. package/dist/cjs/providers/phoneAuthProvider.d.ts +0 -17
  22. package/dist/cjs/providers/phoneAuthProvider.js +0 -219
  23. package/dist/cjs/providers/usernameAuthProvider.d.ts +0 -5
  24. package/dist/cjs/providers/usernameAuthProvider.js +0 -169
  25. package/dist/cjs/providers/weixinAuthProvider.d.ts +0 -28
  26. package/dist/cjs/providers/weixinAuthProvider.js +0 -294
  27. package/dist/esm/common.d.ts +0 -8
  28. package/dist/esm/common.js +0 -61
  29. package/dist/esm/constants.d.ts +0 -12
  30. package/dist/esm/constants.js +0 -14
  31. package/dist/esm/providers/anonymousAuthProvider.d.ts +0 -15
  32. package/dist/esm/providers/anonymousAuthProvider.js +0 -253
  33. package/dist/esm/providers/base.d.ts +0 -21
  34. package/dist/esm/providers/base.js +0 -149
  35. package/dist/esm/providers/customAuthProvider.d.ts +0 -5
  36. package/dist/esm/providers/customAuthProvider.js +0 -147
  37. package/dist/esm/providers/emailAuthProvider.d.ts +0 -9
  38. package/dist/esm/providers/emailAuthProvider.js +0 -247
  39. package/dist/esm/providers/oauth2AuthProvider.d.ts +0 -61
  40. package/dist/esm/providers/oauth2AuthProvider.js +0 -401
  41. package/dist/esm/providers/phoneAuthProvider.d.ts +0 -17
  42. package/dist/esm/providers/phoneAuthProvider.js +0 -216
  43. package/dist/esm/providers/usernameAuthProvider.d.ts +0 -5
  44. package/dist/esm/providers/usernameAuthProvider.js +0 -166
  45. package/dist/esm/providers/weixinAuthProvider.d.ts +0 -28
  46. package/dist/esm/providers/weixinAuthProvider.js +0 -291
  47. package/src/common.ts +0 -21
  48. package/src/constants.ts +0 -13
  49. package/src/providers/anonymousAuthProvider.ts +0 -126
  50. package/src/providers/base.ts +0 -78
  51. package/src/providers/customAuthProvider.ts +0 -69
  52. package/src/providers/emailAuthProvider.ts +0 -142
  53. package/src/providers/oauth2AuthProvider.ts +0 -585
  54. package/src/providers/phoneAuthProvider.ts +0 -132
  55. package/src/providers/usernameAuthProvider.ts +0 -77
  56. package/src/providers/weixinAuthProvider.ts +0 -193
package/src/index.ts CHANGED
@@ -1,82 +1,79 @@
1
1
  import { ICloudbase } from '@cloudbase/types';
2
- import { events, adapters, utils, constants, helpers } from '@cloudbase/utilities';
2
+ import { utils, constants, helpers, events } from '@cloudbase/utilities';
3
3
  import { ICloudbaseCache } from '@cloudbase/types/cache';
4
4
  import { ICloudbaseRequest } from '@cloudbase/types/request';
5
- import { ICloudbaseAuthConfig, ICredential, IUser, IUserInfo, IAuthProvider, ILoginState } from '@cloudbase/types/auth';
5
+ import { ICloudbaseAuthConfig, IUser, IUserInfo, ILoginState } from '@cloudbase/types/auth';
6
6
  import { ICloudbaseComponent } from '@cloudbase/types/component';
7
- import { checkFromAuthV2 } from './common'
8
7
 
9
- import { LOGINTYPE, OAUTH2_LOGINTYPE_PREFIX } from './constants';
10
-
11
- import { AuthProvider } from './providers/base';
12
-
13
- import { OAuth2AuthProvider, IOAuth2AuthProviderOptions } from './providers/oauth2AuthProvider';
14
-
15
- import { AnonymousAuthProvider } from './providers/anonymousAuthProvider';
16
- import { CustomAuthProvider } from './providers/customAuthProvider';
17
- import { EmailAuthProvider } from './providers/emailAuthProvider';
18
- import { PhoneAuthProvider, SIGN_METHOD } from './providers/phoneAuthProvider'
19
- import { UsernameAuthProvider } from './providers/usernameAuthProvider';
20
- import { WeixinAuthProvider } from './providers/weixinAuthProvider';
8
+ import { authModels, CloudbaseOAuth } from '@cloudbase/oauth'
21
9
 
22
10
  declare const cloudbase: ICloudbase;
23
11
 
24
- const { CloudbaseEventEmitter } = events;
25
- const { RUNTIME } = adapters;
26
- const { printWarn, throwError, transformPhone } = utils;
12
+ const { printWarn, throwError } = utils;
27
13
  const { ERRORS, COMMUNITY_SITE_URL } = constants;
28
14
  const { catchErrorsDecorator } = helpers;
15
+ const { CloudbaseEventEmitter } = events;
29
16
 
30
17
  const COMPONENT_NAME = 'auth';
31
18
 
19
+ const EVENTS = {
20
+ // 登录态改变后触发
21
+ LOGIN_STATE_CHANGED: 'loginStateChanged',
22
+ };
23
+
32
24
  interface UserInfo {
33
- openid: string;
34
- nickname?: string;
35
- sex?: number;
36
- province?: string;
37
- city?: string;
38
- country?: string;
39
- headimgurl?: string;
40
- privilege?: [string];
41
- unionid?: string;
25
+ uid?: string;
26
+ gender?: string;
27
+ avatarUrl?: string;
28
+ picture?: string;
29
+ email?: string;
30
+ email_verified?: boolean;
31
+ phone_number?: string;
32
+ username?: string;
33
+ name?: string;
34
+ birthdate?: string;
35
+ zoneinfo?: string;
36
+ locale?: string;
37
+ sub?: string;
38
+ created_from?: string;
42
39
  }
43
40
 
44
41
  const eventBus = new CloudbaseEventEmitter();
45
42
 
46
43
  interface IUserOptions {
47
44
  cache: ICloudbaseCache;
48
- request: ICloudbaseRequest;
45
+ // request: ICloudbaseRequest;
46
+ oauthInstance: CloudbaseOAuth
49
47
  }
50
48
 
51
49
  class User implements IUser {
52
- public uid: string;
53
- public loginType: string;
54
- public openid: string;
55
- public wxOpenId: string;
56
- public wxPublicId: string;
57
- public unionId: string;
58
- public qqMiniOpenId: string;
59
- public customUserId: string;
60
- public nickName: string;
61
- public gender: string;
62
- public avatarUrl: string;
63
- public email: string;
64
- public hasPassword: boolean;
65
- public phone?: string;
50
+ public uid?: string;
51
+ public gender?: string;
52
+ public avatarUrl?: string;
53
+ public picture?: string;
54
+ public email?: string;
55
+ public email_verified?: boolean;
56
+ public phone_number?: string;
66
57
  public username?: string;
67
- public location?: {
68
- country?: string;
69
- province?: string;
70
- city?: string;
71
- };
58
+ public name?: string;
59
+ public providers?: {
60
+ id?: string;
61
+ provider_user_id?: string;
62
+ name?: string;
63
+ }[]
64
+ public birthdate?: string;
65
+ public zoneinfo?: string;
66
+ public locale?: string;
67
+ public sub?: string;
68
+ public created_from?: string;
72
69
 
73
70
  private _cache: ICloudbaseCache;
74
- private _request: ICloudbaseRequest;
71
+ private _oauthInstance: CloudbaseOAuth // CloudbaseOAuth 类型
75
72
 
76
73
  constructor(options: IUserOptions) {
77
- const { cache, request } = options;
74
+ const { cache, oauthInstance } = options;
78
75
  this._cache = cache;
79
- this._request = request;
76
+ this._oauthInstance = oauthInstance
80
77
 
81
78
  this._setUserInfo();
82
79
  }
@@ -84,149 +81,44 @@ class User implements IUser {
84
81
  * 获取本地用户信息-同步
85
82
  */
86
83
  public async checkLocalInfo() {
87
- this.uid = this._getLocalUserInfo('uid');
88
- this.loginType = this._getLocalUserInfo('loginType');
89
- this.openid = this._getLocalUserInfo('wxOpenId');
90
- this.wxOpenId = this._getLocalUserInfo('wxOpenId');
91
- this.wxPublicId = this._getLocalUserInfo('wxPublicId');
92
- this.unionId = this._getLocalUserInfo('wxUnionId');
93
- this.qqMiniOpenId = this._getLocalUserInfo('qqMiniOpenId');
94
- this.customUserId = this._getLocalUserInfo('customUserId');
95
- this.nickName = this._getLocalUserInfo('nickName');
96
- this.gender = this._getLocalUserInfo('gender');
97
- this.avatarUrl = this._getLocalUserInfo('avatarUrl');
98
- this.email = this._getLocalUserInfo('email');
99
- this.hasPassword = Boolean(this._getLocalUserInfo('hasPassword'));
100
- this.phone = this._getLocalUserInfo('phone')
101
- this.username = this._getLocalUserInfo('username')
102
- this.location = {
103
- country: this._getLocalUserInfo('country'),
104
- province: this._getLocalUserInfo('province'),
105
- city: this._getLocalUserInfo('city')
106
- };
84
+ this.uid = this._getLocalUserInfo('uid') as string;
85
+ this.gender = this._getLocalUserInfo('gender') as string;
86
+ this.picture = this._getLocalUserInfo('picture') as string;
87
+ this.avatarUrl = this._getLocalUserInfo('avatarUrl') as string;
88
+ this.email = this._getLocalUserInfo('email') as string;
89
+ this.email_verified = this._getLocalUserInfo('email_verified') as boolean;
90
+ this.phone_number = this._getLocalUserInfo('phone_number') as string
91
+ this.username = this._getLocalUserInfo('username') as string
92
+ this.name = this._getLocalUserInfo('name') as string
93
+ this.birthdate = this._getLocalUserInfo('birthdate') as string
94
+ this.zoneinfo = this._getLocalUserInfo('zoneinfo') as string
95
+ this.locale = this._getLocalUserInfo('locale') as string
96
+ this.sub = this._getLocalUserInfo('sub') as string
97
+ this.created_from = this._getLocalUserInfo('created_from') as string
98
+ this.providers = this._getLocalUserInfo('providers') as any
107
99
  }
108
100
  /**
109
101
  * 获取本地用户信息-异步
110
102
  */
111
103
  public async checkLocalInfoAsync() {
112
104
  this.uid = await this._getLocalUserInfoAsync('uid');
113
- this.loginType = await this._getLocalUserInfoAsync('loginType');
114
- this.openid = await this._getLocalUserInfoAsync('wxOpenId');
115
- this.wxOpenId = await this._getLocalUserInfoAsync('wxOpenId');
116
- this.wxPublicId = await this._getLocalUserInfoAsync('wxPublicId');
117
- this.unionId = await this._getLocalUserInfoAsync('wxUnionId');
118
- this.qqMiniOpenId = await this._getLocalUserInfoAsync('qqMiniOpenId');
119
- this.customUserId = await this._getLocalUserInfoAsync('customUserId');
120
- this.nickName = await this._getLocalUserInfoAsync('nickName');
121
105
  this.gender = await this._getLocalUserInfoAsync('gender');
106
+ this.picture = this._getLocalUserInfo('picture') as string;
122
107
  this.avatarUrl = await this._getLocalUserInfoAsync('avatarUrl');
123
108
  this.email = await this._getLocalUserInfoAsync('email');
124
- this.hasPassword = Boolean(await this._getLocalUserInfoAsync('hasPassword'));
125
- this.phone = await this._getLocalUserInfoAsync('phone')
109
+ this.email_verified = this._getLocalUserInfo('email_verified') as boolean;
110
+ this.phone_number = this._getLocalUserInfo('phone_number') as string
126
111
  this.username = await this._getLocalUserInfoAsync('username')
127
- this.location = {
128
- country: await this._getLocalUserInfoAsync('country'),
129
- province: await this._getLocalUserInfoAsync('province'),
130
- city: await this._getLocalUserInfoAsync('city')
131
- };
112
+ this.name = this._getLocalUserInfo('name') as string
113
+ this.birthdate = this._getLocalUserInfo('birthdate') as string
114
+ this.zoneinfo = this._getLocalUserInfo('zoneinfo') as string
115
+ this.locale = this._getLocalUserInfo('locale') as string
116
+ this.sub = this._getLocalUserInfo('sub') as string
117
+ this.created_from = this._getLocalUserInfo('created_from') as string
118
+ this.providers = this._getLocalUserInfo('providers') as any
132
119
  }
133
120
 
134
- /**
135
- * 将当前账户与自定义登录 Ticket 进行绑定,绑定之后便可以通过自定义登录登录当前云开发账户。
136
- * @param {string} ticket 自定义登录ticket
137
- */
138
- @catchErrorsDecorator({
139
- title: '绑定自定义登录失败',
140
- messages: [
141
- '请确认以下各项:',
142
- ' 1 - 调用 User.linkWithTicket() 的语法或参数是否正确',
143
- ' 2 - 此账户是否已经绑定自定义登录',
144
- ' 3 - ticket 参数是否归属当前环境',
145
- ' 4 - 创建 ticket 的自定义登录私钥是否过期',
146
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
147
- ]
148
- })
149
- public linkWithTicket(ticket: string): Promise<void> {
150
- if (typeof ticket !== 'string') {
151
- throw new Error('ticket must be string');
152
- }
153
- return this._request.send('auth.linkWithTicket', { ticket });
154
- }
155
- /**
156
- * 将当前账户与第三方鉴权提供方,以重定向的形式,进行绑定,绑定之后便可以通过第三方鉴权提供方登录当前的云开发账户。
157
- * @param provider 特定登录方式的provider,必须具备signInWithRedirect方法
158
- */
159
- @catchErrorsDecorator({
160
- title: '绑定第三方登录方式失败',
161
- messages: [
162
- '请确认以下各项:',
163
- ' 1 - 调用 User.linkWithRedirect() 的语法或参数是否正确',
164
- ' 2 - 此账户是否已经绑定此第三方',
165
- ' 3 - 此第三方是否已经授权',
166
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
167
- ]
168
- })
169
- public linkWithRedirect(provider: IAuthProvider): void {
170
- provider.signInWithRedirect();
171
- }
172
- /**
173
- * 获取当前账户的微信 UnionID 绑定的云开发账户列表。如果当前账户不存在 UnionID,会返回错误。
174
- */
175
- @catchErrorsDecorator({
176
- title: '获取账户列表失败',
177
- messages: [
178
- '请确认以下各项:',
179
- ' 1 - 调用 User.getLinkedUidList() 的语法或参数是否正确',
180
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
181
- ]
182
- })
183
- public async getLinkedUidList() {
184
- const { data } = await this._request.send('auth.getLinkedUidList', {});
185
- let hasPrimaryUid = false;
186
- const users = data.users as IUserInfo[];
187
- for (const user of users) {
188
- if (user.wxOpenId && user.wxPublicId) {
189
- hasPrimaryUid = true;
190
- break;
191
- }
192
- }
193
- return {
194
- users,
195
- hasPrimaryUid
196
- };
197
- }
198
- /**
199
- * 设置微信主账号,通常搭配和 User.getLinkedUidList() 使用,用于在同个微信 UnionID 对应的多个云开发账号中,设置其中一个为主账号
200
- * 设置之后,通过 UnionID 登录便会登录至主账号之上。
201
- * @param uid
202
- */
203
- @catchErrorsDecorator({
204
- title: '设置微信主账号失败',
205
- messages: [
206
- '请确认以下各项:',
207
- ' 1 - 调用 User.setPrimaryUid() 的语法或参数是否正确',
208
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
209
- ]
210
- })
211
- public setPrimaryUid(uid: string) {
212
- return this._request.send('auth.setPrimaryUid', { uid });
213
- }
214
- /**
215
- * 解绑某个登录方式
216
- * @param loginType
217
- */
218
- @catchErrorsDecorator({
219
- title: '接触绑定失败',
220
- messages: [
221
- '请确认以下各项:',
222
- ' 1 - 调用 User.unlink() 的语法或参数是否正确',
223
- ' 2 - 当前账户是否已经与此登录方式解绑',
224
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
225
- ]
226
- })
227
- public unlink(loginType: 'CUSTOM' | 'WECHAT-OPEN' | 'WECHAT-PUBLIC' | 'WECHAT-UNION' | 'PHONE') {
228
- return this._request.send('auth.unlink', { platform: loginType });
229
- }
121
+
230
122
  /**
231
123
  * 更新用户信息
232
124
  * @param userInfo
@@ -241,8 +133,9 @@ class User implements IUser {
241
133
  ]
242
134
  })
243
135
  public async update(userInfo: IUserInfo): Promise<void> {
244
- const { nickName, gender, avatarUrl, province, country, city } = userInfo;
245
- const { data: newUserInfo } = await this._request.send('auth.updateUserInfo', { nickName, gender, avatarUrl, province, country, city });
136
+ const { name, gender, avatarUrl, province, country, city } = userInfo;
137
+ const newUserInfo = await this._oauthInstance.authApi.setUserProfile({ name, gender, avatarUrl, province, country, city })
138
+
246
139
  this._setLocalUserInfo(newUserInfo);
247
140
  }
248
141
  /**
@@ -260,30 +153,12 @@ class User implements IUser {
260
153
  ]
261
154
  })
262
155
  public updatePassword(newPassword: string, oldPassword: string) {
263
- return this._request.send('auth.updatePassword', {
264
- oldPassword,
265
- newPassword
266
- });
267
- }
268
- /**
269
- * 更新邮箱地址
270
- * @param newEmail
271
- */
272
- @catchErrorsDecorator({
273
- title: '更新邮箱地址失败',
274
- messages: [
275
- '请确认以下各项:',
276
- ' 1 - 调用 User.updateEmail() 的语法或参数是否正确',
277
- ' 2 - 当前环境是否开通了邮箱密码登录',
278
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
279
- ]
280
- })
281
- public updateEmail(newEmail: string, password?: string) {
282
- return this._request.send('auth.updateEmail', {
283
- newEmail,
284
- password
285
- });
156
+ return this._oauthInstance.authApi.updatePasswordByOld({
157
+ old_password: oldPassword,
158
+ new_password: newPassword
159
+ })
286
160
  }
161
+
287
162
  /**
288
163
  * 更新用户名
289
164
  * @param username
@@ -302,10 +177,11 @@ class User implements IUser {
302
177
  throwError(ERRORS.INVALID_PARAMS, 'username must be a string');
303
178
  }
304
179
 
305
- return this._request.send('auth.updateUsername', {
180
+ return this.update({
306
181
  username
307
- });
182
+ })
308
183
  }
184
+
309
185
  /**
310
186
  * 刷新本地用户信息。当用户在其他客户端更新用户信息之后,可以调用此接口同步更新之后的信息。
311
187
  */
@@ -318,54 +194,12 @@ class User implements IUser {
318
194
  ]
319
195
  })
320
196
  public async refresh(): Promise<IUserInfo> {
321
- const action = 'auth.getUserInfo';
322
- const { data: userInfo } = await this._request.send(action, {});
323
- this._setLocalUserInfo(userInfo);
324
- return userInfo;
325
- }
326
-
327
- /**
328
- * 绑定手机号
329
- * @param phoneNumber
330
- * @param phoneCode
331
- */
332
- @catchErrorsDecorator({
333
- title: '绑定手机号失败',
334
- messages: [
335
- '请确认以下各项:',
336
- ' 1 - 调用 auth().linkWithPhoneNumber() 的语法或参数是否正确',
337
- ' 2 - 当前环境是否开通了短信验证码登录',
338
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
339
- ]
340
- })
341
- public async linkWithPhoneNumber(phoneNumber: string, phoneCode: string) {
342
- return this._request.send('auth.linkOrUpdatePhoneNumber', {
343
- phoneNumber: transformPhone(phoneNumber),
344
- phoneCode
345
- });
346
- }
347
- /**
348
- * 更新手机号
349
- * @param phoneNumber
350
- * @param phoneCode
351
- */
352
- @catchErrorsDecorator({
353
- title: '更新手机号失败',
354
- messages: [
355
- '请确认以下各项:',
356
- ' 1 - 调用语法或参数是否正确',
357
- ' 2 - 当前环境是否开通了短信验证码登录',
358
- `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
359
- ]
360
- })
361
- public async updatePhoneNumber(phoneNumber: string, phoneCode: string) {
362
- return this._request.send('auth.linkOrUpdatePhoneNumber', {
363
- phoneNumber: transformPhone(phoneNumber),
364
- phoneCode
365
- });
197
+ const newUserInfo = await this._oauthInstance.authApi.getUserInfo()
198
+ this._setLocalUserInfo(newUserInfo);
199
+ return newUserInfo;
366
200
  }
367
201
 
368
- private _getLocalUserInfo(key: string): string {
202
+ private _getLocalUserInfo(key: string): string | boolean {
369
203
  const { userInfoKey } = this._cache.keys;
370
204
  const userInfo = this._cache.getStore(userInfoKey);
371
205
  return userInfo[key];
@@ -382,29 +216,24 @@ class User implements IUser {
382
216
  const userInfo = this._cache.getStore(userInfoKey);
383
217
  [
384
218
  'uid',
385
- 'loginType',
386
- 'openid',
387
- 'wxOpenId',
388
- 'wxPublicId',
389
- 'unionId',
390
- 'qqMiniOpenId',
391
219
  'email',
392
- 'hasPassword',
393
- 'customUserId',
394
- 'nickName',
220
+ 'name',
395
221
  'gender',
222
+ 'picture',
396
223
  'avatarUrl',
397
224
  'phone',
225
+ 'email_verified',
226
+ 'phone_number',
227
+ 'birthdate',
228
+ 'zoneinfo',
229
+ 'locale',
230
+ 'sub',
231
+ 'created_from',
232
+ 'providers',
398
233
  'username'
399
234
  ].forEach(infoKey => {
400
235
  this[infoKey] = userInfo[infoKey];
401
236
  });
402
-
403
- this.location = {
404
- country: userInfo['country'],
405
- province: userInfo['province'],
406
- city: userInfo['city']
407
- };
408
237
  }
409
238
 
410
239
  private _setLocalUserInfo(userInfo: any) {
@@ -417,108 +246,143 @@ interface ILoginStateOptions extends IUserOptions {
417
246
  envId: string;
418
247
  }
419
248
  export class LoginState implements ILoginState {
420
- public credential: ICredential;
421
249
  public user: IUser;
250
+ public oauthLoginState: any
422
251
 
252
+ private _oauthInstance: CloudbaseOAuth
423
253
  private _cache: ICloudbaseCache;
424
- private _loginType: string;
425
254
 
426
255
  constructor(options: ILoginStateOptions) {
427
- const { envId, cache, request } = options;
256
+ const { envId, cache, oauthInstance } = options;
428
257
  if (!envId) {
429
258
  throwError(ERRORS.INVALID_PARAMS, 'envId is not defined');
430
259
  }
431
260
  this._cache = cache;
261
+ this._oauthInstance = oauthInstance
432
262
 
433
263
  this.user = new User({
434
- cache,
435
- request
264
+ cache: this._cache,
265
+ oauthInstance
436
266
  });
437
267
  }
438
268
 
439
-
440
- public async checkLocalState() {
441
- const { refreshTokenKey, accessTokenKey, accessTokenExpireKey } = this._cache.keys;
442
- const refreshToken = this._cache.getStore(refreshTokenKey);
443
- const accessToken = this._cache.getStore(accessTokenKey);
444
- const accessTokenExpire = this._cache.getStore(accessTokenExpireKey);
445
-
446
- this.credential = {
447
- refreshToken,
448
- accessToken,
449
- accessTokenExpire
450
- };
451
-
452
- this._loginType = this._cache.getStore(this._cache.keys.loginTypeKey);
453
-
269
+ public checkLocalState() {
270
+ this.oauthLoginState = this._oauthInstance?.authApi.hasLoginStateSync()
454
271
  this.user.checkLocalInfo();
455
272
  }
456
- public async checkLocalStateAsync() {
457
- const { refreshTokenKey, accessTokenKey, accessTokenExpireKey } = this._cache.keys;
458
- const refreshToken = await this._cache.getStoreAsync(refreshTokenKey);
459
- const accessToken = await this._cache.getStoreAsync(accessTokenKey);
460
- const accessTokenExpire = await this._cache.getStoreAsync(accessTokenExpireKey);
461
-
462
- this.credential = {
463
- refreshToken,
464
- accessToken,
465
- accessTokenExpire
466
- };
467
-
468
- this._loginType = await this._cache.getStoreAsync(this._cache.keys.loginTypeKey);
469
-
470
273
 
274
+ public async checkLocalStateAsync() {
275
+ await this._oauthInstance?.authApi.getLoginState()
471
276
  await this.user.checkLocalInfoAsync();
472
277
  }
278
+ }
473
279
 
474
- get isAnonymousAuth() {
475
- return this.loginType === LOGINTYPE.ANONYMOUS;
476
- }
280
+ class Auth {
281
+ private readonly _config: ICloudbaseAuthConfig;
282
+ private readonly _cache: ICloudbaseCache
283
+ // private readonly _request: ICloudbaseRequest;
477
284
 
478
- get isCustomAuth() {
479
- return this.loginType === LOGINTYPE.CUSTOM;
480
- }
285
+ private _oauthInstance: CloudbaseOAuth
481
286
 
482
- get isWeixinAuth() {
483
- return this.loginType === LOGINTYPE.WECHAT || this.loginType === LOGINTYPE.WECHAT_OPEN || this.loginType === LOGINTYPE.WECHAT_PUBLIC;
287
+ constructor(config: ICloudbaseAuthConfig & { cache: ICloudbaseCache, request?: ICloudbaseRequest, runtime?: string }) {
288
+ this._config = config;
289
+ this._cache = config.cache;
290
+ // this._request = config.request;
291
+ this._oauthInstance = config.oauthInstance
484
292
  }
485
293
 
486
- get isUsernameAuth() {
487
- return this.loginType === LOGINTYPE.USERNAME;
294
+ /**
295
+ * 绑定手机号
296
+ * @param phoneNumber
297
+ * @param phoneCode
298
+ */
299
+ @catchErrorsDecorator({
300
+ title: '绑定手机号失败',
301
+ messages: [
302
+ '请确认以下各项:',
303
+ ' 1 - 调用 auth().bindPhoneNumber() 的语法或参数是否正确',
304
+ ' 2 - 当前环境是否开通了短信验证码登录',
305
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
306
+ ]
307
+ })
308
+ public async bindPhoneNumber(params: authModels.BindPhoneRequest) {
309
+ return this._oauthInstance.authApi.bindPhone(params)
488
310
  }
489
311
 
490
- get loginType() {
491
- return this._loginType
312
+ /**
313
+ * 解绑三方绑定
314
+ * @param loginType
315
+ */
316
+ @catchErrorsDecorator({
317
+ title: '解除三方绑定失败',
318
+ messages: [
319
+ '请确认以下各项:',
320
+ ' 1 - 调用 auth().unbindProvider() 的语法或参数是否正确',
321
+ ' 2 - 当前账户是否已经与此登录方式解绑',
322
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
323
+ ]
324
+ })
325
+ public async unbindProvider(params: authModels.UnbindProviderRequest): Promise<void> {
326
+ return this._oauthInstance.authApi.unbindProvider(params)
492
327
  }
493
328
 
494
- get isPhoneAuth() {
495
- return this.loginType === LOGINTYPE.PHONE
329
+ /**
330
+ * 更新邮箱地址
331
+ * @param email
332
+ * @param sudo_token
333
+ * @param verification_token
334
+ */
335
+ @catchErrorsDecorator({
336
+ title: '绑定邮箱地址失败',
337
+ messages: [
338
+ '请确认以下各项:',
339
+ ' 1 - 调用 auth().bindEmail() 的语法或参数是否正确',
340
+ ' 2 - 当前环境是否开通了邮箱密码登录',
341
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
342
+ ]
343
+ })
344
+ public bindEmail(params: authModels.BindEmailRequest) {
345
+ return this._oauthInstance.authApi.bindEmail(params)
496
346
  }
497
- }
498
347
 
499
- class Auth {
500
- private readonly _config: ICloudbaseAuthConfig;
501
- private readonly _cache: ICloudbaseCache
502
- private readonly _request: ICloudbaseRequest;
503
- private readonly _runtime: string;
504
- private _anonymousAuthProvider: AnonymousAuthProvider;
505
- private _customAuthProvider: CustomAuthProvider;
506
- private _weixinAuthProvider: WeixinAuthProvider;
507
- private _emailAuthProvider: EmailAuthProvider;
508
- private _usernameAuthProvider: UsernameAuthProvider;
509
- private _phoneAuthProvider: PhoneAuthProvider;
510
- // private _fromApp: ICloudbase
511
-
512
- private _oAuth2AuthProvider: OAuth2AuthProvider;
513
-
514
- constructor(config: ICloudbaseAuthConfig & { cache: ICloudbaseCache, request: ICloudbaseRequest, runtime?: string }) {
515
- this._config = config;
516
- this._cache = config.cache;
517
- this._request = config.request;
518
- this._runtime = config.runtime || RUNTIME.WEB
519
- // this._fromApp = config._fromApp
348
+ /**
349
+ * verify
350
+ * @param {authModels.VerifyRequest} params
351
+ * @returns {Promise<authModels.VerifyResponse>}
352
+ * @memberof User
353
+ */
354
+ @catchErrorsDecorator({
355
+ title: '验证码验证失败',
356
+ messages: [
357
+ '请确认以下各项:',
358
+ ' 1 - 调用 auth().verify() 的语法或参数是否正确',
359
+ ' 2 - 当前环境是否开通了手机验证码/邮箱登录',
360
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
361
+ ]
362
+ })
363
+ public async verify(params: authModels.VerifyRequest): Promise<authModels.VerifyResponse> {
364
+ return this._oauthInstance.authApi.verify(params)
365
+ }
520
366
 
521
- eventBus.on(EVENTS.LOGIN_TYPE_CHANGED, this._onLoginTypeChanged.bind(this));
367
+ /**
368
+ * 获取验证码
369
+ * @param {authModels.GetVerificationRequest} params
370
+ * @returns {Promise<authModels.GetVerificationResponse>}
371
+ * @memberof User
372
+ */
373
+ @catchErrorsDecorator({
374
+ title: '获取验证码失败',
375
+ messages: [
376
+ '请确认以下各项:',
377
+ ' 1 - 调用 auth().getVerification() 的语法或参数是否正确',
378
+ ' 2 - 当前环境是否开通了手机验证码/邮箱登录',
379
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
380
+ ]
381
+ })
382
+ public async getVerification(
383
+ params: authModels.GetVerificationRequest,
384
+ ): Promise<authModels.GetVerificationResponse> {
385
+ return this._oauthInstance.authApi.getVerification(params)
522
386
  }
523
387
 
524
388
  /**
@@ -527,7 +391,7 @@ class Auth {
527
391
  get currentUser() {
528
392
  if (this._cache.mode === 'async') {
529
393
  // async storage的平台调用此API提示
530
- printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use getCurrenUser insteed');
394
+ printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use getCurrentUser insteed');
531
395
  return;
532
396
  }
533
397
 
@@ -540,13 +404,6 @@ class Auth {
540
404
  }
541
405
  }
542
406
 
543
- /**
544
- * 获取当前登录类型-同步
545
- */
546
- get loginType(): LOGINTYPE {
547
- return this._cache.getStore(this._cache.keys.loginTypeKey);
548
- }
549
-
550
407
  /**
551
408
  * 获取当前登录的用户信息-异步
552
409
  */
@@ -558,14 +415,7 @@ class Auth {
558
415
  `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
559
416
  ]
560
417
  })
561
- public async getCurrenUser() {
562
- const { _fromApp } = this._config
563
- const authObj = await checkFromAuthV2(_fromApp)
564
- const { authType, instance } = authObj
565
- if (authType === 'oauth') {
566
- return await instance.getUserInfo()
567
- }
568
-
418
+ public async getCurrentUser() {
569
419
  const loginState = await this.getLoginState();
570
420
  if (loginState) {
571
421
  await loginState.user.checkLocalInfoAsync();
@@ -574,131 +424,99 @@ class Auth {
574
424
  return null;
575
425
  }
576
426
  }
427
+
428
+
577
429
  /**
578
- * 获取当前登录类型-异步
430
+ * 匿名登录
431
+ * @returns {Promise<LoginState>}
432
+ * @memberof Auth
579
433
  */
580
- public async getLoginType(): Promise<LOGINTYPE> {
581
- return await this._cache.getStoreAsync(this._cache.keys.loginTypeKey) as LOGINTYPE;
582
- }
583
- public async getAccessToken() {
584
- return {
585
- accessToken: (await this._request.getAccessToken()).accessToken,
586
- env: this._config.env
587
- };
588
- }
589
- public weixinAuthProvider({ appid, scope, state }): WeixinAuthProvider {
590
- if (!this._weixinAuthProvider) {
591
- this._weixinAuthProvider = new WeixinAuthProvider({
592
- ...this._config,
593
- cache: this._cache,
594
- request: this._request,
595
- runtime: this._runtime
596
- }, appid, scope, state);
597
- }
598
- return this._weixinAuthProvider;
599
- }
600
- public anonymousAuthProvider(): AnonymousAuthProvider {
601
- if (!this._anonymousAuthProvider) {
602
- this._anonymousAuthProvider = new AnonymousAuthProvider({
603
- ...this._config,
604
- cache: this._cache,
605
- request: this._request,
606
- // _fromApp: this._fromApp
607
- });
608
- }
609
- return this._anonymousAuthProvider;
610
- }
611
- public customAuthProvider(): CustomAuthProvider {
612
- if (!this._customAuthProvider) {
613
- this._customAuthProvider = new CustomAuthProvider({
614
- ...this._config,
615
- cache: this._cache,
616
- request: this._request
617
- });
618
- }
619
- return this._customAuthProvider;
620
- }
621
- public emailAuthProvider(): EmailAuthProvider {
622
- if (!this._emailAuthProvider) {
623
- this._emailAuthProvider = new EmailAuthProvider({
624
- ...this._config,
625
- cache: this._cache,
626
- request: this._request
627
- });
628
- }
629
- return this._emailAuthProvider;
630
- }
631
- public usernameAuthProvider(): UsernameAuthProvider {
632
- if (!this._usernameAuthProvider) {
633
- this._usernameAuthProvider = new UsernameAuthProvider({
634
- ...this._config,
635
- cache: this._cache,
636
- request: this._request
637
- });
638
- }
639
- return this._usernameAuthProvider;
434
+ @catchErrorsDecorator({
435
+ title: '匿名登录失败',
436
+ messages: [
437
+ '请确认以下各项:',
438
+ ' 1 - 当前环境是否开启了匿名登录',
439
+ ' 2 - 调用 auth().signInAnonymously() 的语法或参数是否正确',
440
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
441
+ ]
442
+ })
443
+ public async signInAnonymously(): Promise<LoginState> {
444
+ await this._oauthInstance.authApi.signInAnonymously()
445
+ return this.createLoginState()
640
446
  }
641
447
 
642
- public phoneAuthProvider(): PhoneAuthProvider {
643
- if (!this._phoneAuthProvider) {
644
- this._phoneAuthProvider = new PhoneAuthProvider({
645
- ...this._config,
646
- cache: this._cache,
647
- request: this._request
648
- });
649
- }
650
- return this._phoneAuthProvider;
448
+ /**
449
+ * 设置获取自定义登录 ticket 函数
450
+ * @param {authModels.GetCustomSignTicketFn} getTickFn
451
+ * @memberof Auth
452
+ */
453
+ public setCustomSignFunc(getTickFn: authModels.GetCustomSignTicketFn): void {
454
+ this._oauthInstance.authApi.setCustomSignFunc(getTickFn)
651
455
  }
652
456
 
653
457
  /**
654
- * oAuth2AuthProvider
655
- * options
656
- * {
657
- * providerId: 'google',
658
- * scope: 'openid+email+profile',
659
- * redirectUri: 'https://'
660
- * }
661
- * @param {Object} options
662
- * @param {string} options.providerId - 供应商Id,如 WeChat、Google、Github 等
663
- * @param {string} options.clientId - 客户端Id,平台提供的客户端标识Id
664
- * @param {string} [options.responseType=token] - 响应类型:token、code
665
- * @param {string} options.scope - 权限范围
666
- * @param {string} options.redirectUri - 授权成功回调地址
667
- * @param {boolean} options.syncProfile - 是否同步用户 Profile 信息
668
- * @param {boolean} options.forceDisableSignUp - 是否强制关闭用户注册
669
- * @returns
458
+ *
459
+ * @returns {Promise<LoginState>}
460
+ * @memberof Auth
670
461
  */
671
- public oAuth2AuthProvider(options: IOAuth2AuthProviderOptions = {}): OAuth2AuthProvider {
672
- if (!this._oAuth2AuthProvider) {
673
- this._oAuth2AuthProvider = new OAuth2AuthProvider({
674
- ...this._config,
675
- cache: this._cache,
676
- request: this._request,
677
- runtime: this._runtime
678
- }, options)
679
- }
680
- return this._oAuth2AuthProvider
462
+ @catchErrorsDecorator({
463
+ title: '自定义登录失败',
464
+ messages: [
465
+ '请确认以下各项:',
466
+ ' 1 - 当前环境是否开启了自定义登录',
467
+ ' 2 - 调用 auth().signInWithCustomTicket() 的语法或参数是否正确',
468
+ ' 3 - ticket 是否归属于当前环境',
469
+ ' 4 - 创建 ticket 的自定义登录私钥是否过期',
470
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
471
+ ]
472
+ })
473
+ public async signInWithCustomTicket(): Promise<LoginState> {
474
+ await this._oauthInstance.authApi.signInWithCustomTicket()
475
+ return this.createLoginState()
681
476
  }
682
477
 
683
478
  /**
684
- * signWithOAuth2Popup - OAuth2弹窗登录
479
+ *
480
+ * @param {authModels.SignInRequest} params
481
+ * @returns {Promise<LoginState>}
482
+ * @memberof Auth
685
483
  */
686
- public signWithOAuth2Popup() {
687
- this._oAuth2AuthProvider.signInWithPopup()
484
+ public async signIn(params: authModels.SignInRequest): Promise<LoginState> {
485
+ await this._oauthInstance.authApi.signIn(params)
486
+ return this.createLoginState()
688
487
  }
689
488
 
690
- public signInWithOAuth2Modal(elemId: string) {
691
- this._oAuth2AuthProvider.signInWithModal(elemId)
489
+ /**
490
+ *
491
+ * @param {authModels.SignUpRequest} params
492
+ * @returns {Promise<LoginState>}
493
+ * @memberof Auth
494
+ */
495
+ @catchErrorsDecorator({
496
+ title: '注册失败',
497
+ messages: [
498
+ '请确认以下各项:',
499
+ ' 1 - 当前环境是否开启了指定登录方式',
500
+ ' 2 - 调用 auth().signUp() 的语法或参数是否正确',
501
+ `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
502
+ ]
503
+ })
504
+ public async signUp(params: authModels.SignUpRequest): Promise<LoginState> {
505
+ console.log('ggg')
506
+ await this._oauthInstance.authApi.signUp(params)
507
+ return this.createLoginState()
692
508
  }
693
509
 
694
510
  /**
695
- * 用户名密码登录
696
- * @param username
697
- * @param password
511
+ * 设置密码
512
+ * @param {authModels.SetPasswordRequest} params
513
+ * @returns {Promise<void>}
514
+ * @memberof Auth
698
515
  */
699
- public async signInWithUsernameAndPassword(username: string, password: string) {
700
- return this.usernameAuthProvider().signIn(username, password);
516
+ public async setPassword(params: authModels.SetPasswordRequest): Promise<void> {
517
+ return this._oauthInstance.authApi.setPassword(params)
701
518
  }
519
+
702
520
  /**
703
521
  * 检测用户名是否已经占用
704
522
  * @param username
@@ -716,34 +534,14 @@ class Auth {
716
534
  throwError(ERRORS.INVALID_PARAMS, 'username must be a string');
717
535
  }
718
536
 
719
- const { data } = await this._request.send('auth.isUsernameRegistered', {
720
- username
721
- });
722
- return data?.isRegistered;
723
- }
724
- /**
725
- * 邮箱密码登录
726
- * @param email
727
- * @param password
728
- */
729
- public async signInWithEmailAndPassword(email: string, password: string) {
730
- return this.emailAuthProvider().signIn(email, password);
731
- }
732
- /**
733
- * 邮箱密码注册
734
- * @param email
735
- * @param password
736
- */
737
- public async signUpWithEmailAndPassword(email: string, password: string) {
738
- return this.emailAuthProvider().signUp(email, password);
739
- }
740
- /**
741
- * 重置邮箱密码
742
- * @param email
743
- */
744
- public async sendPasswordResetEmail(email: string) {
745
- return this.emailAuthProvider().resetPassword(email);
537
+ try {
538
+ await this._oauthInstance.authApi.checkUsername({ username })
539
+ return true
540
+ } catch (e) {
541
+ return false
542
+ }
746
543
  }
544
+
747
545
  /**
748
546
  * 登出
749
547
  */
@@ -757,136 +555,35 @@ class Auth {
757
555
  ]
758
556
  })
759
557
  public async signOut() {
760
- // 兼容 oauth
761
- const { _fromApp } = this._config
762
- const authObj = await checkFromAuthV2(_fromApp)
763
- const { authType, instance } = authObj
764
- if (authType === 'oauth') {
765
- return await instance.signOut()
766
- }
767
-
768
- const loginType = await this.getLoginType()
769
- // if (loginType === LOGINTYPE.ANONYMOUS) {
770
- // throw new Error(JSON.stringify({
771
- // code: ERRORS.INVALID_OPERATION,
772
- // msg: 'anonymous user doesn\'t support signOut action'
773
- // }))
774
- // }
775
- const { refreshTokenKey, accessTokenKey, accessTokenExpireKey } = this._cache.keys
776
-
777
- const refresh_token = await this._cache.getStoreAsync(refreshTokenKey);
778
- if (!refresh_token) {
779
- return
780
- }
781
-
782
- if (loginType.startsWith(OAUTH2_LOGINTYPE_PREFIX)) {
783
- const accessToken = await this._cache.getStoreAsync(accessTokenKey)
784
- const accessTokenExpire = Number(await this._cache.getStoreAsync(accessTokenExpireKey))
785
- if (accessToken) {
786
- if (Date.now() < accessTokenExpire) {
787
- const resp = await this._request.fetch('/auth/v1/revoke', {
788
- method: 'POST',
789
- headers: {
790
- 'Accept': 'application/json',
791
- 'Content-Type': 'application/json'
792
- },
793
- body: JSON.stringify({
794
- token: accessToken
795
- })
796
- })
797
- const seqIdFromHeader = resp.headers.get('SeqId') || resp.headers.get('RequestId')
798
- if (resp.status >= 400 && resp.status < 500) {
799
- const body: any = await resp.json()
800
- const seqId = body.request_id || seqIdFromHeader
801
- throw new Error(`[OAuth2AuthProvider][status:${resp.status}][${body.error}(${body.error_code})] ${body.error_description} (${seqId})`)
802
- }
803
- else if (resp.status >= 500) {
804
- const body: any = await resp.json()
805
- const seqId = body.request_id || seqIdFromHeader
806
- throw new Error(`[OAuth2AuthProvider][status:${resp.status}][${body.error}(${body.error_code})] ${body.error_description} (${seqId})`)
807
- }
808
- }
809
- else {
810
- // console.warn(`[SignOut] accesstoken expired`)
811
- }
812
- }
813
- else {
814
- // console.warn(`[SignOut] accesstoken not exists`)
815
- }
816
- }
817
- else {
818
- await this._request.send('auth.logout', { refresh_token })
819
- }
820
-
821
- this._cache.removeStoreAsync(refreshTokenKey)
822
- this._cache.removeStoreAsync(accessTokenKey)
823
- this._cache.removeStoreAsync(accessTokenExpireKey)
824
-
558
+ const { userInfoKey } = this._cache.keys;
559
+ await this._oauthInstance.authApi.signOut()
560
+ await this._cache.removeStoreAsync(userInfoKey)
825
561
  eventBus.fire(EVENTS.LOGIN_STATE_CHANGED)
826
- eventBus.fire(EVENTS.LOGIN_TYPE_CHANGED, {
827
- env: this._config.env,
828
- loginType: LOGINTYPE.NULL,
829
- persistence: this._config.persistence
830
- })
831
-
832
- return true
833
- }
834
- public async onLoginStateChanged(callback: Function) {
835
- eventBus.on(EVENTS.LOGIN_STATE_CHANGED, async () => {
836
- const loginState = await this.getLoginState();
837
- callback.call(this, loginState);
838
- });
839
- // 立刻执行一次回调
840
- const loginState = await this.getLoginState();
841
- callback.call(this, loginState);
842
- }
843
- public onLoginStateExpired(callback: Function) {
844
- eventBus.on(EVENTS.LOGIN_STATE_EXPIRED, callback.bind(this));
845
- }
846
- public onAccessTokenRefreshed(callback: Function) {
847
- eventBus.on(EVENTS.ACCESS_TOKEN_REFRESHD, callback.bind(this));
848
- }
849
- public onAnonymousConverted(callback: Function) {
850
- eventBus.on(EVENTS.ANONYMOUS_CONVERTED, callback.bind(this));
851
- }
852
- public onLoginTypeChanged(callback: Function) {
853
- eventBus.on(EVENTS.LOGIN_TYPE_CHANGED, async () => {
854
- const loginState = await this.getLoginState();
855
- callback.call(this, loginState);
856
- });
857
562
  }
563
+
858
564
  /**
859
565
  * 获取本地登录态-同步
860
566
  */
861
- public hasLoginState(): ILoginState | null {
862
- // 兼容oauth 逻辑,判断当前登录体系 auth or oauth
863
- const { _fromApp } = this._config
864
- const oauthInstance = _fromApp.oauthInstance
865
- const oauthLoginState = oauthInstance?.hasLoginStateSync()
866
- if (oauthLoginState) {
867
- return oauthLoginState
868
- }
869
-
567
+ public hasLoginState(): LoginState | null {
870
568
  if (this._cache.mode === 'async') {
871
569
  // async storage的平台调用此API提示
872
570
  printWarn(ERRORS.INVALID_OPERATION, 'current platform\'s storage is asynchronous, please use getLoginState insteed');
873
571
  return;
874
572
  }
875
- const { refreshTokenKey } = this._cache.keys;
876
- const refreshToken = this._cache.getStore(refreshTokenKey);
877
573
 
878
- if (refreshToken) {
574
+ const oauthLoginState = this._oauthInstance?.authApi.hasLoginStateSync()
575
+ if (oauthLoginState) {
879
576
  const loginState = new LoginState({
880
577
  envId: this._config.env,
881
578
  cache: this._cache,
882
- request: this._request
883
- });
884
- loginState.checkLocalState();
885
- return loginState;
579
+ oauthInstance: this._oauthInstance,
580
+ })
581
+ return loginState
886
582
  } else {
887
- return null;
583
+ return null
888
584
  }
889
585
  }
586
+
890
587
  /**
891
588
  * 获取本地登录态-异步
892
589
  * 此API为兼容异步storage的平台
@@ -900,40 +597,19 @@ class Auth {
900
597
  ]
901
598
  })
902
599
  public async getLoginState() {
903
- // 检查当前登录体系 auth or oauth
904
- // const { _fromApp } = this._config
905
- // const authObj = await checkFromAuthV1OrV2(_fromApp)
906
- // const { authType, instance } = authObj
907
- // if (authType === 'oauth') {
908
- // return await instance.getLoginState()
909
- // }
910
- const { _fromApp } = this._config
911
- const oauthInstance = _fromApp.oauthInstance || (_fromApp as any).oauth()
912
- const oauthLoginState = oauthInstance && await oauthInstance.getLoginState()
600
+ const oauthLoginState = await this._oauthInstance.authApi.getLoginState()
913
601
  if (oauthLoginState) {
914
- return oauthLoginState
915
- }
916
-
917
- // auth 体系走默认逻辑
918
- const { refreshTokenKey } = this._cache.keys;
919
- const refreshToken = await this._cache.getStoreAsync(refreshTokenKey);
920
- if (refreshToken) {
921
602
  const loginState = new LoginState({
922
603
  envId: this._config.env,
923
604
  cache: this._cache,
924
- request: this._request
925
- });
926
- await loginState.checkLocalStateAsync();
927
- return loginState;
928
- } else {
929
- return null;
605
+ oauthInstance: this._oauthInstance,
606
+ })
607
+ return loginState
930
608
  }
931
- }
932
609
 
933
- public shouldRefreshAccessToken(hook) {
934
- // @ts-ignore
935
- this._request._shouldRefreshAccessTokenHook = hook.bind(this);
610
+ return null
936
611
  }
612
+
937
613
  @catchErrorsDecorator({
938
614
  title: '获取用户信息失败',
939
615
  messages: [
@@ -943,160 +619,148 @@ class Auth {
943
619
  `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
944
620
  ]
945
621
  })
946
- public async getUserInfo(): Promise<any> {
947
- const action = 'auth.getUserInfo';
948
-
949
- const res = await this._request.send(action, {});
950
- if (res.code) {
951
- return res;
952
- } else {
953
- return {
954
- ...res.data,
955
- requestId: res.seqId
956
- };
957
- }
958
- }
959
- /**
960
- * 获取Http鉴权header,用于云接入 HTTP 访问云函数时的鉴权
961
- */
962
- public getAuthHeader() {
963
- const { refreshTokenKey, accessTokenKey } = this._cache.keys;
964
- const refreshToken = this._cache.getStore(refreshTokenKey);
965
- const accessToken = this._cache.getStore(accessTokenKey);
966
- return {
967
- 'x-cloudbase-credentials': accessToken + '/@@/' + refreshToken
968
- };
622
+ public async getUserInfo(): Promise<IUserInfo> {
623
+ return this._oauthInstance.authApi.getUserInfo()
969
624
  }
970
- /**
971
- * 异步模式获取Http鉴权header,用于云接入 HTTP 访问云函数时的鉴权
972
- * 调用此API会刷新登录态
973
- */
974
- public async getAuthHeaderAsync() {
975
- await this._request.refreshAccessToken();
976
625
 
977
- const { refreshTokenKey, accessTokenKey } = this._cache.keys;
978
- const refreshToken = await this._cache.getStoreAsync(refreshTokenKey);
979
- const accessToken = await this._cache.getStoreAsync(accessTokenKey);
980
- return {
981
- 'x-cloudbase-credentials': accessToken + '/@@/' + refreshToken
982
- };
983
- }
984
626
 
985
627
  /**
986
- * 发送验证码
987
- * @param phoneNumber
988
- * @param phoneCode
989
- */
628
+ * 为已有账户绑第三方账户
629
+ * @param {authModels.BindWithProviderRequest} params
630
+ * @returns {Promise<void>}
631
+ * @memberof Auth
632
+ */
990
633
  @catchErrorsDecorator({
991
- title: '发送短信验证码失败',
634
+ title: '绑定第三方登录方式失败',
992
635
  messages: [
993
636
  '请确认以下各项:',
994
- ' 1 - 调用语法或参数是否正确',
995
- ' 2 - 当前环境是否开通了短信验证码登录',
637
+ ' 1 - 调用 auth().bindWithProvider() 的语法或参数是否正确',
638
+ ' 2 - 此账户是否已经绑定此第三方',
996
639
  `如果问题依然存在,建议到官方问答社区提问或寻找帮助:${COMMUNITY_SITE_URL}`
997
640
  ]
998
641
  })
999
- public async sendPhoneCode(phoneNumber: string): Promise<boolean> {
1000
- const { data } = await this._request.send('auth.sendPhoneCode', {
1001
- phoneNumber: transformPhone(phoneNumber)
1002
- });
1003
- return data.SendStatus === 'Ok'
642
+ public async bindWithProvider(
643
+ params: authModels.BindWithProviderRequest,
644
+ ): Promise<void> {
645
+ return this._oauthInstance.authApi.bindWithProvider(params)
1004
646
  }
1005
647
 
1006
648
  /**
1007
- * 手机短信注册
1008
- * @param email
1009
- * @param password
649
+ * 查询用户
650
+ * @param {authModels.QueryUserProfileRequest} appended_params
651
+ * @returns {Promise<authModels.UserProfile>}
652
+ * @memberof Auth
1010
653
  */
1011
- public async signUpWithPhoneCode(phoneNumber: string, phoneCode: string, password: string) {
1012
- return this.phoneAuthProvider().signUp(phoneNumber, phoneCode, password);
654
+ public async queryUser(
655
+ queryObj: authModels.QueryUserProfileRequest,
656
+ ): Promise<authModels.QueryUserProfileResponse> {
657
+ return this._oauthInstance.authApi.queryUserProfile(queryObj)
1013
658
  }
1014
659
 
1015
- /**
1016
- * 手机验证码 or 密码登录
1017
- * @param email
1018
- * @param password
1019
- */
1020
- public async signInWithPhoneCodeOrPassword(param: {
1021
- phoneNumber: string
1022
- phoneCode?: string
1023
- password?: string
1024
- signMethod?: string
1025
- }) {
1026
- return this.phoneAuthProvider().signIn(param);
660
+ public async getAccessToken() {
661
+ const oauthAccessTokenRes = await this._oauthInstance.oauth2client.getAccessToken()
662
+ return {
663
+ accessToken: oauthAccessTokenRes,
664
+ env: this._config.env
665
+ };
666
+ }
667
+
668
+ public async grantProviderToken(
669
+ params: authModels.GrantProviderTokenRequest,
670
+ ): Promise<authModels.GrantProviderTokenResponse> {
671
+ return this._oauthInstance.authApi.grantProviderToken(params)
672
+ }
673
+
674
+ public async signInWithProvider(
675
+ params: authModels.SignInWithProviderRequest,
676
+ ): Promise<LoginState> {
677
+ await this._oauthInstance.authApi.signInWithProvider(params)
678
+ return this.createLoginState()
679
+ }
680
+
681
+ public async grantToken(params: authModels.GrantTokenRequest): Promise<LoginState> {
682
+ await this._oauthInstance.authApi.grantToken(params)
683
+ return this.createLoginState()
684
+ }
685
+
686
+ public async genProviderRedirectUri(
687
+ params: authModels.GenProviderRedirectUriRequest,
688
+ ): Promise<authModels.GenProviderRedirectUriResponse> {
689
+ return this._oauthInstance.authApi.genProviderRedirectUri(params)
1027
690
  }
1028
691
 
1029
- public async forceResetPwdByPhoneCode(param: {
1030
- phoneNumber: string
1031
- phoneCode: string
1032
- password: string
1033
- }) {
1034
- return this.phoneAuthProvider().signIn({
1035
- ...param,
1036
- signMethod: SIGN_METHOD.FORCERESETPWD
692
+ public async resetPassword(params: authModels.ResetPasswordRequest): Promise<void> {
693
+ return this._oauthInstance.authApi.resetPassword(params)
694
+ }
695
+
696
+ public async deviceAuthorize(params: authModels.DeviceAuthorizeRequest): Promise<authModels.DeviceAuthorizeResponse> {
697
+ return this._oauthInstance.authApi.deviceAuthorize(params)
698
+ }
699
+
700
+ public async sudo(params: authModels.SudoRequest): Promise<authModels.SudoResponse> {
701
+ return this._oauthInstance.authApi.sudo(params)
702
+ }
703
+
704
+ public async onLoginStateChanged(callback: Function) {
705
+ eventBus.on(EVENTS.LOGIN_STATE_CHANGED, async () => {
706
+ const loginState = await this.getLoginState();
707
+ callback.call(this, loginState);
1037
708
  });
709
+ // 立刻执行一次回调
710
+ const loginState = await this.getLoginState();
711
+ callback.call(this, loginState);
1038
712
  }
1039
713
 
1040
- private async _onLoginTypeChanged(ev) {
1041
- const { loginType, persistence, env } = ev.data;
1042
- if (env !== this._config.env) {
1043
- return;
1044
- }
1045
- // 登录态转变后迁移cache,防止在匿名登录状态下cache混用
1046
- await this._cache.updatePersistenceAsync(persistence);
1047
- await this._cache.setStoreAsync(this._cache.keys.loginTypeKey, loginType);
714
+ private async createLoginState(): Promise<LoginState> {
715
+ const loginState = new LoginState({
716
+ envId: this._config.env,
717
+ cache: this._cache,
718
+ oauthInstance: this._oauthInstance,
719
+ })
720
+
721
+ await loginState.checkLocalStateAsync();
722
+ await loginState.user.refresh();
723
+ eventBus.fire(EVENTS.LOGIN_STATE_CHANGED);
724
+ return loginState
1048
725
  }
1049
726
  }
1050
727
 
1051
- const EVENTS = {
1052
- // 登录态改变后触发
1053
- LOGIN_STATE_CHANGED: 'loginStateChanged',
1054
- // 登录态过期后触发
1055
- LOGIN_STATE_EXPIRED: 'loginStateExpire',
1056
- // 登录类型改变后触发
1057
- LOGIN_TYPE_CHANGED: 'loginTypeChanged',
1058
- // 匿名账户被转正后触发
1059
- ANONYMOUS_CONVERTED: 'anonymousConverted',
1060
- // access token刷新后触发
1061
- ACCESS_TOKEN_REFRESHD: 'refreshAccessToken'
1062
- };
1063
-
1064
728
  const component: ICloudbaseComponent = {
1065
729
  name: COMPONENT_NAME,
1066
730
  namespace: 'auth',
1067
- injectEvents: {
1068
- bus: eventBus,
1069
- events: [
1070
- EVENTS.LOGIN_TYPE_CHANGED,
1071
- EVENTS.LOGIN_STATE_EXPIRED,
1072
- EVENTS.LOGIN_STATE_CHANGED,
1073
- EVENTS.ACCESS_TOKEN_REFRESHD,
1074
- EVENTS.ANONYMOUS_CONVERTED
1075
- ]
1076
- },
1077
731
  entity: function (config: Pick<ICloudbaseAuthConfig, 'region' | 'persistence'> = { region: '', persistence: 'local' }) {
1078
732
  if (this.authInstance) {
1079
733
  printWarn(ERRORS.INVALID_OPERATION, 'every cloudbase instance should has only one auth object');
1080
734
  return this.authInstance;
1081
735
  }
1082
736
  const { adapter, runtime } = this.platform;
1083
- // 如不明确指定persistence则优先取各平台adapter首选,其次session
737
+ // 如不明确指定persistence则优先取各平台adapter首选,其次localStorage
1084
738
  const newPersistence = config.persistence || adapter.primaryStorage;
1085
739
  if (newPersistence && (newPersistence !== this.config.persistence)) {
1086
740
  this.updateConfig({ persistence: newPersistence })
1087
741
  }
1088
742
 
1089
- const { env, persistence, debug } = this.config;
743
+ const { env, persistence, debug, clientId } = this.config;
744
+ const oauthInstance = new CloudbaseOAuth({
745
+ clientId: clientId,
746
+ apiOrigin: this.request.getBaseEndPoint(),
747
+ })
748
+
749
+ this.oauthInstance = oauthInstance
750
+
1090
751
  this.authInstance = new Auth({
1091
752
  env,
1092
753
  region: config.region,
1093
754
  persistence,
1094
755
  debug,
1095
756
  cache: this.cache,
1096
- request: this.request,
757
+ // request: this.request,
1097
758
  runtime: runtime,
1098
- _fromApp: this
759
+ _fromApp: this,
760
+ // oauthInstance: this.oauthInstance || (this as any).oauth()
761
+ oauthInstance
1099
762
  });
763
+
1100
764
  return this.authInstance;
1101
765
  }
1102
766
  }
@@ -1110,9 +774,6 @@ try {
1110
774
  export {
1111
775
  UserInfo,
1112
776
  Auth,
1113
- AuthProvider,
1114
- EVENTS,
1115
- eventBus
1116
777
  };
1117
778
  /**
1118
779
  * @api 手动注册至cloudbase app
@@ -1125,29 +786,3 @@ export function registerAuth(app: Pick<ICloudbase, 'registerComponent'>) {
1125
786
  }
1126
787
  }
1127
788
 
1128
- type IProvider = new (...args: any[]) => any;
1129
- /**
1130
- * 注册provider,如果
1131
- * @param name
1132
- * @param provider
1133
- * @example
1134
- * // 注册
1135
- * registerProvider('emailAuthProvider',function(){
1136
- * // ...
1137
- * });
1138
- * // 使用新provider登录
1139
- * cloudbase.auth().emailAuthProvider().signIn();
1140
- */
1141
- export function registerProvider(name: string, provider: IProvider) {
1142
- const proto = Auth.prototype;
1143
- proto[name] = function (options: object) {
1144
- const privateName = `_${name}`;
1145
- if (!this[privateName]) {
1146
- this[privateName] = new provider({
1147
- ...options,
1148
- ...this._config
1149
- });
1150
- }
1151
- return this[privateName];
1152
- };
1153
- }