• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Haixing-Hu / js-common-app / 2a33f248-a845-4b6c-9a40-eb779de30f37

03 Dec 2024 07:03AM UTC coverage: 55.017% (+1.7%) from 53.312%
2a33f248-a845-4b6c-9a40-eb779de30f37

push

circleci

Haixing-Hu
refactor: 重构 BasicUserStore

101 of 188 branches covered (53.72%)

Branch coverage included in aggregate %.

0 of 62 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

228 of 410 relevant lines covered (55.61%)

9.96 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.37
/src/store/basic-user-store.js
1
////////////////////////////////////////////////////////////////////////////////
2
//
3
//    Copyright (c) 2022 - 2024.
4
//    Haixing Hu, Qubit Co. Ltd.
5
//
6
//    All rights reserved.
7
//
8
////////////////////////////////////////////////////////////////////////////////
9
import { Logger, Log } from '@haixing_hu/logging';
10
import { RawField } from '@haixing_hu/pinia-decorator';
11
import config from '@haixing_hu/config';
12
import AuthStorage from '../auth-storage';
13

14
const logger = Logger.getLogger('store.user');
3✔
15

16
/**
17
 * 管理用户登录状态的 Pinia Store 类的基类。
18
 *
19
 * @author 胡海星
20
 */
21
class BasicUserStore {
22
  /**
23
   * 用于处理用户登录认证的API对象。
24
   *
25
   * 此对象必须有以下接口:
26
   *
27
   * - `loginByUsername(username, password)`: 使用用户名和密码登录;
28
   * - `loginByMobile(mobile, verifyCode)`: 使用手机号码和验证码登录;
29
   * - `loginByOpenId(socialNetwork, appId, openId)`: 使用Open ID登录;
30
   * - `bindOpenId(socialNetwork, appId, openId)`: 绑定Open ID;
31
   * - `logout()`: 登出;
32
   * - `getLoginInfo()`: 获取登录用户的信息;
33
   * - `checkToken(userId, tokenValue)`: 检查用户的Token的值是否合法。
34
   *
35
   * @type {object}
36
   */
37
  @RawField
38
  _userAuthenticateApi = null;
×
39

40
  /**
41
   * 用于处理发送验证码的API对象。
42
   *
43
   * 此对象必须有一个`sendBySms(mobile, scene)`方法,用于发送短信验证码。
44
   *
45
   * @type {object}
46
   */
47
  @RawField
48
  _verifyCodeApi = null;
×
49

50
  /**
51
   * 当前应用程序的代码,用于设置`Cookies`、`LocalStorage`和`SessionStorage`中存储
52
   * 的数据项的键值前缀。
53
   *
54
   * @type {string}
55
   */
56
  @RawField
57
  _appCode = '';
×
58

59
  /**
60
   * 用于存储用户认证信息的存储对象。
61
   *
62
   * @type {AuthStorage}
63
   */
64
  @RawField
65
  _authStorage = null;
×
66

67
  /**
68
   * 当前用户信息。
69
   *
70
   * 用户信息包括:
71
   * - `id`: 用户ID;
72
   * - `username`: 用户名;
73
   * - `nickname`: 用户昵称;
74
   * - `avatar`: 用户头像;
75
   * - `name`: 用户姓名;
76
   * - `gender`: 用户性别;
77
   * - `mobile`: 用户手机号码。
78
   *
79
   * @type {object}
80
   */
81
  user = null;
×
82

83
  /**
84
   * 当前用户的密码。
85
   *
86
   * @type {string}
87
   */
88
  password = '';
×
89

90
  /**
91
   * 当前用户是否需要保存登录信息。
92
   *
93
   * @type {boolean}
94
   */
95
  saveLogin = false;
×
96

97
  /**
98
   * 用户Open ID所属的社交网络。
99
   *
100
   * @type {string}
101
   */
102
  socialNetwork = null;
×
103

104
  /**
105
   * 用户Open ID所属的社交网络上的APP ID。
106
   *
107
   * @type {string}
108
   */
109
  appId = null;
×
110

111
  /**
112
   * 用户Open ID。
113
   *
114
   * @type {string}
115
   */
116
  openId = null;
×
117

118
  /**
119
   * 当前用户的Access Token。
120
   *
121
   * @type {object}
122
   */
123
  token = null;
×
124

125
  /**
126
   * 当前用户的权限。
127
   *
128
   * @type {array<string>}
129
   */
130
  privileges = [];
×
131

132
  /**
133
   * 当前用户的角色。
134
   *
135
   * @type {array<string>}
136
   */
137
  roles = [];
×
138

139
  /**
140
   * 构造一个新的`BasicUserStore`对象。
141
   *
142
   * 该函数需要一个用于处理登录认证的API对象和一个用于发送验证码的API对象。
143
   *
144
   * @param {object} userAuthenticateApi
145
   *     用于处理用户登录认证的API对象。此API对象需要提供以下接口:
146
   *     - `loginByUsername(username, password)`: 使用用户名和密码登录;
147
   *     - `loginByMobile(mobile, verifyCode)`: 使用手机号码和验证码登录;
148
   *     - `loginByOpenId(socialNetwork, appId, openId)`: 使用Open ID登录;
149
   *     - `bindOpenId(socialNetwork, appId, openId)`: 绑定Open ID;
150
   *     - `logout()`: 登出;
151
   *     - `getLoginInfo()`: 获取登录用户的信息;
152
   *     - `checkToken(userId, tokenValue)`: 检查用户的Token的值是否合法。
153
   * @param {object} verifyCodeApi
154
   *     用于处理发送验证码的API对象。
155
   *     - `sendBySms(mobile, scene)`:发送短信验证码。
156
   * @param {string} appCode
157
   *     当前应用程序的代码,用于设置`Cookies`、`LocalStorage`和`SessionStorage`中存储
158
   *     的数据项的键值前缀。
159
   */
160
  constructor(userAuthenticateApi, verifyCodeApi, appCode) {
161
    if (!userAuthenticateApi) {
×
162
      throw new Error('The API object for authenticating users is required.');
×
163
    }
164
    if (!verifyCodeApi) {
×
165
      throw new Error('The API object for sending verify code is required.');
×
166
    }
167
    if (!appCode) {
×
168
      throw new Error('The app code is required.');
×
169
    }
170
    this._userAuthenticateApi = userAuthenticateApi;
×
171
    this._verifyCodeApi = verifyCodeApi;
×
172
    this._appCode = appCode;
×
173
    this._authStorage = new AuthStorage(appCode);
×
174
    this.user = this._authStorage.loadUserInfo() ?? null;
×
175
    this.password = this._authStorage.loadPassword() ?? '';
×
176
    this.saveLogin = this._authStorage.loadSaveLogin() ?? false;
×
NEW
177
    this.socialNetwork = config.get('social_network', null);
×
NEW
178
    this.appId = config.get('social_network_app_id', null);
×
179
    this.token = this._authStorage.loadToken() ?? null;
×
180
    this.privileges = this._authStorage.loadPrivileges() ?? [];
×
181
    this.roles = this._authStorage.loadRoles() ?? [];
×
182
  }
183

184
  /**
185
   * 用于存储用户认证信息的存储对象。
186
   *
187
   * @return {AuthStorage}
188
   *     用于存储用户认证信息的存储对象。
189
   */
190
  get authStorage() {
191
    return this._authStorage;
×
192
  }
193

194
  /**
195
   * 当前用户是否已经登录。
196
   *
197
   * @return {boolean}
198
   *     如果当前用户已经登录,则返回`true`;否则返回`false`。
199
   */
200
  get loggedIn() {
201
    return !!this.token?.value;
×
202
  }
203

204
  /**
205
   * 确保当前用户信息对象存在。
206
   *
207
   * @return {object}
208
   *     当前用户信息对象。
209
   */
210
  @Log
211
  ensureUserExist() {
NEW
212
    if (!this.user) {
×
NEW
213
      this.user = {
×
214
        id: null,
215
        username: '',
216
        nickname: '',
217
        avatar: '',
218
        name: '',
219
        gender: '',
220
        mobile: '',
221
      };
222
    }
NEW
223
    return this.user;
×
224
  }
225

226
  /**
227
   * 重置状态。
228
   */
229
  @Log
230
  resetState() {
231
    this.$reset();
×
232
    logger.debug('state was reset to:', this.$state);
×
233
  }
234

235
  /**
236
   * 设置用户基本信息。
237
   *
238
   * @param {object} user
239
   *     用户基本信息。
240
   */
241
  @Log
242
  setUserInfo(user) {
243
    this.user = { ...user };
×
244
    if (this.saveLogin) {
×
245
      this._authStorage.storeUserInfo(this.user);
×
246
    }
247
  }
248

249
  /**
250
   * 设置用户ID。
251
   *
252
   * @param {number|bigint|string} userId
253
   *     用户ID。
254
   */
255
  @Log
256
  setUserId(userId) {
NEW
257
    const user = this.ensureUserExist();
×
258
    user.id = userId;
×
259
    if (this.saveLogin) {
×
260
      this._authStorage.storeUserId(userId);
×
261
    } else {
262
      this._authStorage.removeUserId();
×
263
    }
264
  }
265

266
  /**
267
   * 设置用户名。
268
   *
269
   * @param {string} username
270
   *     用户名。
271
   */
272
  @Log
273
  setUsername(username) {
NEW
274
    const user = this.ensureUserExist();
×
275
    user.username = username;
×
276
    if (this.saveLogin) {
×
277
      this._authStorage.storeUsername(username);
×
278
    } else {
279
      this._authStorage.removeUsername();
×
280
    }
281
  }
282

283
  /**
284
   * 设置用户密码。
285
   *
286
   * @param {string} password
287
   *     用户密码。
288
   */
289
  @Log
290
  setPassword(password) {
291
    this.password = password;
×
292
    if (this.saveLogin) {
×
293
      this._authStorage.storePassword(password);
×
294
    } else {
295
      this._authStorage.removePassword();
×
296
    }
297
  }
298

299
  /**
300
   * 设置用户手机号码。
301
   *
302
   * @param {string} mobile
303
   *     用户手机号码。
304
   */
305
  @Log
306
  setMobile(mobile) {
NEW
307
    const user = this.ensureUserExist();
×
308
    user.mobile = mobile;
×
309
    if (this.saveLogin) {
×
310
      this._authStorage.storeMobile(mobile);
×
311
    } else {
312
      this._authStorage.removeMobile();
×
313
    }
314
  }
315

316
  /**
317
   * 设置用户头像。
318
   *
319
   * @param {string} avatar
320
   *     用户头像。
321
   */
322
  @Log
323
  setAvatar(avatar) {
NEW
324
    const user = this.ensureUserExist();
×
325
    user.avatar = avatar ?? '';
×
326
    this._authStorage.storeAvatar(avatar);
×
327
  }
328

329
  /**
330
   * 设置用户是否保存登录信息。
331
   *
332
   * @param {boolean} saveLogin
333
   *     用户是否保存登录信息。
334
   */
335
  @Log
336
  setSaveLogin(saveLogin) {
337
    this.saveLogin = saveLogin;
×
338
    this._authStorage.storeSaveLogin(saveLogin);
×
339
  }
340

341
  /**
342
   * 设置用户的登录令牌。
343
   *
344
   * @param {object} token
345
   *     用户的登录令牌。
346
   */
347
  @Log
348
  setToken(token) {
349
    this.token = { ...token };
×
350
    if (this.saveLogin) {
×
351
      this._authStorage.storeToken(token);
×
352
    } else {
353
      this._authStorage.removeToken();
×
354
    }
355
  }
356

357
  /**
358
   * 移除用户的登录令牌。
359
   */
360
  @Log
361
  removeToken() {
362
    this.token = null;
×
363
    this._authStorage.removeToken();
×
364
  }
365

366
  /**
367
   * 重置用户的Token值。
368
   *
369
   * 此函数将删除用户的Token值,并重置用户的状态。
370
   */
371
  @Log
372
  resetToken() {
373
    this.removeToken();  // must remove  token  first
×
374
    this.resetState();
×
375
  }
376

377
  /**
378
   * 设置用户的权限列表。
379
   *
380
   * @param {array<string>} privileges
381
   *     用户的权限列表。
382
   */
383
  @Log
384
  setPrivileges(privileges) {
385
    this.privileges = privileges ?? [];
×
386
    this._authStorage.storePrivileges(this.privileges);
×
387
  }
388

389
  /**
390
   * 设置用户的角色列表。
391
   *
392
   * @param {array<string>} roles
393
   *     用户的角色列表。
394
   */
395
  @Log
396
  setRoles(roles) {
397
    this.roles = roles ?? [];
×
398
    this._authStorage.storeRoles(this.roles);
×
399
  }
400

401
  /**
402
   * 设置用户的Open ID。
403
   *
404
   * @param {string} socialNetwork
405
   *     Open ID 所属社交网络。
406
   * @param {string} appId
407
   *     Open ID 所属社交网络上的APP ID。
408
   * @param {string} openId
409
   *     Open ID。
410
   */
411
  @Log
412
  setOpenId(socialNetwork, appId, openId) {
413
    this.socialNetwork = socialNetwork;
×
414
    this.appId = appId;
×
415
    this.openId = openId;
×
416
  }
417

418
  /**
419
   * 设置用户登录后服务器返回的响应数据。
420
   *
421
   * 响应数据包括用户基本信息、Token、权限列表和角色列表。
422
   *
423
   * @param {object} response
424
   *     用户登录后服务器返回的响应数据。
425
   */
426
  @Log
427
  setLoginResponse(response) {
428
    logger.debug('Set the login response:', response);
×
429
    this.setUserInfo(response.user);
×
430
    this.setToken(response.token);
×
431
    this.setPrivileges(response.privileges);
×
432
    this.setRoles(response.roles);
×
NEW
433
    this.refreshAvatar();
×
434
  }
435

436
  /**
437
   * 刷新用户的头像。
438
   */
439
  @Log
440
  refreshAvatar() {
NEW
441
    const user = this.ensureUserExist();
×
NEW
442
    if (!user.avatar && user.gender) {
×
NEW
443
      switch (user.gender) {
×
444
        case 'MALE':
NEW
445
          this.setAvatar(config.get('default_avatar_male', ''));
×
NEW
446
          break;
×
447
        case 'FEMALE':
NEW
448
          this.setAvatar(config.get('default_avatar_female', ''));
×
NEW
449
          break;
×
450
        default:
NEW
451
          this.setAvatar('');
×
NEW
452
          break;
×
453
      }
454
    }
455
  }
456

457
  /**
458
   * 合并用户信息。
459
   *
460
   * @param {object} info
461
   *     待合并的用户信息。
462
   */
463
  @Log
464
  mergeUserInfo(info) {
NEW
465
    const user = this.ensureUserExist();
×
NEW
466
    if (!user.username && info.username) {
×
NEW
467
      user.username = info.username;
×
468
    }
NEW
469
    if (!user.name && info.name) {
×
NEW
470
      user.name = info.name;
×
471
    }
NEW
472
    if (!user.nickname && info.nickname) {
×
NEW
473
      user.nickname = info.nickname;
×
474
    }
NEW
475
    if (!user.gender && info.gender) {
×
NEW
476
      user.gender = info.gender;
×
477
    }
NEW
478
    if (!user.avatar && info.avatar) {
×
NEW
479
      user.avatar = info.avatar;
×
480
    }
NEW
481
    if (!user.mobile && info.mobile) {
×
NEW
482
      user.mobile = info.mobile;
×
483
    }
NEW
484
    this.refreshAvatar();
×
NEW
485
    if (this.saveLogin) {
×
NEW
486
      this._authStorage.storeUserInfo(user);
×
487
    }
488
  }
489

490
  /**
491
   * 尝试获取用户的Token值。
492
   *
493
   * @returns {Promise<object|null>}
494
   *     如果成功获取用户的Token值,则返回该值;否则返回`null`。
495
   */
496
  @Log
497
  async loadToken() {
NEW
498
    if ((await this.loadTokenFromDevice())
×
499
        || (await this.loadTokenFromAuthStorage())) {
NEW
500
      logger.info('The user token value is:', this.token.value);
×
501
      await this.refreshLoginInfo();
×
502
      return this.token;
×
503
    } else {
504
      return null;
×
505
    }
506
  }
507

508
  /**
509
   * 从本地存储中获取当前绑定用户的登录信息。
510
   *
511
   * @return {Promise<boolean>}
512
   *     如果成功获取用户的登录信息,则保存userId和token并返回`true`;否则返回`false`。
513
   */
514
  async loadTokenFromAuthStorage() {
NEW
515
    const user = this._authStorage.loadUserInfo();
×
NEW
516
    if (user?.username) {       // 如果有用户信息,则保存用户信息,以便于后继登录自动填写用户名和手机号码
×
NEW
517
      logger.debug('Found user information in the local storage:', user);
×
NEW
518
      this.setUserInfo(user);
×
519
    }
NEW
520
    const password = this._authStorage.loadPassword();
×
NEW
521
    if (password) {             // 如果有密码,则保存密码,以便于后继登录自动填写密码
×
NEW
522
      logger.debug('Found password in the local storage:', password);
×
NEW
523
      this.setPassword(password);
×
524
    }
NEW
525
    const saveLogin = this._authStorage.loadSaveLogin();
×
NEW
526
    if (saveLogin) {  // 如果有保存登录信息,则保存保存登录信息标志
×
NEW
527
      logger.debug('Found save login information in the local storage:', saveLogin);
×
NEW
528
      this.setSaveLogin(saveLogin);
×
529
    }
NEW
530
    const token = this._authStorage.loadToken();
×
NEW
531
    if (user?.id && token?.value) {
×
NEW
532
      logger.debug('Successfully load access token from the local storage:', token);
×
NEW
533
      if (await this.isTokenValid(user.id, token.value)) {
×
NEW
534
        this.setUserId(user.id);
×
NEW
535
        this.setToken(token);
×
NEW
536
        return true;
×
537
      } else {
NEW
538
        logger.info('The access token is invalid or expired, remove it:', token);
×
NEW
539
        this._authStorage.removeLoginResponse();
×
NEW
540
        return false;
×
541
      }
542
    } else {
NEW
543
      logger.error('No access token found in local storage.');
×
NEW
544
      return false;
×
545
    }
546
  }
547

548
  /**
549
   * 从底层设备的存储中获取当前绑定用户的登录信息。
550
   *
551
   * **注意:** 此方法的默认实现总是返回`false`。派生类可以重写此方法以实现从设备获取用户登录
552
   * 信息的业务逻辑。
553
   *
554
   * @return {Promise<boolean>}
555
   *     如果成功获取用户的登录信息,则保存userId和token并返回`true`;否则返回`false`。
556
   */
557
  async loadTokenFromDevice() {
NEW
558
    return false;
×
559
  }
560

561
  /**
562
   * 使用用户名和密码登录。
563
   *
564
   * @param {string} username
565
   *     用户名。
566
   * @param {string} password
567
   *     密码。
568
   * @param {boolean} saveLogin
569
   *     是否保存登录信息。
570
   * @return {Promise<LoginResponse|ErrorInfo>}
571
   *     此 HTTP 请求的 Promise,若操作成功,解析成功并返回一个`LoginResponse`对象,包含
572
   *     了指定用户的登录信息;若操作失败,解析失败并返回一个`ErrorInfo`对象。
573
   */
574
  @Log
575
  loginByUsername(username, password, saveLogin) {
576
    this.setSaveLogin(saveLogin);
×
577
    this.setUsername(username);
×
578
    this.setPassword(password);
×
579
    this.removeToken();           // 注意调用login API时必须先清除已保存的Access Token
×
580
    return this._userAuthenticateApi.loginByUsername(username, password).then((response) => {
×
581
      logger.debug('Successfully logged in with:', response);
×
582
      this.setLoginResponse(response);
×
583
      return response;
×
584
    });
585
  }
586

587
  /**
588
   * 使用手机号码和验证码登录。
589
   *
590
   * @param {string} mobile
591
   *     手机号码。
592
   * @param {string} verifyCode
593
   *     该手机收到的验证码。
594
   * @param {boolean} saveLogin
595
   *     是否保存登录信息。
596
   * @return {Promise<LoginResponse|ErrorInfo>}
597
   *     此 HTTP 请求的 Promise,若操作成功,解析成功并返回一个`LoginResponse`对象,包含
598
   *     了指定用户的登录信息;若操作失败,解析失败并返回一个`ErrorInfo`对象。
599
   */
600
  @Log
601
  loginByMobile(mobile, verifyCode, saveLogin) {
602
    this.setSaveLogin(saveLogin);
×
603
    this.setMobile(mobile);
×
604
    this.removeToken();           // 注意调用login API时必须先清除已保存的Access Token
×
605
    return this._userAuthenticateApi.loginByMobile(mobile, verifyCode).then((response) => {
×
606
      logger.debug('Successfully logged in with:', response);
×
607
      this.setLoginResponse(response);
×
608
      return response;
×
609
    });
610
  }
611

612
  /**
613
   * 使用社交网络的Open ID登录。
614
   *
615
   * @param {SocialNetwork} socialNetwork
616
   *     指定的社交网络枚举名称。
617
   * @param {string} appId
618
   *     该社交网络下的APP(公众号)的ID。
619
   * @param {string} openId
620
   *     用户在该社交网络指定的APP(公众号)下的Open ID。
621
   * @return {Promise<LoginResponse|ErrorInfo>}
622
   *     此 HTTP 请求的 Promise,若操作成功,解析成功并返回一个`LoginResponse`对象,包含
623
   *     了指定用户的登录信息;若操作失败,解析失败并返回一个`ErrorInfo`对象。
624
   */
625
  @Log
626
  loginByOpenId(socialNetwork, appId, openId) {
627
    this.removeToken();           // 注意调用login API时必须先清除已保存的Access Token
×
628
    return this._userAuthenticateApi.loginByOpenId(socialNetwork, appId, openId).then((response) => {
×
629
      logger.debug('Successfully logged in with:', response);
×
630
      this.setOpenId(socialNetwork, appId, openId);
×
631
      this.setLoginResponse(response);
×
632
      return response;
×
633
    });
634
  }
635

636
  /**
637
   * 将当前登录用户的账号绑定到指定的Open ID。
638
   *
639
   * @param {SocialNetwork} socialNetwork
640
   *     指定的社交网络枚举名称。
641
   * @param {string} appId
642
   *     该社交网络下的APP(公众号)的ID。
643
   * @param {string} openId
644
   *     用户在该社交网络指定的APP(公众号)下的Open ID。
645
   * @return
646
   *     此 HTTP 请求的 Promise。若操作成功,解析成功且没有返回值;若操作失败,解析失败并
647
   *     返回一个`ErrorInfo`对象。
648
   */
649
  @Log
650
  bindOpenId(socialNetwork, appId, openId) {
651
    return this._userAuthenticateApi.bindOpenId(socialNetwork, appId, openId).then(() => {
×
UNCOV
652
      logger.debug('Successfully bind the Open ID for the current user.');
×
653
      this.setOpenId(socialNetwork, appId, openId);
×
654
    });
655
  }
656

657
  /**
658
   * 用户注销登录。
659
   *
660
   * @return {Promise<void|ErrorInfo>}
661
   *     此 HTTP 请求的 Promise;若操作成功,解析成功且没有返回值;若操作失败,解析失败并返
662
   *     回一个`ErrorInfo`对象。
663
   */
664
  @Log
665
  logout() {
666
    return this._userAuthenticateApi.logout().then(() => {
×
667
      this.removeToken(); // must remove  token  first
×
668
      this.resetState();
×
669
    });
670
  }
671

672
  /**
673
   * 刷新当前已登录用户的登录信息。
674
   *
675
   * @return {Promise<LoginResponse|ErrorInfo>}
676
   *     此 HTTP 请求的 Promise,若操作成功,解析成功并返回一个`LoginResponse`对象,包含
677
   *     了指定用户的登录信息;若操作失败,解析失败并返回一个`ErrorInfo`对象。
678
   */
679
  @Log
680
  refreshLoginInfo() {
681
    return this._userAuthenticateApi.getLoginInfo().then((response) => {
×
682
      logger.debug('Successfully get the login information of the current user:', response);
×
683
      this.setLoginResponse(response);
×
684
      return response;
×
685
    });
686
  }
687

688
  /**
689
   * 发送登录验证码。
690
   *
691
   * @param {string} mobile
692
   *     登录用户的手机号码。
693
   */
694
  @Log
695
  sendLoginVerifyCode(mobile) {
696
    return this._verifyCodeApi.sendBySms(mobile, 'LOGIN').then(() => {
×
697
      logger.info('Successfully sent the login verify code to:', mobile);
×
698
    });
699
  }
700

701
  /**
702
   * 检查指定的 Token 的值对于指定的用户是否依然合法。
703
   *
704
   * @param {string} userId
705
   *     用户的ID。
706
   * @param {string} tokenValue
707
   *     Token的值。
708
   * @returns {Promise<boolean|ErrorInfo>}
709
   *     此 HTTP 请求的 Promise,若操作成功,解析成功,如果Token的值对于指定的用户依然合法,
710
   *     则返回`true`;否则返回`false`;若操作失败,解析失败并返回一个`ErrorInfo`对象。
711
   */
712
  @Log
713
  async isTokenValid(userId, tokenValue) {
714
    try {
×
715
      logger.info('Checking the whether token value for the user %s is valid:', userId, tokenValue);
×
716
      const token = await this._userAuthenticateApi.checkToken(userId, tokenValue);
×
717
      const valid = !!token;
×
718
      logger.info('The validity of the token value is:', valid);
×
719
      return valid;
×
720
    } catch (error) {
721
      logger.info('The token value is invalid.');
×
722
      return false;
×
723
    }
724
  }
725
}
726

727
export default BasicUserStore;
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc