@cloudbase/oauth 2.5.41-beta.0 → 2.5.43-beta.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.
- package/dist/cjs/auth/apis.d.ts +16 -0
- package/dist/cjs/auth/apis.js +27 -8
- package/dist/cjs/auth/consts.d.ts +3 -0
- package/dist/cjs/auth/consts.js +4 -1
- package/dist/cjs/captcha/captcha.js +52 -28
- package/dist/cjs/oauth2client/consts.js +1 -1
- package/dist/cjs/utils/mp.d.ts +2 -0
- package/dist/cjs/utils/mp.js +58 -0
- package/dist/esm/auth/apis.d.ts +16 -0
- package/dist/esm/auth/apis.js +27 -8
- package/dist/esm/auth/consts.d.ts +3 -0
- package/dist/esm/auth/consts.js +4 -1
- package/dist/esm/captcha/captcha.js +52 -28
- package/dist/esm/oauth2client/consts.js +1 -1
- package/dist/esm/utils/mp.d.ts +2 -0
- package/dist/esm/utils/mp.js +53 -0
- package/package.json +2 -2
- package/src/auth/apis.ts +100 -127
- package/src/auth/consts.ts +6 -2
- package/src/captcha/captcha.ts +86 -50
- package/src/oauth2client/consts.ts +3 -2
- package/src/utils/mp.ts +53 -0
package/src/auth/apis.ts
CHANGED
|
@@ -48,18 +48,19 @@ import {
|
|
|
48
48
|
import { SimpleStorage, RequestFunction } from '../oauth2client/interface'
|
|
49
49
|
import { OAuth2Client, defaultStorage } from '../oauth2client/oauth2client'
|
|
50
50
|
import { Credentials } from '../oauth2client/models'
|
|
51
|
-
import { Captcha } from '../captcha/captcha'
|
|
51
|
+
import { Captcha, CaptchaOptions } from '../captcha/captcha'
|
|
52
52
|
import { deepClone } from '../utils'
|
|
53
53
|
import { getEncryptInfo } from '../utils/encrypt'
|
|
54
54
|
|
|
55
55
|
export interface AuthOptions {
|
|
56
|
-
apiOrigin: string
|
|
57
|
-
clientId: string
|
|
58
|
-
credentialsClient?: OAuth2Client
|
|
59
|
-
request?: RequestFunction
|
|
60
|
-
baseRequest?: RequestFunction
|
|
61
|
-
storage?: SimpleStorage
|
|
62
|
-
anonymousSignInFunc?: (Credentials) => Promise<Credentials | void
|
|
56
|
+
apiOrigin: string
|
|
57
|
+
clientId: string
|
|
58
|
+
credentialsClient?: OAuth2Client
|
|
59
|
+
request?: RequestFunction
|
|
60
|
+
baseRequest?: RequestFunction
|
|
61
|
+
storage?: SimpleStorage
|
|
62
|
+
anonymousSignInFunc?: (Credentials) => Promise<Credentials | void>
|
|
63
|
+
captchaOptions?: Partial<CaptchaOptions>
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
/**
|
|
@@ -100,6 +101,7 @@ export class Auth {
|
|
|
100
101
|
clientId: opts.clientId,
|
|
101
102
|
request: baseRequest,
|
|
102
103
|
storage: opts.storage,
|
|
104
|
+
...opts.captchaOptions,
|
|
103
105
|
})
|
|
104
106
|
request = captcha.request.bind(captcha)
|
|
105
107
|
}
|
|
@@ -142,13 +144,10 @@ export class Auth {
|
|
|
142
144
|
}
|
|
143
145
|
|
|
144
146
|
const body = await this.getEncryptParams(res.params)
|
|
145
|
-
const credentials: Credentials = await this.config.request<Credentials>(
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
body,
|
|
150
|
-
}
|
|
151
|
-
)
|
|
147
|
+
const credentials: Credentials = await this.config.request<Credentials>(res.url, {
|
|
148
|
+
method: 'POST',
|
|
149
|
+
body,
|
|
150
|
+
})
|
|
152
151
|
await this.config.credentialsClient.setCredentials({
|
|
153
152
|
...credentials,
|
|
154
153
|
version,
|
|
@@ -161,15 +160,12 @@ export class Auth {
|
|
|
161
160
|
* @return {Promise<Credentials>} A Promise<Credentials> object.
|
|
162
161
|
*/
|
|
163
162
|
public async signInAnonymously(data: {
|
|
164
|
-
provider_token?: string
|
|
165
|
-
} = {}): Promise<Credentials> {
|
|
166
|
-
const credentials: Credentials = await this.config.request<Credentials>(
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
body: data,
|
|
171
|
-
}
|
|
172
|
-
)
|
|
163
|
+
provider_token?: string
|
|
164
|
+
} = {},): Promise<Credentials> {
|
|
165
|
+
const credentials: Credentials = await this.config.request<Credentials>(ApiUrls.AUTH_SIGN_IN_ANONYMOUSLY_URL, {
|
|
166
|
+
method: 'POST',
|
|
167
|
+
body: data,
|
|
168
|
+
})
|
|
173
169
|
await this.config.credentialsClient.setCredentials(credentials)
|
|
174
170
|
return Promise.resolve(credentials)
|
|
175
171
|
}
|
|
@@ -180,13 +176,10 @@ export class Auth {
|
|
|
180
176
|
* @return {Promise<Credentials>} A Promise<Credentials> object.
|
|
181
177
|
*/
|
|
182
178
|
public async signUp(params: SignUpRequest): Promise<Credentials> {
|
|
183
|
-
const data: Credentials = await this.config.request<Credentials>(
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
body: params,
|
|
188
|
-
}
|
|
189
|
-
)
|
|
179
|
+
const data: Credentials = await this.config.request<Credentials>(ApiUrls.AUTH_SIGN_UP_URL, {
|
|
180
|
+
method: 'POST',
|
|
181
|
+
body: params,
|
|
182
|
+
})
|
|
190
183
|
await this.config.credentialsClient.setCredentials(data)
|
|
191
184
|
return Promise.resolve(data)
|
|
192
185
|
}
|
|
@@ -196,7 +189,7 @@ export class Auth {
|
|
|
196
189
|
* @return {Object} A Promise<void> object.
|
|
197
190
|
*/
|
|
198
191
|
public async signOut(): Promise<any> {
|
|
199
|
-
const accessToken: string =
|
|
192
|
+
const accessToken: string = await this.config.credentialsClient.getAccessToken()
|
|
200
193
|
const data = await this.config.request(ApiUrls.AUTH_REVOKE_URL, {
|
|
201
194
|
method: 'POST',
|
|
202
195
|
body: {
|
|
@@ -223,15 +216,12 @@ export class Auth {
|
|
|
223
216
|
withCredentials = true
|
|
224
217
|
}
|
|
225
218
|
}
|
|
226
|
-
return this.config.request<GetVerificationResponse>(
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
withCredentials,
|
|
233
|
-
}
|
|
234
|
-
)
|
|
219
|
+
return this.config.request<GetVerificationResponse>(ApiUrls.VERIFICATION_URL, {
|
|
220
|
+
method: 'POST',
|
|
221
|
+
body: params,
|
|
222
|
+
withCaptcha: true,
|
|
223
|
+
withCredentials,
|
|
224
|
+
})
|
|
235
225
|
}
|
|
236
226
|
|
|
237
227
|
/**
|
|
@@ -262,15 +252,12 @@ export class Auth {
|
|
|
262
252
|
* @return {Promise<GenProviderRedirectUriResponse>} A Promise<GenProviderRedirectUriResponse> object.
|
|
263
253
|
*/
|
|
264
254
|
public async genProviderRedirectUri(params: GenProviderRedirectUriRequest): Promise<GenProviderRedirectUriResponse> {
|
|
265
|
-
let url = `${ApiUrls.PROVIDER_URI_URL}?client_id=${
|
|
266
|
-
|
|
267
|
-
}&
|
|
255
|
+
let url = `${ApiUrls.PROVIDER_URI_URL}?client_id=${this.config.clientId}&provider_id=${
|
|
256
|
+
params.provider_id
|
|
257
|
+
}&redirect_uri=${encodeURIComponent(params.provider_redirect_uri)}&state=${params.state}`
|
|
268
258
|
const { other_params: otherParams } = params
|
|
269
259
|
if (otherParams) {
|
|
270
|
-
if (
|
|
271
|
-
typeof otherParams.sign_out_uri === 'string'
|
|
272
|
-
&& otherParams.sign_out_uri.length > 0
|
|
273
|
-
) {
|
|
260
|
+
if (typeof otherParams.sign_out_uri === 'string' && otherParams.sign_out_uri.length > 0) {
|
|
274
261
|
url += `&other_params[sign_out_uri]=${otherParams.sign_out_uri}`
|
|
275
262
|
}
|
|
276
263
|
}
|
|
@@ -285,13 +272,10 @@ export class Auth {
|
|
|
285
272
|
* @return {Promise<GrantProviderTokenResponse>} A Promise<GrantProviderTokenResponse> object.
|
|
286
273
|
*/
|
|
287
274
|
public async grantProviderToken(params: GrantProviderTokenRequest): Promise<GrantProviderTokenResponse> {
|
|
288
|
-
return this.config.request<GrantProviderTokenResponse>(
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
body: params,
|
|
293
|
-
}
|
|
294
|
-
)
|
|
275
|
+
return this.config.request<GrantProviderTokenResponse>(ApiUrls.PROVIDER_TOKEN_URL, {
|
|
276
|
+
method: 'POST',
|
|
277
|
+
body: params,
|
|
278
|
+
})
|
|
295
279
|
}
|
|
296
280
|
|
|
297
281
|
/**
|
|
@@ -300,13 +284,10 @@ export class Auth {
|
|
|
300
284
|
* @return {Promise<PatchProviderTokenResponse>} A Promise<PatchProviderTokenResponse> object.
|
|
301
285
|
*/
|
|
302
286
|
public async patchProviderToken(params: PatchProviderTokenRequest): Promise<PatchProviderTokenResponse> {
|
|
303
|
-
return this.config.request<PatchProviderTokenResponse>(
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
body: params,
|
|
308
|
-
}
|
|
309
|
-
)
|
|
287
|
+
return this.config.request<PatchProviderTokenResponse>(ApiUrls.PROVIDER_TOKEN_URL, {
|
|
288
|
+
method: 'PATCH',
|
|
289
|
+
body: params,
|
|
290
|
+
})
|
|
310
291
|
}
|
|
311
292
|
|
|
312
293
|
/**
|
|
@@ -315,17 +296,11 @@ export class Auth {
|
|
|
315
296
|
* @return {Promise<Credentials>} A Promise<Credentials> object.
|
|
316
297
|
*/
|
|
317
298
|
public async signInWithProvider(params: SignInWithProviderRequest): Promise<Credentials> {
|
|
318
|
-
const res = this.getParamsByVersion(
|
|
319
|
-
|
|
320
|
-
'
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
res.url,
|
|
324
|
-
{
|
|
325
|
-
method: 'POST',
|
|
326
|
-
body: res.params,
|
|
327
|
-
}
|
|
328
|
-
)
|
|
299
|
+
const res = this.getParamsByVersion(params, 'AUTH_SIGN_IN_WITH_PROVIDER_URL')
|
|
300
|
+
const credentials: Credentials = await this.config.request<Credentials>(res.url, {
|
|
301
|
+
method: 'POST',
|
|
302
|
+
body: res.params,
|
|
303
|
+
})
|
|
329
304
|
await this.config.credentialsClient.setCredentials({
|
|
330
305
|
...credentials,
|
|
331
306
|
version: params?.version || 'v1',
|
|
@@ -350,9 +325,7 @@ export class Auth {
|
|
|
350
325
|
* Get the user profile.
|
|
351
326
|
* @return {Promise<UserProfile>} A Promise<UserProfile> object.
|
|
352
327
|
*/
|
|
353
|
-
public async getUserProfile(params: {
|
|
354
|
-
version?: string;
|
|
355
|
-
}): Promise<UserProfile> {
|
|
328
|
+
public async getUserProfile(params: { version?: string }): Promise<UserProfile> {
|
|
356
329
|
return this.getUserInfo(params)
|
|
357
330
|
}
|
|
358
331
|
|
|
@@ -433,14 +406,11 @@ export class Auth {
|
|
|
433
406
|
* @return {Promise<Credentials>} A Promise<Credentials> object.
|
|
434
407
|
*/
|
|
435
408
|
public async transByProvider(params: TransByProviderRequest): Promise<Credentials> {
|
|
436
|
-
return this.config.request<Credentials>(
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
withCredentials: true,
|
|
442
|
-
}
|
|
443
|
-
)
|
|
409
|
+
return this.config.request<Credentials>(ApiUrls.USER_TRANS_BY_PROVIDER_URL, {
|
|
410
|
+
method: 'PATCH',
|
|
411
|
+
body: params,
|
|
412
|
+
withCredentials: true,
|
|
413
|
+
})
|
|
444
414
|
}
|
|
445
415
|
|
|
446
416
|
/**
|
|
@@ -473,13 +443,10 @@ export class Auth {
|
|
|
473
443
|
* @return {Promise<any>}
|
|
474
444
|
*/
|
|
475
445
|
public async unbindProvider(params: UnbindProviderRequest): Promise<void> {
|
|
476
|
-
return this.config.request<any>(
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
withCredentials: true,
|
|
481
|
-
}
|
|
482
|
-
)
|
|
446
|
+
return this.config.request<any>(`${ApiUrls.PROVIDER_UNBIND_URL}/${params.provider_id}`, {
|
|
447
|
+
method: 'DELETE',
|
|
448
|
+
withCredentials: true,
|
|
449
|
+
})
|
|
483
450
|
}
|
|
484
451
|
|
|
485
452
|
/**
|
|
@@ -567,15 +534,12 @@ export class Auth {
|
|
|
567
534
|
*/
|
|
568
535
|
public async getCurUserVerification(params: GetVerificationRequest): Promise<GetVerificationResponse> {
|
|
569
536
|
params.target = 'CUR_USER'
|
|
570
|
-
return this.config.request<GetVerificationResponse>(
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
withCaptcha: true,
|
|
577
|
-
}
|
|
578
|
-
)
|
|
537
|
+
return this.config.request<GetVerificationResponse>(ApiUrls.VERIFICATION_URL, {
|
|
538
|
+
method: 'POST',
|
|
539
|
+
body: params,
|
|
540
|
+
withCredentials: true,
|
|
541
|
+
withCaptcha: true,
|
|
542
|
+
})
|
|
579
543
|
}
|
|
580
544
|
|
|
581
545
|
/**
|
|
@@ -584,16 +548,13 @@ export class Auth {
|
|
|
584
548
|
* @return {Promise<GetVerificationResponse>} A Promise<GetVerificationResponse> object.
|
|
585
549
|
*/
|
|
586
550
|
public async changeBindedProvider(params: ChangeBindedProviderRequest): Promise<ChangeBindedProviderResponse> {
|
|
587
|
-
return this.config.request<ChangeBindedProviderResponse>(
|
|
588
|
-
|
|
589
|
-
{
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
withCredentials: true,
|
|
595
|
-
}
|
|
596
|
-
)
|
|
551
|
+
return this.config.request<ChangeBindedProviderResponse>(`${ApiUrls.PROVIDER_LIST}/${params.provider_id}/trans`, {
|
|
552
|
+
method: 'POST',
|
|
553
|
+
body: {
|
|
554
|
+
provider_trans_token: params.trans_token,
|
|
555
|
+
},
|
|
556
|
+
withCredentials: true,
|
|
557
|
+
})
|
|
597
558
|
}
|
|
598
559
|
|
|
599
560
|
/**
|
|
@@ -618,13 +579,10 @@ export class Auth {
|
|
|
618
579
|
// let url = new URL(ApiUrls.USER_QUERY_URL);
|
|
619
580
|
const searchParams = new URLSearchParams(params as any)
|
|
620
581
|
// url.search = searchParams.toString();
|
|
621
|
-
return this.config.request<QueryUserProfileResponse>(
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
withCredentials: true,
|
|
626
|
-
}
|
|
627
|
-
)
|
|
582
|
+
return this.config.request<QueryUserProfileResponse>(`${ApiUrls.USER_QUERY_URL}?${searchParams.toString()}`, {
|
|
583
|
+
method: 'GET',
|
|
584
|
+
withCredentials: true,
|
|
585
|
+
})
|
|
628
586
|
}
|
|
629
587
|
|
|
630
588
|
/**
|
|
@@ -639,9 +597,7 @@ export class Auth {
|
|
|
639
597
|
* SignInWithCustomTicket custom signIn
|
|
640
598
|
* @constructor
|
|
641
599
|
*/
|
|
642
|
-
public async signInWithCustomTicket(params?: {
|
|
643
|
-
version?: string;
|
|
644
|
-
}): Promise<Credentials> {
|
|
600
|
+
public async signInWithCustomTicket(params?: { version?: string }): Promise<Credentials> {
|
|
645
601
|
const customTicket = await this.getCustomSignTicketFn()
|
|
646
602
|
return this.signInWithProvider({
|
|
647
603
|
...params,
|
|
@@ -689,12 +645,9 @@ export class Auth {
|
|
|
689
645
|
public async checkIfUserExist(params: CheckIfUserExistRequest): Promise<CheckIfUserExistResponse> {
|
|
690
646
|
const searchParams = new URLSearchParams(params as any)
|
|
691
647
|
|
|
692
|
-
return this.config.request<CheckIfUserExistResponse>(
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
method: 'GET',
|
|
696
|
-
}
|
|
697
|
-
)
|
|
648
|
+
return this.config.request<CheckIfUserExistResponse>(`${ApiUrls.CHECK_IF_USER_EXIST}?${searchParams.toString()}`, {
|
|
649
|
+
method: 'GET',
|
|
650
|
+
})
|
|
698
651
|
}
|
|
699
652
|
|
|
700
653
|
public async loginScope(): Promise<string> {
|
|
@@ -706,7 +659,7 @@ export class Auth {
|
|
|
706
659
|
}
|
|
707
660
|
|
|
708
661
|
public async refreshTokenForce(params: { version?: string }) {
|
|
709
|
-
const credentials: Credentials =
|
|
662
|
+
const credentials: Credentials = await this.config.credentialsClient.getCredentials()
|
|
710
663
|
return await this.config.credentialsClient.refreshToken({
|
|
711
664
|
...credentials,
|
|
712
665
|
version: params?.version || 'v1',
|
|
@@ -773,4 +726,24 @@ export class Auth {
|
|
|
773
726
|
},
|
|
774
727
|
})
|
|
775
728
|
}
|
|
729
|
+
|
|
730
|
+
/**
|
|
731
|
+
* get provider sub type
|
|
732
|
+
* @returns
|
|
733
|
+
*/
|
|
734
|
+
public async varifyCaptchaData({ token, key }: { token: string; key: string }) {
|
|
735
|
+
return this.config.request<{ captcha_token: string; expires_in: number }>(ApiUrls.VARIFY_CAPTCHA_DATA_URL, {
|
|
736
|
+
method: 'POST',
|
|
737
|
+
body: { token, key },
|
|
738
|
+
withCredentials: false,
|
|
739
|
+
})
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
public async createCaptchaData({ state, redirect_uri = undefined }) {
|
|
743
|
+
return this.config.request<{ captcha_token: string; expires_in: number }>(ApiUrls.CAPTCHA_DATA_URL, {
|
|
744
|
+
method: 'POST',
|
|
745
|
+
body: { state, redirect_uri },
|
|
746
|
+
withCredentials: false,
|
|
747
|
+
})
|
|
748
|
+
}
|
|
776
749
|
}
|
package/src/auth/consts.ts
CHANGED
|
@@ -15,6 +15,10 @@ export enum ApiUrls {
|
|
|
15
15
|
USER_TRANS_BY_PROVIDER_URL = '/auth/v1/user/trans/by/provider',
|
|
16
16
|
VERIFICATION_URL = '/auth/v1/verification',
|
|
17
17
|
VERIFY_URL = '/auth/v1/verification/verify',
|
|
18
|
+
CAPTCHA_DATA_URL = '/auth/v1/captcha/data',
|
|
19
|
+
VARIFY_CAPTCHA_DATA_URL = '/auth/v1/captcha/data/verify',
|
|
20
|
+
GET_CAPTCHA_URL = '/auth/v1/captcha/init',
|
|
21
|
+
|
|
18
22
|
PROVIDER_LIST = '/auth/v1/user/provider',
|
|
19
23
|
PROVIDER_UNBIND_URL = '/auth/v1/user/provider',
|
|
20
24
|
CHECK_PWD_URL = '/auth/v1/user/sudo',
|
|
@@ -25,7 +29,7 @@ export enum ApiUrls {
|
|
|
25
29
|
AUTH_GET_DEVICE_CODE = '/auth/v1/device/code',
|
|
26
30
|
CHECK_USERNAME = '/auth/v1/checkUsername',
|
|
27
31
|
CHECK_IF_USER_EXIST = '/auth/v1/checkIfUserExist',
|
|
28
|
-
GET_PROVIDER_TYPE = '/auth/v1/mgr/provider/providerSubType'
|
|
32
|
+
GET_PROVIDER_TYPE = '/auth/v1/mgr/provider/providerSubType',
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
export enum ApiUrlsV2 {
|
|
@@ -34,7 +38,7 @@ export enum ApiUrlsV2 {
|
|
|
34
38
|
USER_ME_URL = '/auth/v2/user/me',
|
|
35
39
|
VERIFY_URL = '/auth/v2/signin/verificationcode',
|
|
36
40
|
AUTH_SIGN_IN_WITH_PROVIDER_URL = '/auth/v2/signin/with/provider',
|
|
37
|
-
AUTH_PUBLIC_KEY = '/auth/v2/signin/publichkey'
|
|
41
|
+
AUTH_PUBLIC_KEY = '/auth/v2/signin/publichkey',
|
|
38
42
|
}
|
|
39
43
|
|
|
40
44
|
export enum VerificationUsages {
|
package/src/captcha/captcha.ts
CHANGED
|
@@ -1,25 +1,27 @@
|
|
|
1
|
+
import { ApiUrls, ErrorType } from '../auth/consts'
|
|
1
2
|
import { SimpleStorage, RequestFunction } from '../oauth2client/interface'
|
|
2
3
|
import { AuthClientRequestOptions } from '../oauth2client/models'
|
|
3
4
|
import { defaultStorage } from '../oauth2client/oauth2client'
|
|
5
|
+
import { isInMpWebView, isMp } from '../utils/mp'
|
|
4
6
|
|
|
5
7
|
export interface CaptchaOptions {
|
|
6
8
|
clientId: string
|
|
7
|
-
request: RequestFunction
|
|
8
|
-
storage: SimpleStorage
|
|
9
|
+
request: RequestFunction
|
|
10
|
+
storage: SimpleStorage
|
|
9
11
|
// 打开网页并通过URL回调获取 CaptchaToken,针对不通的平台,该函数可以自定义实现, 默认集成浏览器端认证
|
|
10
|
-
openURIWithCallback?: OpenURIWithCallbackFuction
|
|
12
|
+
openURIWithCallback?: OpenURIWithCallbackFuction
|
|
11
13
|
}
|
|
12
14
|
|
|
13
|
-
type OpenURIWithCallbackFuction = (url: string) => Promise<CaptchaToken
|
|
15
|
+
type OpenURIWithCallbackFuction = (url: string) => Promise<CaptchaToken>
|
|
14
16
|
|
|
15
17
|
export interface CaptchaToken {
|
|
16
18
|
captcha_token: string
|
|
17
19
|
expires_in: number
|
|
18
|
-
expires_at?: Date | null
|
|
20
|
+
expires_at?: Date | null
|
|
19
21
|
}
|
|
20
22
|
|
|
21
23
|
export interface CaptchaRequestOptions extends AuthClientRequestOptions {
|
|
22
|
-
withCaptcha?: boolean
|
|
24
|
+
withCaptcha?: boolean
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
export interface GetCaptchaResponse {
|
|
@@ -28,8 +30,6 @@ export interface GetCaptchaResponse {
|
|
|
28
30
|
url?: string
|
|
29
31
|
}
|
|
30
32
|
|
|
31
|
-
const GET_CAPTCHA_URL = '/auth/v1/captcha/init'
|
|
32
|
-
|
|
33
33
|
export class Captcha {
|
|
34
34
|
private config: CaptchaOptions
|
|
35
35
|
private tokenSectionName: string
|
|
@@ -45,6 +45,7 @@ export class Captcha {
|
|
|
45
45
|
if (!opts.storage) {
|
|
46
46
|
opts.storage = defaultStorage
|
|
47
47
|
}
|
|
48
|
+
|
|
48
49
|
this.config = opts
|
|
49
50
|
this.tokenSectionName = `captcha_${opts.clientId}`
|
|
50
51
|
}
|
|
@@ -54,10 +55,7 @@ export class Captcha {
|
|
|
54
55
|
* @param {string} url
|
|
55
56
|
* @param {AuthClientRequestOptions} options
|
|
56
57
|
*/
|
|
57
|
-
public async request<T>(
|
|
58
|
-
url: string,
|
|
59
|
-
options?: CaptchaRequestOptions,
|
|
60
|
-
): Promise<T> {
|
|
58
|
+
public async request<T>(url: string, options?: CaptchaRequestOptions): Promise<T> {
|
|
61
59
|
if (!options) {
|
|
62
60
|
options = {}
|
|
63
61
|
}
|
|
@@ -74,8 +72,8 @@ export class Captcha {
|
|
|
74
72
|
try {
|
|
75
73
|
resp = await this.config.request<T>(reqURL, options)
|
|
76
74
|
} catch (err) {
|
|
77
|
-
if (err.error ===
|
|
78
|
-
url = await this.appendCaptchaTokenToURL(url, state, err.error ===
|
|
75
|
+
if (err.error === ErrorType.CAPTCHA_REQUIRED || err.error === ErrorType.CAPTCHA_INVALID) {
|
|
76
|
+
url = await this.appendCaptchaTokenToURL(url, state, err.error === ErrorType.CAPTCHA_INVALID)
|
|
79
77
|
return this.config.request<T>(url, options)
|
|
80
78
|
}
|
|
81
79
|
return Promise.reject(err)
|
|
@@ -84,16 +82,18 @@ export class Captcha {
|
|
|
84
82
|
}
|
|
85
83
|
|
|
86
84
|
private getDefaultOpenURIWithCallback(): OpenURIWithCallbackFuction {
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
if (!isMp() && !isInMpWebView()) {
|
|
86
|
+
if (window.location.search.indexOf('__captcha') > 0) {
|
|
87
|
+
document.body.style.display = 'none'
|
|
88
|
+
}
|
|
89
|
+
if (document.getElementById('captcha_panel_wrap') === null) {
|
|
90
|
+
const elementDiv = document.createElement('div')
|
|
91
|
+
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;'
|
|
92
|
+
elementDiv.setAttribute('id', 'captcha_panel_wrap')
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
document.body.appendChild(elementDiv)
|
|
95
|
+
}, 0)
|
|
96
|
+
}
|
|
97
97
|
}
|
|
98
98
|
return this.defaultOpenURIWithCallback
|
|
99
99
|
}
|
|
@@ -101,13 +101,27 @@ export class Captcha {
|
|
|
101
101
|
/**
|
|
102
102
|
* 默认通过浏览器打开网页并获取回调
|
|
103
103
|
*/
|
|
104
|
-
private async defaultOpenURIWithCallback(
|
|
104
|
+
private async defaultOpenURIWithCallback(
|
|
105
|
+
url: string,
|
|
106
|
+
opts?: { width?: string; height?: string },
|
|
107
|
+
): Promise<CaptchaToken> {
|
|
108
|
+
const { width = '355px', height = '355px' } = opts || {}
|
|
109
|
+
|
|
110
|
+
const matched = url.match(/^(data:.*)$/)
|
|
111
|
+
if (matched) {
|
|
112
|
+
return Promise.reject({
|
|
113
|
+
error: ErrorType.UNIMPLEMENTED,
|
|
114
|
+
error_description: 'need to impl captcha data',
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
105
118
|
const target = document.getElementById('captcha_panel_wrap')
|
|
106
119
|
const iframe = document.createElement('iframe')
|
|
107
120
|
target.innerHTML = ''
|
|
121
|
+
|
|
108
122
|
iframe.setAttribute('src', url)
|
|
109
123
|
iframe.setAttribute('id', 'review-panel-iframe')
|
|
110
|
-
iframe.style.cssText =
|
|
124
|
+
iframe.style.cssText = `min-width:${width};display:block;height:${height};margin:0 auto;background-color: rgb(255, 255, 255);border: none;`
|
|
111
125
|
target.appendChild(iframe)
|
|
112
126
|
target.style.display = 'block'
|
|
113
127
|
return new Promise<CaptchaToken>((resolve, reject) => {
|
|
@@ -115,12 +129,7 @@ export class Captcha {
|
|
|
115
129
|
try {
|
|
116
130
|
const windowLocation = window.location
|
|
117
131
|
const iframeLocation = iframe.contentWindow.location
|
|
118
|
-
if (
|
|
119
|
-
iframeLocation.host
|
|
120
|
-
+ iframeLocation.pathname
|
|
121
|
-
=== windowLocation.host
|
|
122
|
-
+ windowLocation.pathname
|
|
123
|
-
) {
|
|
132
|
+
if (iframeLocation.host + iframeLocation.pathname === windowLocation.host + windowLocation.pathname) {
|
|
124
133
|
target.style.display = 'none'
|
|
125
134
|
const iframeUrlParams = new URLSearchParams(iframeLocation.search)
|
|
126
135
|
const captchToken = iframeUrlParams.get('captcha_token')
|
|
@@ -153,23 +162,50 @@ export class Captcha {
|
|
|
153
162
|
return captchaToken
|
|
154
163
|
}
|
|
155
164
|
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
let captchaTokenResp: {
|
|
166
|
+
url?: string
|
|
167
|
+
captcha_token?: string
|
|
168
|
+
expires_in?: number
|
|
169
|
+
}
|
|
170
|
+
if (!isMp() && !isInMpWebView()) {
|
|
171
|
+
const redirect_uri = `${window.location.origin + window.location.pathname}?__captcha=on`
|
|
172
|
+
captchaTokenResp = await this.config.request<GetCaptchaResponse>(ApiUrls.GET_CAPTCHA_URL, {
|
|
173
|
+
method: 'POST',
|
|
174
|
+
body: {
|
|
175
|
+
client_id: this.config.clientId,
|
|
176
|
+
redirect_uri,
|
|
177
|
+
state,
|
|
178
|
+
},
|
|
179
|
+
withCredentials: false,
|
|
180
|
+
})
|
|
181
|
+
if (captchaTokenResp.captcha_token) {
|
|
182
|
+
const captchaToken = {
|
|
183
|
+
captcha_token: captchaTokenResp.captcha_token,
|
|
184
|
+
expires_in: captchaTokenResp.expires_in,
|
|
185
|
+
}
|
|
186
|
+
this.saveCaptchaToken(captchaToken)
|
|
187
|
+
return captchaTokenResp.captcha_token
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
/**
|
|
191
|
+
* https://iwiki.woa.com/p/4010699417
|
|
192
|
+
*/
|
|
193
|
+
const captchaDataResp = await this.config.request<{
|
|
194
|
+
data: string
|
|
195
|
+
type: 'image'
|
|
196
|
+
token: string
|
|
197
|
+
expires_in: number
|
|
198
|
+
}>(ApiUrls.CAPTCHA_DATA_URL, {
|
|
199
|
+
method: 'POST',
|
|
200
|
+
body: {
|
|
201
|
+
state,
|
|
202
|
+
redirect_uri: '',
|
|
203
|
+
},
|
|
204
|
+
withCredentials: false,
|
|
205
|
+
})
|
|
206
|
+
captchaTokenResp = {
|
|
207
|
+
url: `${captchaDataResp.data}?state=${encodeURIComponent(state)}&token=${encodeURIComponent(captchaDataResp.token,)}`,
|
|
170
208
|
}
|
|
171
|
-
this.saveCaptchaToken(captchaToken)
|
|
172
|
-
return captchaTokenResp.captcha_token
|
|
173
209
|
}
|
|
174
210
|
const captchaToken = await this.config.openURIWithCallback(captchaTokenResp.url)
|
|
175
211
|
this.saveCaptchaToken(captchaToken)
|
|
@@ -187,13 +223,13 @@ export class Captcha {
|
|
|
187
223
|
}
|
|
188
224
|
|
|
189
225
|
private async saveCaptchaToken(token: CaptchaToken) {
|
|
190
|
-
token.expires_at = new Date(Date.now() + (token.expires_in - 10) * 1000
|
|
226
|
+
token.expires_at = new Date(Date.now() + (token.expires_in - 10) * 1000)
|
|
191
227
|
const tokenStr: string = JSON.stringify(token)
|
|
192
228
|
await this.config.storage.setItem(this.tokenSectionName, tokenStr)
|
|
193
229
|
}
|
|
194
230
|
|
|
195
231
|
private async findCaptchaToken(): Promise<string> {
|
|
196
|
-
const tokenStr: string = await this.config.storage.getItem(this.tokenSectionName
|
|
232
|
+
const tokenStr: string = await this.config.storage.getItem(this.tokenSectionName)
|
|
197
233
|
if (tokenStr !== undefined && tokenStr !== null) {
|
|
198
234
|
try {
|
|
199
235
|
const captchaToken = JSON.parse(tokenStr)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ErrorType as _ErrorType } from '../auth/consts'
|
|
1
2
|
export enum Syntax {
|
|
2
3
|
CLIENT_ID = 'client_id',
|
|
3
4
|
CLIENT_SECRET = 'client_secret',
|
|
@@ -38,8 +39,8 @@ export enum ErrorType {
|
|
|
38
39
|
UNAVAILABLE = 'unavailable',
|
|
39
40
|
DATA_LOSS = 'data_loss',
|
|
40
41
|
// CommonError
|
|
41
|
-
CAPTCHA_REQUIRED =
|
|
42
|
-
CAPTCHA_INVALID =
|
|
42
|
+
CAPTCHA_REQUIRED = _ErrorType.CAPTCHA_REQUIRED,
|
|
43
|
+
CAPTCHA_INVALID = _ErrorType.CAPTCHA_INVALID,
|
|
43
44
|
INVALID_PASSWORD = 'invalid_password',
|
|
44
45
|
INVALID_STATUS = 'invalid_status',
|
|
45
46
|
USER_PENDING = 'user_pending',
|