@cloudbase/oauth 3.0.0 → 3.0.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.
Files changed (70) hide show
  1. package/dist/cjs/auth/apis.d.ts +22 -4
  2. package/dist/cjs/auth/apis.js +255 -66
  3. package/dist/cjs/auth/auth-error.d.ts +6 -0
  4. package/dist/cjs/auth/auth-error.js +32 -0
  5. package/dist/cjs/auth/consts.d.ts +22 -0
  6. package/dist/cjs/auth/consts.js +24 -2
  7. package/dist/cjs/auth/models.d.ts +13 -4
  8. package/dist/cjs/auth/models.js +1 -1
  9. package/dist/cjs/captcha/captcha-dom.d.ts +3 -0
  10. package/dist/cjs/captcha/captcha-dom.js +223 -0
  11. package/dist/cjs/captcha/captcha.d.ts +3 -1
  12. package/dist/cjs/captcha/captcha.js +11 -102
  13. package/dist/cjs/index.d.ts +12 -2
  14. package/dist/cjs/index.js +27 -4
  15. package/dist/cjs/oauth2client/interface.d.ts +1 -1
  16. package/dist/cjs/oauth2client/interface.js +1 -1
  17. package/dist/cjs/oauth2client/models.d.ts +15 -1
  18. package/dist/cjs/oauth2client/models.js +1 -1
  19. package/dist/cjs/oauth2client/oauth2client.d.ts +62 -3
  20. package/dist/cjs/oauth2client/oauth2client.js +426 -131
  21. package/dist/cjs/utils/base64.d.ts +5 -0
  22. package/dist/cjs/utils/base64.js +15 -2
  23. package/dist/cjs/utils/encryptlong/index.js +22 -16
  24. package/dist/cjs/utils/index.js +1 -1
  25. package/dist/cjs/utils/mp.js +4 -4
  26. package/dist/cjs/utils/urlSearchParams.js +1 -1
  27. package/dist/esm/auth/apis.d.ts +22 -4
  28. package/dist/esm/auth/apis.js +130 -10
  29. package/dist/esm/auth/auth-error.d.ts +6 -0
  30. package/dist/esm/auth/auth-error.js +9 -0
  31. package/dist/esm/auth/consts.d.ts +22 -0
  32. package/dist/esm/auth/consts.js +22 -0
  33. package/dist/esm/auth/models.d.ts +13 -4
  34. package/dist/esm/captcha/captcha-dom.d.ts +3 -0
  35. package/dist/esm/captcha/captcha-dom.js +129 -0
  36. package/dist/esm/captcha/captcha.d.ts +3 -1
  37. package/dist/esm/captcha/captcha.js +14 -97
  38. package/dist/esm/index.d.ts +12 -2
  39. package/dist/esm/index.js +20 -3
  40. package/dist/esm/oauth2client/interface.d.ts +1 -1
  41. package/dist/esm/oauth2client/models.d.ts +15 -1
  42. package/dist/esm/oauth2client/oauth2client.d.ts +62 -3
  43. package/dist/esm/oauth2client/oauth2client.js +200 -55
  44. package/dist/esm/utils/base64.d.ts +5 -0
  45. package/dist/esm/utils/base64.js +12 -0
  46. package/dist/esm/utils/encryptlong/index.js +21 -15
  47. package/dist/esm/utils/mp.js +3 -3
  48. package/dist/miniprogram/index.js +1 -1
  49. package/package.json +10 -4
  50. package/src/auth/apis.ts +222 -17
  51. package/src/auth/auth-error.ts +21 -0
  52. package/src/auth/consts.ts +28 -0
  53. package/src/auth/models.ts +13 -4
  54. package/src/captcha/captcha-dom.ts +178 -0
  55. package/src/captcha/captcha.ts +25 -114
  56. package/src/index.ts +54 -4
  57. package/src/oauth2client/interface.ts +1 -1
  58. package/src/oauth2client/models.ts +29 -1
  59. package/src/oauth2client/oauth2client.ts +308 -55
  60. package/src/utils/base64.ts +12 -0
  61. package/src/utils/encryptlong/index.js +20 -14
  62. package/src/utils/index.ts +1 -0
  63. package/src/utils/mp.ts +3 -3
  64. package/src/utils/urlSearchParams.ts +2 -0
  65. package/tsconfig.json +1 -0
  66. package/dist/cjs/utils/cloudbase-adapter-wx_mp.d.ts +0 -1
  67. package/dist/cjs/utils/cloudbase-adapter-wx_mp.js +0 -40
  68. package/dist/esm/utils/cloudbase-adapter-wx_mp.d.ts +0 -1
  69. package/dist/esm/utils/cloudbase-adapter-wx_mp.js +0 -35
  70. package/src/utils/cloudbase-adapter-wx_mp.ts +0 -42
@@ -2,17 +2,20 @@ import { ApiUrls, ErrorType } from '../auth/consts'
2
2
  import { SimpleStorage, RequestFunction } from '../oauth2client/interface'
3
3
  import { AuthClientRequestOptions } from '../oauth2client/models'
4
4
  import { defaultStorage } from '../oauth2client/oauth2client'
5
- import { isInMpWebView, isMp } from '../utils/mp'
6
- import MyURLSearchParams from '../utils/urlSearchParams'
5
+ import { isMp } from '../utils/mp'
7
6
  import { SDKAdapterInterface } from '@cloudbase/adapter-interface'
7
+ import { openURIWithCallback } from './captcha-dom'
8
+ import { Auth } from '../auth/apis'
8
9
 
9
10
  export interface CaptchaOptions {
11
+ env: string;
10
12
  clientId: string
11
13
  request: RequestFunction
12
14
  storage: SimpleStorage
13
15
  // 打开网页并通过URL回调获取 CaptchaToken,针对不通的平台,该函数可以自定义实现, 默认集成浏览器端认证
14
16
  openURIWithCallback?: OpenURIWithCallbackFuction
15
17
  adapter?: SDKAdapterInterface & { isMatch?: () => boolean }
18
+ oauthInstance?: Auth
16
19
  }
17
20
 
18
21
  type OpenURIWithCallbackFuction = (url: string) => Promise<CaptchaToken>
@@ -50,7 +53,7 @@ export class Captcha {
50
53
  }
51
54
 
52
55
  this.config = opts
53
- this.tokenSectionName = `captcha_${opts.clientId}`
56
+ this.tokenSectionName = `captcha_${opts.clientId || opts.env}`
54
57
  }
55
58
 
56
59
  public isMatch() {
@@ -89,75 +92,9 @@ export class Captcha {
89
92
  }
90
93
 
91
94
  private getDefaultOpenURIWithCallback(): OpenURIWithCallbackFuction {
92
- if (!this.isMatch() && !isInMpWebView()) {
93
- if (window.location.search.indexOf('__captcha') > 0) {
94
- document.body.style.display = 'none'
95
- }
96
- if (document.getElementById('captcha_panel_wrap') === null) {
97
- const elementDiv = document.createElement('div')
98
- elementDiv.style.cssText = 'background-color: rgba(0, 0, 0, 0.7);position: fixed;left: 0px;right: 0px;top: 0px;bottom: 0px;padding: 9vw 0 0 0;display: none;z-index:100;'
99
- elementDiv.setAttribute('id', 'captcha_panel_wrap')
100
- setTimeout(() => {
101
- document.body.appendChild(elementDiv)
102
- }, 0)
103
- }
104
- }
105
- return this.defaultOpenURIWithCallback
95
+ return (url: string) => openURIWithCallback(url, this.config.oauthInstance)
106
96
  }
107
97
 
108
- /**
109
- * 默认通过浏览器打开网页并获取回调
110
- */
111
- private async defaultOpenURIWithCallback(
112
- url: string,
113
- opts?: { width?: string; height?: string },
114
- ): Promise<CaptchaToken> {
115
- const { width = '355px', height = '355px' } = opts || {}
116
-
117
- const matched = url.match(/^(data:.*)$/)
118
- if (matched) {
119
- return Promise.reject({
120
- error: ErrorType.UNIMPLEMENTED,
121
- error_description: 'need to impl captcha data',
122
- })
123
- }
124
-
125
- const target = document.getElementById('captcha_panel_wrap')
126
- const iframe = document.createElement('iframe')
127
- target.innerHTML = ''
128
-
129
- iframe.setAttribute('src', url)
130
- iframe.setAttribute('id', 'review-panel-iframe')
131
- iframe.style.cssText = `min-width:${width};display:block;height:${height};margin:0 auto;background-color: rgb(255, 255, 255);border: none;`
132
- target.appendChild(iframe)
133
- target.style.display = 'block'
134
- return new Promise<CaptchaToken>((resolve, reject) => {
135
- iframe.onload = function () {
136
- try {
137
- const windowLocation = window.location
138
- const iframeLocation = iframe.contentWindow.location
139
- if (iframeLocation.host + iframeLocation.pathname === windowLocation.host + windowLocation.pathname) {
140
- target.style.display = 'none'
141
- const iframeUrlParams = new MyURLSearchParams(iframeLocation.search)
142
- const captchToken = iframeUrlParams.get('captcha_token')
143
- if (captchToken) {
144
- return resolve({
145
- captcha_token: captchToken,
146
- expires_in: Number(iframeUrlParams.get('expires_in')),
147
- })
148
- }
149
- return reject({
150
- error: iframeUrlParams.get('error'),
151
- error_description: iframeUrlParams.get('error_description'),
152
- })
153
- }
154
- target.style.display = 'block'
155
- } catch (error) {
156
- target.style.display = 'block'
157
- }
158
- }
159
- })
160
- }
161
98
  /**
162
99
  * getCaptchaToken 获取captchaToken
163
100
  */
@@ -169,52 +106,26 @@ export class Captcha {
169
106
  return captchaToken
170
107
  }
171
108
  }
172
- let captchaTokenResp: {
173
- url?: string
174
- captcha_token?: string
175
- expires_in?: number
176
- }
177
- if (!this.isMatch() && !isInMpWebView()) {
178
- const redirect_uri = `${window.location.origin + window.location.pathname}?__captcha=on`
179
- captchaTokenResp = await this.config.request<GetCaptchaResponse>(ApiUrls.GET_CAPTCHA_URL, {
180
- method: 'POST',
181
- body: {
182
- client_id: this.config.clientId,
183
- redirect_uri,
184
- state,
185
- },
186
- withCredentials: false,
187
- })
188
- if (captchaTokenResp.captcha_token) {
189
- const captchaToken = {
190
- captcha_token: captchaTokenResp.captcha_token,
191
- expires_in: captchaTokenResp.expires_in,
192
- }
193
- this.saveCaptchaToken(captchaToken)
194
- return captchaTokenResp.captcha_token
195
- }
196
- } else {
197
- /**
109
+
110
+ /**
198
111
  * https://iwiki.woa.com/p/4010699417
199
112
  */
200
- const captchaDataResp = await this.config.request<{
201
- data: string
202
- type: 'image'
203
- token: string
204
- expires_in: number
205
- }>(ApiUrls.CAPTCHA_DATA_URL, {
206
- method: 'POST',
207
- body: {
208
- state,
209
- redirect_uri: '',
210
- },
211
- withCredentials: false,
212
- })
213
- captchaTokenResp = {
214
- url: `${captchaDataResp.data}?state=${encodeURIComponent(state)}&token=${encodeURIComponent(captchaDataResp.token,)}`,
215
- }
216
- }
217
- const captchaToken = await this.config.openURIWithCallback(captchaTokenResp.url)
113
+ const captchaDataResp = await this.config.request<{
114
+ data: string
115
+ type: 'image'
116
+ token: string
117
+ expires_in: number
118
+ }>(ApiUrls.CAPTCHA_DATA_URL, {
119
+ method: 'POST',
120
+ body: {
121
+ state,
122
+ redirect_uri: '',
123
+ },
124
+ withCredentials: false,
125
+ })
126
+ const captchaTokenUrl = `${captchaDataResp.data}?state=${encodeURIComponent(state)}&token=${encodeURIComponent(captchaDataResp.token,)}`
127
+
128
+ const captchaToken = await this.config.openURIWithCallback(captchaTokenUrl)
218
129
  this.saveCaptchaToken(captchaToken)
219
130
  return captchaToken.captcha_token
220
131
  }
package/src/index.ts CHANGED
@@ -1,19 +1,44 @@
1
1
  import { OAuth2Client } from './oauth2client/oauth2client'
2
2
  import { AuthOptions, Auth } from './auth/apis'
3
3
  import { AUTH_API_PREFIX } from './auth/consts'
4
+ import { Credentials } from './oauth2client/models'
4
5
  export { Auth } from './auth/apis'
5
- export { AUTH_API_PREFIX } from './auth/consts'
6
+ export { AUTH_API_PREFIX, OAUTH_TYPE } from './auth/consts'
7
+ export { AuthError } from './auth/auth-error'
6
8
  export * as authModels from './auth/models'
7
- export type { ProviderProfile } from './auth/models'
9
+ export type { ProviderProfile, UserInfo, ModifyUserBasicInfoRequest } from './auth/models'
8
10
  export type { Credentials, OAuth2ClientOptions, ResponseError, AuthClientRequestOptions } from './oauth2client/models'
9
11
  export type { AuthOptions } from './auth/apis'
12
+ export { weAppJwtDecodeAll } from './utils/base64'
13
+ export { LOGIN_STATE_CHANGED_TYPE, EVENTS, AUTH_STATE_CHANGED_TYPE } from './auth/consts'
10
14
 
11
15
  export class CloudbaseOAuth {
12
16
  public oauth2client: OAuth2Client
13
17
  public authApi: Auth
18
+ private detectSessionInUrl: boolean
14
19
 
15
20
  constructor(authOptions: AuthOptions) {
16
- const { apiOrigin, apiPath = AUTH_API_PREFIX, clientId, env, storage, request, baseRequest, anonymousSignInFunc, wxCloud, adapter, onCredentialsError, headers, i18n, publishable_key } = authOptions
21
+ // eslint-disable-next-line max-len
22
+ const {
23
+ apiOrigin,
24
+ apiPath = AUTH_API_PREFIX,
25
+ clientId,
26
+ env,
27
+ storage,
28
+ request,
29
+ baseRequest,
30
+ anonymousSignInFunc,
31
+ wxCloud,
32
+ adapter,
33
+ onCredentialsError,
34
+ headers,
35
+ i18n,
36
+ useWxCloud,
37
+ eventBus,
38
+ detectSessionInUrl,
39
+ debug,
40
+ } = authOptions
41
+ this.detectSessionInUrl = detectSessionInUrl ?? false
17
42
  this.oauth2client = new OAuth2Client({
18
43
  apiOrigin,
19
44
  apiPath,
@@ -26,7 +51,9 @@ export class CloudbaseOAuth {
26
51
  onCredentialsError,
27
52
  headers: headers || {},
28
53
  i18n,
29
- publishable_key,
54
+ useWxCloud,
55
+ eventBus,
56
+ debug,
30
57
  })
31
58
 
32
59
  this.authApi = new Auth({
@@ -36,5 +63,28 @@ export class CloudbaseOAuth {
36
63
  request: request ? this.oauth2client.request.bind(this.oauth2client) : undefined,
37
64
  adapter,
38
65
  })
66
+
67
+ // Set the getInitialSession callback after Auth is created
68
+ // This allows Auth.getInitialSession to handle URL detection and OAuth verification
69
+ if (detectSessionInUrl) {
70
+ this.oauth2client.setGetInitialSession(this.authApi.getInitialSession.bind(this.authApi))
71
+ }
72
+ // Note: Do NOT auto-call initialize() here.
73
+ // Upper layer (packages/auth) should call initializeSession() after setting up onInitialSessionObtained callback
74
+ }
75
+
76
+ /**
77
+ * Setup the onInitialSessionObtained callback and trigger initialization.
78
+ * This should be called by upper layer (packages/auth) after creating Auth instance.
79
+ * @param onUserObtained Callback to handle user info storage after session is obtained
80
+ */
81
+ public initializeSession(onUserObtained?: (data: { session: Credentials; user?: any; type?: string }, error?: any) => void | Promise<void>): void {
82
+ if (!this.detectSessionInUrl) {
83
+ this.oauth2client.initialize(Promise.resolve({ error: null }))
84
+ return
85
+ }
86
+ this.oauth2client.setOnInitialSessionObtained(onUserObtained)
87
+ // Pass callback directly to initialize() to ensure it's set before initialization starts
88
+ this.oauth2client.initialize()
39
89
  }
40
90
  }
@@ -15,7 +15,7 @@ export abstract class AuthClient {
15
15
  /**
16
16
  * Sets the auth credentials.
17
17
  */
18
- abstract setCredentials(credentials?: Credentials): void;
18
+ abstract setCredentials(credentials?: Credentials): Promise<void>;
19
19
 
20
20
  /**
21
21
  * get the current accessToken from AuthClient, you can use this to detect login status
@@ -46,6 +46,12 @@ export interface AuthClientRequestOptions extends RequestOptions {
46
46
  withBasicAuth?: boolean;
47
47
  retry?: number;
48
48
  useWxCloud?: boolean;
49
+ /**
50
+ * Custom getCredentials function for this request.
51
+ * When provided, uses this function instead of the default getCredentials() call
52
+ * to avoid potential deadlocks during initialization.
53
+ */
54
+ getCredentials?: () => Credentials | Promise<Credentials | null> | null;
49
55
 
50
56
  [key: string]: any;
51
57
  }
@@ -71,5 +77,27 @@ export interface OAuth2ClientOptions {
71
77
  wxCloud?: any;
72
78
  onCredentialsError?: AuthOptions['onCredentialsError']
73
79
  i18n?: ICloudbaseConfig['i18n']
74
- publishable_key?: string;
80
+ useWxCloud?: boolean
81
+ eventBus?: any
82
+ /**
83
+ * Enable debug logging
84
+ */
85
+ debug?: boolean
86
+ /**
87
+ * Callback function to get initial session (e.g., from OAuth callback in URL).
88
+ * Called by OAuth2Client.initialize() if set.
89
+ * The callback should handle URL detection, OAuth verification, and return credentials.
90
+ * Returns { data: { session: Credentials, user?: any }, error: null } on success,
91
+ * or { data: null, error: Error } on failure.
92
+ */
93
+ getInitialSession?: () => Promise<{
94
+ data: { session: Credentials; user?: any } | null
95
+ error: Error | null
96
+ }>
97
+ /**
98
+ * Callback invoked after initial session is obtained and stored.
99
+ * Used to let upper layer (e.g., packages/auth) handle user info storage.
100
+ * Called with session and user data.
101
+ */
102
+ onInitialSessionObtained?: (data: { session: Credentials; user?: any }) => void | Promise<void>
75
103
  }