@cloudbase/auth 3.2.0 → 3.2.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudbase/auth",
3
- "version": "3.2.0",
3
+ "version": "3.2.2",
4
4
  "description": "cloudbase javascript sdk auth componets",
5
5
  "main": "dist/cjs/index.js",
6
6
  "module": "dist/esm/index.js",
@@ -32,14 +32,14 @@
32
32
  "license": "Apache-2.0",
33
33
  "dependencies": {
34
34
  "@cloudbase/adapter-wx_mp": "^1.3.1",
35
- "@cloudbase/oauth": "3.2.0",
36
- "@cloudbase/utilities": "3.2.0"
35
+ "@cloudbase/oauth": "3.2.2",
36
+ "@cloudbase/utilities": "3.2.2"
37
37
  },
38
38
  "devDependencies": {
39
- "@cloudbase/types": "3.2.0",
39
+ "@cloudbase/types": "3.2.2",
40
40
  "@types/node": "^22.1.0",
41
41
  "terser-webpack-plugin": "^3.0.2",
42
42
  "webpack-bundle-analyzer": "^4.9.1"
43
43
  },
44
- "gitHead": "55df54d2e1e0ec420b879d2b41b2df1f88164ad9"
44
+ "gitHead": "2528b011771ed5a5d309880307e9d3249b1d0894"
45
45
  }
package/src/index.ts CHANGED
@@ -13,6 +13,7 @@ import {
13
13
  OAUTH_TYPE,
14
14
  weAppJwtDecodeAll,
15
15
  AuthError,
16
+ AuthErrorCategory,
16
17
  authModels,
17
18
  DEFAULT_NODE_ACCESS_SCOPE,
18
19
  } from '@cloudbase/oauth'
@@ -416,7 +417,20 @@ class Auth extends AuthV1Compat {
416
417
  // loginState返回是为了兼容v2版本
417
418
  return { ...(loginState as any), data: { user: session.user, session }, error: null }
418
419
  } catch (error) {
419
- return { data: {}, error: new AuthError(error) }
420
+ const authError = new AuthError(error, { method: 'signInAnonymously' })
421
+ // 匿名登录失败时提供明确指引
422
+ if (authError.category === AuthErrorCategory.PROVIDER_NOT_ENABLED) {
423
+ console.error(authError.helpMessage)
424
+ console.error('[CloudBase Auth] 提示:匿名登录需要在控制台开启「匿名登录」。\n'
425
+ + ' 如果您需要使用用户名密码登录,请改用 auth.signInWithPassword({ username, password })。\n'
426
+ + ' 不要在匿名登录失败后自动回退到密码登录,这两种方式的使用场景不同。',)
427
+ } else {
428
+ console.warn(`[CloudBase Auth] signInAnonymously 失败 [${authError.category}]: ${authError.message}`)
429
+ if (authError.loginMethodHint) {
430
+ console.warn(authError.loginMethodHint)
431
+ }
432
+ }
433
+ return { data: {}, error: authError }
420
434
  }
421
435
  }
422
436
 
@@ -476,14 +490,14 @@ class Auth extends AuthV1Compat {
476
490
 
477
491
  return { data: { user: session.user, session }, error: null }
478
492
  } catch (error) {
479
- return { data: {}, error: new AuthError(error) }
493
+ return { data: {}, error: new AuthError(error, { method: 'signUp' }) }
480
494
  }
481
495
  },
482
496
  },
483
497
  error: null,
484
498
  }
485
499
  } catch (error) {
486
- return { data: {}, error: new AuthError(error) }
500
+ return { data: {}, error: new AuthError(error, { method: 'signUp' }) }
487
501
  }
488
502
  }
489
503
 
@@ -507,7 +521,7 @@ class Auth extends AuthV1Compat {
507
521
  // res返回是为了兼容v2版本
508
522
  return { ...res, data: {}, error: null }
509
523
  } catch (error) {
510
- return { data: {}, error: new AuthError(error) }
524
+ return { data: {}, error: new AuthError(error, { method: 'signOut' }) }
511
525
  }
512
526
  }
513
527
 
@@ -578,14 +592,19 @@ class Auth extends AuthV1Compat {
578
592
 
579
593
  return { data: { user: session.user, session }, error: null }
580
594
  } catch (error) {
581
- const authError = new AuthError(error)
582
- // 优化错误提示:登录失败时提供更友好的排查指引
583
- if (authError.message?.includes('密码不正确') || authError.message?.includes('password')) {
584
- console.warn('[CloudBase Auth] 登录失败提示:\n'
585
- + ' 1. 请确认用户名/邮箱/手机号是否正确\n'
586
- + ' 2. 请确认密码是否正确\n'
587
- + ' 3. 如果用户不存在,请先通过 auth.signUp() 注册用户,或在云开发控制台手动创建用户\n'
588
- + ' 4. 确认当前环境已开启对应的登录方式(控制台 → 环境 → 登录授权)',)
595
+ const authError = new AuthError(error, { method: 'signInWithPassword' })
596
+ // 根据错误分类输出对应的可操作性指引
597
+ if (authError.category === AuthErrorCategory.PROVIDER_NOT_ENABLED) {
598
+ console.error(authError.helpMessage)
599
+ } else if (authError.category === AuthErrorCategory.INVALID_CREDENTIALS) {
600
+ console.warn(authError.helpMessage)
601
+ } else if (authError.category === AuthErrorCategory.USER_NOT_FOUND) {
602
+ console.warn(authError.helpMessage)
603
+ } else {
604
+ console.warn(`[CloudBase Auth] signInWithPassword 失败 [${authError.category}]: ${authError.message}`)
605
+ }
606
+ if (authError.loginMethodHint) {
607
+ console.info(authError.loginMethodHint)
589
608
  }
590
609
  return { data: {}, error: authError }
591
610
  }
@@ -611,7 +630,7 @@ class Auth extends AuthV1Compat {
611
630
 
612
631
  return { data: { user: session.user, session }, error: null }
613
632
  } catch (error) {
614
- return { data: {}, error: new AuthError(error) }
633
+ return { data: {}, error: new AuthError(error, { method: 'signInWithIdToken' }) }
615
634
  }
616
635
  }
617
636
 
@@ -622,7 +641,7 @@ class Auth extends AuthV1Compat {
622
641
  * @returns Promise<SignInWithOtpRes>
623
642
  */
624
643
  async signInWithOtp(params: SignInWithOtpReq): Promise<SignInWithOtpRes> {
625
- if (params.options?.shouldCreateUser === undefined || !!params.options?.shouldCreateUser) {
644
+ if (!params.options?.emailRedirectTo && (params.options?.shouldCreateUser === undefined || !!params.options?.shouldCreateUser)) {
626
645
  return this.signUp({
627
646
  email: params.email,
628
647
  phone: params.phone,
@@ -634,7 +653,10 @@ class Auth extends AuthV1Compat {
634
653
  this.validateAtLeastOne(params, [['email'], ['phone']], 'You must provide either an email or phone number')
635
654
 
636
655
  // 第一步:发送验证码并存储 verificationInfo
637
- const verificationInfo = await this.getVerification(params.email ? { email: params.email } : { phone_number: this.formatPhone(params.phone) },)
656
+ const verificationInfo = await this.getVerification({
657
+ email_redirect_to: params.options?.emailRedirectTo,
658
+ ...(params.email ? { email: params.email } : { phone_number: this.formatPhone(params.phone) }),
659
+ })
638
660
 
639
661
  return {
640
662
  data: {
@@ -651,7 +673,7 @@ class Auth extends AuthV1Compat {
651
673
  error: null,
652
674
  }
653
675
  } catch (error) {
654
- return { data: {}, error: new AuthError(error) }
676
+ return { data: {}, error: new AuthError(error, { method: 'signInWithOtp' }) }
655
677
  }
656
678
  }
657
679
 
@@ -715,7 +737,7 @@ class Auth extends AuthV1Compat {
715
737
 
716
738
  return res
717
739
  } catch (error) {
718
- return { data, error: new AuthError(error) }
740
+ return { data, error: new AuthError(error, { method: 'verifyOAuth' }) }
719
741
  }
720
742
  }
721
743
 
@@ -774,7 +796,7 @@ class Auth extends AuthV1Compat {
774
796
 
775
797
  return { data: { url: finalUri, provider: params.provider }, error: null }
776
798
  } catch (error) {
777
- return { data: {}, error: new AuthError(error) }
799
+ return { data: {}, error: new AuthError(error, { method: 'signInWithOAuth' }) }
778
800
  }
779
801
  }
780
802
 
@@ -785,7 +807,7 @@ class Auth extends AuthV1Compat {
785
807
  const parsedToken = weAppJwtDecodeAll(accessToken)
786
808
  return { data: parsedToken, error: null }
787
809
  } catch (error) {
788
- return { data: {}, error: new AuthError(error) }
810
+ return { data: {}, error: new AuthError(error, { method: 'getClaims' }) }
789
811
  }
790
812
  }
791
813
 
@@ -863,14 +885,14 @@ class Auth extends AuthV1Compat {
863
885
 
864
886
  return res
865
887
  } catch (error) {
866
- return { data: {}, error: new AuthError(error) }
888
+ return { data: {}, error: new AuthError(error, { method: 'resetPasswordForEmail' }) }
867
889
  }
868
890
  },
869
891
  },
870
892
  error: null,
871
893
  }
872
894
  } catch (error) {
873
- return { data: {}, error: new AuthError(error) }
895
+ return { data: {}, error: new AuthError(error, { method: 'resetPasswordForEmail' }) }
874
896
  }
875
897
  }
876
898
 
@@ -891,7 +913,7 @@ class Auth extends AuthV1Compat {
891
913
 
892
914
  return { data: { user: session.user, session }, error: null }
893
915
  } catch (error) {
894
- return { data: {}, error: new AuthError(error) }
916
+ return { data: {}, error: new AuthError(error, { method: 'resetPasswordForOld' }) }
895
917
  }
896
918
  }
897
919
 
@@ -928,7 +950,7 @@ class Auth extends AuthV1Compat {
928
950
 
929
951
  return { data: { user: session.user, session }, error: null }
930
952
  } catch (error) {
931
- return { data: {}, error: new AuthError(error) }
953
+ return { data: {}, error: new AuthError(error, { method: 'verifyOtp' }) }
932
954
  }
933
955
  }
934
956
 
@@ -949,7 +971,7 @@ class Auth extends AuthV1Compat {
949
971
 
950
972
  return { data: { session: { ...credentials, user }, user }, error: null }
951
973
  } catch (error) {
952
- return { data: {}, error: new AuthError(error) }
974
+ return { data: {}, error: new AuthError(error, { method: 'getSession' }) }
953
975
  }
954
976
  }
955
977
 
@@ -968,7 +990,7 @@ class Auth extends AuthV1Compat {
968
990
 
969
991
  return { data: { user, session: { ...newTokens, user } }, error: null }
970
992
  } catch (error) {
971
- return { data: {}, error: new AuthError(error) }
993
+ return { data: {}, error: new AuthError(error, { method: 'refreshSession' }) }
972
994
  }
973
995
  }
974
996
 
@@ -982,7 +1004,7 @@ class Auth extends AuthV1Compat {
982
1004
  const user = this.convertToUser(await this.getCurrentUser())
983
1005
  return { data: { user }, error: null }
984
1006
  } catch (error) {
985
- return { data: {}, error: new AuthError(error) }
1007
+ return { data: {}, error: new AuthError(error, { method: 'getUser' }) }
986
1008
  }
987
1009
  }
988
1010
 
@@ -997,7 +1019,7 @@ class Auth extends AuthV1Compat {
997
1019
  const { data: { session } = {} } = await this.getSession()
998
1020
  return { data: { user: session.user, session }, error: null }
999
1021
  } catch (error) {
1000
- return { data: {}, error: new AuthError(error) }
1022
+ return { data: {}, error: new AuthError(error, { method: 'refreshUser' }) }
1001
1023
  }
1002
1024
  }
1003
1025
 
@@ -1084,7 +1106,7 @@ class Auth extends AuthV1Compat {
1084
1106
 
1085
1107
  return { data: { user }, error: null }
1086
1108
  } catch (error) {
1087
- return { data: {}, error: new AuthError(error) }
1109
+ return { data: {}, error: new AuthError(error, { method: 'updateUser' }) }
1088
1110
  }
1089
1111
  },
1090
1112
  }
@@ -1099,7 +1121,7 @@ class Auth extends AuthV1Compat {
1099
1121
 
1100
1122
  return { data: { user, ...extraRes }, error: null }
1101
1123
  } catch (error) {
1102
- return { data: {}, error: new AuthError(error) }
1124
+ return { data: {}, error: new AuthError(error, { method: 'updateUser' }) }
1103
1125
  }
1104
1126
  }
1105
1127
 
@@ -1119,7 +1141,7 @@ class Auth extends AuthV1Compat {
1119
1141
  error: null,
1120
1142
  }
1121
1143
  } catch (error) {
1122
- return { data: {}, error: new AuthError(error) }
1144
+ return { data: {}, error: new AuthError(error, { method: 'getUserIdentities' }) }
1123
1145
  }
1124
1146
  }
1125
1147
 
@@ -1145,7 +1167,7 @@ class Auth extends AuthV1Compat {
1145
1167
 
1146
1168
  return { data: { provider: params.provider }, error: null }
1147
1169
  } catch (error) {
1148
- return { data: {}, error: new AuthError(error) }
1170
+ return { data: {}, error: new AuthError(error, { method: 'linkIdentity' }) }
1149
1171
  }
1150
1172
  }
1151
1173
 
@@ -1166,7 +1188,7 @@ class Auth extends AuthV1Compat {
1166
1188
 
1167
1189
  return { data: {}, error: null }
1168
1190
  } catch (error) {
1169
- return { data: {}, error: new AuthError(error) }
1191
+ return { data: {}, error: new AuthError(error, { method: 'unlinkIdentity' }) }
1170
1192
  }
1171
1193
  }
1172
1194
 
@@ -1224,14 +1246,14 @@ class Auth extends AuthV1Compat {
1224
1246
 
1225
1247
  return { data: { user: session.user, session }, error: null }
1226
1248
  } catch (error) {
1227
- return { data: {}, error: new AuthError(error) }
1249
+ return { data: {}, error: new AuthError(error, { method: 'reauthenticate' }) }
1228
1250
  }
1229
1251
  },
1230
1252
  },
1231
1253
  error: null,
1232
1254
  }
1233
1255
  } catch (error) {
1234
- return { data: {}, error: new AuthError(error) }
1256
+ return { data: {}, error: new AuthError(error, { method: 'reauthenticate' }) }
1235
1257
  }
1236
1258
  }
1237
1259
 
@@ -1266,7 +1288,7 @@ class Auth extends AuthV1Compat {
1266
1288
  } catch (error: any) {
1267
1289
  return {
1268
1290
  data: {},
1269
- error: new AuthError(error),
1291
+ error: new AuthError(error, { method: 'resend' }),
1270
1292
  }
1271
1293
  }
1272
1294
  }
@@ -1292,7 +1314,7 @@ class Auth extends AuthV1Compat {
1292
1314
 
1293
1315
  return { data: { user: session.user, session }, error: null }
1294
1316
  } catch (error) {
1295
- return { data: {}, error: new AuthError(error) }
1317
+ return { data: {}, error: new AuthError(error, { method: 'setSession' }) }
1296
1318
  }
1297
1319
  }
1298
1320
 
@@ -1318,7 +1340,7 @@ class Auth extends AuthV1Compat {
1318
1340
 
1319
1341
  return { data: {}, error: null }
1320
1342
  } catch (error) {
1321
- return { data: {}, error: new AuthError(error) }
1343
+ return { data: {}, error: new AuthError(error, { method: 'deleteUser' }) }
1322
1344
  }
1323
1345
  }
1324
1346
 
@@ -1346,7 +1368,7 @@ class Auth extends AuthV1Compat {
1346
1368
  }
1347
1369
  return { data: {}, error: null }
1348
1370
  } catch (error) {
1349
- return { data: {}, error: new AuthError(error) }
1371
+ return { data: {}, error: new AuthError(error, { method: 'toDefaultLoginPage' }) }
1350
1372
  }
1351
1373
  }
1352
1374
 
@@ -1369,7 +1391,7 @@ class Auth extends AuthV1Compat {
1369
1391
  // loginState返回是为了兼容v2版本
1370
1392
  return { ...(loginState as any), data: { user: session.user, session }, error: null }
1371
1393
  } catch (error) {
1372
- return { data: {}, error: new AuthError(error) }
1394
+ return { data: {}, error: new AuthError(error, { method: 'signInWithCustomTicket' }) }
1373
1395
  }
1374
1396
  }
1375
1397
 
@@ -1445,7 +1467,7 @@ class Auth extends AuthV1Compat {
1445
1467
  // loginState返回是为了兼容v2版本
1446
1468
  return { ...(loginState as any), data: { user: session.user, session }, error: null }
1447
1469
  } catch (error) {
1448
- return { data: {}, error: new AuthError(error) }
1470
+ return { data: {}, error: new AuthError(error, { method: 'signInWithOpenId' }) }
1449
1471
  }
1450
1472
  }
1451
1473
 
@@ -1481,7 +1503,7 @@ class Auth extends AuthV1Compat {
1481
1503
  throw signInRes
1482
1504
  }
1483
1505
  } catch (error) {
1484
- return { data: {}, error: new AuthError(error) }
1506
+ return { data: {}, error: new AuthError(error, { method: 'signInWithPhoneAuth' }) }
1485
1507
  }
1486
1508
 
1487
1509
  const loginState = await this.createLoginState()
@@ -2773,6 +2795,8 @@ try {
2773
2795
  } catch (e) {}
2774
2796
 
2775
2797
  export { UserInfo, Auth, WeixinAuthProvider, CustomAuthProvider, AnonymousAuthProvider }
2798
+ // 导出错误分类枚举和 AuthError,方便开发者进行错误分类处理
2799
+ export { AuthErrorCategory, AuthError } from '@cloudbase/oauth'
2776
2800
  /**
2777
2801
  * @api 手动注册至cloudbase app
2778
2802
  */
package/src/type.ts CHANGED
@@ -1,7 +1,22 @@
1
1
  import type { authModels, OAUTH_TYPE } from '@cloudbase/oauth'
2
- import { AuthError } from '@cloudbase/oauth'
2
+ import { AuthError, AuthErrorCategory } from '@cloudbase/oauth'
3
3
 
4
+ export { AuthErrorCategory }
4
5
 
6
+
7
+ /**
8
+ * signInAnonymously 请求参数
9
+ *
10
+ * **前置条件**:使用此方法前,请确保已在云开发控制台(环境 → 登录授权 → 身份源列表)开启「匿名登录」。
11
+ *
12
+ * **使用场景**:
13
+ * - 无需用户注册即可使用应用功能
14
+ * - 临时访问或快速体验场景
15
+ * - 测试/自动化环境中不需要真实用户凭据时
16
+ *
17
+ * **注意**:匿名登录与密码登录是两种独立的登录方式,不要在匿名登录失败后自动回退到密码登录。
18
+ * 如果匿名登录返回 PROVIDER_NOT_ENABLED 错误,说明需要在控制台开启匿名登录功能。
19
+ */
5
20
  export interface SignInAnonymouslyReq {
6
21
  provider_token?: string // 提供令牌
7
22
  }
@@ -48,6 +63,24 @@ export declare type Session = {
48
63
  user: User // 用户信息
49
64
  }
50
65
 
66
+ /**
67
+ * signInWithPassword 请求参数
68
+ *
69
+ * **重要提示**:使用此方法前,请确保已在云开发控制台(环境 → 登录授权 → 身份源列表)
70
+ * 开启「用户名密码登录」方式。如未开启,登录时会返回 AuthErrorCategory.PROVIDER_NOT_ENABLED 错误。
71
+ *
72
+ * **凭据来源**:
73
+ * - 用户手动输入(交互式场景)
74
+ * - 环境变量 ENV_ID / USER_NAME / PASSWORD(自动化/agent 场景)
75
+ * - 请确保凭据对应的用户已在目标 envId 环境中注册
76
+ *
77
+ * **常见错误**:
78
+ * - `invalid_username_or_password`:用户名或密码错误,请核实凭据
79
+ * - `PROVIDER_NOT_ENABLED`:用户名密码登录未开启,需在控制台配置
80
+ * - `not_found`:用户不存在,需先注册
81
+ *
82
+ * **注意**:不同云开发环境的用户库是隔离的,请确认 envId 与凭据匹配。
83
+ */
51
84
  export interface SignInWithPasswordReq {
52
85
  username?: string // 用户名称(可选,与邮箱、手机号三选一),长度 5-24 位,支持字符中英文、数字、特殊字符(仅支持_-),不支持中文
53
86
  email?: string // 邮箱(可选,与用户名、手机号三选一)
@@ -62,6 +95,35 @@ export interface CommonRes {
62
95
  error: AuthError | null // 错误信息,成功时为null
63
96
  }
64
97
 
98
+ /**
99
+ * 登录操作响应类型
100
+ *
101
+ * 当 error 不为 null 时,error 对象包含:
102
+ * - `category`: 错误分类(AuthErrorCategory 枚举),可用于程序化判断错误类型
103
+ * - `helpMessage`: 可操作性指引信息,包含排查步骤和解决方案
104
+ * - `loginMethodHint`: 登录方式选择建议,帮助选择正确的登录方法
105
+ * - `code`: 服务端返回的错误码(如 'invalid_username_or_password'、'invalid_password')
106
+ * - `message`: 错误描述
107
+ *
108
+ * 示例:
109
+ * ```typescript
110
+ * const { data, error } = await auth.signInWithPassword({ username: 'test', password: '123' })
111
+ * if (error) {
112
+ * if (error.category === AuthErrorCategory.PROVIDER_NOT_ENABLED) {
113
+ * // 身份源未开启,引导用户或管理员开启
114
+ * console.log(error.helpMessage)
115
+ * } else if (error.category === AuthErrorCategory.INVALID_CREDENTIALS) {
116
+ * // 凭据错误(包括 invalid_username_or_password),提示用户检查密码
117
+ * console.log(error.helpMessage)
118
+ * }
119
+ * }
120
+ * ```
121
+ *
122
+ * **agent/自动化场景注意**:
123
+ * - 不要在 signInAnonymously() 失败后自动回退到 signInWithPassword()
124
+ * - 两种登录方式的适用场景不同,应根据任务需求明确选择
125
+ * - 使用 error.loginMethodHint 获取当前登录方式的使用建议
126
+ */
65
127
  export interface SignInRes {
66
128
  data: {
67
129
  user?: User // 用户信息
@@ -229,6 +291,7 @@ export interface SignInWithOtpReq {
229
291
  phone?: string // 手机号(可选,与邮箱二选一)
230
292
  options?: {
231
293
  shouldCreateUser?: boolean // 如果用户不存在是否创建用户,默认为true
294
+ emailRedirectTo?: string // 邮箱登录回调地址,填写后则会发送认证链接至邮箱,否则发送验证码
232
295
  }
233
296
  }
234
297